diff options
Diffstat (limited to 'main.c')
| -rw-r--r-- | main.c | 114 |
1 files changed, 64 insertions, 50 deletions
@@ -9,6 +9,7 @@ #include "lex.h" #include "arena.h" #include "dynarr.h" +#include "strio.h" #include "ir.h" int no_opt = 0; @@ -101,14 +102,53 @@ void parse_stmt(Lexer *l, Proc *p) { } } + +Type parse_type(Lexer *l, Proc *proc) { + (void)proc; + Type t = { .lvl = T_BOT }; + if (str_eql(l->ident, S("i64"))) { + t.t = T_INT; + } else if (str_eql(l->ident, S("bool"))) { + t.t = T_BOOL; + } else { + lex_error(l, LE_ERROR, S("unknown type")); + } + lex_next(l); + return t; +} + +void parse_args_list(Lexer *l, Proc *proc) { + Node *start = proc->start; + int i = 0; + while (l->tok != TOK_RPAREN && l->tok != TOK_EOF) { + lex_expect(l, TM_IDENT); + Str name = l->ident; + LexSpan pos = l->pos; + lex_expect(l, TM_IDENT); + Value v = (Value) { .type = parse_type(l, proc) }; + ZDA_PUSH(&start->val.tuple, v, &proc->arena); + lex_expected(l, TM_RPAREN | TM_COMMA); + Node *proj = node_new(proc, N_PROJ, proc->start); + proj->val.type = v.type; + proj->val.i = i++; + scope_bind(&proc->scope, name, proj, pos, proc); + } + lex_expected(l, TM_RPAREN); + lex_next(l); +} + Proc *parse_proc(Lexer *l, Unit *u) { DA_FIT(&u->procs, u->procs.len + 1); Proc *proc = &u->procs.data[u->procs.len++]; lex_expect(l, TM_IDENT); proc_init(proc, l->ident); - lex_expect(l, TM_LBRACE); - lex_next(l); scope_push(&proc->scope, proc); + lex_expect(l, TM_LPAREN | TM_LBRACE); + if (l->tok == TOK_LPAREN) { + parse_args_list(l, proc); + } + lex_expected(l, TM_LBRACE); + lex_next(l); while (l->tok != TOK_RBRACE) { lex_expected_not(l, TM_EOF); parse_stmt(l, proc); @@ -119,39 +159,6 @@ Proc *parse_proc(Lexer *l, Unit *u) { return proc; } -int type_check(Node *n) { - /*fprintf(stderr, "::\n"); - for (int i = 0; i < n->in.len; i++) { - fprintf(stderr, "%d: %d/%d\n", i, - n->in.data[i]->val.type.lvl, - n->in.data[i]->val.type.t); - }*/ - switch (n->type) { - case N_OP_NEG: - n->val.type = (Type) { .lvl = T_TOP, .t = T_INT }; - return n->in.data[0]->val.type.t == T_INT; - case N_OP_NOT: - n->val.type = (Type) { .lvl = T_TOP, .t = n->in.data[0]->val.type.t }; - return n->in.data[0]->val.type.t == T_INT || n->in.data[0]->val.type.t == T_BOOL; - case N_OP_ADD: case N_OP_SUB: case N_OP_MUL: case N_OP_DIV: - case N_OP_AND: case N_OP_OR: case N_OP_XOR: - case N_OP_SHL: case N_OP_SHR: - n->val.type = (Type) { .lvl = T_TOP, .t = T_INT }; - return n->in.data[0]->val.type.t == T_INT && n->in.data[1]->val.type.t == T_INT; - case N_CMP_LES: case N_CMP_GTR: - case N_CMP_LTE: case N_CMP_GTE: - n->val.type = (Type) { .lvl = T_TOP, .t = T_BOOL }; - return n->in.data[0]->val.type.t == T_INT && n->in.data[1]->val.type.t == T_INT; - case N_CMP_EQL: - case N_CMP_NEQ: - n->val.type = (Type) { .lvl = T_TOP, .t = T_BOOL }; - return (n->in.data[0]->val.type.t == T_INT && n->in.data[1]->val.type.t == T_INT) - || (n->in.data[0]->val.type.t == T_BOOL && n->in.data[1]->val.type.t == T_BOOL); - default: - return 1; - } -} - Node *parse_term(Lexer *l, Proc *p) { Node *node = NULL; NodeType op_after = N_START; @@ -166,11 +173,7 @@ Node *parse_term(Lexer *l, Proc *p) { default: return node; } if (post_op == N_START) return node; - Node *r = node_new(p, post_op, node); - if (!type_check(r)) { - lex_error_at(l, r->src_pos, LE_ERROR, S("type mismatch")); - } - return node_peephole(r, p, l); + return node_peephole(node_new(p, post_op, node), p, l); } if (l->tok == TOK_LPAREN) { lex_next(l); @@ -242,9 +245,6 @@ Node *parse_expr(Lexer *l, Proc *p) { } Node *n = node_peephole(lhs, p, l); n->src_pos = (LexSpan) { pos.ofs, l->pos.ofs - pos.ofs }; - if (!type_check(n)) { - lex_error_at(l, n->src_pos, LE_ERROR, S("type mismatch")); - } return n; } @@ -273,8 +273,17 @@ void parse_unit(Lexer *l) { /* graph output */ -void node_print(Node *n) { - if (n->type == N_LIT) { +void node_print(Node *n, Proc *p) { + if (n->type == N_START) { + Str s = S(""); + int c = n->val.tuple.len; + Value *v = n->val.tuple.data; + for (int i = 0; i < c; i++) { + if (i > 0) str_cat(&s, S(", "), &p->arena); + str_cat(&s, type_desc(&v[i].type, &p->arena), &p->arena); + } + printf("\t%d [label=\"start(%.*s)\"]\n", n->id, (int)s.n, s.s); + } else if (n->type == N_LIT) { switch (n->val.type.t) { case T_INT: printf("\t%d [label=\"%ld\"]\n", n->id, n->val.i); @@ -286,6 +295,8 @@ void node_print(Node *n) { printf("\t%d [label=\"literal %d\"]\n", n->id, n->id); break; } + } else if (n->type == N_PROJ) { + printf("\t%d [label=\"PROJ(%ld)\", shape=record]\n", n->id, n->val.i); } else { printf("\t%d [label=\"%s\", shape=record]\n", n->id, node_type_name(n->type)); } @@ -294,21 +305,24 @@ void node_print(Node *n) { } 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); + Node *o = n->out.data[i]; + if (o->type == N_LIT) { + printf("\t%d -> %d [style=dashed]\n", n->id, o->id); } else { - printf("\t%d -> %d\n", n->id, n->out.data[i]->id); + int j; + for (j = 0; j < o->in.len && o->in.data[j] != n; j++); + printf("\t%d -> %d [label=%d]\n", n->id, o->id, j); } } for (int i = 0; i < n->out.len; i++) { - node_print(n->out.data[i]); + node_print(n->out.data[i], p); } } 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); + node_print(p->start, p); if (no_opt) { for (NameBinding *b = p->scope.free_bind; b; b = b->prev) { uint64_t id = (uintptr_t)b->node; |
