diff --git a/15_A4.y b/15_A4.y index 259f5dd..a7ec989 100644 --- a/15_A4.y +++ b/15_A4.y @@ -124,7 +124,7 @@ constant: | CHARCONST primary_expression: - IDENTIFIER {Symbol *sym = SymLookup($1); if (sym == NULL) { + IDENTIFIER {Symbol *sym = SymLookup($1, 1); if (sym == NULL) { char err[384]; sprintf(err, "Symbol not found: %s", $1); yyerror(err); @@ -242,7 +242,7 @@ unary_expression: $$ = PURE_EXPR(SymInit(kind)); - $$.sym = SymLookup(name); + $$.sym = SymLookup(name, 1); if ($$.sym != NULL) { free(name); @@ -258,7 +258,8 @@ unary_expression: Emit(UnaryOp(DEREF, ASym($$), ASym($2))); } | '+' unary_expression { - $$ = PURE_EXPR(GenTemp()); + $$ = PURE_EXPR(GenTemp()); + if ($2.sym->initial_value != 0) { $$.sym->initial_value = $2.sym->initial_value; } else { @@ -288,7 +289,17 @@ unary_expression: multiplicative_expression: unary_expression | multiplicative_expression '*' unary_expression { - $$ = PURE_EXPR(GenTemp()); + $$ = PURE_EXPR(GenTemp()); + + // if (!TypeEqual($1.sym->type, $3.sym->type)) { + + // if (TypeCompatible($1.sym->type, $3.sym->type)) { + // $3.sym = Cast($3.sym, $1.sym->type); + // } + + // yyerror("can't multiply different types"); + // YYABORT; + // } if ($1.sym->initial_value != 0 && $3.sym->initial_value != 0) { $$.sym->initial_value = $1.sym->initial_value * $3.sym->initial_value; @@ -466,6 +477,7 @@ assignment_expression: } Emit(Mov(ASym($1), ASym($3))); + $$ = $1; } expression: @@ -508,7 +520,7 @@ declaration: YYABORT; } - Symbol *existing = SymLookup($$.sym->name); + Symbol *existing = SymLookup($$.sym->name, 1); $$.sym->size = GetSize($$.sym->type); if (existing != NULL && $$.sym->type.kind != FUNC_T) { @@ -715,7 +727,7 @@ jump_statement: $$ = NULL; if ($2.has_expr == 1) { - Emit(Mov(((Addr){SYMBOL_A, .sym = SymLookup("__retval")}), ASym($2.expr))); + Emit(Mov(((Addr){SYMBOL_A, .sym = SymLookup("__retval", 0)}), ASym($2.expr))); } Emit(Return(AImm(0))); @@ -750,7 +762,7 @@ function_definition: current_table = &glb_table; - Symbol *existing = SymLookup($2.sym->name); + Symbol *existing = SymLookup($2.sym->name, 0); if (existing != NULL) { // TODO: validate signature against existing entry @@ -766,8 +778,12 @@ function_definition: } compound_statement { current_table = &glb_table; - Backpatch($4, quads_size); - Emit(Return(AImm(0))); + if (quads[quads_size - 1].opcode != RET) { + Backpatch($4, quads_size); + Emit(Return(AImm(0))); + } else { + Backpatch($4, quads_size - 1); + } } %% diff --git a/15_A4_translator.c b/15_A4_translator.c index 9c58f94..302979b 100644 --- a/15_A4_translator.c +++ b/15_A4_translator.c @@ -125,7 +125,7 @@ void Emit(Quad q) { static void DisplayAddr(Addr a) { switch (a.kind) { case IMMEDIATE: printf("%d", a.imm); break; - case SYMBOL_A: printf("%s", a.sym->name); break; + case SYMBOL_A: printf("%s", a.sym->name); if(a.sym->initial_value != 0) printf("(%d)", a.sym->initial_value); break; } } @@ -136,7 +136,8 @@ void DisplayQuad(Quad q) { case MUL: case DIV: case MOD: - printf("%s = ", q.rd.sym->name); + DisplayAddr(q.rd); + printf(" = ", q.rd.sym->name); DisplayAddr(q.rs); printf(" %s ", OpSym[q.opcode]); DisplayAddr(q.rt); @@ -145,21 +146,25 @@ void DisplayQuad(Quad q) { case NEG: case ADDR: case DEREF: - printf("%s = %s", q.rd.sym->name, OpSym[q.opcode]); + DisplayAddr(q.rd); + printf(" = %s", q.rd.sym->name, OpSym[q.opcode]); DisplayAddr(q.rs); break; case JMP: - printf("goto %d", q.rd.imm); + printf("goto "); + DisplayAddr(q.rd); break; case JIF: printf("if "); DisplayAddr(q.rs); - printf(" goto %d", q.rd.imm); + printf(" goto "); + DisplayAddr(q.rd); break; case JNT: printf("ifFalse "); DisplayAddr(q.rs); - printf(" goto %d", q.rd.imm); + printf(" goto "); + DisplayAddr(q.rd); break; case JLT: case JGT: @@ -171,42 +176,58 @@ void DisplayQuad(Quad q) { DisplayAddr(q.rs); printf(" %s ", OpSym[q.opcode]); DisplayAddr(q.rt); - printf(" goto %d", q.rd.imm); + printf(" goto "); + DisplayAddr(q.rd); break; case PAR: printf("param "); DisplayAddr(q.rs); break; case CAL: - if (q.rs.kind == SYMBOL_A) - printf("%s = call %s, %d", q.rs.sym->name, q.rd.sym->name, q.rt.imm); - else if (q.rs.kind == IMMEDIATE) { - printf("call %s, %d", q.rd.sym->name, q.rd.imm); + if (q.rs.kind == SYMBOL_A) { + DisplayAddr(q.rs); + printf(" = call "); + DisplayAddr(q.rd); + printf(", "); + DisplayAddr(q.rt); + } else if (q.rs.kind == IMMEDIATE) { + printf("call "); + DisplayAddr(q.rd); + printf(", "); + DisplayAddr(q.rt); } break; case RET: printf("return"); if (q.rs.kind != IMMEDIATE) { - printf(" %s", q.rs.sym->name); + printf(" "); + DisplayAddr(q.rs); } break; case INDR: - printf("%s = %s[", q.rd.sym->name, q.rs.sym->name); + DisplayAddr(q.rd); + printf(" = "); + DisplayAddr(q.rs); + printf("["); DisplayAddr(q.rt); printf("]"); break; case INDW: - printf("%s[", q.rd.sym->name); + DisplayAddr(q.rd); + printf("["); DisplayAddr(q.rs); printf("] = "); DisplayAddr(q.rt); break; case PTRW: - printf("*%s = ", q.rd.sym->name); + printf("*"); + DisplayAddr(q.rd); + printf(" = "); DisplayAddr(q.rs); break; case MOV: - printf("%s = ", q.rd.sym->name); + DisplayAddr(q.rd); + printf(" = "); DisplayAddr(q.rs); break; case FN_LABEL: @@ -528,7 +549,7 @@ Symbol *Cast(Symbol *sym, Type type) { return new; } -Symbol *SymLookup(const char *name) { +Symbol *SymLookup(const char *name, char traverse_up) { Symbol *sym = current_table->sym_head; while (sym) { if (!strcmp(sym->name, name)) @@ -537,10 +558,12 @@ Symbol *SymLookup(const char *name) { sym = sym->next; } + if (!traverse_up) return NULL; + SymbolTable *tab = current_table; if (current_table->parent != NULL) { current_table = current_table->parent; - sym = SymLookup(name); + sym = SymLookup(name, 1); current_table = tab; return sym; @@ -549,29 +572,6 @@ Symbol *SymLookup(const char *name) { return NULL; } -Symbol *SymLookupOrInsert(const char *name) { - Symbol *sym = SymLookup(name); - - if (sym == NULL) { - sym = malloc(sizeof(*sym)); - - sym->name = strdup(name); - sym->type = (Type) { - .kind = PRIMITIVE_T, - .primitive = INT_T - }; - sym->initial_value = 0; - sym->size = size_of_int; - sym->offset = 0; - sym->inner_table = NULL; - sym->next = NULL; - - SymInsert(sym); - } - - return sym; -} - Symbol *StringLookupOrInsert(const char *str) { size_t len = strlen(str); char *name = malloc(len + 7); @@ -581,7 +581,7 @@ Symbol *StringLookupOrInsert(const char *str) { SymbolTable *c = current_table; current_table = &glb_table; - Symbol *sym = SymLookup(name); + Symbol *sym = SymLookup(name, 0); char new = sym == NULL; @@ -616,7 +616,25 @@ Symbol *GenTemp() char name[20]; sprintf(name, "__t_%d_", current_table->temp_count++); - Symbol *sym = SymLookupOrInsert(name); + Symbol *sym = SymLookup(name, 0); + + if (sym == NULL) { + sym = malloc(sizeof(*sym)); + + sym->name = strdup(name); + sym->type = (Type) { + .kind = PRIMITIVE_T, + .primitive = INT_T + }; + sym->initial_value = 0; + sym->size = size_of_int; + sym->offset = 0; + sym->inner_table = NULL; + sym->next = NULL; + + SymInsert(sym); + } + sym->type.kind = PRIMITIVE_T; sym->is_temp = 1; sym->type.primitive = INT_T; diff --git a/15_A4_translator.h b/15_A4_translator.h index d7e0374..46bda39 100644 --- a/15_A4_translator.h +++ b/15_A4_translator.h @@ -128,8 +128,7 @@ typedef struct _Symbol { Symbol *SymInit(enum KIND_T kind); Symbol *SymClone(Symbol *sym); Symbol *Cast(Symbol *sym, Type type); -Symbol *SymLookup(const char *name); -Symbol *SymLookupOrInsert(const char *name); +Symbol *SymLookup(const char *name, char traverse_up); Symbol *StringLookupOrInsert(const char *str); Symbol *GenTemp(); void SymInsert(Symbol *sym); diff --git a/testsimple.nc b/testsimple.nc index 7cb1b43..dacb49c 100644 --- a/testsimple.nc +++ b/testsimple.nc @@ -4,7 +4,8 @@ char POPPING_thing = 'c'; void printf(char *c, int argv); int main(int argc, char *argv) { - int i = GLOB; + int i; + i = GLOB * 5; for (i = 0; i < argc; i = i + 1) {