ref: ee1ed56428b090dd694f50b49f4957c4d2e11bc2
parent: 8dc7c659e34ad5d244477e01b1ebf4def63be24d
author: Peter Mikkelsen <[email protected]>
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)
{