ADD: vars can be declared as mutable.

main
bog 2023-08-25 18:38:06 +02:00
parent 067dfdc638
commit b14bd5cc28
8 changed files with 70 additions and 4 deletions

View File

@ -30,6 +30,29 @@ void compile_node(compiler* self, node* root, program* prog)
program_add_instr(prog, OP_ADEREF, NO_PARAM); program_add_instr(prog, OP_ADEREF, NO_PARAM);
} }
// Variables stuff // 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) else if (root->type == NODE_VARDECL)
{ {
cstatic cs; cstatic cs;

View File

@ -309,7 +309,8 @@ int cstatic_check(cstatic* self, node* ast, symtable* sym, char* msg, size_t siz
return 1; return 1;
} }
if (ast->type == NODE_VARDECL) if (ast->type == NODE_VARDECL
|| ast->type == NODE_CONSTDECL)
{ {
char const* name = ast->children.data[0]->value; 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]); type* ty = cstatic_resolve_new(self, sym, ast->children.data[1]);
assert(ty); 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); type_free(ty);
free(ty); free(ty);
return 1; return 1;

View File

@ -26,6 +26,7 @@ IDENT [_A-Za-z][_A-Za-z0-9]*
return TYPE; return TYPE;
} }
"let!" { return LET_MUT; }
"let" { return LET; } "let" { return LET; }
"assert" { return ASSERT; } "assert" { return ASSERT; }
"<=" { return LE; } "<=" { return LE; }

View File

@ -11,7 +11,8 @@
G(NODE_UADD), G(NODE_USUB), G(NODE_ADD), G(NODE_SUB), \ 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_MUL), G(NODE_DIV), G(NODE_MOD), G(NODE_POW), \
G(NODE_ARRAY), G(NODE_INDEX), G(NODE_LT), G(NODE_LE), \ 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" #include "mutils.h"

View File

@ -35,7 +35,7 @@
%left NOT %left NOT
%token OPAR CPAR %token OPAR CPAR
%token OSQUARE CSQUARE COMMA %token OSQUARE CSQUARE COMMA
%token LET ASSIGN %token LET LET_MUT ASSIGN
%type <n_children> expr_unop %type <n_children> expr_unop
%% %%
@ -102,6 +102,21 @@ expr:
| ident { | 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 { | LET ident ASSIGN expr {
node* n = malloc(sizeof(node)); node* n = malloc(sizeof(node));
node_init(n, NODE_VARDECL, "", line); node_init(n, NODE_VARDECL, "", line);

View File

@ -34,6 +34,16 @@ void symtable_free(symtable* self)
self->entries.data = NULL; 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) size_t symtable_declare(symtable* self, char const* name, type* ty, node* sym_node)
{ {
assert(self); 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]->name = str_new(name);
self->entries.data[self->entries.size]->ty = type_new_clone(ty); 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]->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.data[self->entries.size]->sym_node = node_new_clone(sym_node);
self->entries.size++; self->entries.size++;

View File

@ -7,6 +7,7 @@
typedef struct { typedef struct {
size_t id; size_t id;
int is_mut;
char* name; char* name;
type* ty; type* ty;
node* sym_node; node* sym_node;
@ -26,6 +27,7 @@ void symtable_init(symtable* self);
void symtable_free(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(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); symentry* symtable_find(symtable* self, char const* name);
#endif #endif

View File

@ -13,3 +13,6 @@ let e = 0
let f = 1 let f = 1
assert [2, 4] == d[e] assert [2, 4] == d[e]
assert [6, 8] == d[f] assert [6, 8] == d[f]
let! g = 4