From 9c746ad15be570c4cb1fc97c4875109bd2efad0d Mon Sep 17 00:00:00 2001 From: zongor Date: Sat, 4 Jul 2026 15:01:14 -0700 Subject: [PATCH] WIP array fixes --- compiler.c | 185 +++++++++++++++++++++++++++++------------------------ 1 file changed, 102 insertions(+), 83 deletions(-) diff --git a/compiler.c b/compiler.c index 5fffe1c..b2079f0 100644 --- a/compiler.c +++ b/compiler.c @@ -209,7 +209,7 @@ expect(TokenType type) { if(!consume(type)) { emitter->error(parser->previous.start, parser->previous.length, - parser->previous.line); + parser->previous.line); } } @@ -278,20 +278,21 @@ calculate_strides(List *dims, List *strides) u32 num_dims = dims->count; u32 current_stride = 1; - if (num_dims == 1) { + if(num_dims == 1) { List_push(arena, strides, ¤t_stride, sizeof(u32)); - return; + return; } for(i = num_dims - 1; i > 0; i--) { List_push(arena, strides, ¤t_stride, sizeof(u32)); /* this is very slow but for small numbers of dimensions its fine */ - num = (u32*)List_get(dims, i); - if (num){ + num = (u32 *)List_get(dims, i); + if(num) { current_stride *= (*num); } else { - emitter->error("Tried to get a dimension that did not exist", 43, parser->previous.line); + emitter->error("Tried to get a dimension that did not exist", 43, + parser->previous.line); } } } @@ -303,7 +304,7 @@ define_array(void) TokenType tt = parser->previous.type; SymbolType st = token_type_to_sym_type(tt); Symbol *array; - + List *dims = List_init(arena); List *strides = List_init(arena); advance(); @@ -324,7 +325,7 @@ define_array(void) size = emitter->get_size(st) * flat_array_length; array = scope_add_symbol(parser->current.start, parser->current.length, - SYMBOL_ARRAY, size); + SYMBOL_ARRAY, size); array->secondary_type = st; calculate_strides(dims, strides); array->args = dims; @@ -334,9 +335,8 @@ define_array(void) void define_string(void) { - scope_add_symbol(parser->current.start, - parser->current.length, - SYMBOL_STR, 0); + scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_STR, + 0); } void @@ -358,14 +358,13 @@ build_symbol_table(char *source) define_plex(); } else if(match(TOKEN_KEYWORD_TRAIT)) { define_trait(); - } else if (parser->previous.type != TOKEN_KEYWORD_AS && match(TOKEN_TYPE_STR)) { + } else if(parser->previous.type != TOKEN_KEYWORD_AS && + match(TOKEN_TYPE_STR)) { define_string(); - } else if (parser->current.type >= TOKEN_TYPE_I8 && - parser->current.type <= TOKEN_TYPE_PTR) { + } else if(parser->current.type >= TOKEN_TYPE_I8 && + parser->current.type <= TOKEN_TYPE_PTR) { advance(); - if (check(TOKEN_LBRACKET)) { - define_array(); - } + if(check(TOKEN_LBRACKET)) define_array(); } else { /* in binary bytecode output mode we need to count the bytes here */ /* otherwise ignore everything */ @@ -389,51 +388,47 @@ variable_declaration(Symbol *def) Symbol *variable; List *array_literal; - - if (tt == TOKEN_TYPE_STR) { - variable = scope_get_symbol(parser->current_scope, - parser->current.start, - parser->current.length); - if (!variable) { + if(tt == TOKEN_TYPE_STR) { + variable = scope_get_symbol(parser->current_scope, parser->current.start, + parser->current.length); + if(!variable) { emitter->error("cannot find str symbol", 23, parser->current.line); return 0; } advance(); - if (match(TOKEN_EQ)) { + if(match(TOKEN_EQ)) { expect(TOKEN_LITERAL_STR); variable->size = parser->previous.length - 2; - emitter->emit_str(arena, memory, variable, parser->previous.start, parser->previous.length); + emitter->emit_str(arena, memory, variable, parser->previous.start, + parser->previous.length); expect(TOKEN_SEMICOLON); } parser->current_type = st; return emitter->get_size(st); - } - - if (parser->current.type == TOKEN_LBRACKET) { - while(!check(TOKEN_RBRACKET)) { - advance(); - } + } + + if(parser->current.type == TOKEN_LBRACKET) { + while(!check(TOKEN_RBRACKET)) advance(); advance(); - variable = scope_get_symbol(parser->current_scope, - parser->current.start, - parser->current.length); - if (!variable) { + variable = scope_get_symbol(parser->current_scope, parser->current.start, + parser->current.length); + if(!variable) { emitter->error("cannot find array symbol", 25, parser->current.line); return 0; } advance(); - if (match(TOKEN_EQ)) { + if(match(TOKEN_EQ)) { expect(TOKEN_LBRACKET); array_literal = List_init(arena); - while (!match(TOKEN_RBRACKET)) { - StrBuf_append_exactly(arena, array_literal, - (char*)parser->current.start, - parser->current.length); + while(!match(TOKEN_RBRACKET)) { + StrBuf_append_exactly(arena, array_literal, + (char *)parser->current.start, + parser->current.length); advance(); if(match(TOKEN_RBRACKET)) break; expect(TOKEN_COMMA); @@ -443,11 +438,13 @@ variable_declaration(Symbol *def) emitter->emit_array(arena, memory, variable, array_literal); } else { expect(TOKEN_SEMICOLON); - + emitter->emit_array(arena, memory, variable, nil); - emitter->emit_zero_block(arena, memory, variable->size * emitter->get_size(variable->secondary_type)); + emitter->emit_zero_block(arena, memory, + variable->size * + emitter->get_size(variable->secondary_type)); } - + parser->current_type = st; return emitter->get_size(st); } @@ -455,7 +452,8 @@ variable_declaration(Symbol *def) if(st != SYMBOL_UNDEFINED) { size = emitter->get_size(st); - variable = scope_add_symbol(parser->current.start, parser->current.length, st, size); + variable = scope_add_symbol(parser->current.start, parser->current.length, + st, size); if(!def && (parser->pass == 0)) return size; @@ -475,7 +473,7 @@ variable_declaration(Symbol *def) if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size; if(def) emitter->error(parser->previous.start, parser->previous.length, - parser->previous.line); + parser->previous.line); if(parser->pass == 0) return size; if(match(TOKEN_EQ)) { @@ -583,7 +581,7 @@ dot(void) parser->before.length); if(sym == nil) { emitter->error(parser->current.start, parser->current.length, - parser->current.line); + parser->current.line); } } @@ -595,7 +593,7 @@ variable(void) if(sym == nil) { return; emitter->error(parser->previous.start, parser->previous.length, - parser->previous.line); + parser->previous.line); } if(sym->type == SYMBOL_FUNCTION) { @@ -603,83 +601,87 @@ variable(void) return; } - if (sym->type == SYMBOL_STR) { + if(sym->type == SYMBOL_STR) { emitter->emit_deref_prolog(arena, code, sym); - if (match(TOKEN_LBRACKET)) { + if(match(TOKEN_LBRACKET)) { /* add offset of "length"*/ emitter->emit_nat(arena, code, "2", 1); emitter->emit_add(arena, code, 2); - expression(); - emitter->emit_add(arena, code, 2); - while (!match(TOKEN_RBRACKET)) { + expression(); + emitter->emit_add(arena, code, 2); + while(!match(TOKEN_RBRACKET)) { } - if (match(TOKEN_EQ)) { + if(match(TOKEN_EQ)) { expression(); emitter->emit_stack_rot(arena, code, 1); - emitter->emit_stack_rot(arena, code, 1); + emitter->emit_stack_rot(arena, code, 1); emitter->emit_ref_store(arena, code, 1); - } else { + } else { emitter->emit_deref(arena, code, 1); } parser->current_type = SYMBOL_BYTE; - } else if (match(TOKEN_DOT)) { - if (sleq("length", parser->current.start, parser->current.length)) { + } else if(match(TOKEN_DOT)) { + if(sleq("length", parser->current.start, parser->current.length)) { emitter->emit_deref(arena, code, 2); } else { - emitter->error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser->current.line); + emitter->error("arrays currently can only get their length, don't do " + "anything fancy yet...", + 75, parser->current.line); } parser->current_type = SYMBOL_NAT; advance(); } else { emitter->emit_nat(arena, code, "2", 1); - emitter->emit_add(arena, code, 2); + emitter->emit_add(arena, code, 2); /* emitter->emit_deref(arena, code); */ } return; } - if (sym->type == SYMBOL_ARRAY) { + if(sym->type == SYMBOL_ARRAY) { u32 size = emitter->get_size(sym->secondary_type); - if (match(TOKEN_LBRACKET)) { + if(match(TOKEN_LBRACKET)) { emitter->emit_deref_prolog(arena, code, sym); expression(); - emitter->emit_address(arena, code, 2); - emitter->emit_mul(arena, code, 2); + emitter->emit_address(arena, code, 2); + emitter->emit_mul(arena, code, 2); emitter->emit_add(arena, code, 2); /* add offset of "length"*/ emitter->emit_nat(arena, code, "2", 1); - emitter->emit_add(arena, code, 2); + emitter->emit_add(arena, code, 2); - while (!match(TOKEN_RBRACKET)) { + while(!match(TOKEN_RBRACKET)) { /* eventually do something with multidimensional arrays */ } - if (match(TOKEN_EQ)) { + if(match(TOKEN_EQ)) { expression(); - if (size == 1) { + if(size == 1) { emitter->emit_stack_rot(arena, code, 1); emitter->emit_stack_rot(arena, code, 1); } else { - emitter->emit_stack_swap(arena, code, 2); + emitter->emit_stack_swap(arena, code, 2); } emitter->emit_ref_store(arena, code, size); - } else { + } else { emitter->emit_deref(arena, code, size); } parser->current_type = sym->secondary_type; - } else if (match(TOKEN_DOT)) { + } else if(match(TOKEN_DOT)) { emitter->emit_deref_prolog(arena, code, sym); - if (sleq("length", parser->current.start, parser->current.length)) { + if(sleq("length", parser->current.start, parser->current.length)) { emitter->emit_deref(arena, code, size); } else { - emitter->error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser->current.line); + emitter->error("arrays currently can only get their length, don't do " + "anything fancy yet...", + 75, parser->current.line); } parser->current_type = SYMBOL_NAT; advance(); @@ -789,14 +791,16 @@ cast_type(void) break; } default: - emitter->error("Type cast not implemented for this type (oops)", 46, parser->previous.line); + emitter->error("Type cast not implemented for this type (oops)", 46, + parser->previous.line); } } void declaration(void) { - if(is_type() && (parser->current.type == TOKEN_IDENTIFIER || parser->current.type == TOKEN_LBRACKET) ) + if(is_type() && (parser->current.type == TOKEN_IDENTIFIER || + parser->current.type == TOKEN_LBRACKET)) variable_declaration(nil); else statement(); @@ -826,7 +830,8 @@ if_statement(void) statement(); emitter->else_if_depth--; } - if(emitter->else_if_depth == 0) emitter->emit_patch_if_done(arena, code, emitter->ifs++); + if(emitter->else_if_depth == 0) + emitter->emit_patch_if_done(arena, code, emitter->ifs++); } void @@ -930,19 +935,33 @@ grouping(void) void number(void) { - emitter->emit_int(arena, code, parser->previous.start, parser->previous.length); + switch(parser->current_type) { + case SYMBOL_BOOL: + case SYMBOL_BYTE: + case SYMBOL_U8: + case SYMBOL_I8: + emitter->emit_char(arena, code, parser->previous.start, + parser->previous.length); + break; + default: + emitter->emit_nat(arena, code, parser->previous.start, + parser->previous.length); + break; + } } void string(void) { - emitter->emit_inline_str(arena, code, parser->previous.start, parser->previous.length); + emitter->emit_inline_str(arena, code, parser->previous.start, + parser->previous.length); } void character(void) { - emitter->emit_char(arena, code, parser->previous.start, parser->previous.length); + emitter->emit_char(arena, code, parser->previous.start, + parser->previous.length); } void @@ -992,7 +1011,7 @@ ParseRule rules[] = { /* TOKEN_RBRACE */ {nil, nil, PREC_NONE}, /* TOKEN_LBRACKET */ {nil, nil, PREC_NONE}, /* TOKEN_RBRACKET */ {nil, nil, PREC_NONE}, - /* TOKEN_DOT */ {nil, dot, PREC_CALL}, + /* TOKEN_DOT */ {nil, dot, PREC_CALL}, /* TOKEN_IDENTIFIER */ {variable, nil, PREC_NONE}, /* TOKEN_LITERAL_INT */ {number, nil, PREC_NONE}, /* TOKEN_LITERAL_NAT */ {number, nil, PREC_NONE}, @@ -1025,7 +1044,7 @@ ParseRule rules[] = { /* TOKEN_KEYWORD_THIS */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_OPEN */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_READ */ {read, nil, PREC_NONE}, - /* TOKEN_KEYWORD_WRITE */ { write, nil, PREC_NONE}, + /* TOKEN_KEYWORD_WRITE */ {write, nil, PREC_NONE}, /* TOKEN_KEYWORD_STAT */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_CLOSE */ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_LOOP */ {nil, nil, PREC_NONE}, @@ -1070,7 +1089,7 @@ ParseRule rules[] = { /* TOKEN_KEYWORD_DEVMAP*/ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_BYTE*/ {nil, nil, PREC_NONE}, /* TOKEN_KEYWORD_CHAR*/ {character, nil, PREC_NONE}, - }; +}; void parse_precedence(Precedence precedence) @@ -1106,12 +1125,12 @@ emit_program(char *source) emitter->prolog(arena, code); while(!match(TOKEN_EOF)) declaration(); - + /*emitter->epilogue(arena, code);*/ } bool -compile(Arena *a, List *c, List* m, Emitter *e, char *source) +compile(Arena *a, List *c, List *m, Emitter *e, char *source) { Parser p = {0}; arena = a;