diff options
author | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-02-22 11:05:30 +0000 |
---|---|---|
committer | Peter Mikkelsen <petermikkelsen10@gmail.com> | 2022-02-22 11:05:30 +0000 |
commit | df6c3247c40b05266894d45136dc64f96b0cbac9 (patch) | |
tree | 568b29e803bc9e58a1147b64dedb9cbd3b34c13d | |
parent | 7c39c4eab3e16c201b22e0bf29e51006f60e99e7 (diff) |
Implement lexical scope instead of dynamic scope rules.
-rw-r--r-- | apl9.h | 6 | ||||
-rw-r--r-- | functions.c | 4 | ||||
-rw-r--r-- | lexer.c | 1 | ||||
-rw-r--r-- | symbol.c | 5 |
4 files changed, 11 insertions, 5 deletions
@@ -153,6 +153,7 @@ struct Function QuadnameDef *quad; FunctionTrain train; }; + DfnFrame *scope; Array *left; }; @@ -219,7 +220,8 @@ struct DfnFrame Array *right; Datum *lefto; Datum *righto; - DfnFrame *prev; + DfnFrame *prev; /* prev in the call stack */ + DfnFrame *chain; /* prev in the lexical scope */ }; struct ThreadData @@ -279,7 +281,7 @@ Datum *eval(Statement *, int); Symbol *getsym(Rune *, int); void initsymtab(void); DfnFrame *getcurrentdfn(void); -DfnFrame *pushdfnframe(Rune *, Datum *, Datum *, Array *, Array *); +DfnFrame *pushdfnframe(Rune *, DfnFrame *, Datum *, Datum *, Array *, Array *); void popdfnframe(void); vlong globalIO(void); void globalIOset(vlong); diff --git a/functions.c b/functions.c index 46cbe7a..7e462c3 100644 --- a/functions.c +++ b/functions.c @@ -141,7 +141,7 @@ runfunc(Function f, Array *left, Array *right) code = f.operator.dop; } - pushdfnframe(code, lefto, righto, left, right); + pushdfnframe(code, f.scope, lefto, righto, left, right); Datum *dfnres = evalline(code, nil, 0); popdfnframe(); @@ -228,6 +228,7 @@ rundfn(Rune *code, Datum *lefto, Datum *righto, Array *left, Array *right) Function dfn; dfn.type = FunctypeDfn; dfn.dfn = code; + dfn.scope = getcurrentdfn(); return runfunc(dfn, left, right); }else if(lefto != nil){ Function dop; @@ -237,6 +238,7 @@ rundfn(Rune *code, Datum *lefto, Datum *righto, Array *left, Array *right) dop.operator.right = righto; dop.operator.dyadic = righto != nil; dop.operator.dop = code; + dop.scope = getcurrentdfn(); return runfunc(dop, left, right); }else{ throwerror(L"Malformed call to rundfn", ENotImplemented); @@ -118,6 +118,7 @@ lexline(InputStream *input, int toplevel) stmt->toks[stmt->ntoks] = allocdatum(FunctionTag, 0); stmt->toks[stmt->ntoks]->func.type = FunctypeDfn; stmt->toks[stmt->ntoks]->func.dfn = runestrdup(buf); + stmt->toks[stmt->ntoks]->func.scope = getcurrentdfn(); }else{ stmt->toks[stmt->ntoks] = allocdatum(oplevel == 1 ? MonadicOpTag : DyadicOpTag, 0); stmt->toks[stmt->ntoks]->operator.type = OperatortypeDop; @@ -34,7 +34,7 @@ getsym(Rune *name, int fresh) return tab->syms[i]; } if(dfn) - dfn = dfn->prev; + dfn = dfn->chain; else done = 1; }while(!done && !fresh); @@ -108,7 +108,7 @@ getcurrentdfn(void) } DfnFrame * -pushdfnframe(Rune *code, Datum *lefto, Datum *righto, Array *left, Array *right) +pushdfnframe(Rune *code, DfnFrame *scope, Datum *lefto, Datum *righto, Array *left, Array *right) { ThreadData *td = getthreaddata(); DfnFrame *new = emalloc(sizeof(DfnFrame)); @@ -129,6 +129,7 @@ pushdfnframe(Rune *code, Datum *lefto, Datum *righto, Array *left, Array *right) new->right = right; incarrayref(right); new->prev = td->currentdfn; + new->chain = scope; td->currentdfn = new; return new; } |