summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-02 07:01:47 -0400
committerWormHeamer2025-08-02 07:01:47 -0400
commit483334888ae5098ba4d9088698bcdea7ba4703ef (patch)
tree57da8ac719019e19360a9f9efbfaf9924a2eb833 /main.c
parenteb9581e4f599470748fdfdceacce61fd8e8f52c7 (diff)
better error reporting
Diffstat (limited to 'main.c')
-rw-r--r--main.c88
1 files changed, 47 insertions, 41 deletions
diff --git a/main.c b/main.c
index 13bfa69..8c6b837 100644
--- a/main.c
+++ b/main.c
@@ -66,6 +66,7 @@ typedef struct Node {
typedef struct NameBinding {
struct NameBinding *prev;
+ LexSpan src_pos;
Str name;
Node *node;
} NameBinding;
@@ -155,16 +156,14 @@ void node_add(Proc *p, Node *src, Node *dest) {
src->refs++;
dest->refs++;
if (dest->src_pos.n == 0) dest->src_pos = src->src_pos;
- else {
- LexSpan *sp = &src->src_pos, *dp = &dest->src_pos;
- if (sp->ofs < dp->ofs) {
- dp->n = (dp->ofs + dp->n) - sp->ofs;
- dp->ofs = sp->ofs;
- }
- if ((sp->ofs + sp->n) > (dp->ofs + dp->n)) {
- dp->n = (sp->ofs + sp->n) - dp->ofs;
- }
- }
+}
+
+void node_remove(Proc *p, Node *src, Node *dest) {
+ node_del_out(src, dest);
+ node_del_in(dest, src);
+ if (dest->refs < 1) node_die(dest, p);
+ if (src->refs < 1) node_die(src, p);
+ else if (src->out.len < 1) node_kill(src, p);
}
static int global_node_count = 0;
@@ -224,12 +223,13 @@ void proc_print(Proc *p) {
if (p->start) {
printf("\t\"%.*s\" -> %d\n", (int)p->name.n, p->name.s, p->start->id);
node_print(p->start);
- /*if (no_opt) {
+ if (no_opt) {
for (NameBinding *b = p->scope.free_bind; b; b = b->prev) {
- printf("\t\"%.*s\" [shape=none,fontcolor=blue]\n", (int)b->name.n, b->name.s);
- printf("\t\"%.*s\" -> %d [arrowhead=none,style=dotted,color=blue]\n", (int)b->name.n, b->name.s, b->node->id);
+ uint64_t id = (uintptr_t)b->node;
+ printf("\t\t%lu [label=\"%.*s\",shape=none,fontcolor=blue]\n", id, (int)b->name.n, b->name.s);
+ printf("\t\t%lu -> %d [arrowhead=none,style=dotted,color=blue]\n", id, b->node->id);
}
- }*/
+ }
}
}
@@ -355,20 +355,21 @@ NameBinding *scope_find(Scope *scope, Str name) {
return NULL;
}
-ScopeFrame *scope_push(Scope *scope, Arena *arena) {
+ScopeFrame *scope_push(Scope *scope, Proc *proc) {
ScopeFrame *f;
if (scope->free_scope) {
f = scope->free_scope;
+ *f = (ScopeFrame) { 0 };
scope->free_scope = f->prev;
} else {
- f = new(arena, ScopeFrame);
+ f = new(&proc->arena, ScopeFrame);
}
f->prev = scope->tail;
scope->tail = f;
return f;
}
-ScopeFrame *scope_pop(Scope *scope) {
+ScopeFrame *scope_pop(Scope *scope, Proc *proc) {
ScopeFrame *f = scope->tail;
scope->tail = f->prev;
f->prev = scope->free_scope;
@@ -377,28 +378,30 @@ ScopeFrame *scope_pop(Scope *scope) {
NameBinding *p = b->prev;
b->prev = scope->free_bind;
scope->free_bind = b;
+ node_remove(proc, b->node, proc->keepalive);
b = p;
}
return scope->tail;
}
/* returns previous value */
-Node *scope_bind(Scope *scope, Str name, Node *value, Arena *arena) {
- NameBinding *b = scope_find(scope, name);
- Node *og = b ? b->node : NULL;
- if (!b) {
- if (scope->free_bind) {
- b = scope->free_bind;
- scope->free_bind = b->prev;
- } else {
- b = new(arena, NameBinding);
- }
- b->name = name;
- b->prev = scope->tail->latest;
- scope->tail->latest = b;
+NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Proc *proc) {
+ 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(&proc->arena, NameBinding);
}
+ b->name = name;
+ b->prev = scope->tail->latest;
+ scope->tail->latest = b;
b->node = value;
- return og;
+ b->src_pos = pos;
+ node_add(proc, value, proc->keepalive);
+ return prev;
}
/* parsing */
@@ -414,13 +417,13 @@ void parse_let(Lexer *l, Proc *p) {
recurse:
lex_expect(l, TM_IDENT);
Str name = l->ident;
+ LexSpan pos = l->pos;
lex_expect(l, TM_EQUALS);
lex_next(l);
Node *rhs = parse_expr(l, p);
- node_add(p, rhs, p->keepalive);
- Node *b = scope_bind(&p->scope, name, rhs, &p->arena);
+ NameBinding *b = scope_bind(&p->scope, name, rhs, pos, p);
if (b) {
- lex_error_at(l, rhs->src_pos, LE_WARN, S("shadowing previous declaration"));
+ lex_error_at(l, pos, LE_WARN, S("shadowing previous declaration"));
lex_error_at(l, b->src_pos, LE_WARN, S("declared here"));
}
if (l->tok == TOK_COMMA) goto recurse;
@@ -431,11 +434,12 @@ void parse_stmt(Lexer *l, Proc *p);
/* TODO: return node from this! */
void parse_block(Lexer *l, Proc *p) {
lex_next(l);
- scope_push(&p->scope, &p->arena);
- while (l->tok != TOK_RBRACE && l->tok != TOK_EOF) {
+ scope_push(&p->scope, p);
+ while (l->tok != TOK_RBRACE) {
+ lex_expected_not(l, TM_EOF);
parse_stmt(l, p);
}
- scope_pop(&p->scope);
+ scope_pop(&p->scope, p);
lex_expected(l, TM_RBRACE);
lex_next(l);
}
@@ -469,13 +473,12 @@ Proc *parse_proc(Lexer *l, Unit *u) {
proc->name = l->ident;
lex_expect(l, TM_LBRACE);
lex_next(l);
- scope_push(&proc->scope, &proc->arena);
+ scope_push(&proc->scope, proc);
while (l->tok != TOK_RBRACE) {
lex_expected_not(l, TM_EOF);
parse_stmt(l, proc);
}
- scope_pop(&proc->scope);
- node_kill(proc->keepalive, proc);
+ scope_pop(&proc->scope, proc);
lex_expected(l, TM_RBRACE);
lex_next(l);
return proc;
@@ -527,6 +530,7 @@ Node *parse_term(Lexer *l, Proc *p) {
/* TODO: operator precedence would be kinda nice actually, sad to say */
Node *parse_expr(Lexer *l, Proc *p) {
+ LexSpan pos = l->pos;
Node *lhs = parse_term(l, p);
if (TMASK(l->tok) & (TM_PLUS | TM_MINUS | TM_ASTERISK | TM_SLASH | TM_NOT | TM_AND | TM_XOR | TM_OR)) {
Token t = l->tok;
@@ -546,7 +550,9 @@ Node *parse_expr(Lexer *l, Proc *p) {
}
lhs = node_new(p, nt, lhs, rhs);
}
- return node_peephole(lhs, p, l);
+ Node *n = node_peephole(lhs, p, l);
+ n->src_pos = (LexSpan) { pos.ofs, l->pos.ofs - pos.ofs };
+ return n;
}
void parse_toplevel(Lexer *l, Unit *u) {