]> git.mdlowis.com Git - proto/obnc.git/commitdiff
implemented function calls
authorMichael D. Lowis <mike.lowis@gentex.com>
Wed, 14 Jul 2021 17:14:07 +0000 (13:14 -0400)
committerMichael D. Lowis <mike.lowis@gentex.com>
Wed, 14 Jul 2021 17:14:07 +0000 (13:14 -0400)
cerise/src/ast.c
cerise/src/grammar.c
cerise/tests/Module.m

index f9a316366e0d0666b72d6076adc899c5571f189e..51760aa8ad7dad25db571f31938d1012e1d78f73 100644 (file)
@@ -6,6 +6,8 @@
     * (Done) Dead code elimination - (when building conditional and loop nodes)
     * (Done) Block coalescing (see above)
 
+    * Commutative property for constant folding
+
     * https://en.wikipedia.org/wiki/Bounds-checking_elimination
     * https://en.wikipedia.org/wiki/Compile-time_function_execution
     * https://en.wikipedia.org/wiki/Common_subexpression_elimination
@@ -358,17 +360,17 @@ AstNode* ast_block(void)
     return ast_new(BEGIN, &VoidType, NULL, NULL, NULL);
 }
 
-static void append(AstNode* node, AstNode* first, AstNode* last)
+static void append(AstNode* node, int offset, AstNode* first, AstNode* last)
 {
-    if (!node->links[0])
+    if (!node->links[offset + 0])
     {
-        node->links[0] = first;
-        node->links[1] = last;
+        node->links[offset + 0] = first;
+        node->links[offset + 1] = last;
     }
     else
     {
-        node->links[1]->hdr.next = first;
-        node->links[1] = last;
+        node->links[offset + 1]->hdr.next = first;
+        node->links[offset + 1] = last;
     }
 }
 
@@ -379,12 +381,12 @@ void ast_block_add(AstNode* blk, AstNode* stmt)
         appending all its statemtents */
     if (stmt->hdr.code == BEGIN)
     {
-        append(blk, stmt->links[0], stmt->links[1]);
+        append(blk, 0, stmt->links[0], stmt->links[1]);
     }
     /* otherwise just append the statement to the block */
     else
     {
-        append(blk, stmt, stmt);
+        append(blk, 0, stmt, stmt);
     }
 }
 
@@ -395,7 +397,7 @@ AstNode* ast_call(AstNode* func)
 
 void ast_call_add(AstNode* func, AstNode* arg)
 {
-    append(func, arg, arg);
+    append(func, 1, arg, arg);
 }
 
 AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2)
@@ -487,29 +489,34 @@ static void print(Parser* p, AstNode* node, int indent)
             break;
 
         case BEGIN:
+            printf("(begin\n");
+            for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next)
             {
-                printf("(begin\n");
-                for (AstNode* curr = node->links[0]; curr; curr = curr->hdr.next)
-                {
-                    print(p, curr, indent+1);
-                }
-                print_indent(indent, ")");
+                print(p, curr, indent+1);
             }
+            print_indent(indent, ")");
             break;
 
-        case IF:
+        case CALL:
+            printf("(call\n");
+            print(p, node->links[0], indent+1);
+            for (AstNode* curr = node->links[1]; curr; curr = curr->hdr.next)
             {
-                printf("(if\n");
-                print(p, node->links[0], indent+1);
-                print(p, node->links[1], indent+1);
-                if (node->links[2])
-                {
-                    print(p, node->links[2], indent+1);
-                }
-                print_indent(indent, ")");
+                print(p, curr, indent+1);
             }
+            print_indent(indent, ")");
             break;
 
+        case IF:
+            printf("(if\n");
+            print(p, node->links[0], indent+1);
+            print(p, node->links[1], indent+1);
+            if (node->links[2])
+            {
+                print(p, node->links[2], indent+1);
+            }
+            print_indent(indent, ")");
+            break;
 
         default:
             if (node->links[1])
index de79f236dfc10f38de00a7247c04668400994a48..125ffc7c2b0170642eaff1a59f403fb025e6c838 100644 (file)
@@ -20,7 +20,7 @@
 
 /* Item Handling
  *****************************************************************************/
-Field* add_field(Parser* p, Type* type, char* name, bool export)
+static Field* add_field(Parser* p, Type* type, char* name, bool export)
 {
     Field* prev = NULL;
     Field* curr = type->fields;
@@ -163,47 +163,44 @@ static AstNode* factor(Parser* p)
 
         case IDENT:
             expr = designator(p);
-//            if (accept(p, '('))
-//            {
-//                Symbol* proc = symbol_get(p, item->imm.s, SYM_PROC);
-//                item->type = proc->type->base;
-//                Field* args = proc->type->fields;
-//                Item arglist = {0};
-//                Item** currarg = &(arglist.next);
-//                while (args && !matches(p, ')'))
-//                {
-//                    Item argdef = { .type = args->type };
-//                    Item* argval = calloc(1, sizeof(Item));
-//                    expression(p, argval);
-//                    check_types(p, &argdef, argval);
-//                    codegen_setarg(p, argval, (arglist.next == 0));
-//                    *currarg = argval;
-//                    currarg = &(argval->next);
-//                    args = args->next;
-//                    if (args)
-//                    {
-//                        expect(p, ',');
-//                    }
-//                }
-//                if (args)
-//                {
-//                    error(p, "too few arguments to function '%s'", proc->name);
-//                }
-//                else if (!matches(p, ')'))
-//                {
-//                    bool comma = accept(p, ',');
-//                    if (comma && matches(p, ')'))
-//                    {
-//                        error(p, "trailing comma in argument list");
-//                    }
-//                    else
-//                    {
-//                        error(p, "too many arguments to function '%s'", proc->name);
-//                    }
-//                }
-//                codegen_call(p, item, arglist.next);
-//                expect(p, ')');
-//            }
+            if (accept(p, '('))
+            {
+                expr = ast_call(expr);
+                if (expr->hdr.type->form != FORM_PROC)
+                {
+                    error(p, "attempting to call a non-procedural value");
+                }
+
+                Field* args = expr->hdr.type->fields;
+                while (args && !matches(p, ')'))
+                {
+                    AstNode* val = expression(p);
+                    check_type(p, args->type, val);
+                    ast_call_add(expr, val);
+                    args = args->next;
+                    if (args)
+                    {
+                        expect(p, ',');
+                    }
+                }
+                if (args)
+                {
+                    error(p, "too few arguments to function");
+                }
+                else if (!matches(p, ')'))
+                {
+                    bool comma = accept(p, ',');
+                    if (comma && matches(p, ')'))
+                    {
+                        error(p, "trailing comma in argument list");
+                    }
+                    else
+                    {
+                        error(p, "too many arguments to function");
+                    }
+                }
+                expect(p, ')');
+            }
             break;
 
         default:
index 64187f5b3e2f7d47bf75b9a553c3c91bad04a6d4..836fe83060b33967491a115c78f29884d3851cb2 100644 (file)
@@ -151,4 +151,6 @@ begin
 #    c = Bar(42);
 #    c = 42;
 #    c = 24;
+
+    Bar(42);
 end