From: Michael D. Lowis Date: Tue, 13 Jul 2021 20:57:25 +0000 (-0400) Subject: tweaked ast printing X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=32c2d47caacf70c4b77a73d293aa11f22f78f275;p=proto%2Fobnc.git tweaked ast printing --- diff --git a/cerise/build.sh b/cerise/build.sh index 2eafd8c..b8bd72c 100755 --- a/cerise/build.sh +++ b/cerise/build.sh @@ -3,15 +3,15 @@ CCCMD="cc -g -Wall -Wextra --std=c99 -Iinc/" TEST_BACKEND=backend/test +# Update tag database and print todos ctags -R & +grep -rh TODO src/*.* backend/*/*.* | sed -E -e 's/ *\/\/ *//' -e 's/ *\/\* *(.*) *\*\//\1/' +# Now build and test it $CCCMD -D CERISE_TESTS -o cerisec-test src/*.c backend/test/*.c \ && $CCCMD -o cerisec src/*.c "backend/ssa"/*.c \ && ./cerisec-test \ && ./cerisec tests/Module.m -#&& $CCCMD -o cerisec src/*.c "backend/c99"/*.c \ -#&& $CCCMD -o cerisec-x86_64 src/*.c "backend/x86_64"/*.c \ - rm -f Module diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 221c0bc..059aeb7 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -205,7 +205,7 @@ double ast_asreal(Parser* p, AstNode* node); AstNode* ast_binop(int op, AstNode* left, AstNode* right); AstNode* ast_unop(int op, AstNode* operand); -// TODO: Add a store operation handler +AstNode* ast_store(AstNode* dest, AstNode* value); AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname); AstNode* ast_index(Parser* p, AstNode* array, AstNode* index); @@ -216,7 +216,7 @@ void ast_call_add(AstNode* func, AstNode* arg); AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2); AstNode* ast_return(AstNode* expr); -void ast_print(AstNode* expr); +void ast_print(Parser* p, AstNode* expr); /* Backend Code Generation and Base Type Definitions *****************************************************************************/ diff --git a/cerise/src/ast.c b/cerise/src/ast.c index 0391fee..ea5d876 100644 --- a/cerise/src/ast.c +++ b/cerise/src/ast.c @@ -40,7 +40,6 @@ bool ast_isconst(AstNode* node) case BOOL: case INT: case REAL: - case IDENT: ret = true; break; @@ -181,8 +180,6 @@ AstNode* ast_binop(int op, AstNode* left, AstNode* right) a->hdr.type = &BoolType; break; - // case IS: break; - default: assert(!"not a valid op"); break; @@ -291,21 +288,55 @@ AstNode* ast_unop(int op, AstNode* operand) return ret; } +AstNode* ast_store(AstNode* dest, AstNode* value) +{ + /* TODO: validate left-hand side is assignable */ + return ast_new('=', &VoidType, dest, value, NULL); +} + +static Field* get_field(Parser* p, Type* type, char* name) +{ + Field* curr = type->fields; + while (curr) + { + if (curr->name && !strcmp(curr->name, name)) + { + break; + } + curr = curr->next; + } + if (!curr) + { + error(p, "record has no such field '%s'\n", name); + } + return curr; +} + AstNode* ast_fieldref(Parser* p, AstNode* record, char* fname) { - /* TODO: actually access the field and check that it exists */ + Field* field = get_field(p, record->hdr.type, fname); + AstNode* offset = ast_int(field->offset); + if (record->hdr.code == '.') + { + /* accumulate the offset into an existing record access */ + record->links[1] = ast_binop('+', record->links[1], offset); + record->hdr.type = field->type; + } + else + { + /* create a new record access node */ + record = ast_new('.', field->type, record, offset, NULL); + } return record; } AstNode* ast_index(Parser* p, AstNode* array, AstNode* index) { - /* TODO: actually access the array index */ - /* - * offset = index * sizeof(base) - * array->type = array->type->base; - * return new ast(ARRAY, base, offset) - */ - return array; + if (ast_isconst(index) && ast_asint(p, index) >= array->hdr.type->size) + { + error(p, "constant array index out of bounds"); + } + return ast_new('[', array->hdr.type->base, array, index, NULL); } AstNode* ast_block(void) @@ -315,8 +346,17 @@ AstNode* ast_block(void) void ast_block_add(AstNode* blk, AstNode* stmt) { - /* TODO: append to linked list */ - (void)blk, (void)stmt; + assert(blk->hdr.code == BEGIN); + if (!blk->links[0]) + { + blk->links[0] = stmt; + blk->links[1] = stmt; + } + else + { + blk->links[1]->hdr.next = stmt; + blk->links[1] = stmt; + } } AstNode* ast_call(AstNode* func) @@ -340,9 +380,38 @@ AstNode* ast_return(AstNode* expr) return ast_new(RETURN, &VoidType, expr, NULL, NULL); } -void ast_print(AstNode* node) +static void print_indent(int indent, char* str) +{ + /* print the indent */ + for (int i = 0; i < indent; i++) + { + printf(" "); + } + if (str) + { + printf("%s", str); + } +} + +static void print_opcode(AstNode* node) +{ + int op = node->hdr.code; + if (op < 256) + { + printf("(%c\n", op); + } + else + { + printf("(%d\n", op); + } +} + +static void print(Parser* p, AstNode* node, int indent) { assert(node); + print_indent(indent, NULL); + + /* now print the data */ switch(node->hdr.code) { case BOOL: @@ -358,20 +427,51 @@ void ast_print(AstNode* node) break; case IDENT: - printf("S:%lld", ((AstValue*)node)->val.i); + { + Symbol* s = symbol_getbyid(p, ((AstValue*)node)->val.i); + printf("S:%s", s->name); + } + break; + + case '.': + printf("(field-ref)"); + break; + + case '[': + printf("(array-index)"); + break; + + case BEGIN: + { + printf("(begin\n"); + for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next) + { + print(p, curr, indent+1); + } + printf(")"); + } break; default: if (node->links[1]) { - printf("(binop)"); + print_opcode(node); + print(p, node->links[0], indent+1); + print(p, node->links[1], indent+1); + print_indent(indent, ")"); } else { - printf("(%d ", node->hdr.code); - ast_print(node->links[0]); - printf(")"); + print_opcode(node); + print(p, node->links[0], indent+1); + print_indent(indent, ")"); } break; } + puts(""); +} + +void ast_print(Parser* p, AstNode* node) +{ + print(p, node, 0); } diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index 0c4fd17..63ba7f1 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -439,7 +439,7 @@ static AstNode* statement_seq(Parser* p) { AstNode* right = expression(p); check_types(p, expr, right); - expr = ast_binop('=', expr, right); + expr = ast_store(expr, right); } expect(p, ';'); ast_block_add(block, expr); @@ -500,10 +500,9 @@ static void const_decl(Parser* p) sym = symbol_new(p, 0, name, SYM_CONST, export); expect(p, '='); sym->value = expression(p); - ast_print(sym->value); - puts(""); } while (matches(p, IDENT)); + EXIT_RULE(); } @@ -647,16 +646,12 @@ static void module(Parser* p) // proc_decl(p); // } -// codegen_startproc(p, NULL); if (accept(p, BEGIN)) { -// codegen_imports(p); AstNode* block = statement_seq(p); - ast_print(block); - puts(""); + ast_print(p, block); expect(p, END); } -// codegen_endproc(p); if (!matches(p, END_FILE)) { @@ -692,7 +687,6 @@ void compile(char* fname) char* fcontents = file_load(fname); Parser* p = &(Parser){ .name = NULL, -// .scope = &RealSym, .file = &(LexFile){ .path = fname, .fbeg = fcontents, @@ -705,11 +699,7 @@ void compile(char* fname) symbol_new(p, 0, "Int", SYM_TYPE, 0)->type = &IntType; symbol_new(p, 0, "Real", SYM_TYPE, 0)->type = &RealType; symbol_new(p, 0, "String", SYM_TYPE, 0)->type = &StringType; - -// codegen_startmod(p); module(p); -// codegen_main(p); -// codegen_endmod(p); } /* Grammar Unit Tests diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 7904aee..15c976a 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -59,7 +59,7 @@ var # return a; #end -#begin +begin # h[1].i = 42; # a = true; # a = A; @@ -71,7 +71,7 @@ var # b = -b; # # # Arithmetic ops -# c = b + 1; + c = b + 1; # c = b - 1; # c = b * 1; # c = b / 1; @@ -142,4 +142,4 @@ var # c = Bar(42); # c = 42; # c = 24; -#end +end