#include #include #include #include "apl9.h" Symtab *globalsymtab; DfnFrame *currentdfn; Symtab *newsymtab(void); void freesymtab(Symtab *); Symbol * getsym(Rune *name, int fresh) { DfnFrame *dfn = currentdfn; Symtab *tab; int done = 0; 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; else done = 1; }while(!done && !fresh); tab->nsyms++; tab->syms = realloc(tab->syms, sizeof(Symbol *) * tab->nsyms); tab->syms[tab->nsyms-1] = emalloc(sizeof(Symbol)); tab->syms[tab->nsyms-1]->name = runestrdup(name); tab->syms[tab->nsyms-1]->undefined = 1; tab->syms[tab->nsyms-1]->getfn = nil; tab->syms[tab->nsyms-1]->setfn = nil; return tab->syms[tab->nsyms-1]; } Symtab * newsymtab(void) { Symtab *tab = emalloc(sizeof(Symtab)); tab->nsyms = 0; tab->syms = nil; tab->io = globalIO(); tab->div = globalDIV(); return tab; } void freesymtab(Symtab *tab) { int i; for(i = 0; i < tab->nsyms; i++){ Symbol *s = tab->syms[i]; if(s->undefined == 0 && s->value.tag == ArrayTag) freearray(s->value.array); } 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; }