~pmikkelsen/lpa

5af5764e62f81ec4057e99a3bd03902b723cd7b8 — Peter Mikkelsen 2 months ago 2e8f865
Support optional left argument in function definitions
3 files changed, 26 insertions(+), 4 deletions(-)

M dat.h
M eval.c
M parse.c
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);