diff options
author | Peter Mikkelsen <peter@pmikkelsen.com> | 2022-02-22 20:41:56 +0000 |
---|---|---|
committer | Peter Mikkelsen <peter@pmikkelsen.com> | 2022-02-22 20:41:56 +0000 |
commit | ae6471f1c94f51df540d95edc09c7749002f44e8 (patch) | |
tree | d810e349ef9926b256d73b0af5b2497a0d355555 /symbol.c | |
parent | e8e6feeb95cdc3b81a2c17b5a342a3d0b170ccb4 (diff) |
Implement some form of error guards. It may not be perfect yet
Diffstat (limited to 'symbol.c')
-rw-r--r-- | symbol.c | 63 |
1 files changed, 57 insertions, 6 deletions
@@ -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; } } |