From 74f5c58f23855ba431a00b28bef1b2a899ce2772 Mon Sep 17 00:00:00 2001 From: zongor Date: Sun, 28 Jun 2026 21:50:51 -0700 Subject: [PATCH] Initial Array Handling!! --- compiler.c | 49 ++++++-- emit.h | 5 + emit/rer/emit.c | 8 +- emit/uxn/emit.c | 52 ++++++--- test/array.ul | 3 +- test/tal/array.tal | 280 +++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 371 insertions(+), 26 deletions(-) create mode 100644 test/tal/array.tal diff --git a/compiler.c b/compiler.c index c3bf308..d7c6991 100644 --- a/compiler.c +++ b/compiler.c @@ -173,6 +173,17 @@ check(TokenType type) return parser.current.type == type; } +bool +consume_is_type() +{ + if(is_type()) { + advance(); + return true; + } + + return false; +} + bool consume(TokenType type) { @@ -384,22 +395,30 @@ variable_declaration(Symbol *def) Symbol *variable; List *array_literal; - if (parser.current.type == TOKEN_LBRACE) { + if (parser.current.type == TOKEN_LBRACKET) { while(!check(TOKEN_RBRACKET)) { advance(); } + advance(); variable = scope_get_symbol(parser.current_scope, - parser.previous.start, - parser.previous.length); + parser.current.start, + parser.current.length); + if (!variable) { + emitter.error("cannot find array symbol", 24, parser.current.line); + return 0; + } + advance(); if (match(TOKEN_EQ)) { expect(TOKEN_LBRACKET); + array_literal = List_init(arena); while (!match(TOKEN_RBRACKET)) { StrBuf_append_exactly(arena, array_literal, - (char*)parser.previous.start, - parser.previous.length); + (char*)parser.current.start, + parser.current.length); + advance(); if(match(TOKEN_RBRACKET)) break; expect(TOKEN_COMMA); } @@ -550,6 +569,21 @@ variable() return; } + if (sym->type == SYMBOL_ARRAY) { + emitter.emit_deref_prolog(arena, code, sym); + + if (match(TOKEN_LBRACKET)) { + expression(); + emitter.emit_address(arena, code, emitter.get_size(sym->secondary_type)); + emitter.emit_mul(arena, code); + emitter.emit_add(arena, code); + emitter.emit_deref(arena, code); + while (!match(TOKEN_RBRACKET)) { + } + } + return; + } + parser.current_type = sym->type; if(match(TOKEN_EQ)) { expression(); @@ -659,7 +693,7 @@ cast_type() void declaration() { - if(is_type() && parser.current.type == TOKEN_IDENTIFIER) + if(is_type() && (parser.current.type == TOKEN_IDENTIFIER || parser.current.type == TOKEN_LBRACKET) ) variable_declaration(nil); else statement(); @@ -934,9 +968,10 @@ emit_program(char *source) advance(); emitter.prolog(arena, code); - emitter.epilogue(arena, memory); while(!match(TOKEN_EOF)) declaration(); + + emitter.epilogue(arena, code); } bool diff --git a/emit.h b/emit.h index d1401dc..f88939c 100644 --- a/emit.h +++ b/emit.h @@ -13,6 +13,7 @@ typedef void (*StrArgEmit)(Arena *a, List *out, const char *str, i32 length); typedef void (*VarEmit)(Arena *a, List *out, Symbol *sym, bool local); typedef void (*MultipleEmit)(Arena *a, List *out, Symbol *sym, List* in); typedef void (*I32ArgEmit)(Arena *a, List *out, i32 val); +typedef void (*U32ArgEmit)(Arena *a, List *out, u32 ptr); typedef struct emitter_s Emitter; struct emitter_s { @@ -100,6 +101,10 @@ struct emitter_s { I32ArgEmit emit_patch_while; VoidArgEmit emit_early_return; VoidArgEmit emit_halt; + SymbolEmit emit_deref_prolog; + VoidArgEmit emit_deref; + VoidArgEmit emit_ref; + U32ArgEmit emit_address; }; Emitter rer_emitter(); diff --git a/emit/rer/emit.c b/emit/rer/emit.c index 4f8c0a0..33bcde5 100644 --- a/emit/rer/emit.c +++ b/emit/rer/emit.c @@ -273,10 +273,12 @@ rer_emit_constant(Arena *a, List *out, Symbol *sym, bool local) } void -rer_emit_array(Arena *a, List *out) +rer_emit_array(Arena *a, List *out, Symbol *sym, List *in) { USED(a); USED(out); + USED(sym); + USED(in); } bool @@ -767,5 +769,9 @@ rer_emitter() rer_emit_patch_while, rer_emit_early_return, rer_emit_halt, + nil, + nil, + nil, + nil, }; } diff --git a/emit/uxn/emit.c b/emit/uxn/emit.c index 9b2585c..b97a76b 100644 --- a/emit/uxn/emit.c +++ b/emit/uxn/emit.c @@ -844,6 +844,9 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in) sprintf(uxn_temp_strbuf, "@%.*s ", sym->name_length, sym->name); StrBuf_append(a, out, uxn_temp_strbuf); + //sprintf(uxn_temp_strbuf, "%04x ", in->count); + //StrBuf_append(a, out, uxn_temp_strbuf); + switch(t) { case SYMBOL_BOOL: { curr = in->head; @@ -870,18 +873,19 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in) } break; } + case SYMBOL_I16: case SYMBOL_INT: { curr = in->head; while (curr) { char* tmp_str = node_value(curr); - i32 i = (i32)strtol(tmp_str, nil, 10); + i16 i = (i16)strtol(tmp_str, nil, 10); sprintf(uxn_temp_strbuf, "%04x ", i); StrBuf_append(a, out, uxn_temp_strbuf); curr = curr->next; } break; } - case SYMBOL_U32: + case SYMBOL_U16: case SYMBOL_ARRAY: case SYMBOL_PLEX: case SYMBOL_STR: @@ -889,7 +893,7 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in) curr = in->head; while (curr) { char* tmp_str = node_value(curr); - u32 i = (u32)strtol(tmp_str, nil, 10); + u16 i = (u16)strtol(tmp_str, nil, 10); sprintf(uxn_temp_strbuf, "%04x ", i); StrBuf_append(a, out, uxn_temp_strbuf); curr = curr->next; @@ -907,23 +911,12 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in) } break; } - case SYMBOL_I16: { + case SYMBOL_U32:{ curr = in->head; while (curr) { char* tmp_str = node_value(curr); - i16 i = (i16)strtol(tmp_str, nil, 10); - sprintf(uxn_temp_strbuf, "%04x ", i); - StrBuf_append(a, out, uxn_temp_strbuf); - curr = curr->next; - } - break; - } - case SYMBOL_U16: { - curr = in->head; - while (curr) { - char* tmp_str = node_value(curr); - u16 i = (u16)strtol(tmp_str, nil, 10); - sprintf(uxn_temp_strbuf, "%04x ", i); + u32 i = (u32)strtol(tmp_str, nil, 10); + sprintf(uxn_temp_strbuf, "%08x ", i); StrBuf_append(a, out, uxn_temp_strbuf); curr = curr->next; } @@ -951,6 +944,20 @@ uxn_emit_array(Arena *a, List *out, Symbol *sym, List *in) StrBuf_append(a, out, "\n\n"); } + +void +uxn_emit_deref_prolog(Arena *a, List *out, Symbol *sym) +{ + sprintf(uxn_temp_strbuf, ";%.*s ", sym->name_length, sym->name); + StrBuf_append(a, out, uxn_temp_strbuf); +} + +void +uxn_emit_deref(Arena *a, List *out) +{ + StrBuf_append(a, out, "LDA2 "); +} + bool fn_loop_emit_args(Arena *a, List *out, void *data) { @@ -1351,6 +1358,13 @@ uxn_emit_halt(Arena *a, List *out) StrBuf_append(a, out, "POP2r BRK "); } +void +uxn_emit_address(Arena *a, List *out, u32 ptr) +{ + sprintf(uxn_temp_strbuf, "#%04x ", ptr); + StrBuf_append(a, out, uxn_temp_strbuf); +} + Emitter uxn_emitter() { @@ -1439,5 +1453,9 @@ uxn_emitter() uxn_emit_patch_while, uxn_emit_early_return, uxn_emit_halt, + uxn_emit_deref_prolog, + uxn_emit_deref, + nil, + uxn_emit_address }; } diff --git a/test/array.ul b/test/array.ul index 325e1c2..b950410 100644 --- a/test/array.ul +++ b/test/array.ul @@ -2,7 +2,8 @@ nat[6] fixed_size = [1, 2, 3, 4, 5, 6]; nat i = 0; -while (i < fixed_size.length) { +//while (i < fixed_size.length) { +while (i < 6) { print(fixed_size[i] as str); print(" "); i = i + 1; diff --git a/test/tal/array.tal b/test/tal/array.tal new file mode 100644 index 0000000..4d4897c --- /dev/null +++ b/test/tal/array.tal @@ -0,0 +1,280 @@ +|100 + LIT2r 0000 + +!{ @i $2 } #0000 ;i STA2 +&while.0 ;i LDA2 #0006 LTH2 #03 JCN !{ +;fixed_size ;i LDA2 #0002 MUL2 ADD2 LDA2 nat_to_str_ str/ +;{ #0002 ADD2 } !{ 20 00 } str/ +;i LDA2 #0001 ADD2 ;i STA2 !&while.0 } +;{ #0002 ADD2 } !{ 0a 00 } str/ +POP2r BRK @sext + #80 ANDk EQU #ff MUL SWP JMP2r +@sdiv + OVR #80 AND ?&b_neg &b_pos OVR2 POP #80 AND ?&a_neg_b_pos DIV2 JMP2r &a_neg_b_pos SWP2 #0000 SWP2 SUB2 SWP2 DIV2 #0000 SWP2 SUB2 JMP2r + &b_neg #0000 SWP2 SUB2 OVR2 POP #80 AND ?&a_neg_b_neg DIV2 #0000 SWP2 SUB2 JMP2r + &a_neg_b_neg #0000 ROT2 SUB2 SWP2 DIV2 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 + +@areturn_ ( size* src* checkpoint* -- result* ) + OVR2r LIT2r 000a SUB2r STH2kr #0008 ADD2 STA2 + STH2kr #0006 ADD2 STA2 + STH2kr #0004 ADD2 STA2 + ;mem_ STH2kr #0008 ADD2 LDA2 ADD2 STH2kr INC2 INC2 STA2 + STH2kr #0006 ADD2 LDA2 STH2kr INC2 INC2 LDA2 NEQ2 ?&end.1 + STH2kr #0006 ADD2 LDA2 !&return + + &end.1 + #0000 STH2kr STA2 + + &begin.2 + STH2kr LDA2 STH2kr #0004 ADD2 LDA2 LTH2 #00 EQU ?&break.2 + STH2kr #0006 ADD2 LDA2 STH2kr LDA2 ADD2 LDA sext + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 STA + POP + + &continue.2 + STH2kr LDA2k INC2k ROT2 STA2 + POP2 !&begin.2 + + &break.2 + STH2kr #0008 ADD2 LDA2 STH2kr #0004 ADD2 LDA2 ADD2 ;mem_length_ STA2 + #0000 ;mem_ ;mem_length_ LDA2 ADD2 STA + POP STH2kr INC2 INC2 LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@afree_ ( -- result* ) + OVR2r #0000 ;mem_length_ STA2 + #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 + +@int_to_str_ ( n* -- result* ) + OVR2r LIT2r 000c SUB2r STH2kr #000a ADD2 STA2 + #0006 STH2kr INC2 INC2 STA2 + STH2kr #000a ADD2 LDA2 #8000 EOR2 #8000 LTH2 #00 SWP #0000 NEQ2 #00 SWP STH2kr STA + POP LDAkr STHr sext + #0000 EQU2 ?&end.1 + #0000 STH2kr #000a ADD2 LDA2 SUB2 STH2kr #000a ADD2 STA2 + + &end.1 + + &begin.2 + STH2kr #000a ADD2 LDA2 #000a OVR2 OVR2 sdiv/b_pos + MUL2 SUB2 #0030 ADD2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP STH2kr #000a ADD2 LDA2k #000a sdiv/b_pos + SWP2 STA2 + + &continue.2 + #8000 STH2kr #000a ADD2 LDA2 #8000 EOR2 LTH2 ?&begin.2 + + &break.2 + LDAkr STHr sext + #0000 EQU2 ?&end.3 + #002d STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2k #0001 SUB2 SWP2 STA2k + POP2 ADD2 STA + POP + + &end.3 + #0006 STH2kr INC2 INC2 LDA2 SUB2 STH2kr #0004 ADD2 STH2kr INC2 INC2 LDA2 ADD2 amcpy_ + !&return + #0000 + + &return + POP2r JMP2r + +@int_to_nat_ ( n* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@nat_to_int_ ( n* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 !&return + #0000 + + &return + POP2r JMP2r + +@int_add_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 ADD2 !&return + #0000 + + &return + POP2r JMP2r + +@int_sub_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 SUB2 !&return + #0000 + + &return + POP2r JMP2r + +@int_mul_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 MUL2 !&return + #0000 + + &return + POP2r JMP2r + +@int_div_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 sdiv + !&return + #0000 + + &return + POP2r JMP2r + +@int_eq_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 EQU2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_ne_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 STH2kr LDA2 NEQ2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_lt_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 #8000 EOR2 STH2kr LDA2 #8000 EOR2 LTH2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_le_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr INC2 INC2 LDA2 #8000 EOR2 STH2kr LDA2 #8000 EOR2 GTH2 #00 SWP #01 EOR !&return + #0000 + + &return + POP2r JMP2r + +@int_gt_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr LDA2 #8000 EOR2 STH2kr INC2 INC2 LDA2 #8000 EOR2 LTH2 #00 SWP !&return + #0000 + + &return + POP2r JMP2r + +@int_ge_ ( b* a* -- result* ) + OVR2r LIT2r 0004 SUB2r STH2kr INC2 INC2 STA2 + STH2kr STA2 + STH2kr LDA2 #8000 EOR2 STH2kr INC2 INC2 LDA2 #8000 EOR2 GTH2 #00 SWP #01 EOR !&return + #0000 + + &return + POP2r JMP2r + +@int_neg_ ( f* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + #0000 STH2kr LDA2 SUB2 !&return + #0000 + + &return + POP2r JMP2r + +@int_abs_ ( f* -- result* ) + OVR2r LIT2r 0002 SUB2r STH2kr STA2 + STH2kr LDA2 #8000 EOR2 #8000 LTH2 ?&then.1 + STH2kr LDA2 !&end.1 + + &then.1 + #0000 STH2kr LDA2 SUB2 + + &end.1 + !&return + #0000 + + &return + POP2r JMP2r + +@str/ ( str* -- ) + LDAk DUP ?{ POP POP2 JMP2r } + #18 DEO + INC2 !/ + +@mem_length_ #0000 +@mem_ @fixed_size 0001 0002 0003 0004 0005 0006 +