From 1a90ef4318c18161aaccf7390016a61c635ac748 Mon Sep 17 00:00:00 2001 From: WormHeamer Date: Sun, 3 Aug 2025 19:52:18 -0400 Subject: add assignment statements --- ir.c | 9 +++++ ir.h | 1 + lex.c | 6 ++++ lex.h | 7 ++-- main.c | 110 +++++++++++++++++++++++++++++++++++++------------------------- test.lang | 10 +++--- 6 files changed, 89 insertions(+), 54 deletions(-) diff --git a/ir.c b/ir.c index 2e3e3b2..c75113e 100644 --- a/ir.c +++ b/ir.c @@ -306,3 +306,12 @@ NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Proc * node_add(proc, value, proc->keepalive); return prev; } + +NameBinding *scope_update(Scope *scope, Str name, Node *to, Proc *proc) { + NameBinding *b = scope_find(scope, name); + if (!b) return NULL; + node_remove(proc, b->node, proc->keepalive); + node_add(proc, to, proc->keepalive); + b->node = to; + return b; +} diff --git a/ir.h b/ir.h index dd2e496..9351864 100644 --- a/ir.h +++ b/ir.h @@ -101,5 +101,6 @@ ScopeFrame *scope_push(Scope *scope, Proc *proc); ScopeFrame *scope_pop(Scope *scope, Proc *proc); NameBinding *scope_find(Scope *scope, Str name); NameBinding *scope_bind(Scope *scope, Str name, Node *value, LexSpan pos, Proc *proc); +NameBinding *scope_update(Scope *scope, Str name, Node *to, Proc *proc); #endif diff --git a/lex.c b/lex.c index 922ef17..733fb52 100644 --- a/lex.c +++ b/lex.c @@ -215,6 +215,12 @@ recurse: default: T(TOK_GTR); break; } break; + case ':': + switch (l->buf.s[i]) { + case '=': T(TOK_ASSIGN); i++; break; + case '>': T(TOK_SHR); break; + } + break; } } if (l->tok == TOK_MAX) { diff --git a/lex.h b/lex.h index 922a217..a83905c 100644 --- a/lex.h +++ b/lex.h @@ -19,7 +19,6 @@ X(MINUS, "-")\ X(ASTERISK, "*")\ X(SLASH, "/")\ - X(EQUALS, "=")\ X(COLON, ":")\ X(COMMA, ",")\ X(NOT, "~")\ @@ -28,7 +27,8 @@ X(XOR, "xor")\ X(SHL, "<<")\ X(SHR, ">>")\ - X(ASSSIGN, ":=")\ + X(ASSIGN, ":=")\ + X(EQL, "=")\ X(NEQ, "<>")\ X(LES, "<")\ X(GTR, ">")\ @@ -47,8 +47,7 @@ X(TOK_MINUS, '-')\ X(TOK_ASTERISK, '*')\ X(TOK_SLASH, '/')\ - X(TOK_EQUALS, '=')\ - X(TOK_COLON, ':')\ + X(TOK_EQL, '=')\ X(TOK_COMMA, ',')\ X(TOK_NOT, '~')\ X(TOK_AND, '&')\ diff --git a/main.c b/main.c index 05c639c..ee759dd 100644 --- a/main.c +++ b/main.c @@ -28,50 +28,6 @@ void unit_free(Unit *u) { free(u->procs.data); } -void node_print(Node *n) { - if (n->type == N_LIT) { - printf("\t%d [label=\"%ld\"]\n", n->id, n->val.i); - } else { - printf("\t%d [label=\"%s\", shape=record]\n", n->id, node_type_name(n->type)); - } - if (n->walked) { - return; - } - n->walked = 1; - for (int i = 0; i < n->out.len; i++) { - if (n->out.data[i]->type == N_LIT) { - printf("\t%d -> %d [style=dashed]\n", n->id, n->out.data[i]->id); - } else { - printf("\t%d -> %d\n", n->id, n->out.data[i]->id); - } - } - for (int i = 0; i < n->out.len; i++) { - node_print(n->out.data[i]); - } -} - -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) { - for (NameBinding *b = p->scope.free_bind; b; b = b->prev) { - 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); - } - } - } -} - -void unit_print(Unit *u) { - puts("digraph {"); - for (int i = 0; i < u->procs.len; i++) { - proc_print(&u->procs.data[i]); - } - puts("}"); -} - /* parsing */ Node *parse_expr(Lexer *l, Proc *p); @@ -86,7 +42,7 @@ recurse: lex_expect(l, TM_IDENT); Str name = l->ident; LexSpan pos = l->pos; - lex_expect(l, TM_EQUALS); + lex_expect(l, TM_EQL); lex_next(l); Node *rhs = parse_expr(l, p); NameBinding *b = scope_bind(&p->scope, name, rhs, pos, p); @@ -112,6 +68,17 @@ void parse_block(Lexer *l, Proc *p) { lex_next(l); } +void parse_assign(Lexer *l, Proc *p) { + Str name = l->ident; + LexSpan pos = l->pos; + lex_expect(l, TM_ASSIGN); + lex_next(l); + Node *e = parse_expr(l, p); + if (!scope_update(&p->scope, name, e, p)) { + lex_error_at(l, pos, LE_ERROR, S("undeclared identifier")); + } +} + void parse_stmt(Lexer *l, Proc *p) { /* TODO */ (void)l; @@ -125,6 +92,9 @@ void parse_stmt(Lexer *l, Proc *p) { case TOK_LBRACE: parse_block(l, p); break; + case TOK_IDENT: + parse_assign(l, p); + break; default: lex_expected(l, TM_RBRACE); break; @@ -233,6 +203,8 @@ void parse_toplevel(Lexer *l, Unit *u) { } } + +void unit_print(Unit *u); void parse_unit(Lexer *l) { Unit u = { 0 }; unit_init(&u); @@ -243,6 +215,54 @@ void parse_unit(Lexer *l) { unit_free(&u); } +/* graph output */ + +void node_print(Node *n) { + if (n->type == N_LIT) { + printf("\t%d [label=\"%ld\"]\n", n->id, n->val.i); + } else { + printf("\t%d [label=\"%s\", shape=record]\n", n->id, node_type_name(n->type)); + } + if (n->walked) { + return; + } + n->walked = 1; + for (int i = 0; i < n->out.len; i++) { + if (n->out.data[i]->type == N_LIT) { + printf("\t%d -> %d [style=dashed]\n", n->id, n->out.data[i]->id); + } else { + printf("\t%d -> %d\n", n->id, n->out.data[i]->id); + } + } + for (int i = 0; i < n->out.len; i++) { + node_print(n->out.data[i]); + } +} + +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) { + for (NameBinding *b = p->scope.free_bind; b; b = b->prev) { + 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); + } + } + } +} + +void unit_print(Unit *u) { + puts("digraph {"); + for (int i = 0; i < u->procs.len; i++) { + proc_print(&u->procs.data[i]); + } + puts("}"); +} + +/* main */ + int main(int argc, const char **argv) { if (argc != 2) { fprintf(stderr, "Usage: %s FILE\n", argv[0]); diff --git a/test.lang b/test.lang index 7e83dc3..0f2d4b8 100644 --- a/test.lang +++ b/test.lang @@ -9,9 +9,9 @@ // also single-line now proc main { - let a = 2, b = 3 - let c = a + b, d = a * b * c, e = d + d - let f = e + (c * e * b * a) - let r = (((f << 16) | (f >> 16)) xor (f * 1875387131)) - return (r xor (r * 1875387131)) & 31 + let a = 3 << 2 + let b = 1 << a + let c = b xor 2381 + b := b + c + return (a + b) * c } -- cgit v1.2.3