diff options
| author | gingerBill <ginger.bill.22@gmail.com> | 2016-08-14 22:19:39 +0100 |
|---|---|---|
| committer | gingerBill <ginger.bill.22@gmail.com> | 2016-08-14 22:19:39 +0100 |
| commit | 0f48a7d299a80c2e461bdcf5b37b5f624a48d7e8 (patch) | |
| tree | 09132199d7777f3f31623505e9867468d3f487d8 /src | |
| parent | 0edae8c8482dd4763737b01deb09a4732a2f35ec (diff) | |
#foreign "custom_name"; <N x i1> bugs (see test.ll and test2.ll)
Diffstat (limited to 'src')
| -rw-r--r-- | src/checker/stmt.cpp | 24 | ||||
| -rw-r--r-- | src/checker/type.cpp | 2 | ||||
| -rw-r--r-- | src/codegen/codegen.cpp | 14 | ||||
| -rw-r--r-- | src/codegen/print_llvm.cpp | 6 | ||||
| -rw-r--r-- | src/codegen/ssa.cpp | 12 | ||||
| -rw-r--r-- | src/parser.cpp | 65 | ||||
| -rw-r--r-- | src/printer.cpp | 1 |
7 files changed, 81 insertions, 43 deletions
diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp index f3625def1..9b127b7aa 100644 --- a/src/checker/stmt.cpp +++ b/src/checker/stmt.cpp @@ -418,28 +418,12 @@ void check_proc_decl(Checker *c, Entity *e, DeclInfo *d, b32 check_body_later) { check_procedure_type(c, proc_type, pd->type); - b32 is_foreign = false; - b32 is_inline = false; - b32 is_no_inline = false; - for (AstNode *tag = pd->tag_list; tag != NULL; tag = tag->next) { - GB_ASSERT(tag->kind == AstNode_TagExpr); - - ast_node(te, TagExpr, tag); - String tag_name = te->name.string; - if (are_strings_equal(tag_name, make_string("foreign"))) { - is_foreign = true; - } else if (are_strings_equal(tag_name, make_string("inline"))) { - is_inline = true; - } else if (are_strings_equal(tag_name, make_string("no_inline"))) { - is_no_inline = true; - } else { - error(&c->error_collector, ast_node_token(tag), "Unknown procedure tag"); - } - // TODO(bill): Other tags - } + b32 is_foreign = (pd->tags & ProcTag_foreign) != 0; + b32 is_inline = (pd->tags & ProcTag_inline) != 0; + b32 is_no_inline = (pd->tags & ProcTag_no_inline) != 0; if (is_inline && is_no_inline) { - error(&c->error_collector, ast_node_token(pd->tag_list), + error(&c->error_collector, ast_node_token(pd->type), "You cannot apply both `inline` and `no_inline` to a procedure"); } diff --git a/src/checker/type.cpp b/src/checker/type.cpp index 4504cd06f..e0ce88c03 100644 --- a/src/checker/type.cpp +++ b/src/checker/type.cpp @@ -560,7 +560,7 @@ i64 type_align_of(BaseTypeSizes s, gbAllocator allocator, Type *t) { case Type_Vector: { i64 size = type_size_of(s, allocator, t->vector.elem); // TODO(bill): Type_Vector type_align_of - return gb_clamp(size, 1, 2*s.max_align); + return gb_clamp(size, s.max_align, 2*s.max_align); } break; case Type_Structure: { diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp index 4cb4a98be..0c36ca8f3 100644 --- a/src/codegen/codegen.cpp +++ b/src/codegen/codegen.cpp @@ -18,6 +18,11 @@ b32 ssa_gen_init(ssaGen *s, Checker *c) { return false; } + isize tc = c->parser->total_token_count; + if (tc < 2) { + return false; + } + ssa_module_init(&s->module, c); // TODO(bill): generate appropriate output name @@ -79,8 +84,13 @@ void ssa_gen_code(ssaGen *s) { } break; case Entity_Procedure: { - AstNode *body = decl->proc_decl->ProcDecl.body; - ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, e->token.string); + auto *pd = &decl->proc_decl->ProcDecl; + String name = e->token.string; + AstNode *body = pd->body; + if (pd->foreign_name.len > 0) { + name = pd->foreign_name; + } + ssaValue *p = ssa_make_value_procedure(a, m, e->type, decl->type_expr, body, name); map_set(&m->values, hash_pointer(e), p); map_set(&m->members, hash_string(name), p); } break; diff --git a/src/codegen/print_llvm.cpp b/src/codegen/print_llvm.cpp index 2c9277f4d..5f2160182 100644 --- a/src/codegen/print_llvm.cpp +++ b/src/codegen/print_llvm.cpp @@ -269,7 +269,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { Type *type = instr->local.entity->type; ssa_fprintf(f, "%%%d = alloca ", value->id); ssa_print_type(f, m->sizes, type); - ssa_fprintf(f, ", align %lld ", type_align_of(m->sizes, gb_heap_allocator(), type)); + ssa_fprintf(f, ", align %lld ", type_align_of(m->sizes, m->allocator, type)); { String str = instr->local.entity->token.string; if (str.len > 0) @@ -304,7 +304,7 @@ void ssa_print_instr(gbFile *f, ssaModule *m, ssaValue *value) { ssa_print_type(f, m->sizes, type); ssa_fprintf(f, "* "); ssa_print_value(f, m, instr->load.address, type); - ssa_fprintf(f, "\n"); + ssa_fprintf(f, ", align %lld\n", type_align_of(m->sizes, m->allocator, type)); } break; case ssaInstr_GetElementPtr: { @@ -616,7 +616,7 @@ void ssa_print_proc(gbFile *f, ssaModule *m, ssaProcedure *proc) { ssa_fprintf(f, ") "); if (proc->body == NULL) { - ssa_fprintf(f, "\t; foreign procedure\n\n"); + ssa_fprintf(f, "; foreign procedure\n\n"); } else { ssa_fprintf(f, "{\n"); gb_for_array(i, proc->blocks) { diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp index 19b4f1e3e..f20100a8b 100644 --- a/src/codegen/ssa.cpp +++ b/src/codegen/ssa.cpp @@ -2067,6 +2067,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { ssa_build_proc(value, proc); } else { String name = pd->name->Ident.token.string; + if (pd->foreign_name.len > 0) { + name = pd->foreign_name; + } Entity **found = map_get(&proc->module->info->definitions, hash_pointer(pd->name)); GB_ASSERT(found != NULL); @@ -2240,6 +2243,9 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(is, IfStmt, node); if (is->init != NULL) { + ssaBlock *init = ssa_add_block(proc, node, make_string("if.init")); + ssa_emit_jump(proc, init); + proc->curr_block = init; ssa_build_stmt(proc, is->init); } ssaBlock *then = ssa_add_block(proc, node, make_string("if.then")); @@ -2265,9 +2271,12 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { case_ast_node(fs, ForStmt, node); if (fs->init != NULL) { + ssaBlock *init = ssa_add_block(proc, node, make_string("for.init")); + ssa_emit_jump(proc, init); + proc->curr_block = init; ssa_build_stmt(proc, fs->init); } - ssaBlock *body = ssa_add_block(proc, node, make_string("for.body")); + ssaBlock *body = ssa__make_block(proc, node, make_string("for.body")); ssaBlock *done = ssa__make_block(proc, node, make_string("for.done")); // NOTE(bill): Append later ssaBlock *loop = body; @@ -2283,6 +2292,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) { proc->curr_block = loop; if (loop != body) { ssa_build_cond(proc, fs->cond, body, done); + gb_array_append(proc->blocks, body); proc->curr_block = body; } diff --git a/src/parser.cpp b/src/parser.cpp index 9e9992fa5..328220cfa 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -71,6 +71,12 @@ enum DeclKind { Declaration_Count, }; +enum ProcTag { + ProcTag_foreign = GB_BIT(0), + ProcTag_inline = GB_BIT(1), + ProcTag_no_inline = GB_BIT(2), +}; + #define AST_NODE_KINDS \ AST_NODE_KIND(Invalid, struct{}) \ AST_NODE_KIND(BasicLit, Token) \ @@ -163,11 +169,11 @@ AST_NODE_KIND(_DeclBegin, struct{}) \ isize name_count, value_count; \ }) \ AST_NODE_KIND(ProcDecl, struct { \ - AstNode *name; \ - AstNode *type; \ - AstNode *body; \ - AstNode *tag_list; \ - isize tag_count; \ + AstNode *name; \ + AstNode *type; \ + AstNode *body; \ + u64 tags; \ + String foreign_name; \ }) \ AST_NODE_KIND(TypeDecl, struct { Token token; AstNode *name, *type; }) \ AST_NODE_KIND(AliasDecl, struct { Token token; AstNode *name, *type; }) \ @@ -701,13 +707,13 @@ gb_inline AstNode *make_proc_type(AstFile *f, Token token, AstNode *param_list, return result; } -gb_inline AstNode *make_proc_decl(AstFile *f, AstNode *name, AstNode *proc_type, AstNode *body, AstNode *tag_list, isize tag_count) { +gb_inline AstNode *make_proc_decl(AstFile *f, AstNode *name, AstNode *proc_type, AstNode *body, u64 tags, String foreign_name) { AstNode *result = make_node(f, AstNode_ProcDecl); result->ProcDecl.name = name; result->ProcDecl.type = proc_type; result->ProcDecl.body = body; - result->ProcDecl.tag_list = tag_list; - result->ProcDecl.tag_count = tag_count; + result->ProcDecl.tags = tags; + result->ProcDecl.foreign_name = foreign_name; return result; } @@ -1589,7 +1595,7 @@ AstNode *parse_body(AstFile *f, AstScope *scope) { return make_block_stmt(f, statement_list, statement_list_count, open, close); } - AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { +AstNode *parse_proc_decl(AstFile *f, Token proc_token, AstNode *name) { AstNode *param_list = NULL; AstNode *result_list = NULL; isize param_count = 0; @@ -1600,21 +1606,50 @@ AstNode *parse_body(AstFile *f, AstScope *scope) { parse_procedure_signature(f, scope, ¶m_list, ¶m_count, &result_list, &result_count); AstNode *body = NULL; - AstNode *tag_list = NULL; - AstNode *tag_list_curr = NULL; - isize tag_count = 0; + u64 tags = 0; + String foreign_name = {}; while (f->cursor[0].kind == Token_Hash) { - DLIST_APPEND(tag_list, tag_list_curr, parse_tag_expr(f, NULL)); - tag_count++; + AstNode *tag_expr = parse_tag_expr(f, NULL); + ast_node(te, TagExpr, tag_expr); + String tag_name = te->name.string; + if (are_strings_equal(tag_name, make_string("foreign"))) { + tags |= ProcTag_foreign; + if (f->cursor[0].kind == Token_String) { + foreign_name = f->cursor[0].string; + // TODO(bill): Check if valid string + if (foreign_name.len == 0) { + ast_file_err(f, ast_node_token(tag_expr), "Invalid alternative foreign procedure name"); + } + + next_token(f); + } + } else if (are_strings_equal(tag_name, make_string("inline"))) { + tags |= ProcTag_inline; + } else if (are_strings_equal(tag_name, make_string("no_inline"))) { + tags |= ProcTag_no_inline; + } else { + ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag"); + } + } + + b32 is_inline = (tags & ProcTag_inline) != 0; + b32 is_no_inline = (tags & ProcTag_no_inline) != 0; + + if (is_inline && is_no_inline) { + ast_file_err(f, f->cursor[0], "You cannot apply both `inline` and `no_inline` to a procedure"); } + if (f->cursor[0].kind == Token_OpenBrace) { + if ((tags & ProcTag_foreign) != 0) { + ast_file_err(f, f->cursor[0], "A procedure tagged as `#foreign` cannot have a body"); + } body = parse_body(f, scope); } close_ast_scope(f); AstNode *proc_type = make_proc_type(f, proc_token, param_list, param_count, result_list, result_count); - return make_proc_decl(f, name, proc_type, body, tag_list, tag_count); + return make_proc_decl(f, name, proc_type, body, tags, foreign_name); } AstNode *parse_decl(AstFile *f, AstNode *name_list, isize name_count) { diff --git a/src/printer.cpp b/src/printer.cpp index 465714783..cbac29f94 100644 --- a/src/printer.cpp +++ b/src/printer.cpp @@ -143,7 +143,6 @@ void print_ast(AstNode *node, isize indent) { gb_printf("(decl:proc)\n"); print_ast(node->ProcDecl.type, indent+1); print_ast(node->ProcDecl.body, indent+1); - print_ast(node->ProcDecl.tag_list, indent+1); break; case AstNode_TypeDecl: |