From fad545d52c78bc61bc7b3e56865bb507680b7cff Mon Sep 17 00:00:00 2001 From: zongor Date: Fri, 3 Jul 2026 10:36:25 -0700 Subject: [PATCH] add ability to set a variable in a static array. --- compiler.c | 19 +- emit.h | 3 +- emit/rer/emit.c | 776 +----------------------------------------------- emit/uxn/emit.c | 57 ++-- test/array.ul | 8 +- test/rw.ul | 4 - 6 files changed, 63 insertions(+), 804 deletions(-) delete mode 100644 test/rw.ul diff --git a/compiler.c b/compiler.c index c994889..f5a181d 100644 --- a/compiler.c +++ b/compiler.c @@ -635,21 +635,32 @@ variable(void) if (sym->type == SYMBOL_ARRAY) { u32 size = emitter->get_size(sym->secondary_type); - emitter->emit_deref_prolog(arena, code, sym); if (match(TOKEN_LBRACKET)) { + emitter->emit_deref_prolog(arena, code, sym); expression(); emitter->emit_address(arena, code, size); emitter->emit_mul(arena, code, size); emitter->emit_add(arena, code, size); /* add offset of "length"*/ emitter->emit_nat(arena, code, "2", 1); - emitter->emit_add(arena, code, size); - emitter->emit_deref(arena, code, size); - parser->current_type = sym->secondary_type; + emitter->emit_add(arena, code, size); + while (!match(TOKEN_RBRACKET)) { + /* eventually do something with multidimensional arrays */ } + + if (match(TOKEN_EQ)) { + expression(); + emitter->emit_stack_swap(arena, code, size); + emitter->emit_ref_store(arena, code, size); + } else { + emitter->emit_deref(arena, code, size); + } + parser->current_type = sym->secondary_type; + } else if (match(TOKEN_DOT)) { + emitter->emit_deref_prolog(arena, code, sym); if (sleq("length", parser->current.start, parser->current.length)) { emitter->emit_deref(arena, code, size); } else { diff --git a/emit.h b/emit.h index a067b3e..e421e29 100644 --- a/emit.h +++ b/emit.h @@ -104,11 +104,12 @@ struct emitter_s { VoidArgEmit emit_halt; SymbolEmit emit_deref_prolog; U32ArgEmit emit_deref; - VoidArgEmit emit_ref; U32ArgEmit emit_address; U32ArgEmit emit_zero_block; StrArgEmit emit_char; StrArgEmit emit_inline_str; + U32ArgEmit emit_ref_store; + U32ArgEmit emit_stack_swap; }; Emitter rer_emitter(void); diff --git a/emit/rer/emit.c b/emit/rer/emit.c index 3806c82..d0d5c63 100644 --- a/emit/rer/emit.c +++ b/emit/rer/emit.c @@ -1,780 +1,8 @@ #include "../../emit.h" -#include -#include - -char rer_temp_strbuf[256]; - -void -rer_emit_error(const char *str, i32 length, i32 line) -{ - fprintf(stderr, "\n===\nError at line: %d '%.*s'\n===\n", line, length, str); - exit(1); -} - -void -rer_mem(u32 a) -{ - USED(a); -} - -void -rer_prolog(Arena *a, List *out) -{ - /*StrBuf_append(a, out, "|100\n\tLIT2r 0000 main_ POP2r BRK\n\n");*/ - StrBuf_append(a, out, "|100\n\tLIT2r 0000\n\n"); -} - -void -rer_epilogue(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_add(Arena *a, List *out) -{ - StrBuf_append(a, out, "ADD2 "); -} - -void -rer_emit_sub(Arena *a, List *out) -{ - StrBuf_append(a, out, "SUB2 "); -} - -void -rer_emit_mul(Arena *a, List *out) -{ - StrBuf_append(a, out, "MUL2 "); -} - -void -rer_emit_div(Arena *a, List *out) -{ - StrBuf_append(a, out, "DIV2 "); -} - -void -rer_emit_lt(Arena *a, List *out) -{ - StrBuf_append(a, out, "LTH2 "); -} - -void -rer_emit_le(Arena *a, List *out) -{ - StrBuf_append(a, out, "ROT SWP LTH ?{ LTH #00 EQU JMPr } GTH JMPr "); -} - -void -rer_emit_gt(Arena *a, List *out) -{ - StrBuf_append(a, out, "GTH2 "); -} - -void -rer_emit_ge(Arena *a, List *out) -{ - StrBuf_append(a, out, "ROT SWP GTH ?{ GTH #00 EQU JMPr } LTH JMPr "); -} - -void -rer_emit_ne(Arena *a, List *out) -{ - StrBuf_append(a, out, "NEQ2 "); -} - -void -rer_emit_eq(Arena *a, List *out) -{ - StrBuf_append(a, out, "EQU2 "); -} - -void -rer_emit_false(Arena *a, List *out) -{ - StrBuf_append(a, out, "#0000 "); -} - -void -rer_emit_true(Arena *a, List *out) -{ - StrBuf_append(a, out, "#0001 "); -} - -void -rer_emit_nil(Arena *a, List *out) -{ - StrBuf_append(a, out, "#0000 "); -} - -void -rer_emit_neg(Arena *a, List *out) -{ - StrBuf_append(a, out, "#0000 SUB2 "); -} - -void -rer_emit_not(Arena *a, List *out) -{ - StrBuf_append(a, out, "#0000 EQU2 "); -} - -void -rer_emit_void(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -u32 -rer_get_size(SymbolType t) -{ - switch(t) { - case SYMBOL_BOOL: - return 1; - case SYMBOL_BYTE: - return 1; - case SYMBOL_INT: - return 2; - case SYMBOL_NAT: - return 2; - case SYMBOL_REAL: - return 2; - case SYMBOL_STR: - return 2; - case SYMBOL_U8: - return 1; - case SYMBOL_I8: - return 1; - case SYMBOL_I16: - return 2; - case SYMBOL_U16: - return 2; - case SYMBOL_I32: - return 4; - case SYMBOL_U32: - return 4; - case SYMBOL_F32: - return 4; - default: - break; - } - - return 0; -} - -void -rer_emit_type(Arena *a, List *out, Symbol *sym, bool local) -{ - if(local) { - if(sym->ref) { - sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2\n", sym->ref); - StrBuf_append(a, out, rer_temp_strbuf); - } else { - sprintf(rer_temp_strbuf, "\tSTH2kr LDA2\n"); - StrBuf_append(a, out, rer_temp_strbuf); - } - } else { - sprintf(rer_temp_strbuf, "!{ @%.*s $%d } ", sym->name_length, sym->name, - rer_get_size(sym->type)); - StrBuf_append(a, out, rer_temp_strbuf); - } -} - -void -rer_emit_int(Arena *a, List *out, const char *str, i32 length) -{ - i32 i = (i32)strtol(str, nil, 10); - sprintf(rer_temp_strbuf, "#%04x ", i); - StrBuf_append(a, out, rer_temp_strbuf); - USED(length); -} - -void -rer_emit_nat(Arena *a, List *out, const char *str, i32 length) -{ - u32 i = (u32)strtol(str, nil, 10); - sprintf(rer_temp_strbuf, "#%04x ", i); - StrBuf_append(a, out, rer_temp_strbuf); - USED(length); -} - -void -rer_emit_real(Arena *a, List *out, const char *str, i32 length) -{ - USED(str); - USED(length); - USED(a); - USED(out); - /// TODO: implement this -} - -void -rer_emit_byte(Arena *a, List *out, const char *str, i32 length) -{ - u8 i = (u8)strtol(str, nil, 10); - sprintf(rer_temp_strbuf, "#%04x ", i); - StrBuf_append(a, out, rer_temp_strbuf); - USED(length); -} - -void -rer_emit_str(Arena *a, List *out, const char *str, i32 length) -{ - /* set a pointer to the string literal and then jump over it */ - StrBuf_append(a, out, ";{ #0002 ADD2 } !{ "); - - i32 i = 1; - while(i < length - 1) { - char c = str[i++]; - if(c == '\\' && i < length - 1) { - switch(str[i++]) { - case 'n': - c = '\n'; - break; - case 't': - c = '\t'; - break; - case 'r': - c = '\r'; - break; - case '\\': - case '"': - case '\'': - break; - default: - i--; /* Rewind for unknown escapes */ - } - } - sprintf(rer_temp_strbuf, "%02x ", c); - StrBuf_append(a, out, rer_temp_strbuf); - } - - StrBuf_append(a, out, "00 } "); -} - -void -rer_emit_constant(Arena *a, List *out, Symbol *sym, bool local) -{ - if(local) { - if(sym->ref) { - sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref); - StrBuf_append(a, out, rer_temp_strbuf); - } else { - sprintf(rer_temp_strbuf, "\tSTH2kr STA2\n"); - StrBuf_append(a, out, rer_temp_strbuf); - } - } else { - sprintf(rer_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name); - StrBuf_append(a, out, rer_temp_strbuf); - } -} - -void -rer_emit_array(Arena *a, List *out, Symbol *sym, List *in) -{ - USED(a); - USED(out); - USED(sym); - USED(in); -} - -bool -rer_fn_loop_emit_args(Arena *a, List *out, void *data) -{ - Symbol *sym = ((Symbol *)data); - - if(sym->ref) { - sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2\n", sym->ref); - StrBuf_append(a, out, rer_temp_strbuf); - } else { - sprintf(rer_temp_strbuf, "\tSTH2kr STA2\n"); - - StrBuf_append(a, out, rer_temp_strbuf); - } - return true; -} - -bool -rer_fn_loop_emit_args_comment(Arena *a, List *out, void *data) -{ - Symbol *sym = ((Symbol *)data); - sprintf(rer_temp_strbuf, "%.*s ", sym->name_length, sym->name); - StrBuf_append(a, out, rer_temp_strbuf); - return true; -} - -void -rer_emit_function(Arena *a, List *out, Symbol *sym) -{ - sprintf(rer_temp_strbuf, "@%.*s_ ( ", sym->name_length, sym->name); - StrBuf_append(a, out, rer_temp_strbuf); - List_map_out(a, out, sym->args, rer_fn_loop_emit_args_comment); - sprintf(rer_temp_strbuf, " -- "); - StrBuf_append(a, out, rer_temp_strbuf); - if(sym->secondary_type != SYMBOL_UNDEFINED && - sym->secondary_type != SYMBOL_VOID) { - sprintf(rer_temp_strbuf, " res "); - StrBuf_append(a, out, rer_temp_strbuf); - } - sprintf(rer_temp_strbuf, ")\n"); - StrBuf_append(a, out, rer_temp_strbuf); - if(sym->size > 0) { - sprintf(rer_temp_strbuf, "\tOVR2r LIT2r %04x SUB2r\n", sym->size); - StrBuf_append(a, out, rer_temp_strbuf); - } - List_map_out(a, out, sym->args, rer_fn_loop_emit_args); - StrBuf_append(a, out, "\n"); -} - -void -rer_emit_arena_fn_return(Arena *a, List *out) -{ - StrBuf_append(a, out, "\t&return\n\t\tPOP2r JMP2r\n\n"); -} - -void -rer_emit_arena_fn_call(Arena *a, List *out, Symbol *sym) -{ - sprintf(rer_temp_strbuf, "%.*s_ ", sym->name_length, sym->name); - StrBuf_append(a, out, rer_temp_strbuf); -} - -void -rer_emit_plex(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_method(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_trait(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_const(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_open_paren(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_close_paren(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_variable(Arena *a, List *out, Symbol *sym, bool local) -{ - if(local) { - if(sym->ref) { - sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 LDA2 ", sym->ref); - StrBuf_append(a, out, rer_temp_strbuf); - } else { - sprintf(rer_temp_strbuf, "\tSTH2kr LDA2 "); - StrBuf_append(a, out, rer_temp_strbuf); - } - } else { - sprintf(rer_temp_strbuf, ";%.*s LDA2 ", sym->name_length, sym->name); - StrBuf_append(a, out, rer_temp_strbuf); - } -} - -void -rer_emit_set_variable(Arena *a, List *out, Symbol *sym, bool local) -{ - if(local) { - if(sym->ref) { - sprintf(rer_temp_strbuf, "\tSTH2kr #%04x ADD2 STA2 ", sym->ref); - StrBuf_append(a, out, rer_temp_strbuf); - } else { - sprintf(rer_temp_strbuf, "\tSTH2kr STA2 "); - StrBuf_append(a, out, rer_temp_strbuf); - } - } else { - sprintf(rer_temp_strbuf, ";%.*s STA2 ", sym->name_length, sym->name); - StrBuf_append(a, out, rer_temp_strbuf); - } -} - -void -rer_emit_write(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_read(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_open(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_close(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_stat(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_end_statement(Arena *a, List *out) -{ - StrBuf_append(a, out, "\n"); -} - -void -rer_emit_set_value(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_plex_def(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_cast_int_to_nat(Arena *a, List *out) -{ - StrBuf_append(a, out, "int_to_nat_ "); -} - -void -rer_emit_cast_int_to_real(Arena *a, List *out) -{ - StrBuf_append(a, out, "int_to_real_ "); -} - -void -rer_emit_cast_int_to_str(Arena *a, List *out) -{ - StrBuf_append(a, out, "int_to_str_ "); -} - -void -rer_emit_cast_nat_to_int(Arena *a, List *out) -{ - StrBuf_append(a, out, "nat_to_int_ "); -} - -void -rer_emit_cast_nat_to_real(Arena *a, List *out) -{ - StrBuf_append(a, out, "nat_to_real_ "); -} - -void -rer_emit_cast_nat_to_str(Arena *a, List *out) -{ - StrBuf_append(a, out, "nat_to_str_ "); -} - -void -rer_emit_cast_real_to_int(Arena *a, List *out) -{ - StrBuf_append(a, out, "real_to_int_ "); -} - -void -rer_emit_cast_real_to_nat(Arena *a, List *out) -{ - StrBuf_append(a, out, "real_to_nat_ "); -} - -void -rer_emit_cast_real_to_str(Arena *a, List *out) -{ - StrBuf_append(a, out, "real_to_str_ "); -} - -void -rer_emit_strbuf_init(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_strbuf_append(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_strbuf_to_str(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_arena_fn_return_plex(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_arena_fn_return_array(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_arena_fn_return_strbuf(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_cast_str_to_int(Arena *a, List *out) -{ - USED(a); - USED(out); -} -void -rer_emit_cast_str_to_nat(Arena *a, List *out) -{ - USED(a); - USED(out); -} -void -rer_emit_cast_str_to_real(Arena *a, List *out) -{ - USED(a); - USED(out); -} - -void -rer_emit_sll(Arena *a, List *out) -{ - StrBuf_append(a, out, "#40 SFT SFT "); -} - -void -rer_emit_srl(Arena *a, List *out) -{ - StrBuf_append(a, out, "SFT "); -} - -void -rer_emit_xor(Arena *a, List *out) -{ - StrBuf_append(a, out, "EOR2 "); -} - -void -rer_emit_mod(Arena *a, List *out) -{ - StrBuf_append(a, out, "DIV2k MUL2 SUB2 "); -} -void -rer_emit_or(Arena *a, List *out) -{ - StrBuf_append(a, out, "ORA2 "); -} - -void -rer_emit_and(Arena *a, List *out) -{ - StrBuf_append(a, out, "AND2 "); -} - -void -rer_emit_print(Arena *a, List *out) -{ - StrBuf_append(a, out, "str/ "); -} - -void -rer_emit_if(Arena *a, List *out) -{ - StrBuf_append(a, out, "#03 JCN !{ \n"); -} - -void -rer_emit_patch_if(Arena *a, List *out, i32 local_ifs) -{ - sprintf(rer_temp_strbuf, "!&if_end.%d } ", local_ifs); - StrBuf_append(a, out, rer_temp_strbuf); -} - -void -rer_emit_patch_if_done(Arena *a, List *out, i32 local_ifs) -{ - sprintf(rer_temp_strbuf, "&if_end.%d \n", local_ifs); - StrBuf_append(a, out, rer_temp_strbuf); -} - -void -rer_emit_while(Arena *a, List *out, i32 local_whiles) -{ - sprintf(rer_temp_strbuf, "&while.%d ", local_whiles); - StrBuf_append(a, out, rer_temp_strbuf); -} - -void -rer_emit_while_postfix(Arena *a, List *out) -{ - StrBuf_append(a, out, "#03 JCN !{ \n"); -} - -void -rer_emit_patch_while(Arena *a, List *out, i32 local_whiles) -{ - sprintf(rer_temp_strbuf, "!&while.%d } \n", local_whiles); - StrBuf_append(a, out, rer_temp_strbuf); -} - -void -rer_emit_early_return(Arena *a, List *out) -{ - StrBuf_append(a, out, "!&return "); -} - -void -rer_emit_halt(Arena *a, List *out) -{ - StrBuf_append(a, out, "POP2r BRK "); -} Emitter rer_emitter() { - return (Emitter){ - 0, - 0, - 0, - 0, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - nil, - }; + Emitter rer = {0}; + return rer; } diff --git a/emit/uxn/emit.c b/emit/uxn/emit.c index f383963..28e7d08 100644 --- a/emit/uxn/emit.c +++ b/emit/uxn/emit.c @@ -1016,24 +1016,6 @@ uxn_emit_str(Arena *a, List *out, Symbol *sym, const char *str, u32 length) StrBuf_append(a, out, "00 "); } - -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, u32 size) -{ - if (size > 1) - StrBuf_append(a, out, "LDA2 "); - else - StrBuf_append(a, out, "LDA "); - -} - bool fn_loop_emit_args(Arena *a, List *out, void *data) { @@ -1432,6 +1414,33 @@ uxn_emit_halt(Arena *a, List *out) StrBuf_append(a, out, "POP2r BRK "); } +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, u32 size) +{ + if (size > 1) + StrBuf_append(a, out, "LDA2 "); + else + StrBuf_append(a, out, "LDA "); + +} + +void +uxn_emit_ref_store(Arena *a, List *out, u32 size) +{ + if (size > 1) + StrBuf_append(a, out, "STA2 "); + else + StrBuf_append(a, out, "STA "); + +} + void uxn_emit_address(Arena *a, List *out, u32 ptr) { @@ -1446,6 +1455,15 @@ uxn_emit_zero_block(Arena *a, List *out, u32 ptr) StrBuf_append(a, out, uxn_temp_strbuf); } +void +uxn_emit_stack_swap(Arena *a, List *out, u32 size) +{ + if (size > 1) + StrBuf_append(a, out, "SWP2 "); + else + StrBuf_append(a, out, "SWP "); +} + Emitter uxn_emitter() { @@ -1536,10 +1554,11 @@ uxn_emitter() uxn_emit_halt, uxn_emit_deref_prolog, uxn_emit_deref, - nil, uxn_emit_address, uxn_emit_zero_block, uxn_emit_char, uxn_emit_inline_str, + uxn_emit_ref_store, + uxn_emit_stack_swap, }; } diff --git a/test/array.ul b/test/array.ul index 325e1c2..143e806 100644 --- a/test/array.ul +++ b/test/array.ul @@ -1,10 +1,14 @@ -nat[6] fixed_size = [1, 2, 3, 4, 5, 6]; +nat[6] fixed_size = [1, 2, 3, 4, 5, 0]; + +fixed_size[5] = 6; nat i = 0; while (i < fixed_size.length) { print(fixed_size[i] as str); - print(" "); + if (i < fixed_size.length - 1) { + print(" "); + } i = i + 1; } print("\n"); diff --git a/test/rw.ul b/test/rw.ul deleted file mode 100644 index ae57f81..0000000 --- a/test/rw.ul +++ /dev/null @@ -1,4 +0,0 @@ - -byte t = read; -write = t; -halt; \ No newline at end of file