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 --- symbol.c | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 8 deletions(-) (limited to 'symbol.c') diff --git a/symbol.c b/symbol.c index d51a730..e67f043 100644 --- a/symbol.c +++ b/symbol.c @@ -5,15 +5,29 @@ #include "apl9.h" Symtab *globalsymtab; -Symtab *currentsymtab; +DfnFrame *currentdfn; + +Symtab *newsymtab(void); +void freesymtab(Symtab *); Symbol * -getsym(Symtab *tab, Rune *name) +getsym(Rune *name) { - for(int i = 0; i < tab->nsyms; i++) - if(runestrcmp(tab->syms[i]->name, name) == 0) - return tab->syms[i]; - + DfnFrame *dfn = currentdfn; + Symtab *tab; + do{ + if(dfn != nil) + tab = dfn->symtab; + else + tab = globalsymtab; + + for(int i = 0; i < tab->nsyms; i++) + if(runestrcmp(tab->syms[i]->name, name) == 0) + return tab->syms[i]; + if(dfn) + dfn = dfn->prev; + }while(dfn != nil); + tab->nsyms++; tab->syms = realloc(tab->syms, sizeof(Symbol *) * tab->nsyms); tab->syms[tab->nsyms-1] = emalloc(sizeof(Symbol)); @@ -30,8 +44,8 @@ newsymtab(void) Symtab *tab = emalloc(sizeof(Symtab)); tab->nsyms = 0; tab->syms = nil; - tab->io = currentsymtab ? currentsymtab->io : 1; - tab->div = currentsymtab ? currentsymtab->div : 0; + tab->io = globalIO(); + tab->div = globalDIV(); return tab; } @@ -48,3 +62,77 @@ freesymtab(Symtab *tab) free(tab->syms); free(tab); } + +void +initsymtab(void) +{ + globalsymtab = newsymtab(); +} + +DfnFrame * +getcurrentdfn(void) +{ + return currentdfn; +} + +DfnFrame * +pushdfnframe(Rune *code) +{ + DfnFrame *new = malloc(sizeof(DfnFrame)); + new->code = code; + new->symtab = newsymtab(); + new->prev = currentdfn; + currentdfn = new; + return new; +} + +void +popdfnframe(void) +{ + if(currentdfn != nil){ + DfnFrame *prev = currentdfn->prev; + freesymtab(currentdfn->symtab); + free(currentdfn); + currentdfn = prev; + } +} + +vlong +globalIO(void) +{ + if(currentdfn) + return currentdfn->symtab->io; + else if(globalsymtab) + return globalsymtab->io; + else + return 1; +} + +void +globalIOset(vlong io) +{ + if(currentdfn) + currentdfn->symtab->io = io; + else + globalsymtab->io = io; +} + +int +globalDIV(void) +{ + if(currentdfn) + return currentdfn->symtab->div; + else if(globalsymtab) + return globalsymtab->div; + else + return 0; +} + +void +globalDIVset(int div) +{ + if(currentdfn) + currentdfn->symtab->div = div; + else + globalsymtab->div = div; +} \ No newline at end of file -- cgit v1.2.3