diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 155 |
1 files changed, 93 insertions, 62 deletions
@@ -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) { |
