summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
authorWormHeamer2025-08-03 19:52:18 -0400
committerWormHeamer2025-08-03 19:52:18 -0400
commit1a90ef4318c18161aaccf7390016a61c635ac748 (patch)
tree90b6cd4e2dc1261bc2250972aad71c847be80844 /main.c
parent62e4b45143e4ff24a1758a2ccd3af5dfe69706ec (diff)
add assignment statements
Diffstat (limited to 'main.c')
-rw-r--r--main.c110
1 files changed, 65 insertions, 45 deletions
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]);