Support optional left argument in function definitions
M dat.h => dat.h +1 -0
@@ 179,6 179,7 @@ struct Ast char *name; int nameclass; int prim; int optional; /* optional left arg */ Ast *funcname; Ast *funcresult;
M eval.c => eval.c +6 -2
@@ 72,9 72,11 @@ codegensub(Session *s, Module *m, ByteCode *c, Ast *a) { Function *fn = alloc(DataFunction); fn->ast = a; if(fn->ast->funcleftarg) if(fn->ast->funcleftarg){ fn->valence = Dyadic; else if(fn->ast->funcrightarg) if(fn->ast->funcleftarg->optional) fn->valence |= Monadic; }else if(fn->ast->funcrightarg) fn->valence = Monadic; else @@ fn->valence = Niladic; 347,6 349,8 @@ evalbc(Session *s, Module *m, ByteCode *c) error(ESyntax, "Function %s does not produce a result", funcname(func)); } pushval(values, y); if(func->valence & Dyadic) /* ambivalent function */ pushval(values, nil); pushcall(calls, func->code, &c, &o); }else{ z = primmonad(func->prim, y);
M parse.c => parse.c +19 -2
@@ 18,6 18,7 @@ static void parseseps(TokenList *, int); static Ast *parseprog(TokenList *); static Ast *parsefuncdef(TokenList *); static Ast *parsefuncheader(TokenList *); static Ast *parsefuncleftopt(TokenList *); static Ast *parselocals(TokenList *); static Ast *parseexpr(TokenList *, Symtab *, Ast *); @@ static Ast *parseexprsub(TokenList *); 202,15 203,18 @@ parsefuncheader(TokenList *t) match(t, TokDel); func->funcleftarg = parsefuncleftopt(t); /* optional left arg */ func->funcname = parsename(t); if(peek(t) == TokLarrow){ if(peek(t) == TokLarrow && !func->funcleftarg){ match(t, TokLarrow); func->funcresult = func->funcname; func->funcleftarg = parsefuncleftopt(t); func->funcname = parsename(t); } if(peek(t) == TokName) func->funcrightarg = parsename(t); if(peek(t) == TokName){ if(peek(t) == TokName && !func->funcleftarg){ func->funcleftarg = func->funcname; func->funcname = func->funcrightarg; @@ func->funcrightarg = parsename(t); 221,6 225,19 @@ parsefuncheader(TokenList *t) } static Ast * parsefuncleftopt(TokenList *t) { Ast *name = nil; if(peek(t) == TokLbrace){ match(t, TokLbrace); name = parsename(t); name->optional = 1; match(t, TokRbrace); } return name; } static Ast * parselocals(TokenList *t) { Ast *locals = alloc(DataAst);