aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-09-13 23:09:46 +0100
committerGinger Bill <bill@gingerbill.org>2016-09-13 23:09:46 +0100
commit1147e17c134da1d5bb93d0754888ca1d0271a0f4 (patch)
treefe746c89b650ed619222a00d694c67df40c72888 /src
parent817ae643c5a469bf2f237525086288a2632fa500 (diff)
Fix addressing modes for selectors
Diffstat (limited to 'src')
-rw-r--r--src/checker/expr.cpp50
-rw-r--r--src/codegen/ssa.cpp8
-rw-r--r--src/parser.cpp10
3 files changed, 44 insertions, 24 deletions
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index 979b4d215..4389b7884 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -704,9 +704,6 @@ Type *check_get_results(Checker *c, Scope *scope, AstNodeArray results) {
void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
ast_node(pt, ProcType, proc_type_node);
-
- // gb_printf("%td -> %td\n", param_count, result_count);
-
b32 variadic = false;
Type *params = check_get_params(c, c->context.scope, pt->params, &variadic);
Type *results = check_get_results(c, c->context.scope, pt->results);
@@ -716,12 +713,14 @@ void check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node) {
if (params) param_count = params ->Tuple.variable_count;
if (results) result_count = results->Tuple.variable_count;
- type->Proc.scope = c->context.scope;
- type->Proc.params = params;
- type->Proc.param_count = param_count;
- type->Proc.results = results;
- type->Proc.result_count = result_count;
- type->Proc.variadic = variadic;
+
+ type->Proc.scope = c->context.scope;
+ type->Proc.params = params;
+ type->Proc.param_count = param_count;
+ type->Proc.results = results;
+ type->Proc.result_count = result_count;
+ type->Proc.variadic = variadic;
+ // type->Proc.implicit_context = implicit_context;
}
@@ -1983,15 +1982,26 @@ Entity *check_selector(Checker *c, Operand *operand, AstNode *node) {
operand->type = entity->type;
operand->expr = node;
- if (entity->kind == Entity_Constant) {
+ switch (entity->kind) {
+ case Entity_Constant:
operand->mode = Addressing_Constant;
operand->value = entity->Constant.value;
- } else if (entity->kind == Entity_TypeName) {
+ break;
+ case Entity_Variable:
+ operand->mode = Addressing_Variable;
+ break;
+ case Entity_TypeName:
operand->mode = Addressing_Type;
- } else {
- if (operand->mode != Addressing_Variable)
- operand->mode = Addressing_Value;
+ break;
+ case Entity_Procedure:
+ operand->mode = Addressing_Value;
+ break;
+ case Entity_Builtin:
+ operand->mode = Addressing_Builtin;
+ operand->builtin_id = entity->Builtin.id;
+ break;
}
+
return entity;
} else {
operand->mode = Addressing_Invalid;
@@ -2896,14 +2906,18 @@ ExprKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
check_call_arguments(c, operand, proc_type, call);
- if (proc_type->Proc.result_count == 0) {
+ switch (proc_type->Proc.result_count) {
+ case 0:
operand->mode = Addressing_NoValue;
- } else if (proc_type->Proc.result_count == 1) {
+ break;
+ case 1:
operand->mode = Addressing_Value;
operand->type = proc_type->Proc.results->Tuple.variables[0]->type;
- } else {
+ break;
+ default:
operand->mode = Addressing_Value;
operand->type = proc_type->Proc.results;
+ break;
}
operand->expr = call;
@@ -3042,7 +3056,7 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
if (gb_array_count(sel.index) > 1) {
error(&c->error_collector, ast_node_token(elem),
- "You cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name));
+ "Cannot assign to an anonymous field `%.*s` in a structure literal (at the moment)", LIT(name));
continue;
}
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index f1e992d7b..89443a1dd 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -2723,6 +2723,13 @@ ssaAddr ssa_build_addr(ssaProcedure *proc, AstNode *expr) {
ssaValue *gep = ssa_emit_zero_gep(proc, e);
return ssa_make_addr(gep, expr);
case_end;
+
+ case_ast_node(ce, CallExpr, expr);
+ ssaValue *e = ssa_build_expr(proc, expr);
+ ssaValue *v = ssa_add_local_generated(proc, ssa_type(e));
+ ssa_emit_store(proc, v, e);
+ return ssa_make_addr(v, expr);
+ case_end;
}
TokenPos token_pos = ast_node_token(expr).pos;
@@ -3506,7 +3513,6 @@ void ssa_insert_code_before_proc(ssaProcedure* proc, ssaProcedure *parent) {
}
}
-
void ssa_build_proc(ssaValue *value, ssaProcedure *parent) {
ssaProcedure *proc = &value->Proc;
diff --git a/src/parser.cpp b/src/parser.cpp
index f6db8267e..bf2cda8fe 100644
--- a/src/parser.cpp
+++ b/src/parser.cpp
@@ -64,7 +64,6 @@ enum ProcTag {
ProcTag_foreign = GB_BIT(2),
ProcTag_inline = GB_BIT(3),
ProcTag_no_inline = GB_BIT(4),
- ProcTag_no_context = GB_BIT(5),
};
enum VarDeclTag {
@@ -75,7 +74,8 @@ enum VarDeclTag {
enum TypeFlag : u32 {
TypeFlag_thread_local = GB_BIT(0),
TypeFlag_volatile = GB_BIT(1),
- TypeFlag_atomic = GB_BIT(1),
+ TypeFlag_atomic = GB_BIT(2),
+
};
enum StmtStateFlag : u32 {
@@ -238,7 +238,7 @@ AST_NODE_KIND(_TypeBegin, "", struct{}) \
}) \
AST_NODE_KIND(ProcType, "procedure type", struct { \
Token token; \
- AstNodeArray params; \
+ AstNodeArray params; \
AstNodeArray results; \
}) \
AST_NODE_KIND(PointerType, "pointer type", struct { \
@@ -1182,8 +1182,8 @@ void parse_proc_tags(AstFile *f, u64 *tags, String *foreign_name) {
check_proc_add_tag(f, tag_expr, tags, ProcTag_inline, tag_name);
} else if (are_strings_equal(tag_name, make_string("no_inline"))) {
check_proc_add_tag(f, tag_expr, tags, ProcTag_no_inline, tag_name);
- } else if (are_strings_equal(tag_name, make_string("no_context"))) {
- check_proc_add_tag(f, tag_expr, tags, ProcTag_no_context, tag_name);
+ // } else if (are_strings_equal(tag_name, make_string("no_context"))) {
+ // check_proc_add_tag(f, tag_expr, tags, ProcTag_no_context, tag_name);
} else {
ast_file_err(f, ast_node_token(tag_expr), "Unknown procedure tag");
}