~pmikkelsen/lpa

ee1ed56428b090dd694f50b49f4957c4d2e11bc2 — Peter Mikkelsen 2 months ago 8dc7c65
Use eval() to parse constants
5 files changed, 34 insertions(+), 31 deletions(-)

M eval.c
M fns.h
M fs.c
M session.c
M value.c
M eval.c => eval.c +2 -5
@@ 8,16 8,13 @@
static ByteCode *codegen(Session *, Module *, Ast *);
static void *evalbc(Session *, Module *, ByteCode *);

void
void *
eval(Session *s, Ast *a)
{
	/* Evaluate some ast in module m in session s. */
	Module *m = s->modules->modules[0]; /* TODO: this isn't nice */
	ByteCode *code = codegen(s, m, a);
	void *v = evalbc(s, m, code);

	if(v)
		appendlog(s, printval(v));
	return evalbc(s, m, code);
}

static void

M fns.h => fns.h +2 -2
@@ 8,7 8,7 @@ Array *simplifyarray(Array *);
char *printarray(Array *);

/* eval.c */
void eval(Session *s, Ast *);
void *eval(Session *s, Ast *);

/* fs.c */
Qid freshobjqid(void);


@@ 58,5 58,5 @@ int getuvlong(u8int *, uvlong *);

/* value.c */
char *printval(void *);
void *parseval(char *, char **);
void *parseval(Session *s, char *, char **);


M fs.c => fs.c +5 -4
@@ 263,13 263,14 @@ static char *
symbolrw(Req *r)
{
	Aux *aux = r->fid->aux;
	Symbol *s = aux->symbol;
	Session *session = aux->session;
	Symbol *symb = aux->symbol;
	char *err = nil;

	if(r->ifcall.type == Tread){
		/* Pretty print the value and readstr() it. */
		if(aux->cachestr == nil)
			aux->cachestr = printval(s->value);
			aux->cachestr = printval(symb->value);
		readstr(r, aux->cachestr);
		if(r->ofcall.count == 0){
			free(aux->cachestr);


@@ 277,10 278,10 @@ symbolrw(Req *r)
		}
	}else{ /* Twrite */
		char *buf = requeststr(r);
		void *v = parseval(buf, &err);
		void *v = parseval(session, buf, &err);
		free(buf);
		if(!err)
			symset(s->table, s->id, v);
			symset(symb->table, symb->id, v);
	}
	return err;
}

M session.c => session.c +3 -1
@@ 57,7 57,9 @@ error:
				goto error;

			debugast(ast, 0);
			eval(s, ast);
			void *val = eval(s, ast);
			if(val)
				appendlog(s, printval(val));
		}
	}
}

M value.c => value.c +22 -19
@@ 7,7 7,7 @@

/* Anything that can have a name in LPA: Arrays, functions, ... */

static Array *evalconstast(Ast *);
static int checkexpr(Ast *);

char *
printval(void *v)


@@ 26,7 26,7 @@ printval(void *v)
}

void *
parseval(char *buf, char **errp)
parseval(Session *s, char *buf, char **errp)
{
	Ast *ast;
	void *val = nil;


@@ 34,13 34,9 @@ parseval(char *buf, char **errp)
	TokenList *tokens = scan(buf, errp);
	if(tokens == nil)
		goto end;
	ast = parse(tokens, 0, errp);
	ast = parse(tokens, nil, errp);
	if(ast == nil)
		goto end;
	debugast(ast, 0);
	/* Check that the ast is either a single function definition,
	 * or a constant (stranding is OK).
	 */
	
	if(!(ast->tag == AstProg && ast->childcount == 1)){
		*errp = "Expected single value or function definition";


@@ 48,24 44,31 @@ parseval(char *buf, char **errp)
	}

	ast = ast->children[0];
	if(checkexpr(ast))
		val = eval(s, ast);
	else
		*errp = "Expected value or function definition";
end:
	return val;
}

static int
checkexpr(Ast *ast)
{
	switch(ast->tag){
	case AstConst:
	case AstStrand:
		val = evalconstast(ast);
		if(val == nil)
			*errp = "Expected constant expression";
		break;
	case AstFunc:
		*errp = "Functions not supported yet";
		break;
		return 1;
	case AstStrand:
		for(uvlong i = 0; i < ast->childcount; i++){
			if(!checkexpr(ast->children[i]))
				return 0;
		}
		return 1;
	default:
		*errp = "Expected constant or function definition";
		break;
		return 0;
	}
end:
	return val;
}

static Array *
evalconstast(Ast *ast)
{