summaryrefslogtreecommitdiff
path: root/symbol.c
diff options
context:
space:
mode:
Diffstat (limited to 'symbol.c')
-rw-r--r--symbol.c104
1 files changed, 96 insertions, 8 deletions
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