diff options
Diffstat (limited to 'symbol.c')
-rw-r--r-- | symbol.c | 104 |
1 files changed, 96 insertions, 8 deletions
@@ -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 |