From 251101ecb896760c436b73c162550842970af992 Mon Sep 17 00:00:00 2001 From: zongor Date: Fri, 22 May 2026 14:31:13 -0700 Subject: [PATCH] fix local variables, wip: globals --- common.h | 1 + compiler.c | 99 ++++++++++++++++++++++++++----------------------- emit.h | 3 +- emit/rer/emit.c | 9 +++-- emit/uxn/emit.c | 9 +++-- test/attack.ul | 8 ++-- test/fib.tal | 82 ++++++++++++++++++++++++++++++++++++++++ test/global.ul | 5 ++- test/if.ul | 18 +++++---- 9 files changed, 168 insertions(+), 66 deletions(-) create mode 100644 test/fib.tal diff --git a/common.h b/common.h index 10912db..29fea62 100644 --- a/common.h +++ b/common.h @@ -37,6 +37,7 @@ struct symbol_s { SymbolType secondary_type; /* return type for functions/methods, or const if type/plex */ u32 ref; /* either constant value or pointer to other thing */ u32 size; /* either size of the plex or length of the array/list/etc. */ + u32 scope; /* scope ref */ List *args; /* function params or plex constructor args */ List *fields; /* either plex variable fields, or method signatures */ }; diff --git a/compiler.c b/compiler.c index 7b5fff4..44e6627 100644 --- a/compiler.c +++ b/compiler.c @@ -89,6 +89,7 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size) new_sym.secondary_type = SYMBOL_VOID; new_sym.size = size; new_sym.ref = parser.current_scope->locals_offset; + new_sym.scope = parser.scope_idx; parser.current_scope->locals_offset += size; if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT || type == SYMBOL_FUNCTION) { @@ -245,7 +246,7 @@ define_function() scope_pop(); continue; } else if(is_type() && parser.current.type == TOKEN_IDENTIFIER) - size += variable_declaration(fn); + size += variable_declaration(nil); advance(); } @@ -274,6 +275,7 @@ build_symbol_table(char *source) } else { /* in binary bytecode output mode we need to count the bytes here */ /* otherwise ignore everything */ + advance(); } } } @@ -284,6 +286,54 @@ void declaration(); ParseRule *get_rule(TokenType type); void parse_precedence(Precedence precedence); +u32 +variable_declaration(Symbol *def) +{ + i32 size = 0; + TokenType tt = parser.previous.type; + SymbolType st = token_type_to_sym_type(tt); + Symbol *variable; + + if(st != SYMBOL_UNDEFINED) { + size = emitter.get_size(st); + + variable = + scope_add_symbol(parser.current.start, parser.current.length, st, size); + if (!def && (parser.pass == 0)) { + return size; + } + + if(def) { + List_push(arena, def->args, variable, sizeof(Symbol)); + } else { + emitter.emit_type(variable, parser.depth); + parser.current_type = st; + } + } else { + /* we need to look up the type */ + emitter.error("Not implemented", 16, parser.previous.line); + } + + advance(); + + if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size; + if(def) + emitter.error(parser.previous.start, parser.previous.length, + parser.previous.line); + if (parser.pass == 0) return size; + + if(match(TOKEN_EQ)) { + emitter.emit_set_value(); + expression(); + emitter.emit_constant(variable, parser.depth); + } + + consume(TOKEN_SEMICOLON); + emitter.emit_end_statement(); + parser.current_type = SYMBOL_UNDEFINED; + return size; +} + void binary() { @@ -388,9 +438,9 @@ variable() parser.current_type = sym->type; if(match(TOKEN_EQ)) { expression(); - emitter.emit_set_variable(sym, parser.depth); + emitter.emit_set_variable(sym, sym->scope); } else { - emitter.emit_variable(sym, parser.depth); + emitter.emit_variable(sym, sym->scope); } } @@ -484,49 +534,6 @@ cast_type() } } -u32 -variable_declaration(Symbol *def) -{ - i32 size = 0; - TokenType tt = parser.previous.type; - Token var = parser.current; - SymbolType st = token_type_to_sym_type(tt); - Symbol *variable; - - if(st != SYMBOL_UNDEFINED) { - size = emitter.get_size(st); - variable = - scope_add_symbol(parser.current.start, parser.current.length, st, size); - if(def) { - List_push(arena, def->args, variable, sizeof(Symbol)); - } else { - emitter.emit_type(variable, parser.depth); - parser.current_type = st; - } - } else { - /* we need to look up the type */ - emitter.error("Not implemented", 16, parser.previous.line); - } - - advance(); - - if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size; - if(def) - emitter.error(parser.previous.start, parser.previous.length, - parser.previous.line); - - if(match(TOKEN_EQ)) { - emitter.emit_set_value(); - expression(); - emitter.emit_constant(var.start, var.length, parser.depth); - } - - consume(TOKEN_SEMICOLON); - emitter.emit_end_statement(); - parser.current_type = SYMBOL_UNDEFINED; - return size; -} - void declaration() { diff --git a/emit.h b/emit.h index 3d8f0a5..b3cfb6f 100644 --- a/emit.h +++ b/emit.h @@ -9,7 +9,6 @@ typedef void (*SymbolEmit)(Symbol *sym); typedef void (*ErrorMsg)(const char *str, i32 length, i32 line); typedef void (*VoidArgEmit)(); typedef void (*StrArgEmit)(const char *str, i32 length); -typedef void (*ConstEmit)(const char *str, i32 length, bool local); typedef void (*VarEmit)(Symbol *sym, bool local); typedef void (*I32ArgEmit)(i32 val); @@ -56,7 +55,7 @@ struct emitter_s { VoidArgEmit emit_not; VoidArgEmit emit_open_paren; VoidArgEmit emit_close_paren; - ConstEmit emit_constant; + VarEmit emit_constant; VarEmit emit_variable; VarEmit emit_set_variable; VoidArgEmit emit_write; diff --git a/emit/rer/emit.c b/emit/rer/emit.c index 4c86b7c..582faff 100644 --- a/emit/rer/emit.c +++ b/emit/rer/emit.c @@ -270,12 +270,15 @@ rer_emit_str(const char *str, i32 length) } void -rer_emit_constant(const char *str, i32 length, bool local) +rer_emit_constant(Symbol *sym, bool local) { if(local) - printf(",/%.*s STR2 ", length, str); + if(sym->ref) + printf("\tSTH2kr #%04x ADD2 LDA2\n", sym->ref); + else + printf("\tSTH2kr LDA2\n"); else - printf(";%.*s STA2 ", length, str); + printf(";%.*s STA2 ", sym->name_length, sym->name); } void diff --git a/emit/uxn/emit.c b/emit/uxn/emit.c index 593354d..9665144 100644 --- a/emit/uxn/emit.c +++ b/emit/uxn/emit.c @@ -435,12 +435,15 @@ uxn_emit_str(const char *str, i32 length) } void -uxn_emit_constant(const char *str, i32 length, bool local) +uxn_emit_constant(Symbol *sym, bool local) { if(local) - printf(",/%.*s STR2 ", length, str); + if(sym->ref) + printf("\tSTH2kr #%04x ADD2 STA2\n", sym->ref); + else + printf("\tSTH2kr STA2\n"); else - printf(";%.*s STA2 ", length, str); + printf(";%.*s STA2 ", sym->name_length, sym->name); } void diff --git a/test/attack.ul b/test/attack.ul index 5b193e1..8a80fc2 100755 --- a/test/attack.ul +++ b/test/attack.ul @@ -2,7 +2,9 @@ str msg = " damage inflicted!\n" nat AT = 14; nat accuracy = 150; -nat dmg = ((AT * accuracy) / 20) - 3; +function main() { + nat dmg = ((AT * accuracy) / 20) - 3; -print(dmg as str); -print(msg); + print(dmg as str); + print(msg); +} diff --git a/test/fib.tal b/test/fib.tal new file mode 100644 index 0000000..1998158 --- /dev/null +++ b/test/fib.tal @@ -0,0 +1,82 @@ +|100 + LIT2r 0000 main_ POP2r BRK + +@main_ ( -- ) + +#0017 fib_ nat_to_str_ str/ + &return + POP2r JMP2r + +@fib_ ( n -- res ) + OVR2r LIT2r 0002 SUB2r + STH2kr STA2 + + STH2kr LDA2 #0002 LTH2 #03 JCN !{ + STH2kr LDA2 !&return !&if_end.0 } &if_end.0 + STH2kr LDA2 #0002 SUB2 fib_ STH2kr LDA2 #0001 SUB2 fib_ ADD2 !&return &return + POP2r JMP2r + +@sext + #80 ANDk EQU #ff MUL SWP JMP2r + +@aalloc_ ( size* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + ;mem_length_ LDA2 STH2kr STA2 + ;mem_length_ LDA2k STH2kr INC2 INC2 LDA2 ADD2 SWP2 STA2 + ;mem_ STH2kr LDA2 ADD2 !&return + #0000 + + &return + POP2r JMP2r + +@amcpy_ ( length* from* -- result* ) + OVR2r LIT2r 0008 SUB2r STH2kr #0006 ADD2 STA2 + STH2kr #0004 ADD2 STA2 + STH2kr #0004 ADD2 LDA2 aalloc_ + STH2kr INC2 INC2 STA2 + #0000 STH2kr STA2 + + &begin.1 + STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.1 + STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA + POP + + &continue.1 + STH2kr LDA2k INC2k ROT2 STA2 + POP2 !&begin.1 + + &break.1 + STH2kr INC2 INC2 LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@nat_to_str_ ( n* -- result* ) + OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2 + #0005 STH2kr STA2 + + &begin.1 + STH2kr #0008 ADD2 LDA2 #000a OVR2 OVR2 DIV2 MUL2 SUB2 #0030 ADD2 STH2kr INC2 INC2 STH2kr LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP STH2kr #0008 ADD2 LDA2k #000a DIV2 SWP2 STA2 + + &continue.1 + #0000 STH2kr #0008 ADD2 LDA2 LTH2 ?&begin.1 + + &break.1 + #0005 STH2kr LDA2 SUB2 STH2kr INC2 INC2 STH2kr LDA2 ADD2 amcpy_ + !&return + #0000 + + &return + POP2r JMP2r + +@str/ ( str* -- ) + LDAk DUP ?{ POP POP2 JMP2r } + #18 DEO + INC2 !/ + +@mem_length_ #0000 +@mem_ diff --git a/test/global.ul b/test/global.ul index 446eb55..18897d2 100755 --- a/test/global.ul +++ b/test/global.ul @@ -1,3 +1,6 @@ int i = 122; int j = 32; -putchar((i - j)); + +function main() { + putchar((i - j)); +} diff --git a/test/if.ul b/test/if.ul index 4de67b7..06f11f6 100755 --- a/test/if.ul +++ b/test/if.ul @@ -1,9 +1,11 @@ -nat x = 20; +function main() { + nat x = 20; -if (x == 10) { - print("x is 10"); -} else if (x == 20) { - print("x is 20"); -} else { - print("x is something else"); -} + if (x == 10) { + print("x is 10"); + } else if (x == 20) { + print("x is 20"); + } else { + print("x is something else"); + } +} \ No newline at end of file