From 0c6dd06840d9710a367d9c0d16427491cb38c406 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Wed, 14 Jul 2021 13:14:07 -0400 Subject: [PATCH] implemented function calls --- cerise/src/ast.c | 55 ++++++++++++++++------------- cerise/src/grammar.c | 81 +++++++++++++++++++++---------------------- cerise/tests/Module.m | 2 ++ 3 files changed, 72 insertions(+), 66 deletions(-) diff --git a/cerise/src/ast.c b/cerise/src/ast.c index f9a3163..51760aa 100644 --- a/cerise/src/ast.c +++ b/cerise/src/ast.c @@ -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]) diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index de79f23..125ffc7 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -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: diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 64187f5..836fe83 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -151,4 +151,6 @@ begin # c = Bar(42); # c = 42; # c = 24; + + Bar(42); end -- 2.49.0