shithub: lpa

Download patch

ref: ee1ed56428b090dd694f50b49f4957c4d2e11bc2
parent: 8dc7c659e34ad5d244477e01b1ebf4def63be24d
author: Peter Mikkelsen <peter@pmikkelsen.com>
date: Mon Jul 22 12:58:31 EDT 2024

Use eval() to parse constants

--- a/eval.c
+++ b/eval.c
@@ -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
--- a/fns.h
+++ b/fns.h
@@ -8,7 +8,7 @@
 char *printarray(Array *);
 
 /* eval.c */
-void eval(Session *s, Ast *);
+void *eval(Session *s, Ast *);
 
 /* fs.c */
 Qid freshobjqid(void);
@@ -58,5 +58,5 @@
 
 /* value.c */
 char *printval(void *);
-void *parseval(char *, char **);
+void *parseval(Session *s, char *, char **);
 
--- a/fs.c
+++ b/fs.c
@@ -263,13 +263,14 @@
 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 @@
 		}
 	}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;
 }
--- a/session.c
+++ b/session.c
@@ -57,7 +57,9 @@
 				goto error;
 
 			debugast(ast, 0);
-			eval(s, ast);
+			void *val = eval(s, ast);
+			if(val)
+				appendlog(s, printval(val));
 		}
 	}
 }
--- a/value.c
+++ b/value.c
@@ -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 @@
 }
 
 void *
-parseval(char *buf, char **errp)
+parseval(Session *s, char *buf, char **errp)
 {
 	Ast *ast;
 	void *val = nil;
@@ -34,13 +34,9 @@
 	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 @@
 	}
 
 	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)
 {