diff --git a/parse.leg b/parse.leg index e7d96cd..d3b5bc7 100644 --- a/parse.leg +++ b/parse.leg @@ -21,7 +21,7 @@ _DO(PostDecVariable) _DO(PostDecMember) _DO(PostDecIndex) \ _DO(GetVariable) _DO(GetMember) _DO(SetMember) _DO(GetIndex) _DO(SetIndex) _DO(Slice) \ _DO(Return) _DO(Break) _DO(Continue) _DO(Throw) _DO(Try) \ - _DO(Quasiquote) _DO(Unquote) + _DO(Quasiquote) _DO(Unquote) _DO(Splice) typedef enum { t_UNDEFINED=0, @@ -757,19 +757,22 @@ postfix = i:value ( DOT s:IDENT a:argumentList { i = newInvoke( ) * { $$ = i } paramList = LPAREN m:makeMap - ( i:IDENT { map_append(m, i) } - ( COMMA i:IDENT { map_append(m, i) } + ( i:ident { map_append(m, i) } + ( COMMA i:ident { map_append(m, i) } ) * ) ? RPAREN { $$ = m } argumentList = LPAREN m:makeMap - ( e:exp { map_append(m, e) } - ( COMMA e:exp { map_append(m, e) } + ( a:argument { map_append(m, a) } + ( COMMA a:argument { map_append(m, a) } ) * ) ? RPAREN { $$ = m } +argument = MULTI e:exp { $$ = newUnary(Splice_proto, e) } + | e:exp { $$ = e } + value = n:NUMBER { $$ = newInteger(n) } | s:string { $$ = newString(s) } | s:symbol { $$ = s } @@ -1475,6 +1478,9 @@ oop eval(oop scope, oop ast) } return apply(scope, this, func, args, ast); } + case t_Splice: { + runtimeError("* outside of argument list"); + } case t_Return: { assert(jbs); @@ -1883,16 +1889,27 @@ oop prim_print(oop scope, oop params) return params; } -oop evalArgs(oop scope, oop args) -{ - int i = 0; - oop params = makeMap(); - oop index; - while ((index = makeInteger(i)), map_hasKey(args, index)) { - map_set(params, index, eval(scope, map_get(args, index))); - i++; - } - return params; +oop evalArgs(oop scope, oop asts) +{ + oop args= makeMap(); + size_t nargs= map_size(asts); + for (size_t i= 0; i < nargs; ++i) { + oop ast= get(asts, Map, elements)[i].value; + if (is(Map, ast) && (Splice_proto == map_get(ast, __proto___symbol))) { + oop splice= eval(scope, map_get(ast, rhs_symbol)); + if (!is(Map, splice)) map_append(args, splice); + else { + size_t nsplice= map_size(splice); + for (size_t j= 0; j < nsplice; ++j) { + map_append(args, get(splice, Map, elements)[j].value); + } + } + } + else { + map_append(args, eval(scope, ast)); + } + } + return args; } oop AST= NULL; diff --git a/test-splice.txt b/test-splice.txt new file mode 100644 index 0000000..269f78f --- /dev/null +++ b/test-splice.txt @@ -0,0 +1,16 @@ +fun f(a, b, c, d, e) { + print(a, " ", b, " ", c, " ", d, " ", e, "\n"); +} + +args = ["a", "b", "c"]; + +f(1, 2, 3, 4, 5); +f(1, *args, 2); + +fun myprintln() { + print(*__arguments__); + print("\n"); +} + +myprintln("Hello, world"); +myprintln("Goodbye, world");