}
block gen_function(const char* name, block formals, block body) {
- block_bind_each(formals, body, OP_IS_CALL_PSEUDO);
inst* i = inst_new(CLOSURE_CREATE);
+ for (inst* i = formals.last; i; i = i->prev) {
+ if (i->op == CLOSURE_PARAM_REGULAR) {
+ i->op = CLOSURE_PARAM;
+ body = gen_var_binding(gen_call(i->symbol, gen_noop()), i->symbol, body);
+ }
+ block_bind_subblock(inst_block(i), body, OP_IS_CALL_PSEUDO | OP_HAS_BINDING);
+ }
i->subfn = body;
i->symbol = strdup(name);
i->arglist = formals;
return b;
}
+block gen_param_regular(const char* name) {
+ return gen_op_unbound(CLOSURE_PARAM_REGULAR, name);
+}
+
block gen_param(const char* name) {
return gen_op_unbound(CLOSURE_PARAM, name);
}
%precedence "catch"
-%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody QQString FuncDef FuncDefs String Import Imports
+%type <blk> Exp Term MkDict MkDictPair ExpD ElseBody QQString FuncDef FuncDefs String Import Imports Param Params
%{
#include "lexer.h"
struct lexer_param {
jv_free($2);
} |
-"def" IDENT '(' IDENT ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2),
- gen_param(jv_string_value($4)),
- $7);
+"def" IDENT '(' Params ')' ':' Exp ';' {
+ $$ = gen_function(jv_string_value($2), $4, $7);
jv_free($2);
- jv_free($4);
-} |
+}
-"def" IDENT '(' IDENT ';' IDENT ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2),
- BLOCK(gen_param(jv_string_value($4)),
- gen_param(jv_string_value($6))),
- $9);
- jv_free($2);
- jv_free($4);
- jv_free($6);
+Params:
+Param {
+ $$ = $1;
} |
+Params ';' Param {
+ $$ = BLOCK($1, $3);
+}
-"def" IDENT '(' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2),
- BLOCK(gen_param(jv_string_value($4)),
- gen_param(jv_string_value($6)),
- gen_param(jv_string_value($8))),
- $11);
+Param:
+'$' IDENT {
+ $$ = gen_param_regular(jv_string_value($2));
jv_free($2);
- jv_free($4);
- jv_free($6);
- jv_free($8);
} |
-"def" IDENT '(' IDENT ';' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2),
- BLOCK(gen_param(jv_string_value($4)),
- gen_param(jv_string_value($6)),
- gen_param(jv_string_value($8)),
- gen_param(jv_string_value($10))),
- $13);
- jv_free($2);
- jv_free($4);
- jv_free($6);
- jv_free($8);
- jv_free($10);
-} |
-
-"def" IDENT '(' IDENT ';' IDENT ';' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2),
- BLOCK(gen_param(jv_string_value($4)),
- gen_param(jv_string_value($6)),
- gen_param(jv_string_value($8)),
- gen_param(jv_string_value($10)),
- gen_param(jv_string_value($12))),
- $15);
- jv_free($2);
- jv_free($4);
- jv_free($6);
- jv_free($8);
- jv_free($10);
- jv_free($12);
-} |
-
-"def" IDENT '(' IDENT ';' IDENT ';' IDENT ';' IDENT ';' IDENT ';' IDENT ')' ':' Exp ';' {
- $$ = gen_function(jv_string_value($2),
- BLOCK(gen_param(jv_string_value($4)),
- gen_param(jv_string_value($6)),
- gen_param(jv_string_value($8)),
- gen_param(jv_string_value($10)),
- gen_param(jv_string_value($12)),
- gen_param(jv_string_value($14))),
- $17);
- jv_free($2);
- jv_free($4);
- jv_free($6);
- jv_free($8);
- jv_free($10);
- jv_free($12);
- jv_free($14);
+IDENT {
+ $$ = gen_param(jv_string_value($1));
+ jv_free($1);
}