summaryrefslogtreecommitdiff
path: root/symbol.c
diff options
context:
space:
mode:
authorPeter Mikkelsen <peter@pmikkelsen.com>2022-02-22 20:41:56 +0000
committerPeter Mikkelsen <peter@pmikkelsen.com>2022-02-22 20:41:56 +0000
commitae6471f1c94f51df540d95edc09c7749002f44e8 (patch)
treed810e349ef9926b256d73b0af5b2497a0d355555 /symbol.c
parente8e6feeb95cdc3b81a2c17b5a342a3d0b170ccb4 (diff)
Implement some form of error guards. It may not be perfect yet
Diffstat (limited to 'symbol.c')
-rw-r--r--symbol.c63
1 files changed, 57 insertions, 6 deletions
diff --git a/symbol.c b/symbol.c
index 6e9aa4a..8e51ba9 100644
--- a/symbol.c
+++ b/symbol.c
@@ -8,6 +8,8 @@
Symtab *globalsymtab;
Symtab *newsymtab(void);
+Symbol *dupsymbol(Symbol *);
+Symtab *dupsymtab(Symtab *);
void freesymtab(Symtab *);
Datum *getalpha(void);
@@ -65,6 +67,28 @@ newsymtab(void)
return tab;
}
+Symbol *
+dupsymbol(Symbol *s)
+{
+ Symbol *new = emalloc(sizeof(Symbol));
+ memcpy(new, s, sizeof(Symbol));
+ new->name = runestrdup(s->name);
+ if(new->value)
+ incdatumref(new->value);
+ return new;
+}
+
+Symtab *
+dupsymtab(Symtab *tab)
+{
+ Symtab *new = newsymtab();
+ memcpy(new, tab, sizeof(Symtab));
+ new->syms = emalloc(sizeof(Symbol*) * new->nsyms);
+ for(int i = 0; i < tab->nsyms; i++)
+ new->syms[i] = dupsymbol(tab->syms[i]);
+ return new;
+}
+
void
freesymtab(Symtab *tab)
{
@@ -130,22 +154,49 @@ pushdfnframe(Rune *code, DfnFrame *scope, Datum *lefto, Datum *righto, Array *le
incarrayref(right);
new->prev = td->currentdfn;
new->chain = scope;
+ new->errorguards = nil;
td->currentdfn = new;
return new;
}
+DfnFrame *
+dupdfnframe(DfnFrame *f)
+{
+ DfnFrame *new = emalloc(sizeof(DfnFrame));
+ memcpy(new, f, sizeof(DfnFrame));
+ new->code = runestrdup(f->code);
+ new->symtab = dupsymtab(f->symtab);
+ if(f->lefto)
+ incdatumref(f->lefto);
+ if(f->righto)
+ incdatumref(f->righto);
+ if(f->left)
+ incdatumref(f->left);
+ if(f->right)
+ incarrayref(f->right);
+ return new;
+}
+
+void
+freedfnframe(DfnFrame *f, int keeperrorguards)
+{
+ freesymtab(f->symtab);
+ freedatum(f->lefto);
+ freedatum(f->righto);
+ freedatum(f->left);
+ freearray(f->right);
+ if(!keeperrorguards)
+ freeerrorguards(f->errorguards);
+ free(f);
+}
+
void
popdfnframe(void)
{
ThreadData *td = getthreaddata();
if(td->currentdfn != nil){
DfnFrame *prev = td->currentdfn->prev;
- freesymtab(td->currentdfn->symtab);
- freedatum(td->currentdfn->lefto);
- freedatum(td->currentdfn->righto);
- freedatum(td->currentdfn->left);
- freearray(td->currentdfn->right);
- free(td->currentdfn);
+ freedfnframe(td->currentdfn, 0);
td->currentdfn = prev;
}
}