From 9a938d3ce26b2d3728d791c0f858acdbd50223b5 Mon Sep 17 00:00:00 2001 From: Peter Mikkelsen Date: Sun, 23 Jan 2022 21:16:02 +0000 Subject: =?UTF-8?q?Rework=20symbol=20lookup=20to=20use=20lexical=20scoping?= =?UTF-8?q?,=20and=20implement=20recursive=20function=20call=20via=20?= =?UTF-8?q?=E2=88=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- functions.c | 50 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 13 deletions(-) (limited to 'functions.c') diff --git a/functions.c b/functions.c index bc4d96c..c8bff78 100644 --- a/functions.c +++ b/functions.c @@ -4,7 +4,7 @@ #include "apl9.h" -Rune primfuncnames[] = L"+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊⍷∪∩~,⍪⍴⌽⊖⍉⍎⍕"; +Rune primfuncnames[] = L"+-×÷*⍟⌹○!?|⌈⌊⊥⊤⊣⊢=≠≤<>≥≡≢∨∧⍲⍱↑↓⊂⊃⊆⌷⍋⍒⍳⍸∊⍷∪∩~,⍪⍴⌽⊖⍉⍎⍕∇"; fnmonad monadfunctiondefs[] = { fnSame, /* + */ @@ -59,6 +59,7 @@ fnmonad monadfunctiondefs[] = { fnTranspose, /* ⍉ */ 0, /* ⍎ */ 0, /* ⍕ */ + fnSelfRef1, /* ∇ */ }; fndyad dyadfunctiondefs[] = { @@ -114,8 +115,11 @@ fndyad dyadfunctiondefs[] = { 0, /* ⍉ */ 0, /* ⍎ */ 0, /* ⍕ */ + fnSelfRef2, /* ∇ */ }; +DfnFrame *currentdfn; /* a stack of active dnf calls */ + vlong gcd_int(vlong, vlong); double gcd_float(double, double); @@ -125,26 +129,23 @@ runfunc(Function f, Array *left, Array *right) { Array *result; if(f.type == FunctypeDfn){ - Symtab *tmpsymtab = currentsymtab; - currentsymtab = newsymtab(); - + pushdfnframe(f.dfn); if(left){ - Symbol *alpha = getsym(currentsymtab, L"⍺"); + Symbol *alpha = getsym(L"⍺"); alpha->value.tag = ArrayTag; alpha->value.array = left; alpha->undefined = 0; incref(left); } - Symbol *omega = getsym(currentsymtab, L"⍵"); + Symbol *omega = getsym(L"⍵"); omega->value.tag = ArrayTag; omega->value.array = right; omega->undefined = 0; incref(right); Datum *dfnres = evalline(f.dfn, 0); - freesymtab(currentsymtab); - currentsymtab = tmpsymtab; + popdfnframe(); result = (*dfnres).array; /* TODO what if the evaluation failed */ }else if(f.type == FunctypePrim){ if(left){ @@ -496,12 +497,13 @@ fnGradeUp(Array *right) int i,j; int len = right->shape[0]; Array **elems = malloc(sizeof(Array *) * len); - Array *index = mkscalarint(currentsymtab->io); + Array *index = mkscalarint(globalIO()); Array *order = allocarray(AtypeInt, 1, len); order->shape[0] = len; + vlong io = globalIO(); for(i = 0; i < len; i++, index->intdata[0]++){ - order->intdata[i] = currentsymtab->io + i; + order->intdata[i] = io + i; elems[i] = fnIndex(index, right); } @@ -541,7 +543,7 @@ fnIndexGenerator(Array *right) vlong n = right->intdata[0]; Array *res = allocarray(AtypeInt, 1, n); res->shape[0] = n; - vlong io = currentsymtab->io; + vlong io = globalIO(); for(vlong i = 0; i < n; i++) res->intdata[i] = i + io; return res; @@ -692,6 +694,17 @@ fnTranspose(Array *right) return res; } +Array * +fnSelfRef1(Array *right) +{ + if(currentdfn != nil) + return rundfn(currentdfn->code, nil, right); + else{ + throwerror(nil, ESyntax); + return nil; + } +} + /* Dyadic functions */ /* macro to define dyadic scalar functions */ @@ -747,7 +760,7 @@ SCALAR_FUNCTION_2(fnTimes, 0, left->type, SCALAR_FUNCTION_2(fnDivide, 1, left->type, case AtypeFloat: if(right->floatdata[i] == 0){ - if(currentsymtab->div) + if(globalDIV()) res->floatdata[i] = 0; else throwerror(nil, EDomain); @@ -994,7 +1007,7 @@ fnTake(Array *left, Array *right) Array * fnIndex(Array *left, Array *right) { - int io = currentsymtab->io; + int io = globalIO(); int i; if(left->rank > 1) @@ -1221,6 +1234,17 @@ fnReshape(Array *left, Array *right) return res; } +Array * +fnSelfRef2(Array *left, Array *right) +{ + if(currentdfn != nil) + return rundfn(currentdfn->code, left, right); + else{ + throwerror(nil, ESyntax); + return nil; + } +} + /* helper functions */ vlong gcd_int(vlong a, vlong b) -- cgit v1.2.3