From b14bd5cc28c4fd9bb5005122fc765c46e9b10a9a Mon Sep 17 00:00:00 2001 From: bog Date: Fri, 25 Aug 2023 18:38:06 +0200 Subject: [PATCH] ADD: vars can be declared as mutable. --- src/compiler.c | 23 +++++++++++++++++++++++ src/cstatic.c | 14 ++++++++++++-- src/lex.l | 1 + src/node.h | 3 ++- src/parser.y | 17 ++++++++++++++++- src/symtable.c | 11 +++++++++++ src/symtable.h | 2 ++ tests/test_vars.wuz | 3 +++ 8 files changed, 70 insertions(+), 4 deletions(-) diff --git a/src/compiler.c b/src/compiler.c index 7d2adeb..e94ee07 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -30,6 +30,29 @@ void compile_node(compiler* self, node* root, program* prog) program_add_instr(prog, OP_ADEREF, NO_PARAM); } // Variables stuff + else if (root->type == NODE_CONSTDECL) + { + cstatic cs; + cstatic_init(&cs); + + type* ty = cstatic_resolve_new(&cs, + self->sym, + root->children.data[1]); + + size_t id = symtable_declare_mut( + self->sym, + root->children.data[0]->value, + ty, + root->children.data[1] + ); + + compile_node(self, root->children.data[1], prog); + program_add_instr(prog, OP_STORE, id); + + type_free(ty); + free(ty); + cstatic_free(&cs); + } else if (root->type == NODE_VARDECL) { cstatic cs; diff --git a/src/cstatic.c b/src/cstatic.c index dd0d3c6..f818601 100644 --- a/src/cstatic.c +++ b/src/cstatic.c @@ -309,7 +309,8 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz return 1; } - if (ast->type == NODE_VARDECL) + if (ast->type == NODE_VARDECL + || ast->type == NODE_CONSTDECL) { char const* name = ast->children.data[0]->value; @@ -323,7 +324,16 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz type* ty = cstatic_resolve_new(self, sym, ast->children.data[1]); assert(ty); - symtable_declare(sym, name, ty, ast->children.data[1]); + + if (ast->type == NODE_VARDECL) + { + symtable_declare(sym, name, ty, ast->children.data[1]); + } + else + { + symtable_declare_mut(sym, name, ty, ast->children.data[1]); + } + type_free(ty); free(ty); return 1; diff --git a/src/lex.l b/src/lex.l index aa89604..0618455 100644 --- a/src/lex.l +++ b/src/lex.l @@ -26,6 +26,7 @@ IDENT [_A-Za-z][_A-Za-z0-9]* return TYPE; } +"let!" { return LET_MUT; } "let" { return LET; } "assert" { return ASSERT; } "<=" { return LE; } diff --git a/src/node.h b/src/node.h index 1d2aaa4..bd19b1b 100644 --- a/src/node.h +++ b/src/node.h @@ -11,7 +11,8 @@ G(NODE_UADD), G(NODE_USUB), G(NODE_ADD), G(NODE_SUB), \ G(NODE_MUL), G(NODE_DIV), G(NODE_MOD), G(NODE_POW), \ G(NODE_ARRAY), G(NODE_INDEX), G(NODE_LT), G(NODE_LE), \ - G(NODE_GT), G(NODE_GE), G(NODE_VARDECL), G(NODE_IDENT) + G(NODE_GT), G(NODE_GE), G(NODE_VARDECL), G(NODE_IDENT), \ + G(NODE_CONSTDECL) #include "mutils.h" diff --git a/src/parser.y b/src/parser.y index 1774d1c..5a6d5e6 100644 --- a/src/parser.y +++ b/src/parser.y @@ -35,7 +35,7 @@ %left NOT %token OPAR CPAR %token OSQUARE CSQUARE COMMA -%token LET ASSIGN +%token LET LET_MUT ASSIGN %type expr_unop %% @@ -101,6 +101,21 @@ expr: // VARIABLES | ident { } + + | LET_MUT ident ASSIGN expr { + node* n = malloc(sizeof(node)); + node_init(n, NODE_CONSTDECL, "", line); + + node* rhs = stack_pop(); + node* lhs = stack_pop(); + + node_add_child(n, lhs); + node_add_child(n, rhs); + + stack_push(n); + + $$ = 1; + } | LET ident ASSIGN expr { node* n = malloc(sizeof(node)); diff --git a/src/symtable.c b/src/symtable.c index 972c4d9..25c2ea1 100644 --- a/src/symtable.c +++ b/src/symtable.c @@ -34,6 +34,16 @@ void symtable_free(symtable* self) self->entries.data = NULL; } +size_t symtable_declare_mut(symtable* self, char const* name, type* ty, node* sym_node) +{ + assert(self); + size_t id = symtable_declare(self, name, ty, sym_node); + + self->entries.data[id]->is_mut = 1; + + return id; +} + size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_node) { assert(self); @@ -56,6 +66,7 @@ size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_no self->entries.data[self->entries.size]->name = str_new(name); self->entries.data[self->entries.size]->ty = type_new_clone(ty); self->entries.data[self->entries.size]->id = self->id; + self->entries.data[self->entries.size]->is_mut = 0; self->entries.data[self->entries.size]->sym_node = node_new_clone(sym_node); self->entries.size++; diff --git a/src/symtable.h b/src/symtable.h index 6a49206..a8d0a97 100644 --- a/src/symtable.h +++ b/src/symtable.h @@ -7,6 +7,7 @@ typedef struct { size_t id; + int is_mut; char* name; type* ty; node* sym_node; @@ -26,6 +27,7 @@ void symtable_init(symtable* self); void symtable_free(symtable* self); size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_node); +size_t symtable_declare_mut(symtable* self, char const* name, type* ty, node* sym_node); symentry* symtable_find(symtable* self, char const* name); #endif diff --git a/tests/test_vars.wuz b/tests/test_vars.wuz index cb73a8d..8438bbd 100644 --- a/tests/test_vars.wuz +++ b/tests/test_vars.wuz @@ -13,3 +13,6 @@ let e = 0 let f = 1 assert [2, 4] == d[e] assert [6, 8] == d[f] + +let! g = 4 +