summaryrefslogtreecommitdiff
path: root/eval.c
diff options
context:
space:
mode:
Diffstat (limited to 'eval.c')
-rw-r--r--eval.c67
1 files changed, 36 insertions, 31 deletions
diff --git a/eval.c b/eval.c
index f6cdb0d..11809a8 100644
--- a/eval.c
+++ b/eval.c
@@ -59,47 +59,46 @@ evalfn evalfns[15][15] = {
};
Datum *
-eval(Datum *tokens, int *ntoks)
+eval(Statement *stmt)
{
errormsg = nil;
/* start by looking up first variable if needed */
- if(*ntoks > 0 && tokens[(*ntoks)-1].tag == NameTag){
- Datum *value = lookup(tokens[(*ntoks)-1]);
+ if(stmt->ntoks > 0 && stmt->toks[stmt->ntoks-1].tag == NameTag){
+ Datum *value = lookup(stmt->toks[stmt->ntoks-1]);
if(value == nil)
- *ntoks = 0;
+ return nil;
else
- tokens[(*ntoks)-1] = *value;
+ stmt->toks[stmt->ntoks-1] = *value;
}
- while(*ntoks > 1){
+ while(stmt->ntoks > 1){
int maxlevel = 0;
int offset;
evalfn fn = nil;
- traceprint("CURRENT: %S\n", ppdatums(tokens, *ntoks));
- for(offset = (*ntoks)-1; offset >= 0; offset--){
+ traceprint("CURRENT: %S\n", ppdatums(stmt->toks, stmt->ntoks));
+ for(offset = stmt->ntoks-1; offset >= 0; offset--){
int level;
retry:
if(offset == 0)
level = 0;
else{
- Datum left = tokens[offset-1];
- Datum right = tokens[offset];
+ Datum left = stmt->toks[offset-1];
+ Datum right = stmt->toks[offset];
level = bindingstrengths[left.tag][right.tag];
}
- if(level == 0 && tokens[offset-1].tag == NameTag){
- Datum *value = lookup(tokens[offset-1]);
- if(value == nil){
- *ntoks = 0;
- return tokens;
- }else{
- tokens[offset-1] = *value;
+ if(level == 0 && stmt->toks[offset-1].tag == NameTag){
+ Datum *value = lookup(stmt->toks[offset-1]);
+ if(value == nil)
+ return nil;
+ else{
+ stmt->toks[offset-1] = *value;
goto retry;
}
}else if(level < maxlevel){
- Datum left = tokens[offset];
- Datum right = tokens[offset+1];
+ Datum left = stmt->toks[offset];
+ Datum right = stmt->toks[offset+1];
fn = evalfns[left.tag][right.tag];
traceprint("Reducing %S and %S (fn=%p, level=%d, max=%d)\n", ppdatum(left), ppdatum(right), fn, level, maxlevel);
break;
@@ -108,15 +107,21 @@ retry:
}
if(maxlevel == 0){
errormsg = L"No reduce rule. Syntax error.";
- *ntoks = 0;
+ return nil;
}else{
- tokens[offset] = fn(tokens[offset],tokens[offset+1]);
- for(int i = offset+1; i < (*ntoks)-1; i++)
- tokens[i] = tokens[i+1];
- (*ntoks)--;
+ stmt->toks[offset] = fn(stmt->toks[offset],stmt->toks[offset+1]);
+ for(int i = offset+1; i < stmt->ntoks-1; i++)
+ stmt->toks[i] = stmt->toks[i+1];
+ stmt->ntoks--;
}
}
- return tokens;
+ if(stmt->ntoks == 1){
+ if(stmt->next)
+ return eval(stmt->next);
+ else
+ return stmt->toks;
+ }else
+ return nil;
}
Datum *
@@ -173,10 +178,10 @@ Datum
lpar(Datum left, Datum right)
{
/* build up a parthenthesised expression */
- left.expr.ntoks++;
- left.expr.toks = realloc(left.expr.toks, sizeof(Datum) * left.expr.ntoks);
- left.expr.toks[left.expr.ntoks-1] = right;
- traceprint("LPAR: %S\n", ppdatums(left.expr.toks, left.expr.ntoks));
+ left.stmt.ntoks++;
+ left.stmt.toks = realloc(left.stmt.toks, sizeof(Datum) * left.stmt.ntoks);
+ left.stmt.toks[left.stmt.ntoks-1] = right;
+ traceprint("LPAR: %S\n", ppdatums(left.stmt.toks, left.stmt.ntoks));
return left;
}
@@ -185,8 +190,8 @@ rpar(Datum left, Datum right)
{
/* evaluate a parenthesis expression and return the result */
USED(right);
- traceprint("RPAR: %S\n", ppdatums(left.expr.toks, left.expr.ntoks));
- Datum *result = eval(left.expr.toks, &left.expr.ntoks);
+ traceprint("RPAR: %S\n", ppdatums(left.stmt.toks, left.stmt.ntoks));
+ Datum *result = eval(&left.stmt);
result[0].array->stranded = 0;
return result[0]; /* TODO handle error if ntoks != 1 */
}