aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGinger Bill <bill@gingerbill.org>2016-10-03 23:28:37 +0100
committerGinger Bill <bill@gingerbill.org>2016-10-03 23:28:37 +0100
commitfee504636f9cd7633217e1877ee1b99e555bba63 (patch)
tree5e5150802c7c87ba82e77f2516bb7d746355dec6
parentf6589d9814e2e26bee9b7941a23b4bef68582f2f (diff)
Code clean up of call arguments
-rw-r--r--code/demo.odin9
-rw-r--r--src/checker/expr.cpp219
-rw-r--r--src/checker/stmt.cpp5
-rw-r--r--src/codegen/ssa.cpp7
4 files changed, 100 insertions, 140 deletions
diff --git a/code/demo.odin b/code/demo.odin
index 17d3bf52a..ff80f434d 100644
--- a/code/demo.odin
+++ b/code/demo.odin
@@ -5,12 +5,5 @@
#import "game.odin"
main :: proc() {
- Vector3 :: struct {
- x, y, z: f32
- }
- Entity :: struct {
- guid: u64
- position: Vector3
- }
-
+ fmt.println("Hellope")
}
diff --git a/src/checker/expr.cpp b/src/checker/expr.cpp
index 24c61fb14..bf17cf2e3 100644
--- a/src/checker/expr.cpp
+++ b/src/checker/expr.cpp
@@ -85,10 +85,13 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
return true;
}
- if (is_type_pointer(dst) && is_type_rawptr(src)) {
- return true;
- }
+ // ^T <- rawptr
+ // TODO(bill): Should C-style (not C++) pointer cast be allowed?
+ // if (is_type_pointer(dst) && is_type_rawptr(src)) {
+ // return true;
+ // }
+ // rawptr <- ^T
if (is_type_rawptr(dst) && is_type_pointer(src)) {
return true;
}
@@ -121,7 +124,7 @@ b32 check_is_assignable_to(Checker *c, Operand *operand, Type *type, b32 is_argu
return true;
}
- if (is_argument) {
+ if (true || is_argument) {
// NOTE(bill): Polymorphism for subtyping
if (check_is_assignable_to_using_subtype(type, src)) {
return true;
@@ -224,16 +227,17 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
defer (map_destroy(&entity_map));
isize other_field_index = 0;
-
Entity *using_index_expr = NULL;
+ struct Delay {
+ Entity *e;
+ AstNode *t;
+ };
+ gbArray(Delay) delayed_const; gb_array_init(delayed_const, gb_heap_allocator());
+ gbArray(Delay) delayed_type; gb_array_init(delayed_type, gb_heap_allocator());
+ defer (gb_array_free(delayed_const));
+ defer (gb_array_free(delayed_type));
- // TODO(bill): Random declarations with DeclInfo
-#if 0
- Entity *e;
- DeclInfo *d;d
- check_entity_decl(c, e, d, NULL);
-#endif
gb_for_array(decl_index, decls) {
AstNode *decl = decls[decl_index];
if (decl->kind == AstNode_ConstDecl) {
@@ -252,7 +256,9 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
Token name_token = name->Ident;
Entity *e = make_entity_constant(c->allocator, c->context.scope, name_token, NULL, v);
entities[entity_index++] = e;
- check_const_decl(c, e, cd->type, value);
+
+ Delay delay = {e, cd->type};
+ gb_array_append(delayed_const, delay);
}
isize lhs_count = gb_array_count(cd->names);
@@ -288,8 +294,8 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
Token name_token = td->name->Ident;
Entity *e = make_entity_type_name(c->allocator, c->context.scope, name_token, NULL);
- add_entity(c, c->context.scope, td->name, e);
- check_type_decl(c, e, td->type, NULL, NULL);
+ Delay delay = {e, td->type};
+ gb_array_append(delayed_type, delay);
if (name_token.string == "_") {
other_fields[other_field_index++] = e;
@@ -302,10 +308,17 @@ void check_fields(Checker *c, AstNode *node, AstNodeArray decls,
map_set(&entity_map, key, e);
other_fields[other_field_index++] = e;
}
+ add_entity(c, c->context.scope, td->name, e);
add_entity_use(c, td->name, e);
}
}
+ }
+ gb_for_array(i, delayed_type) {
+ check_const_decl(c, delayed_type[i].e, delayed_type[i].t, NULL);
+ }
+ gb_for_array(i, delayed_const) {
+ check_type_decl(c, delayed_const[i].e, delayed_const[i].t, NULL, NULL);
}
if (node->kind == AstNode_UnionType) {
@@ -1536,18 +1549,15 @@ b32 check_is_castable_to(Checker *c, Operand *operand, Type *y) {
}
// Cast between pointers
- if (is_type_pointer(xb)) {
- if (is_type_pointer(yb))
+ if (is_type_pointer(xb) && is_type_pointer(yb)) {
return true;
}
// (u)int <-> pointer
- if (is_type_int_or_uint(xb) && !is_type_untyped(xb)) {
- if (is_type_pointer(yb))
+ if (is_type_int_or_uint(xb) && is_type_rawptr(yb)) {
return true;
}
- if (is_type_pointer(xb)) {
- if (is_type_int_or_uint(yb) && !is_type_untyped(yb))
+ if (is_type_rawptr(xb) && is_type_int_or_uint(yb)) {
return true;
}
@@ -2961,137 +2971,98 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
GB_ASSERT(proc_type->kind == Type_Proc);
ast_node(ce, CallExpr, call);
-
- isize error_code = 0;
- isize param_index = 0;
isize param_count = 0;
b32 variadic = proc_type->Proc.variadic;
b32 vari_expand = (ce->ellipsis.pos.line != 0);
- if (proc_type->Proc.params) {
+ if (proc_type->Proc.params != NULL) {
param_count = proc_type->Proc.params->Tuple.variable_count;
+ if (variadic) {
+ param_count--;
+ }
}
- if (ce->ellipsis.pos.line != 0) {
- if (!variadic) {
- error(ce->ellipsis,
- "Cannot use `..` in call to a non-variadic procedure: `%.*s`",
- LIT(ce->proc->Ident.string));
- return;
- }
+ if (vari_expand && !variadic) {
+ error(ce->ellipsis,
+ "Cannot use `..` in call to a non-variadic procedure: `%.*s`",
+ LIT(ce->proc->Ident.string));
+ return;
}
- if (gb_array_count(ce->args) == 0) {
- if (variadic && param_count-1 == 0)
- return;
- if (param_count == 0)
- return;
+ if (gb_array_count(ce->args) == 0 && param_count == 0) {
+ return;
}
- // TODO(bill): Completely redo this entire code.
- // It's from when I used linked lists instead of arrays in the parser
+ isize operand_count = 0;
+ gbArray(Operand) operands;
+ gb_array_init_reserve(operands, gb_heap_allocator(), 2*param_count);
+ defer (gb_array_free(operands));
- if (gb_array_count(ce->args) > param_count && !variadic) {
- error_code = +1;
- } else {
- Entity **sig_params = proc_type->Proc.params->Tuple.variables;
- gb_for_array(arg_index, ce->args) {
- check_multi_expr(c, operand, ce->args[arg_index]);
- if (operand->mode == Addressing_Invalid) {
- param_index++;
- continue;
+ gb_for_array(i, ce->args) {
+ Operand o = {};
+ check_multi_expr(c, &o, ce->args[i]);
+ if (o.type->kind != Type_Tuple) {
+ gb_array_append(operands, o);
+ } else {
+ auto *tuple = &o.type->Tuple;
+ if (variadic && i >= param_count) {
+ error(ast_node_token(ce->args[i]),
+ "`..` in a variadic procedure cannot be applied to a %td-valued expression", tuple->variable_count);
+ operand->mode = Addressing_Invalid;
+ return;
}
- if (operand->type->kind != Type_Tuple) {
- check_not_tuple(c, operand);
- isize index = param_index;
- b32 end_variadic = false;
- b32 variadic_expand = false;
- if (variadic && param_index >= param_count-1) {
- index = param_count-1;
- end_variadic = true;
- if (vari_expand) {
- variadic_expand = true;
- if (param_index != param_count-1) {
- error(ast_node_token(operand->expr),
- "`..` in a variadic procedure can only have one variadic argument at the end");
- break;
- }
- }
- }
- Type *arg_type = sig_params[index]->type;
- if (end_variadic && is_type_slice(arg_type)) {
- if (variadic_expand) {
- check_assignment(c, operand, arg_type, make_string("argument"), true);
- } else {
- arg_type = base_type(arg_type)->Slice.elem;
- check_assignment(c, operand, arg_type, make_string("argument"), true);
- }
- } else {
- check_assignment(c, operand, arg_type, make_string("argument"), true);
- }
- param_index++;
- } else {
- auto *tuple = &operand->type->Tuple;
- isize i = 0;
- for (;
- i < tuple->variable_count && (param_index < param_count && !variadic);
- i++) {
- Entity *e = tuple->variables[i];
- operand->type = e->type;
- operand->mode = Addressing_Value;
- check_not_tuple(c, operand);
- isize index = param_index;
- b32 end_variadic = false;
- if (variadic && param_index >= param_count-1) {
- index = param_count-1;
- end_variadic = true;
- if (vari_expand) {
- error(ast_node_token(operand->expr),
- "`..` in a variadic procedure cannot be applied to a %td-valued expression", tuple->variable_count);
- goto end;
- }
- }
- Type *arg_type = sig_params[index]->type;
- if (end_variadic && is_type_slice(arg_type)) {
- arg_type = base_type(arg_type)->Slice.elem;
- }
- check_assignment(c, operand, arg_type, make_string("argument"), true);
- param_index++;
- }
-
- end:
-
- if (i < tuple->variable_count && param_index == param_count) {
- error_code = +1;
- break;
- }
+ for (isize j = 0; j < tuple->variable_count; j++) {
+ o.type = tuple->variables[j]->type;
+ gb_array_append(operands, o);
}
-
- if (!variadic && param_index >= param_count)
- break;
- }
-
-
- if ((!variadic && param_index < param_count) ||
- (variadic && param_index < param_count-1)) {
- error_code = -1;
}
}
+ operand_count = gb_array_count(operands);
+ i32 error_code = 0;
+ if (operand_count < param_count) {
+ error_code = -1;
+ } else if (!variadic && operand_count > param_count) {
+ error_code = +1;
+ }
if (error_code != 0) {
- char *err_fmt = "";
+ char *err_fmt = "Too many arguments for `%s`, expected %td arguments";
if (error_code < 0) {
err_fmt = "Too few arguments for `%s`, expected %td arguments";
- } else {
- err_fmt = "Too many arguments for `%s`, expected %td arguments";
}
gbString proc_str = expr_to_string(ce->proc);
error(ast_node_token(call), err_fmt, proc_str, param_count);
gb_string_free(proc_str);
-
operand->mode = Addressing_Invalid;
}
+
+ GB_ASSERT(proc_type->Proc.params != NULL);
+ Entity **sig_params = proc_type->Proc.params->Tuple.variables;
+ for (isize i = 0; i < param_count; i++) {
+ Type *arg_type = sig_params[i]->type;
+ check_assignment(c, &operands[i], arg_type, make_string("argument"), true);
+ }
+
+ if (variadic) {
+ b32 variadic_expand = false;
+ Type *slice = sig_params[param_count]->type;
+ Type *elem = base_type(slice)->Slice.elem;
+ Type *t = elem;
+ for (isize i = param_count; i < operand_count; i++) {
+ Operand *o = &operands[i];
+ if (vari_expand) {
+ variadic_expand = true;
+ t = slice;
+ if (i != param_count) {
+ error(ast_node_token(o->expr),
+ "`..` in a variadic procedure can only have one variadic argument at the end");
+ break;
+ }
+ }
+ check_assignment(c, o, t, make_string("argument"), true);
+ }
+ }
}
diff --git a/src/checker/stmt.cpp b/src/checker/stmt.cpp
index 88fb32b4c..0ca457c9a 100644
--- a/src/checker/stmt.cpp
+++ b/src/checker/stmt.cpp
@@ -11,8 +11,6 @@ void check_stmt(Checker *c, AstNode *node, u32 flags);
void check_proc_decl(Checker *c, Entity *e, DeclInfo *d);
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;
@@ -57,7 +55,6 @@ void check_stmt_list(Checker *c, AstNodeArray stmts, u32 flags) {
case_ast_node(td, TypeDecl, node);
Entity *e = make_entity_type_name(c->allocator, c->context.scope, td->name->Ident, NULL);
e->identifier = td->name;
- add_entity(c, c->context.scope, td->name, e);
DeclInfo *d = make_declaration_info(c->allocator, e->scope);
d->type_expr = td->type;
@@ -339,7 +336,7 @@ void check_init_variables(Checker *c, Entity **lhs, isize lhs_count, AstNodeArra
// TODO(bill): Do not use heap allocation here if I can help it
gbArray(Operand) operands;
- gb_array_init(operands, gb_heap_allocator());
+ gb_array_init_reserve(operands, gb_heap_allocator(), 2*lhs_count);
defer (gb_array_free(operands));
gb_for_array(i, inits) {
diff --git a/src/codegen/ssa.cpp b/src/codegen/ssa.cpp
index e8aa3bebf..b355f2acc 100644
--- a/src/codegen/ssa.cpp
+++ b/src/codegen/ssa.cpp
@@ -1799,7 +1799,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
// NOTE(bill): This has to be done beofre `Pointer <-> Pointer` as it's
// subtype polymorphism casting
- if (is_argument) {
+ if (true || is_argument) {
Type *sb = base_type(type_deref(src));
b32 src_is_ptr = src != sb;
if (is_type_struct(sb)) {
@@ -1924,8 +1924,9 @@ ssaValue *ssa_emit_transmute(ssaProcedure *proc, ssaValue *value, Type *t) {
Type *src = base_type(src_type);
Type *dst = base_type(t);
- if (are_types_identical(t, src_type))
+ if (are_types_identical(t, src_type)) {
return value;
+ }
i64 sz = type_size_of(proc->module->sizes, proc->module->allocator, src);
i64 dz = type_size_of(proc->module->sizes, proc->module->allocator, dst);
@@ -1950,8 +1951,6 @@ ssaValue *ssa_emit_down_cast(ssaProcedure *proc, ssaValue *value, Type *t) {
Type *t_u8_ptr = make_type_pointer(allocator, t_u8);
ssaValue *bytes = ssa_emit_conv(proc, value, t_u8_ptr);
- // IMPORTANT TODO(bill): THIS ONLY DOES ONE LAYER DEEP!!! FUCKING HELL THIS IS NOT WHAT I SIGNED UP FOR!
-
i64 offset_ = type_offset_of_from_selection(proc->module->sizes, allocator, type_deref(t), sel);
ssaValue *offset = ssa_make_const_int(allocator, -offset_);
ssaValue *head = ssa_emit_ptr_offset(proc, bytes, offset);