1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
#include <string.h>
#include "proc.h"
/* procedures */
void proc_init(Proc *proc, Str name) {
memset(proc, 0, sizeof(Proc));
Graph *g = &proc->graph;
proc->pool.arena = &proc->perm;
proc->scope.arena = &proc->perm;
g->pool = &proc->pool;
g->start = node_new(g, N_START, NULL);
g->start->type = (Type) {
.lvl = T_BOT,
.t = T_TUPLE,
.next = NULL
};
g->stop = node_new_empty(g, N_STOP);
g->ctrl = g->start;
g->keepalive = node_new(g, N_KEEPALIVE, NULL);
proc->name = name;
}
void proc_free(Proc *proc) {
arena_free(&proc->perm);
arena_free(&proc->scratch);
}
/* scope */
NameBinding *scope_find(Scope *scope, Str name) {
for (ScopeFrame *f = scope->tail; f; f = f->prev) {
for (NameBinding *b = f->latest; b; b = b->prev) {
if (str_eql(b->name, name)) {
return b;
}
}
}
return NULL;
}
ScopeFrame *scope_push(Scope *scope) {
ScopeFrame *f;
if (scope->free_scope) {
f = scope->free_scope;
*f = (ScopeFrame) { 0 };
scope->free_scope = f->prev;
} else {
f = new(scope->arena, ScopeFrame);
}
f->prev = scope->tail;
scope->tail = f;
return f;
}
ScopeFrame *scope_pop(Scope *scope, Graph *g) {
ScopeFrame *f = scope->tail;
scope->tail = f->prev;
f->prev = scope->free_scope;
scope->free_scope = f;
for (NameBinding *b = f->latest; b; ) {
NameBinding *p = b->prev;
b->prev = scope->free_bind;
scope->free_bind = b;
node_remove(g, b->node, g->keepalive);
b = p;
}
return scope->tail;
}
/* returns previous value */
NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Graph *g) {
NameBinding *prev = scope_find(scope, name);
NameBinding *b;
if (scope->free_bind) {
b = scope->free_bind;
*b = (NameBinding) { 0 };
scope->free_bind = b->prev;
} else {
b = new(scope->arena, NameBinding);
}
b->name = name;
b->prev = scope->tail->latest;
scope->tail->latest = b;
b->node = value;
b->src_pos = pos;
node_add(g, value, g->keepalive);
return prev;
}
NameBinding *scope_update(NameBinding *b, Node *to, Graph *g) {
Node *n = b->node;
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_uncollect(Scope *scope, Graph *g, ScopeNameList *nl) {
for (int i = 0; i < nl->len; i++) {
node_remove(g, nl->data[i].node, g->keepalive);
}
}
|