aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <ginger.bill.22@gmail.com>2016-08-14 22:19:39 +0100
committergingerBill <ginger.bill.22@gmail.com>2016-08-14 22:19:39 +0100
commit0f48a7d299a80c2e461bdcf5b37b5f624a48d7e8 (patch)
tree09132199d7777f3f31623505e9867468d3f487d8 /src
parent0edae8c8482dd4763737b01deb09a4732a2f35ec (diff)
#foreign "custom_name"; <N x i1> bugs (see test.ll and test2.ll)
Diffstat (limited to 'src')
-rw-r--r--src/checker/stmt.cpp24
-rw-r--r--src/checker/type.cpp2
-rw-r--r--src/codegen/codegen.cpp14
-rw-r--r--src/codegen/print_llvm.cpp6
-rw-r--r--src/codegen/ssa.cpp12
-rw-r--r--src/parser.cpp65
-rw-r--r--src/printer.cpp1
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, &param_list, &param_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: