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", | ||||
|     "typeinfo": "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 | ||||
| 
 | ||||
| #include <string> | ||||
| #include <vector> | ||||
| 
 | ||||
| class Expr; | ||||
| class Type; | ||||
| 
 | ||||
| typedef std::pair<std::string, Type *> FnArg; | ||||
| 
 | ||||
| class ASTNode | ||||
| { | ||||
| @ -12,38 +16,127 @@ class Stmt : public ASTNode | ||||
| { | ||||
| }; | ||||
| 
 | ||||
| class Decl : public Stmt | ||||
| class Module : public ASTNode | ||||
| { | ||||
| public: | ||||
|   Decl(const std::string &identifier, const Expr *value) | ||||
|       : identifier(identifier), value(value) {} | ||||
|   Module(const std::vector<Stmt *> &stmts) : stmts(std::move(stmts)) {} | ||||
|   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; | ||||
| }; | ||||
| 
 | ||||
| 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 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 | ||||
| { | ||||
| public: | ||||
|   const long value; | ||||
|   IntValue(const long value) : value(value) {} | ||||
| 
 | ||||
|   const long value; | ||||
| }; | ||||
| 
 | ||||
| class FloatValue : public Expr | ||||
| { | ||||
| public: | ||||
|   const double value; | ||||
|   FloatValue(const double value) : value(value) {} | ||||
| }; | ||||
| 
 | ||||
| class Function : public Expr | ||||
| { | ||||
| }; | ||||
| 
 | ||||
| class List : public Expr | ||||
| { | ||||
|   const double value; | ||||
| }; | ||||
|  | ||||
| @ -17,6 +17,7 @@ public: | ||||
| 
 | ||||
|   std::string file; | ||||
|   yy::location location; | ||||
|   Module *module; | ||||
| }; | ||||
| 
 | ||||
| #define YY_DECL yy::parser::symbol_type yylex(ParserDriver &driver) | ||||
|  | ||||
| @ -4,10 +4,10 @@ | ||||
| 
 | ||||
| #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] | ||||
| bindigit    [0-1] | ||||
| @ -16,6 +16,8 @@ hexdigit    [0-9a-fA-F] | ||||
| 
 | ||||
| letter      [a-zA-Z] | ||||
| 
 | ||||
| opchar      ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\") | ||||
| 
 | ||||
| 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); } | ||||
| 
 | ||||
| // TODO: operator '==' won't work this way | ||||
| "->"    { return _token(R_ARR); } | ||||
| "<-"    { return _token(L_ARR); } | ||||
| ";"     { return _token(SEMI); } | ||||
| "="     { return _token(EQUALS); }  | ||||
| 
 | ||||
| ("+"|"-"|"*"|"/"|"%"|"!"|"&"|"$"|"§"|"|"|"="|"<"|">"|"?"|"~"|"#"|":"|"^"|"\\")+  { return _token(OPERATOR); } | ||||
| {opchar}+     { std::string text = yytext; | ||||
|                 if (text == "=") return _token(EQUALS); | ||||
|                 if (text == "->") return _token(RARR); | ||||
|                 return _token(OPERATOR); } | ||||
| 
 | ||||
| ","           { return _token(COMMA); } | ||||
| ";"           { return _token(SEMI); } | ||||
| "("           { return _token(LPAREN); } | ||||
| ")"           { return _token(RPAREN); } | ||||
| "["           { return _token(LBRACKET); } | ||||
| "]"           { return _token(RBRACKET); } | ||||
| 
 | ||||
| "fn"          { return _token(FN); } | ||||
| "unop"        { return _token(UNOP); } | ||||
| @ -44,7 +50,9 @@ whitespace  [ \n\t\r\v]+ | ||||
| "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}                  { ; } | ||||
| 
 | ||||
|  | ||||
| @ -32,15 +32,19 @@ class ParserDriver; | ||||
| %token <long> INT "integer literal" | ||||
| %token <double> FLOAT "float literal" | ||||
| 
 | ||||
| %token <std::string> OPERATOR "operator"; | ||||
| %token <std::string> IDENTIFIER "identifier" | ||||
| %token <std::string> | ||||
|   OPERATOR "operator" | ||||
|   IDENTIFIER "identifier" | ||||
| 
 | ||||
| %token L_ARR "<-" | ||||
| %token R_ARR "->" | ||||
| %token EQUALS "=" | ||||
| %token SEMI ";" | ||||
|   RARR "->" | ||||
|   EQUALS "=" | ||||
|   COMMA "," | ||||
|   SEMI ";" | ||||
|   LPAREN "(" | ||||
|   RPAREN ")" | ||||
|   LBRACKET "[" | ||||
|   RBRACKET "]" | ||||
| 
 | ||||
