fix local variables, wip: globals

This commit is contained in:
zongor 2026-05-22 14:31:13 -07:00
parent 28598e354a
commit 251101ecb8
9 changed files with 168 additions and 66 deletions

View File

@ -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 */
};

View File

@ -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()
{

3
emit.h
View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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);
}

82
test/fib.tal Normal file
View File

@ -0,0 +1,82 @@
|100
LIT2r 0000 main_ POP2r BRK
@main_ ( -- )
#0017 fib_ nat_to_str_ str/<print>
&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/<print> ( str* -- )
LDAk DUP ?{ POP POP2 JMP2r }
#18 DEO
INC2 !/<print>
@mem_length_ #0000
@mem_

View File

@ -1,3 +1,6 @@
int i = 122;
int j = 32;
putchar((i - j));
function main() {
putchar((i - j));
}

View File

@ -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");
}
}