From 3ca04326ddb36b8551acf417ef195d1572bb3d47 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Tue, 21 Oct 2025 05:47:19 -0400 Subject: almost there... --- proc.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 82 insertions(+), 10 deletions(-) (limited to 'proc.c') diff --git a/proc.c b/proc.c index 0877a91..7e983ca 100644 --- a/proc.c +++ b/proc.c @@ -102,26 +102,98 @@ NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Graph return prev; } -NameBinding *scope_update(NameBinding *b, Node *to, Graph *g) { +NameBinding *scope_update(Scope *scope, NameBinding *b, Node *to, Graph *g) { Node *n = b->node; + unsigned nestlvl = scope->nestlvl; + for (ScopeChangeList *l = scope->changes; l; l = l->prev) { + if (b->nestlvl < nestlvl) { + scope_changelist_update(l, b, n, to, g); + } + nestlvl--; + } node_add(g, to, g->keepalive); b->node = to; node_remove(g, n, g->keepalive); return b; } -/* adds to keepalive so these aren't invalidated */ -void scope_collect(Scope *scope, Graph *g, ScopeNameList *nl, Arena *arena) { - for (ScopeFrame *f = scope->tail; f; f = f->prev) { - for (NameBinding *b = f->latest; b; b = b->prev) { - node_add(g, b->node, g->keepalive); - ZDA_PUSH(arena, nl, (ScopeName) { b->name, b->node }); +void scope_changelist_update(ScopeChangeList *l, NameBinding *b, Node *from, Node *to, Graph *g) { + for (unsigned i = 0; i < l->n; i++) { + ScopeChange *chg = XAR_GET(l, i); + if (chg->bind == b) { + node_add(g, to, g->keepalive); + node_remove(g, chg->to, g->keepalive); + chg->to = to; + return; + } + } + ScopeChange *chg = XAR_PUT(l, l->n++, l->arena); + node_add(g, from, g->keepalive); + node_add(g, to, g->keepalive); + chg->bind = b; + chg->from = from; + chg->to = to; +} + +void scope_changelist_push(Scope *scope, ScopeChangeList *l, Arena *a) { + l->arena = a; + l->prev = scope->changes; + scope->changes = l; + scope->nestlvl++; +} + +void scope_changelist_pop(Scope *scope, Graph *g) { + ScopeChangeList *l = scope->changes; + scope->changes = l->prev; + scope->nestlvl--; + for (unsigned i = 0; i < l->n; i++) { + ScopeChange *chg = XAR_GET(l, i); + scope_update(scope, chg->bind, chg->from, g); + } +} + +#include +/* TODO: implement merge, probably will need scratch arena to build up + * a Xar of something like struct { NameBinding *b; Node *y, *n; }. if + * no match for the given bind is found in the opposite change list, + * it gets the "from" value found in the other. + **/ +typedef struct { + NameBinding *b; + Node *y, *n; +} MergeChange; +void scope_changelist_merge(Scope *scope, ScopeChangeList *y, ScopeChangeList *n, Node *region, Graph *graph, Arena *scratch) { + MergeChange *m = new_arr(scratch, MergeChange, y->n + n->n); + unsigned c = 0; + for (unsigned i = 0; i < y->n; i++) { + ScopeChange *chg = XAR_GET(y, i); + m[c].b = chg->bind; + m[c].y = chg->to; + m[c].n = chg->from; + c++; + } + unsigned yc = c; + for (unsigned i = 0; i < n->n; i++) { + ScopeChange *chg = XAR_GET(n, i); + for (unsigned j = 0; j < yc; j++) { + if (m[j].b == chg->bind) { + m[j].n = chg->to; + goto next; + } } + m[c].b = chg->bind; + m[c].y = chg->from; + m[c].n = chg->to; + c++; +next: } + fprintf(stderr, "%u\n", c); } -void scope_uncollect(Scope *scope, Graph *g, ScopeNameList *nl) { - for (int i = 0; i < nl->len; i++) { - node_remove(g, nl->data[i].node, g->keepalive); +void scope_changelist_discard(ScopeChangeList *l, Graph *g) { + for (unsigned i = 0; i < l->n; i++) { + ScopeChange *chg = XAR_GET(l, i); + node_remove(g, chg->from, g->keepalive); + node_remove(g, chg->to, g->keepalive); } } -- cgit v1.2.3