| %token | ||||
|   FN "fn" | ||||
|   UNOP "unop" | ||||
|   BINOP "binop" | ||||
| @ -52,47 +56,144 @@ class ParserDriver; | ||||
| %token END 0 "end of file" | ||||
| 
 | ||||
| %type <std::vector<Stmt *>> stmts; | ||||
| %type <Stmt *> stmt; | ||||
| %type <Decl *> decl; | ||||
| %type <Expr *> expr; | ||||
| %type <Value *> literal; | ||||
| %type <Stmt *> | ||||
|   stmt | ||||
|   decl | ||||
| ; | ||||
| 
 | ||||
| %type <std::string> operator; | ||||
| %type <std::string> identifier; | ||||
| %type <std::string> keyword; | ||||
| %type <FnDecl *> fnDecl; | ||||
| %type <ValDecl *> valDecl; | ||||
| 
 | ||||
| %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   { $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); } | ||||
|        ; | ||||
| 
 | ||||
| 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 | ||||
|     ; | ||||
| 
 | ||||
| expr: literal       { $$ = $1; } | ||||
| 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); } | ||||
|        | FLOAT      { $$ = new FloatValue($1); } | ||||
|        ; | ||||
| 
 | ||||
| operator: L_ARR     { $$ = $1; } | ||||
|         | R_ARR     { $$ = $1; } | ||||
|         | EQUALS    { $$ = $1; } | ||||
| operator: "->"      { $$ = $1; } | ||||
|         | "="       { $$ = $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  { $$ = $1; } | ||||
|           ; | ||||
| 
 | ||||
| keyword: FN       { $$ = $1; } | ||||
|        | VAL      { $$ = $1; } | ||||
|        | UNOP     { $$ = $1; } | ||||
|        | BINOP    { $$ = $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'; | ||||
| } | ||||
|  | ||||
| @ -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 { | ||||
|   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 { | ||||
|   declare unop + -> Int; | ||||
|   declare unop - -> Int; | ||||
|   declare unop + Int; | ||||
|   declare unop - Int; | ||||
| 
 | ||||
|   declare binop ==(b Int) -> Bool; | ||||
|   declare binop !=(b Int) -> Bool; | ||||
|   declare binop >(b Int) -> Bool; | ||||
|   declare binop <(b Int) -> Bool; | ||||
|   declare binop >=(b Int) -> Bool; | ||||
|   declare binop <=(b Int) -> Bool; | ||||
|   declare binop ==(Int) Bool; | ||||
|   declare binop !=(Int) Bool; | ||||
|   declare binop >(Int) Bool; | ||||
|   declare binop <(Int) Bool; | ||||
|   declare binop >=(Int) Bool; | ||||
|   declare binop <=(Int) Bool; | ||||
| 
 | ||||
|   declare binop +(b Int) -> Int; | ||||
|   declare binop -(b Int) -> Int; | ||||
|   declare binop *(b Int) -> Int; | ||||
|   declare binop /(b Int) -> Int; | ||||
|   declare binop %(b Int) -> Int; | ||||
|   declare binop +(Int) Int; | ||||
|   declare binop -(Int) Int; | ||||
|   declare binop *(Int) Int; | ||||
|   declare binop /(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) | ||||
| 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 | ||||
| 
 | ||||
| #include <stdlib.h> | ||||
| #include <stdio.h> | ||||
| #include <stdint.h> | ||||
| #include <stdlib.h> | ||||
| 
 | ||||
| #define DIE             \ | ||||
|   {                     \ | ||||
| @ -14,6 +15,35 @@ | ||||
|     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" | ||||
| 
 | ||||
| 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; | ||||
|   int opaque; | ||||
|   plsm_type_t *base; | ||||
|   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 <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)); | ||||
|   if (!type) | ||||
|     DIE_ERRNO("malloc"); | ||||
|   plsm_type_t *type = GC_malloc(sizeof(plsm_type_t)); | ||||
|   if (type == NULL) | ||||
|     DIE_ERRNO("GC_malloc"); | ||||
| 
 | ||||
|   type->base = base; | ||||
|   type->opaque = opaque; | ||||
|   type->name = name; | ||||
|   type->size = size; | ||||
| 
 | ||||
|   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
	 Ludwig Lehnert
						Ludwig Lehnert