summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ir.c9
-rw-r--r--ir.h1
-rw-r--r--lex.c6
-rw-r--r--lex.h7
-rw-r--r--main.c110
-rw-r--r--test.lang10
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
}