diff options
| author | iamcheeseman <[email protected]> | 2026-04-14 12:44:25 -0400 |
|---|---|---|
| committer | iamcheeseman <[email protected]> | 2026-04-14 12:44:25 -0400 |
| commit | ca004156cbb1c525900f444994112fc17b71d63d (patch) | |
| tree | 8d19ad7199044e4b11fde6725eb758917f317b4e /uscript/parser.c | |
| parent | 752d7967f3cccb4f43e1df7fd99d4944884fc977 (diff) | |
microscript: add globals
Diffstat (limited to 'uscript/parser.c')
| -rw-r--r-- | uscript/parser.c | 51 |
1 files changed, 47 insertions, 4 deletions
diff --git a/uscript/parser.c b/uscript/parser.c index 404e5e5..89a8883 100644 --- a/uscript/parser.c +++ b/uscript/parser.c @@ -185,6 +185,21 @@ int find_local(struct func_parser *fp, struct token name) } static +int find_global(struct token name) +{ + for (int i = da_len(vm.gstack) - 1; i >= 0; i--) { + struct global global = vm.gstack[i]; + if ( + (size_t)name.len == global.name->len && + memcmp(name.start, global.name->chars, name.len) == 0 + ) + return i; + } + + return -1; +} + +static int find_upval(struct parser *p, struct func_parser *fp, struct token name) { if (fp == NULL) @@ -383,6 +398,9 @@ void parse_ident(struct parser *p) } else if ((var = find_upval(p, p->fp, ident)) != -1) { setter = BC_SET_UPVAL; getter = BC_GET_UPVAL; + } else if ((var = find_global(ident)) != -1) { + setter = BC_SET_GLOBAL; + getter = BC_GET_GLOBAL; } if (var == -1) { @@ -396,7 +414,13 @@ void parse_ident(struct parser *p) } else { parser_add_byte(p, getter); } - parser_add_byte(p, (u8)var); + + if (setter == BC_SET_GLOBAL) { + parser_add_byte(p, (var >> 8) & 0xFF); + parser_add_byte(p, var & 0xFF); + } else { + parser_add_byte(p, (u8)var); + } } static @@ -576,7 +600,7 @@ void expr_stat(struct parser *p) } static -void let_stat(struct parser *p) +void var_def_stat(struct parser *p, bool is_global) { do { expect(p, TOKEN_IDENT, "expected variable name"); @@ -587,7 +611,16 @@ void let_stat(struct parser *p) else parser_add_byte(p, BC_ZILCH); - declare_variable(p, name); + if (is_global) { + struct us_str *ident = copy_str(name.start, name.len); + int idx = declare_global(ident); + parser_add_byte(p, BC_SET_GLOBAL); + parser_add_byte(p, (idx >> 8) & 0xFF); + parser_add_byte(p, idx & 0xFF); + parser_add_byte(p, BC_POP); // set global does not pop + } else { + declare_variable(p, name); + } } while (consume(p, ',')); } @@ -824,7 +857,17 @@ static void stat(struct parser *p) { if (consume(p, TOKEN_LET)) { - let_stat(p); + var_def_stat(p, false); + consume(p, ';'); + } else if (consume(p, TOKEN_GLOBAL)) { + if (!p->fp->is_script) { + show_error( + p, + p->cur, + "can only define globals in the outermost scope" + ); + } + var_def_stat(p, true); consume(p, ';'); } else if (consume(p, TOKEN_FUN)) { fun_stat(p); |
