next steps
This commit is contained in:
parent
a70a03b7a8
commit
6c32f09c03
14
.vscode/settings.json
vendored
14
.vscode/settings.json
vendored
@ -71,6 +71,18 @@
|
|||||||
"cinttypes": "cpp",
|
"cinttypes": "cpp",
|
||||||
"typeinfo": "cpp",
|
"typeinfo": "cpp",
|
||||||
"valarray": "cpp",
|
"valarray": "cpp",
|
||||||
"variant": "cpp"
|
"variant": "cpp",
|
||||||
|
"int.h": "c",
|
||||||
|
"macros.h": "c",
|
||||||
|
"stdint.h": "c",
|
||||||
|
"type.h": "c",
|
||||||
|
"stdlib.h": "c",
|
||||||
|
"bitset": "cpp",
|
||||||
|
"codecvt": "cpp",
|
||||||
|
"forward_list": "cpp",
|
||||||
|
"set": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"source_location": "cpp",
|
||||||
|
"shared_mutex": "cpp"
|
||||||
},
|
},
|
||||||
}
|
}
|
@ -1,8 +1,12 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
class Expr;
|
class Expr;
|
||||||
|
class Type;
|
||||||
|
|
||||||
|
typedef std::pair<std::string, Type *> FnArg;
|
||||||
|
|
||||||
class ASTNode
|
class ASTNode
|
||||||
{
|
{
|
||||||
@ -12,38 +16,127 @@ class Stmt : public ASTNode
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
class Decl : public Stmt
|
class Module : public ASTNode
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Decl(const std::string &identifier, const Expr *value)
|
Module(const std::vector<Stmt *> &stmts) : stmts(std::move(stmts)) {}
|
||||||
: identifier(identifier), value(value) {}
|
const std::vector<Stmt *> stmts;
|
||||||
|
};
|
||||||
|
|
||||||
const std::string identifier;
|
class ValDecl : public Stmt
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ValDecl(const std::string &name, const Type *type, const Expr *value)
|
||||||
|
: name(name), type(type), value(value) {}
|
||||||
|
|
||||||
|
const std::string name;
|
||||||
|
const Type *type;
|
||||||
const Expr *value;
|
const Expr *value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class FnDecl : public Stmt
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FnDecl(const std::string &name, const std::vector<FnArg> &args, const Type *returnType, const Expr *body)
|
||||||
|
: name(name), args(std::move(args)), returnType(returnType), body(body) {}
|
||||||
|
|
||||||
|
const std::string name;
|
||||||
|
const std::vector<FnArg> args;
|
||||||
|
const Type *returnType;
|
||||||
|
const Expr *body;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Type : public ASTNode
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
class TupleType : public Type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TupleType(const std::vector<Type *> &types) : types(types) {}
|
||||||
|
const std::vector<Type *> types;
|
||||||
|
};
|
||||||
|
|
||||||
|
class FunctionType : public Type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
FunctionType(const std::vector<Type *> &from, const Type *to)
|
||||||
|
: from(std::move(from)), to(to) {}
|
||||||
|
|
||||||
|
const std::vector<Type *> from;
|
||||||
|
const Type *to;
|
||||||
|
};
|
||||||
|
|
||||||
|
class NamedType : public Type
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NamedType(const std::string &name) : name(name) {}
|
||||||
|
const std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
class Expr : public ASTNode
|
class Expr : public ASTNode
|
||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CallExpr : public Expr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
CallExpr(const Expr *callee, const std::vector<Expr *> &args)
|
||||||
|
: callee(callee), args(std::move(args)) {}
|
||||||
|
|
||||||
|
const Expr *callee;
|
||||||
|
const std::vector<Expr *> args;
|
||||||
|
};
|
||||||
|
|
||||||
|
class UnaryExpr : public Expr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
UnaryExpr(const std::string &op, const Expr *expr)
|
||||||
|
: op(op), expr(expr) {}
|
||||||
|
|
||||||
|
const std::string op;
|
||||||
|
const Expr *expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BinExpr : public Expr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
BinExpr(const Expr *left, const std::string &op, const Expr *right)
|
||||||
|
: left(left), op(op), right(right) {}
|
||||||
|
|
||||||
|
const Expr *left;
|
||||||
|
const std::string op;
|
||||||
|
const Expr *right;
|
||||||
|
};
|
||||||
|
|
||||||
|
class PrefExpr : public Expr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PrefExpr(const Expr *expr) : expr(expr) {}
|
||||||
|
|
||||||
|
const Expr *expr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Identifier : public Expr
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Identifier(const std::string &name) : name(name) {}
|
||||||
|
|
||||||
|
const std::string name;
|
||||||
|
};
|
||||||
|
|
||||||
class IntValue : public Expr
|
class IntValue : public Expr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const long value;
|
|
||||||
IntValue(const long value) : value(value) {}
|
IntValue(const long value) : value(value) {}
|
||||||
|
|
||||||
|
const long value;
|
||||||
};
|
};
|
||||||
|
|
||||||
class FloatValue : public Expr
|
class FloatValue : public Expr
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
const double value;
|
|
||||||
FloatValue(const double value) : value(value) {}
|
FloatValue(const double value) : value(value) {}
|
||||||
};
|
|
||||||
|
|
||||||
class Function : public Expr
|
const double value;
|
||||||
{
|
|
||||||
};
|
|
||||||
|
|
||||||
class List : public Expr
|
|
||||||
{
|
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@ public:
|
|||||||
|
|
||||||
std::string file;
|
std::string file;
|
||||||
yy::location location;
|
yy::location location;
|
||||||
|
Module *module;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define YY_DECL yy::parser::symbol_type yylex(ParserDriver &driver)
|
#define YY_DECL yy::parser::symbol_type yylex(ParserDriver &driver)
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
#define yyterminate() yy::parser::make_END(yy::location())
|
#define yyterminate() yy::parser::make_END(yy::location())
|
||||||
|
|
||||||
#define _token(token) yy::parser::make_##token(driver.location)
|
#define _token(token) yy::parser::make_##token(yytext, driver.location)
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%option noyywrap nounput noinput batch debug
|
%option noyywrap nounput noinput batch
|
||||||
|
|
||||||
digit [0-9]
|
digit [0-9]
|
||||||
bindigit [0-1]
|
bindigit [0-1]
|
||||||
@ -16,6 +16,8 @@ hexdigit [0-9a-fA-F]
|
|||||||
|
|
||||||
letter [a-zA-Z]
|
letter [a-zA-Z]
|
||||||
|
|
||||||
|
opchar ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\")
|
||||||
|
|
||||||
whitespace [ \n\t\r\v]+
|
whitespace [ \n\t\r\v]+
|
||||||
|
|
||||||
%%
|
%%
|
||||||
@ -27,14 +29,18 @@ whitespace [ \n\t\r\v]+
|
|||||||
|
|
||||||
{digit}*"."{digit}+ { return yy::parser::make_FLOAT(std::strtod(yytext, NULL), driver.location); }
|
{digit}*"."{digit}+ { return yy::parser::make_FLOAT(std::strtod(yytext, NULL), driver.location); }
|
||||||
|
|
||||||
// TODO: operator '==' won't work this way
|
|
||||||
"->" { return _token(R_ARR); }
|
{opchar}+ { std::string text = yytext;
|
||||||
"<-" { return _token(L_ARR); }
|
if (text == "=") return _token(EQUALS);
|
||||||
|
if (text == "->") return _token(RARR);
|
||||||
|
return _token(OPERATOR); }
|
||||||
|
|
||||||
|
"," { return _token(COMMA); }
|
||||||
";" { return _token(SEMI); }
|
";" { return _token(SEMI); }
|
||||||
"=" { return _token(EQUALS); }
|
"(" { return _token(LPAREN); }
|
||||||
|
")" { return _token(RPAREN); }
|
||||||
("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\")+ { return _token(OPERATOR); }
|
"[" { return _token(LBRACKET); }
|
||||||
|
"]" { return _token(RBRACKET); }
|
||||||
|
|
||||||
"fn" { return _token(FN); }
|
"fn" { return _token(FN); }
|
||||||
"unop" { return _token(UNOP); }
|
"unop" { return _token(UNOP); }
|
||||||
@ -44,7 +50,9 @@ whitespace [ \n\t\r\v]+
|
|||||||
"declare" { return _token(DECLARE); }
|
"declare" { return _token(DECLARE); }
|
||||||
|
|
||||||
|
|
||||||
{letter}({digit}|{letter})* { return yy::parser::make_IDENTIFIER(yytext, driver.location); }
|
{letter}({digit}|{letter})* { return _token(IDENTIFIER); }
|
||||||
|
|
||||||
|
<<EOF>> { return yy::parser::make_END(driver.location); }
|
||||||
|
|
||||||
{whitespace} { ; }
|
{whitespace} { ; }
|
||||||
|
|
||||||
|
@ -32,15 +32,19 @@ class ParserDriver;
|
|||||||
%token <long> INT "integer literal"
|
%token <long> INT "integer literal"
|
||||||
%token <double> FLOAT "float literal"
|
%token <double> FLOAT "float literal"
|
||||||
|
|
||||||
%token <std::string> OPERATOR "operator";
|
%token <std::string>
|
||||||
%token <std::string> IDENTIFIER "identifier"
|
OPERATOR "operator"
|
||||||
|
IDENTIFIER "identifier"
|
||||||
|
|
||||||
%token L_ARR "<-"
|
RARR "->"
|
||||||
%token R_ARR "->"
|
EQUALS "="
|
||||||
%token EQUALS "="
|
COMMA ","
|
||||||
%token SEMI ";"
|
SEMI ";"
|
||||||
|
LPAREN "("
|
||||||
|
RPAREN ")"
|
||||||
|
LBRACKET "["
|
||||||
|
RBRACKET "]"
|
||||||
|
|
||||||
%token
|
|
||||||
FN "fn"
|
FN "fn"
|
||||||
UNOP "unop"
|
UNOP "unop"
|
||||||
BINOP "binop"
|
BINOP "binop"
|
||||||
@ -52,47 +56,144 @@ class ParserDriver;
|
|||||||
%token END 0 "end of file"
|
%token END 0 "end of file"
|
||||||
|
|
||||||
%type <std::vector<Stmt *>> stmts;
|
%type <std::vector<Stmt *>> stmts;
|
||||||
%type <Stmt *> stmt;
|
%type <Stmt *>
|
||||||
%type <Decl *> decl;
|
stmt
|
||||||
%type <Expr *> expr;
|
decl
|
||||||
%type <Value *> literal;
|
;
|
||||||
|
|
||||||
%type <std::string> operator;
|
%type <FnDecl *> fnDecl;
|
||||||
%type <std::string> identifier;
|
%type <ValDecl *> valDecl;
|
||||||
%type <std::string> keyword;
|
|
||||||
|
%type <Type *>
|
||||||
|
type
|
||||||
|
type0
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <std::vector<Expr *>>
|
||||||
|
exprs
|
||||||
|
args
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <Expr *>
|
||||||
|
expr
|
||||||
|
expr3
|
||||||
|
expr2
|
||||||
|
expr1
|
||||||
|
expr0
|
||||||
|
literal
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <FnArg> fnArg;
|
||||||
|
%type <std::vector<FnArg>>
|
||||||
|
fnArgs
|
||||||
|
fnArgs0
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <std::vector<std::string>>
|
||||||
|
lambdaArgs
|
||||||
|
identifiers
|
||||||
|
;
|
||||||
|
|
||||||
|
%type <std::string>
|
||||||
|
operator
|
||||||
|
identifier
|
||||||
|
keyword
|
||||||
|
;
|
||||||
|
|
||||||
|
%start module
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
module: stmts;
|
module: stmts END { driver.module = new Module($1); };
|
||||||
|
|
||||||
stmts: stmt { $$ = std::vector<Stmt *>(); $$.push_back($1); }
|
stmts: stmt { $$ = std::vector<Stmt *>(); $$.push_back($1); }
|
||||||
| stmts stmt { $1.push_back($2); $$ = std::move($1); }
|
| stmts stmt { $1.push_back($2); $$ = std::move($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
stmt: decl { $$ = $1; }
|
stmt: decl;
|
||||||
|
|
||||||
|
decl: valDecl { $$ = $1; }
|
||||||
|
| fnDecl { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
decl: VAL identifier "=" expr ";" { $$ = new Decl($2, $4); }
|
valDecl: VAL identifier "=" expr ";" { $$ = new ValDecl($2, nullptr, $4); }
|
||||||
|
| VAL identifier type "=" expr ";" { $$ = new ValDecl($2, $3, $5); }
|
||||||
;
|
;
|
||||||
|
|
||||||
expr: literal { $$ = $1; }
|
fnDecl: FN identifier "[" fnArgs "]" type "=" expr ";" { $$ = new FnDecl($2, $4, $6, $8); }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
fnArgs: %empty { $$ = std::vector<FnArg>(); }
|
||||||
|
| fnArgs0 { $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
fnArgs0: fnArg { $$ = std::vector<FnArg>(); $$.push_back($1); }
|
||||||
|
| fnArgs0 "," fnArg { $$.push_back($3); $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
fnArg: identifier type { $$ = FnArg($1, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
type: type0
|
||||||
|
;
|
||||||
|
|
||||||
|
type0: identifier { $$ = new NamedType($1); }
|
||||||
|
| "(" type ")" { $$ = $2; }
|
||||||
|
;
|
||||||
|
|
||||||
|
exprs: expr { $$ = std::vector<Expr *>(); $$.push_back($1); }
|
||||||
|
| exprs "," expr { $1.push_back($3); $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
expr: expr3 { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
expr3: expr2 { $$ = $1; }
|
||||||
|
| "[" lambdaArgs "]" "->" expr { $$ = NULL; }
|
||||||
|
;
|
||||||
|
|
||||||
|
expr2: expr1 { $$ = $1; }
|
||||||
|
| expr2 operator expr1 { $$ = new BinExpr($1, $2, $3); }
|
||||||
|
;
|
||||||
|
|
||||||
|
expr1: expr0 { $$ = $1; }
|
||||||
|
| operator expr1 { $$ = new UnaryExpr($1, $2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
expr0: literal { $$ = $1; }
|
||||||
|
| identifier { $$ = new Identifier($1); }
|
||||||
|
| expr0 "[" args "]" { $$ = new CallExpr($1, $3); }
|
||||||
|
| "(" expr ")" { $$ = new PrefExpr($2); }
|
||||||
|
;
|
||||||
|
|
||||||
|
lambdaArgs: %empty { $$ = std::vector<std::string>(); }
|
||||||
|
| identifiers { $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
args: %empty { $$ = std::vector<Expr *>(); }
|
||||||
|
| exprs { $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
literal: INT { $$ = new IntValue($1); }
|
literal: INT { $$ = new IntValue($1); }
|
||||||
| FLOAT { $$ = new FloatValue($1); }
|
| FLOAT { $$ = new FloatValue($1); }
|
||||||
;
|
;
|
||||||
|
|
||||||
operator: L_ARR { $$ = $1; }
|
operator: "->" { $$ = $1; }
|
||||||
| R_ARR { $$ = $1; }
|
| "=" { $$ = $1; }
|
||||||
| EQUALS { $$ = $1; }
|
|
||||||
| OPERATOR { $$ = $1; }
|
| OPERATOR { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
|
identifiers: identifier { $$ = std::vector<std::string>(); $$.push_back($1); }
|
||||||
|
| identifiers "," identifier { $1.push_back($3); $$ = std::move($1); }
|
||||||
|
;
|
||||||
|
|
||||||
identifier: keyword { $$ = $1; }
|
identifier: keyword { $$ = $1; }
|
||||||
| IDENTIFIER { $$ = $1; }
|
| IDENTIFIER { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
keyword: FN { $$ = $1; }
|
keyword: FN { $$ = $1; }
|
||||||
|
| VAL { $$ = $1; }
|
||||||
| UNOP { $$ = $1; }
|
| UNOP { $$ = $1; }
|
||||||
| BINOP { $$ = $1; }
|
| BINOP { $$ = $1; }
|
||||||
| IMPORT { $$ = $1; }
|
| IMPORT { $$ = $1; }
|
||||||
@ -101,6 +202,6 @@ keyword: FN { $$ = $1; }
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
void yy::parser::error (const location_type& l, const std::string& m) {
|
void yy::parser::error(const location_type& l, const std::string& m) {
|
||||||
std::cerr << l << ": " << m << '\n';
|
std::cerr << l << ": " << m << '\n';
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,30 @@
|
|||||||
#include <string>
|
#include "ParserDriver.h"
|
||||||
|
|
||||||
int main()
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
std::stringstream readFile(const std::string &path)
|
||||||
{
|
{
|
||||||
|
std::ifstream t(path);
|
||||||
|
std::stringstream buffer;
|
||||||
|
buffer << t.rdbuf();
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc != 2)
|
||||||
|
{
|
||||||
|
std::cout << "Usage:" << std::endl
|
||||||
|
<< "\t" << argv[0] << " <path/to/file>" << std::endl;
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto buf = readFile(argv[1]);
|
||||||
|
auto parser = ParserDriver();
|
||||||
|
parser.parse(buf.str());
|
||||||
|
|
||||||
|
auto fn = (FnDecl *)parser.module->stmts.at(0);
|
||||||
|
std::cout << fn->name << std::endl;
|
||||||
}
|
}
|
||||||
|
1
examples/42.plsm
Normal file
1
examples/42.plsm
Normal file
@ -0,0 +1 @@
|
|||||||
|
fn main[] Int = 42;
|
@ -1,30 +1,29 @@
|
|||||||
type Bool = class {
|
type Bool = class {
|
||||||
declare unop ! -> Bool;
|
declare unop ! Bool;
|
||||||
|
|
||||||
declare binop &&(b Bool) -> Bool;
|
declare binop &&(b Bool) Bool;
|
||||||
declare binop ||(b Bool) -> Bool;
|
declare binop ||(b Bool) Bool;
|
||||||
};
|
};
|
||||||
|
|
||||||
type Int = class {
|
type Int = class {
|
||||||
declare unop + -> Int;
|
declare unop + Int;
|
||||||
declare unop - -> Int;
|
declare unop - Int;
|
||||||
|
|
||||||
declare binop ==(b Int) -> Bool;
|
declare binop ==(Int) Bool;
|
||||||
declare binop !=(b Int) -> Bool;
|
declare binop !=(Int) Bool;
|
||||||
declare binop >(b Int) -> Bool;
|
declare binop >(Int) Bool;
|
||||||
declare binop <(b Int) -> Bool;
|
declare binop <(Int) Bool;
|
||||||
declare binop >=(b Int) -> Bool;
|
declare binop >=(Int) Bool;
|
||||||
declare binop <=(b Int) -> Bool;
|
declare binop <=(Int) Bool;
|
||||||
|
|
||||||
declare binop +(b Int) -> Int;
|
declare binop +(Int) Int;
|
||||||
declare binop -(b Int) -> Int;
|
declare binop -(Int) Int;
|
||||||
declare binop *(b Int) -> Int;
|
declare binop *(Int) Int;
|
||||||
declare binop /(b Int) -> Int;
|
declare binop /(Int) Int;
|
||||||
declare binop %(b Int) -> Int;
|
declare binop %(Int) Int;
|
||||||
|
|
||||||
declare fn str() -> String;
|
declare factory (f Float);
|
||||||
|
declare factory ();
|
||||||
|
|
||||||
|
declare fn str() String;
|
||||||
};
|
};
|
||||||
|
|
||||||
type String = class (data List[Char]) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -6,4 +6,5 @@ set(CMAKE_C_STANDARD 11)
|
|||||||
|
|
||||||
file(GLOB_RECURSE sources ${CMAKE_SOURCE_DIR}/src/*.c)
|
file(GLOB_RECURSE sources ${CMAKE_SOURCE_DIR}/src/*.c)
|
||||||
include_directories(${CMAKE_SOURCE_DIR}/include)
|
include_directories(${CMAKE_SOURCE_DIR}/include)
|
||||||
add_library(libplsm SHARED ${sources})
|
add_library(plsm SHARED ${sources})
|
||||||
|
target_link_libraries(plsm gc)
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
|
|
||||||
} function_t;
|
|
3
lib/include/init.h
Normal file
3
lib/include/init.h
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void plsm_init();
|
@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "type.h"
|
|
||||||
#include "value.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
value_t *value;
|
|
||||||
list_node_t *next;
|
|
||||||
} list_node_t;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
type_t *type;
|
|
||||||
list_node_t *head;
|
|
||||||
} list_t;
|
|
@ -1,7 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
#define DIE \
|
#define DIE \
|
||||||
{ \
|
{ \
|
||||||
@ -14,6 +15,35 @@
|
|||||||
DIE; \
|
DIE; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MODINIT(module) void plsmmod_##module##_init()
|
#define TYPE(type) plsm_##type##_t
|
||||||
|
#define TYPESIZE(type) (sizeof(TYPE(type)) - sizeof(plsm_base_t))
|
||||||
|
|
||||||
#define LIB(name) plsmlib_##name
|
#define MAKETYPE(type) plsm_maketype_##type
|
||||||
|
#define DEFMAKETYPE(type) plsm_type_t *MAKETYPE(type)
|
||||||
|
|
||||||
|
#define MAKE(type) plsm_make_##type
|
||||||
|
#define DEFMAKE(type) TYPE(type) MAKE(type)
|
||||||
|
|
||||||
|
#define OP_ADD add
|
||||||
|
#define OP_SUB sub
|
||||||
|
#define OP_MUL mul
|
||||||
|
#define OP_DIV div
|
||||||
|
#define OP_MOD mod
|
||||||
|
#define OP_EQ eq
|
||||||
|
#define OP_NEQ neq
|
||||||
|
#define OP_LAND land
|
||||||
|
#define OP_LOR lor
|
||||||
|
#define OP_GT gt
|
||||||
|
#define OP_GTE gte
|
||||||
|
#define OP_LT lt
|
||||||
|
#define OP_LTE lte
|
||||||
|
#define OP_NOT not
|
||||||
|
|
||||||
|
#define UNOP(action, intype) plsm_unop_##action##_##intype
|
||||||
|
#define DEFUNOP(action, restype, intype) TYPE(restype) UNOP(action, intype)(TYPE(intype) * it)
|
||||||
|
|
||||||
|
#define BINOP(action, ltype, rtype) plsm_binop_##action##_##ltype##_##rtype
|
||||||
|
#define DEFBINOP(action, restype, ltype, rtype) \
|
||||||
|
TYPE(restype) \
|
||||||
|
BINOP(action, ltype, rtype) \
|
||||||
|
(TYPE(ltype) * it, TYPE(rtype) * other)
|
||||||
|
@ -2,13 +2,23 @@
|
|||||||
|
|
||||||
#include "macros.h"
|
#include "macros.h"
|
||||||
|
|
||||||
typedef struct type_t type_t;
|
typedef struct plsm_type_t plsm_type_t;
|
||||||
|
|
||||||
typedef struct type_t
|
typedef struct plsm_type_t
|
||||||
{
|
{
|
||||||
type_t *base;
|
plsm_type_t *base;
|
||||||
int opaque;
|
|
||||||
char *name;
|
char *name;
|
||||||
} type_t;
|
uint32_t size;
|
||||||
|
} plsm_type_t;
|
||||||
|
|
||||||
type_t *LIB(makeType)(type_t *base, int opaque, char *name);
|
plsm_type_t *plsm_maketype(plsm_type_t *base, char *name, uint32_t size);
|
||||||
|
|
||||||
|
typedef struct plsm_base_t
|
||||||
|
{
|
||||||
|
plsm_type_t *type;
|
||||||
|
} plsm_base_t;
|
||||||
|
|
||||||
|
typedef struct TYPE(Bool) TYPE(Bool);
|
||||||
|
|
||||||
|
TYPE(Bool)
|
||||||
|
plsm_instanceof(plsm_base_t *value, plsm_type_t *type);
|
||||||
|
15
lib/include/types/bool.h
Normal file
15
lib/include/types/bool.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "macros.h"
|
||||||
|
#include "type.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
typedef struct TYPE(Bool)
|
||||||
|
{
|
||||||
|
plsm_type_t *type;
|
||||||
|
uint8_t value;
|
||||||
|
} TYPE(Bool);
|
||||||
|
|
||||||
|
DEFMAKE(Bool)
|
||||||
|
(intptr_t value);
|
23
lib/include/types/int.h
Normal file
23
lib/include/types/int.h
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "macros.h"
|
||||||
|
#include "type.h"
|
||||||
|
|
||||||
|
#include <gc.h>
|
||||||
|
|
||||||
|
typedef struct TYPE(Int)
|
||||||
|
{
|
||||||
|
plsm_type_t *type;
|
||||||
|
int64_t value;
|
||||||
|
} TYPE(Int);
|
||||||
|
|
||||||
|
DEFMAKE(Int)
|
||||||
|
(int64_t value);
|
||||||
|
|
||||||
|
DEFBINOP(BINOP_ADD, Int, Int, Int);
|
||||||
|
DEFBINOP(BINOP_SUB, Int, Int, Int);
|
||||||
|
DEFBINOP(BINOP_MUL, Int, Int, Int);
|
||||||
|
DEFBINOP(BINOP_DIV, Int, Int, Int);
|
||||||
|
DEFBINOP(BINOP_MOD, Int, Int, Int);
|
||||||
|
|
||||||
|
DEFBINOP(BINOP_EQ, Bool, Int, Int);
|
4
lib/include/types/types.h
Normal file
4
lib/include/types/types.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "int.h"
|
||||||
|
#include "bool.h"
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "type.h"
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
type_t *type;
|
|
||||||
void *value;
|
|
||||||
} value_t;
|
|
@ -1 +0,0 @@
|
|||||||
#include "function.h"
|
|
15
lib/src/init.c
Normal file
15
lib/src/init.c
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#include "init.h"
|
||||||
|
|
||||||
|
#include <gc.h>
|
||||||
|
|
||||||
|
void plsm_init()
|
||||||
|
{
|
||||||
|
static int initialized = 0;
|
||||||
|
|
||||||
|
if (initialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
GC_INIT();
|
||||||
|
|
||||||
|
initialized = 1;
|
||||||
|
}
|
@ -1,5 +0,0 @@
|
|||||||
#include "macros.h"
|
|
||||||
|
|
||||||
MODINIT(stdlib)
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,16 +1,28 @@
|
|||||||
#include "type.h"
|
#include "type.h"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <gc.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include "types/bool.h"
|
||||||
|
|
||||||
type_t *LIB(makeType)(type_t *base, int opaque, char *name)
|
plsm_type_t *plsm_maketype(plsm_type_t *base, char *name, uint32_t size)
|
||||||
{
|
{
|
||||||
type_t *type = malloc(sizeof(type_t));
|
plsm_type_t *type = GC_malloc(sizeof(plsm_type_t));
|
||||||
if (!type)
|
if (type == NULL)
|
||||||
DIE_ERRNO("malloc");
|
DIE_ERRNO("GC_malloc");
|
||||||
|
|
||||||
type->base = base;
|
type->base = base;
|
||||||
type->opaque = opaque;
|
|
||||||
type->name = name;
|
type->name = name;
|
||||||
|
type->size = size;
|
||||||
|
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TYPE(Bool)
|
||||||
|
plsm_instanceof(plsm_base_t *value, plsm_type_t *type)
|
||||||
|
{
|
||||||
|
for (plsm_type_t *t = value->type; t != NULL; t = t->base)
|
||||||
|
if (t == type)
|
||||||
|
return MAKE(Bool)(1);
|
||||||
|
|
||||||
|
return MAKE(Bool)(0);
|
||||||
|
}
|
||||||
|
@ -1,12 +0,0 @@
|
|||||||
#include "type.h"
|
|
||||||
|
|
||||||
type_t *LIB(typeAny), *LIB(typeNum), *LIB(typeInt), *LIB(typeFloat);
|
|
||||||
|
|
||||||
void LIB(initTypes)()
|
|
||||||
{
|
|
||||||
LIB(typeAny) = LIB(makeType)(NULL, "Any");
|
|
||||||
|
|
||||||
LIB(typeNum) = LIB(makeType)(LIB(typeAny), "Num");
|
|
||||||
LIB(typeInt) = LIB(makeType)(LIB(typeNum), "Int");
|
|
||||||
LIB(typeFloat) = LIB(makeType)(LIB(typeNum), "Float");
|
|
||||||
}
|
|
27
lib/src/types/bool.c
Normal file
27
lib/src/types/bool.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "types/bool.h"
|
||||||
|
|
||||||
|
#include <gc.h>
|
||||||
|
|
||||||
|
DEFMAKE(Bool)
|
||||||
|
(intptr_t value)
|
||||||
|
{
|
||||||
|
return (TYPE(Bool)){
|
||||||
|
.type = NULL,
|
||||||
|
.value = value != 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUNOP(OP_NOT, Bool, Bool)
|
||||||
|
{
|
||||||
|
return MAKE(Bool)(!it->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_LAND, Bool, Bool, Bool)
|
||||||
|
{
|
||||||
|
return MAKE(Bool)(it->value && other->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_LOR, Bool, Bool, Bool)
|
||||||
|
{
|
||||||
|
return MAKE(Bool)(it->value || other->value);
|
||||||
|
}
|
64
lib/src/types/int.c
Normal file
64
lib/src/types/int.c
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
#include "types/int.h"
|
||||||
|
|
||||||
|
#include <gc.h>
|
||||||
|
#include "type.h"
|
||||||
|
#include "types/bool.h"
|
||||||
|
|
||||||
|
DEFMAKETYPE(Int)
|
||||||
|
()
|
||||||
|
{
|
||||||
|
static plsm_type_t *type = NULL;
|
||||||
|
if (type)
|
||||||
|
return type;
|
||||||
|
|
||||||
|
return (type = plsm_maketype(NULL, "Int", TYPESIZE(Int)));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFMAKE(Int)
|
||||||
|
(int64_t value)
|
||||||
|
{
|
||||||
|
return (TYPE(Int)){
|
||||||
|
.type = NULL,
|
||||||
|
.value = value,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUNOP(OP_ADD, Int, Int)
|
||||||
|
{
|
||||||
|
return *it;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFUNOP(OP_SUB, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Int)(it->value * -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_ADD, Int, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Int)(it->value + other->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_SUB, Int, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Int)(it->value - other->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_MUL, Int, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Int)(it->value * other->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_DIV, Int, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Int)(it->value / other->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_MOD, Int, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Int)(it->value % other->value);
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFBINOP(OP_EQ, Bool, Int, Int)
|
||||||
|
{
|
||||||
|
return MAKE(Bool)((intptr_t)(it->value == other->value));
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user