From 59148d666a78d671198d56caabe7fe4d7fb3fee1 Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 31 Mar 2024 23:09:14 +0300 Subject: produce some very limited assembly output + Several subsystems missing critical features, but enough to do some basic things like calling procedures, printing to screen and doing loops --- src/parser.y | 130 ++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 71 insertions(+), 59 deletions(-) (limited to 'src/parser.y') diff --git a/src/parser.y b/src/parser.y index 4a70341..4edcdcf 100644 --- a/src/parser.y +++ b/src/parser.y @@ -12,11 +12,6 @@ #include #include -struct ret_helper { - const char *r; - enum val_type t; -}; - %} %locations @@ -31,7 +26,6 @@ struct ret_helper { %union { struct val val; - struct ret_helper ret; enum val_type type; int64_t integer; char *str; @@ -77,8 +71,10 @@ struct ret_helper { %nterm type %nterm id addr local label -%nterm arg opt_arg -%nterm call_ret opt_call_ret +%nterm arg +%nterm ret + +%nterm placeholder %{ @@ -201,6 +197,22 @@ static inline void do_new_label(struct parser *p, const char *s) new_label(p->f, p->b, s); } +static inline size_t do_cur_insn(struct parser *p) +{ + return vec_len(&p->b->insns); +} + +static inline void do_ins_replace(struct parser *p, size_t i, struct insn n) +{ + insn_at(p->b->insns, i) = n; +} + +#define INS_REPLACE(i, n)\ + do_ins_replace(parser, i, n) + +#define CUR_INSN()\ + do_cur_insn(parser) + #define INSADD(o, t, r, a0, a1)\ do_insadd(parser, o, t, r, a0, a1) @@ -260,7 +272,7 @@ data param : type id { struct val t = IDALLOC($[id]); - INSADD(PARAM, $[type], t, imm_val(parser->idx++, I27), noclass()); + INSADD(PARAM, $[type], t, noclass(), imm_val(parser->idx++, I27)); } params @@ -272,17 +284,6 @@ opt_params : params | {} -ret - : type - -opt_ret - : ret - | {} - -/* only three return args permitted (keep things simple for now) */ -rets - : opt_ret "," opt_ret "," opt_ret - label : id ":" { if (empty_block(parser->b)) { @@ -299,7 +300,7 @@ arg $$ = IDTOVAL($[id]); } | type int { - $$ = imm_val($[type], $[int]); + $$ = imm_val($[int], $[type]); } arith @@ -439,14 +440,24 @@ branch NEW_BLOCK(J, noclass(), noclass(), $[local]); } +ret + : id { + $$ = IDALLOC($[id]); + } + call_ret - : type id { - $$ = (struct ret_helper){.r = $[id], .t = $[type]}; + : ret { + INSADD(RETVAL, NOTYPE, $[ret], noclass(), imm_val(parser->idx++, I27)); } -opt_call_ret - : call_ret - | { $$ = (struct ret_helper){.r = NULL, .t = NOTYPE}; } +call_rets + : call_ret "," call_rets + | call_ret "," + | call_ret + +opt_call_rets + : call_rets + | {} call_arg : arg { @@ -466,43 +477,43 @@ opt_call_args reset_index : {parser->idx = 0;} -call - : "(" opt_call_ret "," opt_call_ret "," opt_call_ret ")" - "=" addr reset_index "(" opt_call_args ")" { - /* call args should have inserted their own nodes */ - INSADD(CALL, NOTYPE, noclass(), imm_ref($[addr]), noclass()); - - if ($2.r) { - struct val t = IDALLOC($2.r); - INSADD(RETVAL, $2.t, t, noclass(), imm_val(0, I27)); - } - - if ($4.r) { - struct val t = IDALLOC($4.r); - INSADD(RETVAL, $4.t, t, noclass(), imm_val(1, I27)); - } - - if ($6.r) { - struct val t = IDALLOC($6.r); - INSADD(RETVAL, $6.t, t, noclass(), imm_val(2, I27)); - } +placeholder + : { + $$ = CUR_INSN(); + INSADD(CALL, NOTYPE, noclass(), noclass(), noclass()); } -opt_arg - : arg - | { $$ = noclass(); } - -return - : "=>" "(" opt_arg "," opt_arg "," opt_arg ")" { - if (!hasnoclass($3)) - INSADD(RET, NOTYPE, noclass(), $3, imm_val(0, I27)); +call + : addr reset_index "(" opt_call_args ")" + "=>" placeholder reset_index "(" opt_call_rets ")" { + /* kind of hacky but works */ + INS_REPLACE($[placeholder], + insn_create(CALL, NOTYPE, + noclass(), imm_ref($[addr]), noclass())); + } + | id reset_index "(" opt_call_args ")" + "=>" placeholder reset_index "(" opt_call_rets ")" { + INS_REPLACE($[placeholder], + insn_create(CALL, NOTYPE, + noclass(), IDTOVAL($[id]), noclass())); + } + +proc_ret + : id { + INSADD(RETARG, NOTYPE, noclass(), IDTOVAL($[id]), imm_val(parser->idx++, I27)); + } - if (!hasnoclass($5)) - INSADD(RET, NOTYPE, noclass(), $5, imm_val(1, I27)); +proc_rets + : proc_ret "," proc_rets + | proc_ret "," + | proc_ret - if (!hasnoclass($7)) - INSADD(RET, NOTYPE, noclass(), $7, imm_val(2, I27)); +opt_proc_rets + : proc_rets + | {} +return + : "=>" reset_index "(" opt_proc_rets ")" { NEW_BLOCK(RET, noclass(), noclass(), NULL); } @@ -524,8 +535,9 @@ body | label | insn ";" +/** @todo add in return type checking? */ function - : id reset_index "(" opt_params "=>" rets ")" "{" body "}" { + : id reset_index "(" opt_params ")" "{" body "}" { NEW_FUNCTION($[id]); } -- cgit v1.3