]> git.mdlowis.com Git - proto/obnc.git/commitdiff
tweaked ast printing
authorMichael D. Lowis <mike.lowis@gentex.com>
Tue, 13 Jul 2021 20:57:25 +0000 (16:57 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Tue, 13 Jul 2021 20:57:25 +0000 (16:57 -0400)
cerise/build.sh
cerise/inc/cerise.h
cerise/src/ast.c
cerise/src/grammar.c
cerise/tests/Module.m

index 2eafd8cb0ffba690c64fc8c9d74f6fd59363680f..b8bd72ca4f57b209af259d2c85ad0663048b5158 100755 (executable)
@@ -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
 
index 221c0bc1bb313c02293696d5216bbaf4d9f4db9b..059aeb710363fe10db0a246069aa1c44474ee756 100644 (file)
@@ -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
  *****************************************************************************/
index 0391fee751a1c669ffd4ef0aa0c4a11d67587308..ea5d87668a1e15c591ea803c822ffe627b0603a4 100644 (file)
@@ -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);
 }
index 0c4fd177c4c0100160d278acb509d6279d87a9da..63ba7f1f87d29327f54076d6c5c930db992b2ec1 100644 (file)
@@ -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
index 7904aee9136c6cab975c4db5d930c130a9e522a0..15c976af9a55b9bfeaa866e5dd7627390826efd5 100644 (file)
@@ -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