diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-09-18 14:46:34 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-09-18 14:46:34 -0400 |
commit | d905377ca9a8648a24d3baf671d4c729596efdd8 (patch) | |
tree | faa88d8c6351922c7eb6103f4995924c17febbe6 | |
parent | ad062bd0ad547447f74840b89fb0dced35be0fdc (diff) |
parser output
-rw-r--r-- | identifiers.c | 3 | ||||
-rw-r--r-- | main.c | 11 | ||||
-rw-r--r-- | parse.c | 25 | ||||
-rw-r--r-- | test.toc | 4 | ||||
-rw-r--r-- | types.c | 82 |
5 files changed, 76 insertions, 49 deletions
diff --git a/identifiers.c b/identifiers.c index 0f083c0..6e993f2 100644 --- a/identifiers.c +++ b/identifiers.c @@ -187,8 +187,7 @@ static void ident_add_decl(Identifier i, struct Declaration *d, struct Block *b) } static IdentDecl *ident_decl(Identifier i) { - assert(i->decls.item_sz); - return (IdentDecl*)arr_last(&i->decls); + return i->decls.item_sz == 0 ? NULL : (IdentDecl*)arr_last(&i->decls); } static void idents_free(Identifiers *ids) { @@ -60,17 +60,18 @@ int main(int argc, char **argv) { return EXIT_FAILURE; } - fprint_parsed_file(stdout, &f); - - tokr_free(&t); - - block_enter(NULL, &f.stmts); /* enter global scope */ if (!types_file(&f)) { err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n")); return EXIT_FAILURE; } + fprint_parsed_file(stdout, &f); + + tokr_free(&t); + + + /* TODO (eventually): use a tmp file (don't overwrite old output if there's an error) */ /* const char *c_out_filename = "out.c"; */ /* const char *h_out_filename = "out.h"; */ @@ -939,6 +939,11 @@ NOTE: this function actually parses all types in the declaration, but it just calls itself to do that. */ +static inline bool ends_decl(Token *t, DeclEndType ends_with) { + return (token_is_kw(t, KW_SEMICOLON) && ends_with == DECL_END_SEMICOLON) + || (token_is_kw(t, KW_RPAREN) && ends_with == DECL_END_RPAREN); +} + static bool parse_single_type_in_decl(Parser *p, Declaration *d, DeclEndType ends_with) { Tokenizer *t = p->tokr; /* OPTIM: Maybe don't use a dynamic array or use parser allocator. */ @@ -1024,8 +1029,7 @@ static bool parse_single_type_in_decl(Parser *p, Declaration *d, DeclEndType end if (!parse_expr(p, &d->expr, expr_find_end(p, 0))) return false; d->flags |= DECL_FLAG_HAS_EXPR; - if ((token_is_kw(t->token, KW_SEMICOLON) && ends_with == DECL_END_SEMICOLON) - || (token_is_kw(t->token, KW_RPAREN) && ends_with == DECL_END_RPAREN)) { + if (ends_decl(t->token, ends_with)) { t->token++; return true; } @@ -1033,8 +1037,7 @@ static bool parse_single_type_in_decl(Parser *p, Declaration *d, DeclEndType end ends_with == DECL_END_SEMICOLON ? ';' : ')'); return false; - } else if ((token_is_kw(t->token, KW_SEMICOLON) && ends_with == DECL_END_SEMICOLON) - || (token_is_kw(t->token, KW_RPAREN) && ends_with == DECL_END_RPAREN)) { + } else if (ends_decl(t->token, ends_with)) { t->token++; return true; } else { @@ -1050,9 +1053,7 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndType ends_with) { arr_create(&d->idents, sizeof(Identifier)); Tokenizer *t = p->tokr; d->flags = 0; - /* TODO: extract cond */ - if ((token_is_kw(t->token, KW_SEMICOLON) && ends_with == DECL_END_SEMICOLON) - || (token_is_kw(t->token, KW_RPAREN) && ends_with == DECL_END_RPAREN)) { + if (ends_decl(t->token, ends_with)) { t->token++; return true; } @@ -1194,7 +1195,11 @@ static void fprint_block(FILE *out, Block *b) { fprint_stmt(out, stmt); } fprintf(out, "}"); - + if (b->ret_expr) { + fprintf(out, " returns "); + fprint_expr(out, b->ret_expr); + } + } static void fprint_fn_expr(FILE *out, FnExpr *f) { @@ -1277,6 +1282,8 @@ static void fprint_expr(FILE *out, Expression *e) { fprint_args(out, &e->direct.args); break; } + fprintf(out, ":"); + fprint_type(out, &e->type); } @@ -1290,7 +1297,7 @@ static void fprint_decl(FILE *out, Declaration *d) { fprintf(out, "[const]"); } fprintf(out, ":"); - if (d->flags & DECL_FLAG_ANNOTATES_TYPE) { + if ((d->flags & DECL_FLAG_FOUND_TYPE) || (d->flags & DECL_FLAG_ANNOTATES_TYPE)) { fprint_type(out, &d->type); } if (d->flags & DECL_FLAG_HAS_EXPR) { @@ -4,9 +4,9 @@ print_int @= fn(x: int) { #C("printf(\"%ld\\n\", (long)x);\n"); }; -times2 @= fn(x: int) int { 5 /* x*/ }; +times2 @= fn(x: int) int { x + x }; main @= fn() { print_int(times2(5)); - foo := fn (x, y, z : float, y:double) {}; + foo := fn (x, y, z : float, A:double) {}; }; @@ -1,49 +1,58 @@ static bool types_stmt(Statement *s); static bool types_expr(Expression *e); +static bool add_ident_decls(Block *b, Declaration *d) { + bool ret = true; + arr_foreach(&d->idents, Identifier, ident) { + Array *decls = &(*ident)->decls; + if (decls->len) { + /* check that it hasn't been declared in this block */ + IdentDecl *prev = arr_last(decls); + if (prev->scope == b) { + err_print(d->where, "Re-declaration of identifier in the same block."); + info_print(prev->decl->where, "Previous declaration was here."); + ret = false; + continue; + } + } + ident_add_decl(*ident, d, b); + } + return ret; +} + +static void remove_ident_decls(Block *b, Declaration *d) { + arr_foreach(&d->idents, Identifier, ident) { + IdentTree *id_info = *ident; + Array *decls = &id_info->decls; + assert(decls->item_sz); + IdentDecl *last_decl = arr_last(decls); + if (last_decl && last_decl->scope == b) { + arr_remove_last(decls); /* remove that declaration */ + } + } +} + /* pass NULL for block for global scope */ static bool block_enter(Block *b, Array *stmts) { bool ret = true; arr_foreach(stmts, Statement, stmt) { if (stmt->kind == STMT_DECL) { Declaration *decl = &stmt->decl; - arr_foreach(&decl->idents, Identifier, ident) { - Array *decls = &(*ident)->decls; - if (decls->len) { - /* check that it hasn't been declared in this block */ - IdentDecl *prev = arr_last(decls); - if (prev->scope == b) { - err_print(decl->where, "Re-declaration of identifier in the same block."); - info_print(prev->decl->where, "Previous declaration was here."); - ret = false; - continue; - } - } - ident_add_decl(*ident, decl, b); - } + if (!add_ident_decls(b, decl)) + ret = false; } } return ret; } -static bool block_exit(Block *b, Array *stmts) { +static void block_exit(Block *b, Array *stmts) { /* OPTIM: figure out some way of not re-iterating over everything */ - bool ret = true; arr_foreach(stmts, Statement, stmt) { if (stmt->kind == STMT_DECL) { Declaration *decl = &stmt->decl; - arr_foreach(&decl->idents, Identifier, ident) { - IdentTree *id_info = *ident; - Array *decls = &id_info->decls; - assert(decls->item_sz); - IdentDecl *last_decl = arr_last(decls); - if (last_decl->scope == b) { - arr_remove_last(decls); /* remove that declaration */ - } - } + remove_ident_decls(b, decl); } } - return ret; } static bool type_eq(Type *a, Type *b) { @@ -240,6 +249,9 @@ static bool type_of_expr(Expression *e, Type *t) { t->builtin = BUILTIN_I64; t->flags |= TYPE_FLAG_FLEXIBLE; break; + case EXPR_STR_LITERAL: + t->kind = TYPE_UNKNOWN; /* TODO */ + break; case EXPR_FLOAT_LITERAL: t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_FLOAT; @@ -267,6 +279,10 @@ static bool type_of_expr(Expression *e, Type *t) { } case EXPR_DIRECT: t->kind = TYPE_UNKNOWN; + /* TODO: make sure direct args have the right type */ + arr_foreach(&e->direct.args, Expression, arg) { + types_expr(arg); + } break; case EXPR_UNARY_OP: { Type *of_type = &e->unary.of->type; @@ -385,7 +401,7 @@ static bool types_block(Block *b) { if (!types_stmt(s)) ret = false; } if (b->ret_expr) types_expr(b->ret_expr); - if (!block_exit(b, &b->stmts)) return false; + block_exit(b, &b->stmts); return ret; } @@ -393,12 +409,16 @@ static bool types_expr(Expression *e) { Type *t = &e->type; if (!type_of_expr(e, t)) return false; switch (e->kind) { - case EXPR_FN: + case EXPR_FN: { + assert(e->type.kind == TYPE_FN); + FnExpr *f = e->fn; + add_ident_decls(&f->body, &f->params); if (!types_block(&e->fn->body)) return false; - assert(e->type.kind == TYPE_FN); + remove_ident_decls(&f->body, &f->params); Type *ret_type = e->type.fn.types.data; - Expression *ret_expr = e->fn->body.ret_expr; + Expression *ret_expr = f->body.ret_expr; + if (ret_expr) { if (!type_eq(ret_type, &ret_expr->type)) { char *got = type_to_str(&ret_expr->type); @@ -415,7 +435,7 @@ static bool types_expr(Expression *e) { free(expected); return false; } - break; + } break; case EXPR_CALL: { bool ret = true; arr_foreach(&e->call.args, Expression, arg) { |