From b61e7208355c1e7f739aa8096395de5576d55838 Mon Sep 17 00:00:00 2001 From: "Michael D. Lowis" Date: Mon, 10 Oct 2022 22:25:33 -0400 Subject: [PATCH] added function call syntax and ssa generation. Backend is segfaulting currently --- cerise/backend/ssa/codegen.c | 26 ++++++++++++ cerise/inc/cerise.h | 10 ++++- cerise/src/grammar.c | 77 ++++++++++++++++++------------------ cerise/src/ssa.c | 18 ++++++++- cerise/tests/Module.m | 12 +++++- 5 files changed, 99 insertions(+), 44 deletions(-) diff --git a/cerise/backend/ssa/codegen.c b/cerise/backend/ssa/codegen.c index 6fa2491..75d227c 100644 --- a/cerise/backend/ssa/codegen.c +++ b/cerise/backend/ssa/codegen.c @@ -390,6 +390,32 @@ void print_op(Parser* p, SsaNode* expr) { printf(" br label %%L%ld\n", SSA_LBLK(expr)->id); } + else if (expr->code == CALL) + { + print_ident(p, &(SSA_VAR(expr))); + +// printf(" ret "); +// emit_type(SSA_TYPE(expr)); +// if (SSA_TYPE(expr)->form != FORM_VOID) +// { +// printf(" "); +// if (expr->mode == MODE_CTRL) +// { +// print_ident(p, &(SSA_VAR(expr))); +// } +// else +// { +// print_const(SSA_TYPE(expr), &(expr->value)); +// } +// } +// puts(""); + + + } + else + { + assert(!"not implemented"); + } break; case MODE_UNOP: diff --git a/cerise/inc/cerise.h b/cerise/inc/cerise.h index 62ac170..9145978 100644 --- a/cerise/inc/cerise.h +++ b/cerise/inc/cerise.h @@ -56,6 +56,7 @@ typedef enum { WHILE, COUNT, CALL, + ARGS, LOAD, STORE, @@ -120,12 +121,17 @@ typedef union { } SsaConst; struct SsaBlock; +struct SsaNode; typedef union { SsaVar var; SsaConst val; struct SsaBlock* block; char* str; + struct { + struct SsaNode** v; + size_t nv; + } args; } SsaValue; //typedef struct SsaNode { @@ -324,8 +330,8 @@ SsaNode* ssa_if(Parser* p, SsaNode* cond, SsaBlock* br1, SsaBlock* br2); SsaNode* ssa_return(Parser* p, SsaNode* expr); SsaNode* ssa_branch(Parser* p, SsaBlock* br); -SsaNode* ssa_call(SsaNode* func); -void ssa_call_add(SsaBlock* call, SsaNode* arg); +SsaNode* ssa_call(Parser* p, SsaNode* func); +void ssa_call_add(Parser* p, SsaNode* call, SsaNode* arg); /* Backend Code Generation and Base Type Definitions *****************************************************************************/ diff --git a/cerise/src/grammar.c b/cerise/src/grammar.c index cf680eb..8948a42 100644 --- a/cerise/src/grammar.c +++ b/cerise/src/grammar.c @@ -171,44 +171,45 @@ static SsaNode* factor(Parser* p) case IDENT: expr = designator(p); -// if (accept(p, '(')) -// { -// expr = ssa_call(expr); -// if (expr->type->form != FORM_PROC) -// { -// error(p, "attempting to call a non-procedural value"); -// } -// -// Field* args = expr->type->fields; -// while (args && !matches(p, ')')) -// { -// SsaNode* val = expression(p); -// check_type(p, args->type, val); -// ssa_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, ')'); -// } + if (accept(p, '(')) + { + SsaNode* call = ssa_call(p, expr); + if (expr->type->form != FORM_PROC) + { + error(p, "attempting to call a non-procedural value"); + } + + Field* args = expr->type->fields; + while (args && !matches(p, ')')) + { + SsaNode* val = expression(p); + check_type(p, args->type, val); + ssa_call_add(p, call, 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, ')'); + expr = call; + } break; default: diff --git a/cerise/src/ssa.c b/cerise/src/ssa.c index 2dde0c0..d07e84e 100644 --- a/cerise/src/ssa.c +++ b/cerise/src/ssa.c @@ -335,8 +335,22 @@ SsaNode* ssa_branch(Parser* p, SsaBlock* br) return node; } -SsaNode* ssa_call(SsaNode* func); -void ssa_call_add(SsaBlock* call, SsaNode* arg); +SsaNode* ssa_call(Parser* p, SsaNode* func) +{ + (void)p; + SsaNode* call = ssa_node(CALL, MODE_CTRL); + call->type = func->type->base; + call->left = func; + return call; +} + +void ssa_call_add(Parser* p, SsaNode* call, SsaNode* arg) +{ + loadmem(p, arg); + call->value.args.nv++; + call->value.args.v = realloc(call->value.args.v, call->value.args.nv); + call->value.args.v[call->value.args.nv - 1] = arg; +} static SsaNode* binop(Parser* p, int op, SsaNode* left, SsaNode* right) { diff --git a/cerise/tests/Module.m b/cerise/tests/Module.m index 9dd680f..7db0f98 100644 --- a/cerise/tests/Module.m +++ b/cerise/tests/Module.m @@ -182,9 +182,17 @@ begin vRec1.b.c = vRec1.b.c + vRec1.b.c; end -procedure TestFunctionCall() +procedure Sum(a: Int, b : Int) : Int begin -# TestFunctionCall(); + return a + b; +end + + +procedure TestFunctionCalls() +begin + TestReturnVoid(); + vInt = TestReturnIntLiteral(); + vInt = Sum(1,2); end #begin -- 2.49.0