From 6c32f09c03e528031bb7a3c67d072882d9c863bf Mon Sep 17 00:00:00 2001 From: Ludwig Lehnert Date: Sun, 25 Feb 2024 22:38:17 +0100 Subject: [PATCH] next steps --- .vscode/settings.json | 14 ++- compiler/include/AST.h | 119 +++++++++++++++++++++++--- compiler/include/ParserDriver.h | 1 + compiler/lexer.ll | 26 ++++-- compiler/parser.yy | 145 +++++++++++++++++++++++++++----- compiler/src/main.cpp | 29 ++++++- examples/42.plsm | 1 + examples/stdlib.plsm | 41 +++++---- lib/CMakeLists.txt | 3 +- lib/include/function.h | 6 -- lib/include/init.h | 3 + lib/include/list.h | 16 ---- lib/include/macros.h | 36 +++++++- lib/include/type.h | 22 +++-- lib/include/types/bool.h | 15 ++++ lib/include/types/int.h | 23 +++++ lib/include/types/types.h | 4 + lib/include/value.h | 9 -- lib/src/function.c | 1 - lib/src/init.c | 15 ++++ lib/src/module.c | 5 -- lib/src/type.c | 24 ++++-- lib/src/types.c | 12 --- lib/src/types/bool.c | 27 ++++++ lib/src/types/int.c | 64 ++++++++++++++ 25 files changed, 528 insertions(+), 133 deletions(-) create mode 100644 examples/42.plsm delete mode 100644 lib/include/function.h create mode 100644 lib/include/init.h delete mode 100644 lib/include/list.h create mode 100644 lib/include/types/bool.h create mode 100644 lib/include/types/int.h create mode 100644 lib/include/types/types.h delete mode 100644 lib/include/value.h delete mode 100644 lib/src/function.c create mode 100644 lib/src/init.c delete mode 100644 lib/src/module.c delete mode 100644 lib/src/types.c create mode 100644 lib/src/types/bool.c create mode 100644 lib/src/types/int.c diff --git a/.vscode/settings.json b/.vscode/settings.json index 0a51fc0..2f9bd90 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -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" }, } \ No newline at end of file diff --git a/compiler/include/AST.h b/compiler/include/AST.h index 9b46c36..ec6162a 100644 --- a/compiler/include/AST.h +++ b/compiler/include/AST.h @@ -1,8 +1,12 @@ #pragma once #include +#include class Expr; +class Type; + +typedef std::pair 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 &stmts) : stmts(std::move(stmts)) {} + const std::vector 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 &args, const Type *returnType, const Expr *body) + : name(name), args(std::move(args)), returnType(returnType), body(body) {} + + const std::string name; + const std::vector args; + const Type *returnType; + const Expr *body; +}; + +class Type : public ASTNode +{ +}; + +class TupleType : public Type +{ +public: + TupleType(const std::vector &types) : types(types) {} + const std::vector types; +}; + +class FunctionType : public Type +{ +public: + FunctionType(const std::vector &from, const Type *to) + : from(std::move(from)), to(to) {} + + const std::vector 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 &args) + : callee(callee), args(std::move(args)) {} + + const Expr *callee; + const std::vector 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; }; diff --git a/compiler/include/ParserDriver.h b/compiler/include/ParserDriver.h index 86ca5b6..454c1ce 100644 --- a/compiler/include/ParserDriver.h +++ b/compiler/include/ParserDriver.h @@ -17,6 +17,7 @@ public: std::string file; yy::location location; + Module *module; }; #define YY_DECL yy::parser::symbol_type yylex(ParserDriver &driver) diff --git a/compiler/lexer.ll b/compiler/lexer.ll index 1f32687..7e3b985 100644 --- a/compiler/lexer.ll +++ b/compiler/lexer.ll @@ -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); } + +<> { return yy::parser::make_END(driver.location); } {whitespace} { ; } diff --git a/compiler/parser.yy b/compiler/parser.yy index 223783e..8abd49b 100644 --- a/compiler/parser.yy +++ b/compiler/parser.yy @@ -32,15 +32,19 @@ class ParserDriver; %token INT "integer literal" %token FLOAT "float literal" -%token OPERATOR "operator"; -%token IDENTIFIER "identifier" +%token + 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 > stmts; -%type stmt; -%type decl; -%type expr; -%type literal; +%type + stmt + decl +; -%type operator; -%type identifier; -%type keyword; +%type fnDecl; +%type valDecl; + +%type + type + type0 +; + +%type > + exprs + args +; + +%type + expr + expr3 + expr2 + expr1 + expr0 + literal +; + +%type fnArg; +%type > + fnArgs + fnArgs0 +; + +%type > + lambdaArgs + identifiers +; + +%type + operator + identifier + keyword +; + +%start module %% -module: stmts; +module: stmts END { driver.module = new Module($1); }; stmts: stmt { $$ = std::vector(); $$.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(); } + | fnArgs0 { $$ = std::move($1); } + ; + +fnArgs0: fnArg { $$ = std::vector(); $$.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(); $$.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(); } + | identifiers { $$ = std::move($1); } + ; + +args: %empty { $$ = std::vector(); } + | 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(); $$.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'; } diff --git a/compiler/src/main.cpp b/compiler/src/main.cpp index 88cc9d6..df22ac9 100644 --- a/compiler/src/main.cpp +++ b/compiler/src/main.cpp @@ -1,5 +1,30 @@ -#include +#include "ParserDriver.h" -int main() +#include +#include +#include + +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] << " " << 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; } diff --git a/examples/42.plsm b/examples/42.plsm new file mode 100644 index 0000000..92eb877 --- /dev/null +++ b/examples/42.plsm @@ -0,0 +1 @@ +fn main[] Int = 42; diff --git a/examples/stdlib.plsm b/examples/stdlib.plsm index b9b2996..ac6e258 100644 --- a/examples/stdlib.plsm +++ b/examples/stdlib.plsm @@ -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]) { - -} diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index 65be2a5..bba78ad 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -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) diff --git a/lib/include/function.h b/lib/include/function.h deleted file mode 100644 index d93157f..0000000 --- a/lib/include/function.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -typedef struct -{ - -} function_t; diff --git a/lib/include/init.h b/lib/include/init.h new file mode 100644 index 0000000..9b3bd84 --- /dev/null +++ b/lib/include/init.h @@ -0,0 +1,3 @@ +#pragma once + +void plsm_init(); diff --git a/lib/include/list.h b/lib/include/list.h deleted file mode 100644 index 3b7fe1f..0000000 --- a/lib/include/list.h +++ /dev/null @@ -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; diff --git a/lib/include/macros.h b/lib/include/macros.h index a68d12e..7836996 100644 --- a/lib/include/macros.h +++ b/lib/include/macros.h @@ -1,7 +1,8 @@ #pragma once -#include #include +#include +#include #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) diff --git a/lib/include/type.h b/lib/include/type.h index 477b6f4..3d5ed2a 100644 --- a/lib/include/type.h +++ b/lib/include/type.h @@ -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); diff --git a/lib/include/types/bool.h b/lib/include/types/bool.h new file mode 100644 index 0000000..920ad4c --- /dev/null +++ b/lib/include/types/bool.h @@ -0,0 +1,15 @@ +#pragma once + +#include "macros.h" +#include "type.h" + +#include + +typedef struct TYPE(Bool) +{ + plsm_type_t *type; + uint8_t value; +} TYPE(Bool); + +DEFMAKE(Bool) +(intptr_t value); diff --git a/lib/include/types/int.h b/lib/include/types/int.h new file mode 100644 index 0000000..2c879f9 --- /dev/null +++ b/lib/include/types/int.h @@ -0,0 +1,23 @@ +#pragma once + +#include "macros.h" +#include "type.h" + +#include + +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); diff --git a/lib/include/types/types.h b/lib/include/types/types.h new file mode 100644 index 0000000..199b1a4 --- /dev/null +++ b/lib/include/types/types.h @@ -0,0 +1,4 @@ +#pragma once + +#include "int.h" +#include "bool.h" \ No newline at end of file diff --git a/lib/include/value.h b/lib/include/value.h deleted file mode 100644 index 23da0ac..0000000 --- a/lib/include/value.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "type.h" - -typedef struct -{ - type_t *type; - void *value; -} value_t; diff --git a/lib/src/function.c b/lib/src/function.c deleted file mode 100644 index d4b693e..0000000 --- a/lib/src/function.c +++ /dev/null @@ -1 +0,0 @@ -#include "function.h" diff --git a/lib/src/init.c b/lib/src/init.c new file mode 100644 index 0000000..6729af3 --- /dev/null +++ b/lib/src/init.c @@ -0,0 +1,15 @@ +#include "init.h" + +#include + +void plsm_init() +{ + static int initialized = 0; + + if (initialized) + return; + + GC_INIT(); + + initialized = 1; +} diff --git a/lib/src/module.c b/lib/src/module.c deleted file mode 100644 index 8ba2c14..0000000 --- a/lib/src/module.c +++ /dev/null @@ -1,5 +0,0 @@ -#include "macros.h" - -MODINIT(stdlib) -{ -} diff --git a/lib/src/type.c b/lib/src/type.c index db03230..77855c2 100644 --- a/lib/src/type.c +++ b/lib/src/type.c @@ -1,16 +1,28 @@ #include "type.h" -#include +#include +#include +#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); +} diff --git a/lib/src/types.c b/lib/src/types.c deleted file mode 100644 index d199ac6..0000000 --- a/lib/src/types.c +++ /dev/null @@ -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"); -} diff --git a/lib/src/types/bool.c b/lib/src/types/bool.c new file mode 100644 index 0000000..371f769 --- /dev/null +++ b/lib/src/types/bool.c @@ -0,0 +1,27 @@ +#include "types/bool.h" + +#include + +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); +} diff --git a/lib/src/types/int.c b/lib/src/types/int.c new file mode 100644 index 0000000..9e8e6f6 --- /dev/null +++ b/lib/src/types/int.c @@ -0,0 +1,64 @@ +#include "types/int.h" + +#include +#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)); +}