From: mike lowis Date: Tue, 11 May 2021 03:00:49 +0000 (-0400) Subject: added array temporaries but assignment is still busted X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=58b8ca6b4ca8fa87e6e9a94eec61143510a801ee;p=proto%2Fobnc.git added array temporaries but assignment is still busted --- diff --git a/cerise/backend/c99/codegen.c b/cerise/backend/c99/codegen.c index 56553f9..89adf8c 100644 --- a/cerise/backend/c99/codegen.c +++ b/cerise/backend/c99/codegen.c @@ -22,7 +22,7 @@ Type StringType = { .size = -1 }; -static char* TypeNames[] = { +static char* TypeNames[FORM_COUNT] = { [FORM_BOOL] = "bool", [FORM_INT] = "long", [FORM_REAL] = "double", @@ -47,32 +47,86 @@ static char* Operators[] = { // [IS] = ??? }; +static declare_var(Parser* p, Symbol* sym, int isref) +{ + char name[8192]; + if (sym->global) + { + printf("%s", (sym->export ? "" : "static ")); + snprintf(name, sizeof(name), "%s_%s", p->name, sym->name); + } + else + { + printf(" "); + snprintf(name, sizeof(name), "(%c%s)", + (char)(isref ? '*' : ' '), sym->name); + } + + if (sym->type->form == FORM_ARRAY) + { + Type* type = sym->type; + for (; type->form == FORM_ARRAY; type = type->base); + printf("%s %s", TypeNames[type->form], name); + for (type = sym->type; type->form == FORM_ARRAY; type = type->base) + { + printf("[%d]", type->size); + } + } + else + { + printf("%s %s", TypeNames[sym->type->form], name); + } +} + +static int declare_temp(Parser* p, Type* type, int isref) +{ + char name[32]; + int reg = p->curr_reg; + snprintf(name, sizeof(name), "_T%d", reg); +// puts("TEMP"); + Symbol sym = { + .class = SYM_VAR, + .name = name, + .type = type, + }; + declare_var(p, &sym, isref); +// puts("END"); + + p->curr_reg++; + return reg; +} + static void load_var(Parser* p, Item* item) { - (void)p; - switch (item->mode) + if (!item->reg) { - case ITEM_CONST: - /* TODO: range check the constant */ - printf(" const %s _T%d = %lld;\n", - TypeNames[item->type->form], p->curr_reg, item->imm.i); - item->reg = p->curr_reg; - p->curr_reg++; - - case ITEM_VAR: - break; - - case ITEM_MVAR: - /* TODO: range check the constant */ - printf(" const %s _T%d = %s_%s;\n", - TypeNames[item->type->form], p->curr_reg, p->name, item->imm.s); - item->reg = p->curr_reg; - p->curr_reg++; - break; - - case ITEM_REG: - /* nothing to do */ - break; + int isref = (item->type->form == FORM_ARRAY); + switch (item->mode) + { + case ITEM_CONST: + /* TODO: range check the constant */ + item->reg = declare_temp(p, item->type, 0); + printf(" = %lld;\n", item->imm.i); + break; + + case ITEM_VAR: + item->reg = declare_temp(p, item->type, isref); + printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s); + break; + + case ITEM_MVAR: + item->reg = declare_temp(p, item->type, isref); + printf(" = %c%s_%s;\n", + (isref ? '&' : ' '), p->name, item->imm.s); + break; + + case ITEM_REG: + /* nothing to do */ + break; + + default: + assert(!"bad load_var()"); + } } } @@ -80,24 +134,20 @@ static void load_var(Parser* p, Item* item) *****************************************************************************/ static void binary_op(Parser* p, int op, Item* a, Item* b) { - char* type = TypeNames[a->type->form]; char* oper = Operators[op]; - assert(type && oper); - printf(" const %s _T%d = _T%d %s _T%d;\n", - type, p->curr_reg, a->reg, oper, b->reg); - a->reg = p->curr_reg; - p->curr_reg++; + assert(oper); + int dest_reg = declare_temp(p, a->type, 0); + printf(" = _T%d %s _T%d;\n", a->reg, oper, b->reg); + a->reg = dest_reg; } static void unary_op(Parser* p, int op, Item* a) { - char* type = TypeNames[a->type->form]; char* oper = Operators[op]; - assert(type && oper); - printf(" const %s _T%d = %s _T%d;\n", - type, p->curr_reg, oper, a->reg); - a->reg = p->curr_reg; - p->curr_reg++; + assert(oper); + int dest_reg = declare_temp(p, a->type, 0); + printf(" = %s _T%d;\n", oper, a->reg); + a->reg = dest_reg; } /* Public Interface @@ -133,15 +183,8 @@ void codegen_imports(Parser* p) void codegen_var(Parser* p, Symbol* sym) { - if (sym->global) - { - printf("%s%s %s_%s;\n", - (sym->export ? "" : "static "), TypeNames[sym->type->form], p->name, sym->name); - } - else - { - printf(" %s %s;\n", TypeNames[sym->type->form], sym->name); - } + declare_var(p, sym, 0); + puts(";"); } void codegen_main(Parser* p) @@ -214,30 +257,29 @@ void codegen_binop(Parser* p, int op, Item* a, Item* b) void codegen_store(Parser* p, Item* a, Item* b) { - item_dump(a); - item_dump(b); +// item_dump(a); +// item_dump(b); if (a->mode == ITEM_MVAR && b->reg == 0) { -// if (a->offset) -// { -// printf(" (%s*)\n", -// TypeNames[a->type->form] -// -// ); -// } printf(" %s_%s = %lld;\n", p->name, a->imm.s, b->imm.i); } else if (a->mode == ITEM_MVAR) { -// if (a->offset) -// { -// printf(" (%s*)\n", -// TypeNames[a->type->form] -// -// ); -// } printf(" %s_%s = _T%d;\n", p->name, a->imm.s, b->reg); } + else if (a->mode == ITEM_VAR && b->reg == 0) + { + printf(" %s = %lld;\n", a->imm.s, b->imm.i); + } + else if (a->mode == ITEM_VAR) + { + printf(" %s = _T%d;\n", a->imm.s, b->reg); + } + else if (a->mode == ITEM_INDEX) + { + load_var(p, b); + printf(" _T%d = _T%d;\n", a->reg, b->reg); + } else { assert(!"bad store op"); @@ -274,7 +316,8 @@ void codegen_prepcall(Parser* p, Item* item) void codegen_call(Parser* p, Item* item, Item* args) { - printf(" const long _T%d = %s(", p->curr_reg, item->imm.s); + int dest_reg = declare_temp(p, item->type, 0); + printf(" = %s(", item->imm.s); while (args) { printf("_T%d", args->reg); @@ -284,8 +327,7 @@ void codegen_call(Parser* p, Item* item, Item* args) } args = args->next; } - item->reg = p->curr_reg; - p->curr_reg++; + item->reg = dest_reg; printf(");\n"); } @@ -296,16 +338,12 @@ void codegen_setarg(Parser* p, Item* item, bool firstarg) void codegen_return(Parser* p, Item* item) { - if (item) - { - load_var(p, item); - printf(" return _T%d;\n", item->reg); - } + load_var(p, item); + printf(" return _T%d;\n", item->reg); } void codegen_index(Parser* p, Item* array, Item* index) { -// codegen_binop(p, '*', index, base); if (index->mode == ITEM_CONST) { if (index->type->form != FORM_INT) @@ -320,7 +358,13 @@ void codegen_index(Parser* p, Item* array, Item* index) { error(p, "negative array index"); } - - array->offset = index->imm.i; } + + load_var(p, index); + load_var(p, array); + array->type = array->type->base; + array->mode = ITEM_INDEX; + int dest_reg = declare_temp(p, array->type, 1); + printf(" = _T%d[_T%d]\;\n", array->reg, index->reg); + array->reg = dest_reg; } diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 26c1a92..f721565 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -79,7 +79,8 @@ typedef struct LexFile { typedef struct Type { enum { - FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING + FORM_BOOL, FORM_INT, FORM_REAL, FORM_ARRAY, FORM_STRING, + FORM_COUNT } form; struct Type* base; int size; @@ -115,7 +116,7 @@ typedef struct Module { typedef struct Item { struct Item* next; enum { - ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG + ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG, ITEM_INDEX } mode; Symbol* sym; Type* type; diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 347be35..a5bb9f0 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -106,39 +106,46 @@ RULE(designator) { qualident(p, item); /* selector */ - switch ((int)peek(p)->type) + for (int done = 0; !done;) { -// case '.': -// expect(p, IDENT); -// break; - - case '[': + switch ((int)peek(p)->type) { - Item index = {0}; - expect(p, '['); - expression(p, &index); - if (item->type->form == FORM_ARRAY) - { - codegen_index(p, item, &index); - item->type = item->type->base; - } - else + // case '.': + // expect(p, IDENT); + // break; + + case '[': { - error(p, "attempting to index non-array value"); + Item index = {0}; + expect(p, '['); + expression(p, &index); + printf("%d\n", item->type->form ); + if (item->type->form == FORM_ARRAY) + { + codegen_index(p, item, &index); + item->type = item->type->base; + } + else + { + error(p, "attempting to index non-array value"); + } + expect(p, ']'); + break; } - expect(p, ']'); - break; - } -// -// case '^': -// expect(p, '^'); -// break; -// -// case '(': -// qualident(p); -// expect(p, ')'); -// break; + // case '^': + // expect(p, '^'); + // break; + + // case '(': + // qualident(p); + // expect(p, ')'); + // break; + + default: + done = 1; + break; + } } } @@ -424,7 +431,7 @@ RULE(var_decl) int nsyms = 0; Symbol* first = NULL; Symbol* sym = NULL; - Symbol* type = NULL; +// Symbol* type = NULL; char* name = NULL; bool export = false; @@ -439,14 +446,17 @@ RULE(var_decl) } while (accept(p, ',')); + Item base_type = {0}; expect(p, ':'); - name = expect_text(p, IDENT); - type = symbol_get(p, SYM_TYPE, name); + type(p, &base_type); + +// name = expect_text(p, IDENT); +// type = symbol_get(p, SYM_TYPE, name); /* apply the type to the newly created symbols */ for (int i = 0; i < nsyms; i++) { - first->type = type->type; + first->type = base_type.type; codegen_var(p, first); sym = first->next; } diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index d7d9328..77ba511 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -21,20 +21,23 @@ var b : Int c : Int d : Real - e : TypeB + e : array 5 of array 10 of Int procedure Foo*(e : Int, z : Int) : Int const FOO = 2 type foo = Int - var z : Int + var + z : Int + q : array 5 of array 10 of Int # procedure Bar() : Int # begin # end begin -# c = b * b; - return c; + c = 1; + z = 2; + return z; end begin @@ -104,5 +107,6 @@ begin # c = Foo(1,2); # e[0] = 1; # Foo(1,2); - e[0] = 1; + e[2][1] = 1; +# e[b] = 1; end