aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-24 10:23:46 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-24 10:23:46 +0100
commitff229054a19a566309a1fea56384bfcdcd9fddad (patch)
treee0cbf20fe192825607e6991237dedc4ee59d9e11 /src
parentdb6abb97066e24c90d0048e6d2b2bc4c08041cf5 (diff)
Any order declarations at procedure scope (except variables)
Diffstat (limited to 'src')
-rw-r--r--src/checker/stmt.cpp96
-rw-r--r--src/codegen/codegen.cpp4
-rw-r--r--src/codegen/ssa.cpp18
3 files changed, 99 insertions, 19 deletions
diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp
index 20d4bb904..c6d206dbf 100644
--- a/src/checker/stmt.cpp
+++ b/src/checker/stmt.cpp
@@ -9,10 +9,91 @@ enum StmtFlag : u32 {
void check_stmt(Checker *c, AstNode *node, u32 flags);
void check_proc_decl(Checker *c, Entity *e, DeclInfo *d);
+void check_const_decl_node(Checker *c, AstNode *node);
void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
// TODO(bill): Allow declaration (expect variable) in any order
// even within a procedure
+ struct Delay {
+ Entity *e;
+ DeclInfo *d;
+ };
+ gbArray(Delay) delayed; gb_array_init(delayed, gb_heap_allocator());
+
+ gb_for_array(i, stmts) {
+ AstNode *node = stmts[i];
+ switch (node->kind) {
+ case_ast_node(cd, ConstDecl, node);
+ gb_for_array(i, cd->values) {
+ AstNode *name = cd->names[i];
+ AstNode *value = cd->values[i];
+ ExactValue v = {ExactValue_Invalid};
+
+ Entity *e = make_entity_constant(c->allocator, c->context.scope, name->Ident, NULL, v);
+ add_entity(c, e->scope, name, e);
+
+ DeclInfo *di = make_declaration_info(c->allocator, e->scope);
+ di->type_expr = cd->type;
+ di->init_expr = value;
+
+ Delay delay = {e, di};
+ gb_array_append(delayed, delay);
+ }
+
+ isize lhs_count = gb_array_count(cd->names);
+ isize rhs_count = gb_array_count(cd->values);
+
+ if (rhs_count == 0 && cd->type == NULL) {
+ error(ast_node_token(node), "Missing type or initial expression");
+ } else if (lhs_count < rhs_count) {
+ error(ast_node_token(node), "Extra initial expression");
+ }
+ case_end;
+
+ case_ast_node(td, TypeDecl, node);
+ Entity *e = make_entity_type_name(c->allocator, c->context.scope, td->name->Ident, NULL);
+ add_entity(c, c->context.scope, td->name, e);
+
+ DeclInfo *d = make_declaration_info(c->allocator, e->scope);
+ d->type_expr = td->type;
+
+ Delay delay = {e, d};
+ gb_array_append(delayed, delay);
+ case_end;
+
+ case_ast_node(pd, ProcDecl, node);
+ ast_node(name, Ident, pd->name);
+ Entity *e = make_entity_procedure(c->allocator, c->context.scope, *name, NULL);
+ add_entity(c, c->context.scope, pd->name, e);
+
+ DeclInfo *d = make_declaration_info(c->allocator, e->scope);
+ d->proc_decl = node;
+
+ Delay delay = {e, d};
+ gb_array_append(delayed, delay);
+ case_end;
+ }
+ }
+
+ auto check_scope_entity = [](Checker *c, gbArray(Delay) delayed, EntityKind kind) {
+ gb_for_array(i, delayed) {
+ auto delay = delayed[i];
+ Entity *e = delay.e;
+ if (e->kind == kind) {
+ DeclInfo *d = delay.d;
+ Scope *prev_scope = c->context.scope;
+ c->context.scope = d->scope;
+ GB_ASSERT(d->scope == e->scope);
+ check_entity_decl(c, e, d, NULL);
+ c->context.scope = prev_scope;
+ }
+ }
+ };
+ check_scope_entity(c, delayed, Entity_TypeName);
+ check_scope_entity(c, delayed, Entity_Constant);
+ check_scope_entity(c, delayed, Entity_Procedure);
+
+
b32 ft_ok = (flags & Stmt_FallthroughAllowed) != 0;
u32 f = flags & (~Stmt_FallthroughAllowed);
@@ -1512,24 +1593,15 @@ void check_stmt(Checker *c, AstNode *node, u32 flags) {
case_end;
case_ast_node(cd, ConstDecl, node);
- check_const_decl_node(c, node);
+ // NOTE(bill): Handled elsewhere
case_end;
case_ast_node(pd, ProcDecl, node);
- ast_node(name, Ident, pd->name);
- Entity *e = make_entity_procedure(c->allocator, c->context.scope, *name, NULL);
- add_entity(c, c->context.scope, pd->name, e);
-
- DeclInfo *decl = make_declaration_info(c->allocator, e->scope);
- decl->proc_decl = node;
- check_proc_decl(c, e, decl);
+ // NOTE(bill): Handled elsewhere
case_end;
case_ast_node(td, TypeDecl, node);
- ast_node(name, Ident, td->name);
- Entity *e = make_entity_type_name(c->allocator, c->context.scope, *name, NULL);
- add_entity(c, c->context.scope, td->name, e);
- check_type_decl(c, e, td->type, NULL, NULL);
+ // NOTE(bill): Handled elsewhere
case_end;
}
}
diff --git a/src/codegen/codegen.cpp b/src/codegen/codegen.cpp
index e66d4fd03..c8a272202 100644
--- a/src/codegen/codegen.cpp
+++ b/src/codegen/codegen.cpp
@@ -635,6 +635,10 @@ void ssa_gen_tree(ssaGen *s) {
ssa_end_procedure_body(proc);
}
+ gb_for_array(i, m->procs) {
+ ssa_build_proc(m->procs[i], m->procs[i]->Proc.parent);
+ }
+
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index 6226424dd..c1f9e7c64 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -62,6 +62,8 @@ struct ssaModule {
Map<String> type_names; // Key: Type *
Map<ssaDebugInfo *> debug_info; // Key: Unique pointer
i32 global_string_index;
+
+ gbArray(ssaValue *) procs; // NOTE(bill): Procedures to generate
};
@@ -405,6 +407,7 @@ void ssa_init_module(ssaModule *m, Checker *c) {
map_init(&m->members, gb_heap_allocator());
map_init(&m->debug_info, gb_heap_allocator());
map_init(&m->type_names, gb_heap_allocator());
+ gb_array_init(m->procs, gb_heap_allocator());
// Default states
m->stmt_state_flags = 0;
@@ -468,6 +471,7 @@ void ssa_destroy_module(ssaModule *m) {
map_destroy(&m->members);
map_destroy(&m->type_names);
map_destroy(&m->debug_info);
+ gb_array_free(m->procs);
gb_arena_free(&m->arena);
}
@@ -3199,10 +3203,11 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
proc->module, e, e->type, pd->type, pd->body, name);
value->Proc.tags = pd->tags;
+ value->Proc.parent = proc;
ssa_module_add_value(proc->module, e, value);
gb_array_append(proc->children, &value->Proc);
- ssa_build_proc(value, proc);
+ gb_array_append(proc->module->procs, value);
} else {
// FFI - Foreign function interace
String original_name = pd->name->Ident.string;
@@ -3390,10 +3395,10 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
Type *ret_type = proc->type->Proc.results;
v = ssa_add_local_generated(proc, ret_type);
gb_for_array(i, results) {
- Type *t = return_type_tuple->variables[i]->type;
- ssaValue *e = ssa_emit_conv(proc, results[i], t);
- ssaValue *gep = ssa_emit_struct_gep(proc, v, i, make_type_pointer(proc->module->allocator, t));
- ssa_emit_store(proc, gep, e);
+ Entity *e = return_type_tuple->variables[i];
+ ssaValue *res = ssa_emit_conv(proc, results[i], e->type);
+ ssaValue *field = ssa_emit_struct_gep(proc, v, i, make_type_pointer(proc->module->allocator, e->type));
+ ssa_emit_store(proc, field, res);
}
v = ssa_emit_load(proc, v);
@@ -3410,7 +3415,7 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
gb_for_array(i, rs->results) {
Entity *e = return_type_tuple->variables[i];
ssaValue *res = ssa_emit_conv(proc, ssa_build_expr(proc, rs->results[i]), e->type);
- ssaValue *field = ssa_emit_struct_gep(proc, v, i, e->type);
+ ssaValue *field = ssa_emit_struct_gep(proc, v, i, make_type_pointer(proc->module->allocator, e->type));
ssa_emit_store(proc, field, res);
}
v = ssa_emit_load(proc, v);
@@ -3452,7 +3457,6 @@ void ssa_build_stmt(ssaProcedure *proc, AstNode *node) {
ssa_emit_defer_stmts(proc, ssaDeferExit_Default, NULL);
proc->scope_index--;
-
ssa_emit_jump(proc, done);
}
gb_array_append(proc->blocks, done);