summaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c155
1 files changed, 93 insertions, 62 deletions
diff --git a/main.c b/main.c
index e8df555..b1e5150 100644
--- a/main.c
+++ b/main.c
@@ -5,6 +5,8 @@
#include <string.h>
#include "lex.h"
+#include "arena.h"
+#include "dynarr.h"
/* node graph */
@@ -20,97 +22,125 @@ typedef enum {
} NodeType;
typedef struct Node {
+ int id;
NodeType type;
- struct Node **inputs, **outputs;
+ DYNARR(struct Node *) in, out;
+ union {
+ int64_t i;
+ } v;
} Node;
typedef struct {
+ Arena arena;
+ int last_id;
Node *start, *stop;
-} ProcGraph;
+} Proc;
+
+typedef struct {
+ DYNARR(Proc) procs;
+} Unit;
+
+void unit_init(Unit *u) {
+ (void)u;
+}
+
+void unit_fini(Unit *u) {
+ free(u->procs.data);
+}
+
+Node *node_new(Proc *p, NodeType t) {
+ Node *n = new(&p->arena, Node);
+ n->type = t;
+ n->id = p->last_id++;
+ return n;
+}
+
+void node_add(Proc *p, Node *src, Node *dest) {
+ ZDA_PUSH(&src->out, dest, &p->arena);
+ ZDA_PUSH(&dest->in, src, &p->arena);
+}
/* parsing */
-void parse_expr(Lexer *l);
+Node *parse_expr(Lexer *l, Proc *p);
-void parse_stmt_let(Lexer *l) {
- lex_expect(l, TMASK(TOK_IDENT));
- Str name = l->ident;
- lex_expect(l, TMASK(TOK_EQUALS) | TMASK(TOK_COLON));
+void parse_return(Lexer *l, Proc *p) {
lex_next(l);
- parse_expr(l);
- printf("name_bind %.*s\n", (int)name.n, name.s);
+ Node *n = parse_expr(l, p);
+ node_add(p, n, p->stop);
}
-void parse_stmt(Lexer *l) {
+void parse_stmt(Lexer *l, Proc *p) {
/* TODO */
(void)l;
switch (l->tok) {
- case TOK_LET:
- parse_stmt_let(l);
- break;
case TOK_RETURN:
- lex_next(l);
- parse_expr(l);
- puts("return");
+ parse_return(l, p);
break;
default:
- lex_expected(l, TMASK(TOK_RBRACE));
+ lex_expected(l, TM_RBRACE);
}
}
-void parse_proc(Lexer *l) {
- lex_expect(l, TMASK(TOK_IDENT));
- lex_expect(l, TMASK(TOK_LBRACE));
+void parse_proc(Lexer *l, Unit *u) {
+ DA_FIT(&u->procs, u->procs.len + 1);
+ Proc *proc = &u->procs.data[u->procs.len++];
+ memset(proc, 0, sizeof(Proc));
+ proc->start = node_new(proc, N_START);
+ proc->stop = node_new(proc, N_STOP);
+ lex_expect(l, TM_IDENT);
+ lex_expect(l, TM_LBRACE);
lex_next(l);
while (l->tok != TOK_RBRACE) {
- lex_expected_not(l, TMASK(TOK_EOF));
- parse_stmt(l);
+ lex_expected_not(l, TM_EOF);
+ parse_stmt(l, proc);
}
- lex_expected(l, TMASK(TOK_RBRACE));
+ lex_expected(l, TM_RBRACE);
lex_next(l);
}
-void parse_term(Lexer *l) {
+Node *parse_term(Lexer *l, Proc *p) {
+ Node *node = NULL;
int negate_after = l->tok == TOK_MINUS;
- if (TMASK(l->tok) & (TMASK(TOK_MINUS) | TMASK(TOK_PLUS))) {
+ if (TMASK(l->tok) & (TM_MINUS | TM_PLUS)) {
lex_next(l);
}
if (l->tok == TOK_LPAREN) {
lex_next(l);
- parse_expr(l);
- lex_expected(l, TMASK(TOK_RPAREN));
+ node = parse_expr(l, p);
+ lex_expected(l, TM_RPAREN);
lex_next(l);
} else {
- lex_expected(l, TMASK(TOK_LIT_NUM) | TMASK(TOK_LIT_STR) | TMASK(TOK_LIT_CHAR) | TMASK(TOK_IDENT));
- switch (l->tok) {
- case TOK_IDENT:
- printf("var %.*s\n", (int)l->ident.n, l->ident.s);
- break;
- case TOK_LIT_STR:
- printf("lit_str %.*s\n", (int)l->ident.n, l->ident.s);
- break;
- case TOK_LIT_CHAR:
- printf("lit_char %.*s\n", (int)l->ident.n, l->ident.s);
- break;
- case TOK_LIT_NUM:
- printf("lit_num %.*s\n", (int)l->ident.n, l->ident.s);
- break;
- default:
- break;
+ lex_expected(l, TM_LIT_NUM);
+ int64_t val = 0;
+ for (int i = 0; i < l->ident.n; i++) {
+ if (!(l->ident.s[i] >= '0' && l->ident.s[i] <= '9')) {
+ lex_error(l, LE_ERROR, S("Not a digit"));
+ break;
+ }
+ val = (val * 10) + (l->ident.s[i] - '0');
}
+ node = node_new(p, N_LIT_INT);
+ node_add(p, p->start, node);
+ node->v.i = val;
lex_next(l);
}
- if (negate_after) puts("negate");
+ if (negate_after) {
+ Node *neg = node_new(p, N_OP_NEG);
+ node_add(p, node, neg);
+ return neg;
+ }
+ return node;
}
-void parse_expr(Lexer *l) {
- parse_term(l);
+Node *parse_expr(Lexer *l, Proc *p) {
+ Node *lhs = parse_term(l, p);
if (l->tok == TOK_LPAREN) {
lex_next(l);
puts("args_start");
for (;;) {
- parse_expr(l);
- lex_expected(l, TMASK(TOK_COMMA) | TMASK(TOK_RPAREN));
+ parse_expr(l, p);
+ lex_expected(l, TM_COMMA | TM_RPAREN);
if (l->tok == TOK_RPAREN) break;
lex_next(l);
}
@@ -118,35 +148,36 @@ void parse_expr(Lexer *l) {
puts("args_end");
puts("func_call");
}
- if (TMASK(l->tok) & (TMASK(TOK_PLUS) | TMASK(TOK_MINUS) | TMASK(TOK_ASTERISK) | TMASK(TOK_SLASH))) {
- Token t = l->tok;
+ if (TMASK(l->tok) & (TM_PLUS | TM_MINUS | TM_ASTERISK | TM_SLASH)) {
+ lex_expected(l, TM_PLUS);
lex_next(l);
- parse_expr(l);
- switch (t) {
- case TOK_PLUS: puts("add"); break;
- case TOK_MINUS: puts("subtract"); break;
- case TOK_ASTERISK: puts("multiply"); break;
- case TOK_SLASH: puts("divide"); break;
- default: break;
- }
+ Node *rhs = parse_expr(l, p);
+ Node *add = node_new(p, N_OP_ADD);
+ node_add(p, lhs, add);
+ node_add(p, rhs, add);
+ return add;
}
+ return lhs;
}
-void parse_toplevel(Lexer *l) {
+void parse_toplevel(Lexer *l, Unit *u) {
switch (l->tok) {
case TOK_PROC:
- parse_proc(l);
+ parse_proc(l, u);
break;
default:
- lex_expected(l, TMASK(TOK_PROC));
+ lex_expected(l, TM_PROC);
break;
}
}
void parse_unit(Lexer *l) {
+ Unit u = { 0 };
+ unit_init(&u);
while (l->tok != TOK_EOF) {
- parse_toplevel(l);
+ parse_toplevel(l, &u);
}
+ unit_fini(&u);
}
int main(int argc, const char **argv) {