Fix exact value bug when updating expressions

This commit is contained in:
Ginger Bill
2016-10-16 00:26:53 +01:00
parent 79af939522
commit b9719df0ad
8 changed files with 86 additions and 52 deletions
+7
View File
@@ -1,6 +1,13 @@
#import "fmt.odin"
main :: proc() {
Thing :: struct {
f: f32
a: any
}
t := Thing{1, "Hello"}
fmt.printf("Here % %\n", 123, 2.0)
}
+7 -8
View File
@@ -74,11 +74,12 @@ type_info_base :: proc(info: ^Type_Info) -> ^Type_Info {
if info == nil {
return nil
}
match type i : info {
base := info
match type i : base {
case Type_Info.Named:
info = i.base
base = i.base
}
return info
return base
}
@@ -259,10 +260,10 @@ __string_eq :: proc(a, b: string) -> bool {
if a.count != b.count {
return false
}
if ^a[0] == ^b[0] {
if a.data == b.data {
return true
}
return mem.compare(^a[0], ^b[0], a.count) == 0
return mem.compare(a.data, b.data, a.count) == 0
}
__string_cmp :: proc(a, b : string) -> int {
@@ -312,9 +313,7 @@ __substring_expr_error :: proc(file: string, line, column: int,
}
__enum_to_string :: proc(info: ^Type_Info, value: i64) -> string {
info = type_info_base(info)
match type ti : info {
match type ti : type_info_base(info) {
case Type_Info.Enum:
// TODO(bill): Search faster than linearly
for i := 0; i < ti.values.count; i++ {
+7 -5
View File
@@ -90,7 +90,8 @@ print_pointer_to_buffer :: proc(buffer: ^[]byte, p: rawptr) #inline {
print_f32_to_buffer :: proc(buffer: ^[]byte, f: f32) #inline { print__f64(buffer, f as f64, 7) }
print_f64_to_buffer :: proc(buffer: ^[]byte, f: f64) #inline { print__f64(buffer, f, 10) }
print_u64_to_buffer :: proc(buffer: ^[]byte, i: u64) {
print_u64_to_buffer :: proc(buffer: ^[]byte, value: u64) {
i := value
buf: [22]byte
len := 0
if i == 0 {
@@ -105,7 +106,8 @@ print_u64_to_buffer :: proc(buffer: ^[]byte, i: u64) {
byte_reverse(buf[:len])
print_string_to_buffer(buffer, buf[:len] as string)
}
print_i64_to_buffer :: proc(buffer: ^[]byte, i: i64) {
print_i64_to_buffer :: proc(buffer: ^[]byte, value: i64) {
i := value
neg := i < 0
if neg {
i = -i
@@ -114,7 +116,8 @@ print_i64_to_buffer :: proc(buffer: ^[]byte, i: i64) {
print_u64_to_buffer(buffer, i as u64)
}
print__f64 :: proc(buffer: ^[]byte, f: f64, decimal_places: int) {
print__f64 :: proc(buffer: ^[]byte, value: f64, decimal_places: int) {
f := value
if f == 0 {
print_rune_to_buffer(buffer, #rune "0")
return
@@ -555,12 +558,11 @@ bprintf :: proc(buf: ^[]byte, fmt: string, args: ..any) {
bprint :: proc(buf: ^[]byte, args: ..any) {
is_type_string :: proc(info: ^Type_Info) -> bool {
using Type_Info
info = type_info_base(info)
if info == nil {
return false
}
match type i : info {
match type i : type_info_base(info) {
case String:
return true
}
+2 -1
View File
@@ -39,7 +39,8 @@ accept_sizes := [256]byte{
0x34, 0x04, 0x04, 0x04, 0x44, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, 0xf1, // 0xf0-0xff
}
encode_rune :: proc(r: rune) -> ([4]byte, int) {
encode_rune :: proc(r_: rune) -> ([4]byte, int) {
r := r_
buf: [4]byte
i := r as u32
mask: byte : 0x3f
+1 -2
View File
@@ -645,7 +645,6 @@ void add_untyped(CheckerInfo *i, AstNode *expression, b32 lhs, AddressingMode mo
map_set(&i->untyped, hash_pointer(expression), make_expression_info(lhs, mode, basic_type, value));
}
void add_type_and_value(CheckerInfo *i, AstNode *expression, AddressingMode mode, Type *type, ExactValue value) {
GB_ASSERT(expression != NULL);
if (mode == Addressing_Invalid)
@@ -1306,7 +1305,7 @@ void check_parsed_files(Checker *c) {
ExpressionInfo *info = &entry->value;
if (info != NULL && expr != NULL) {
if (is_type_typed(info->type)) {
compiler_error("%s (type %s) is typed!", expr_to_string(expr), info->type);
compiler_error("%s (type %s) is typed!", expr_to_string(expr), type_to_string(info->type));
}
add_type_and_value(&c->info, expr, info->mode, info->type, info->value);
}
+36 -18
View File
@@ -933,7 +933,11 @@ void check_identifier(Checker *c, Operand *o, AstNode *n, Type *named_type, Cycl
o->type = t_invalid;
return;
}
o->mode = Addressing_Variable;
// if (e->Variable.param) {
// o->mode = Addressing_Value;
// } else {
o->mode = Addressing_Variable;
// }
break;
case Entity_TypeName: {
@@ -2239,7 +2243,6 @@ void convert_to_typed(Checker *c, Operand *operand, Type *target_type, i32 level
operand->type = target_type;
update_expr_type(c, operand->expr, target_type, true);
}
b32 check_index_value(Checker *c, AstNode *index_value, i64 max_count, i64 *value) {
@@ -3265,7 +3268,6 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
gbTempArenaMemory tmp = gb_temp_arena_memory_begin(&c->tmp_arena);
defer (gb_temp_arena_memory_end(tmp));
isize operand_count = 0;
Array<Operand> operands;
array_init(&operands, c->tmp_allocator, 2*param_count);
@@ -3289,11 +3291,10 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
}
}
operand_count = operands.count;
i32 error_code = 0;
if (operand_count < param_count) {
if (operands.count < param_count) {
error_code = -1;
} else if (!variadic && operand_count > param_count) {
} else if (!variadic && operands.count > param_count) {
error_code = +1;
}
if (error_code != 0) {
@@ -3303,16 +3304,22 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
}
gbString proc_str = expr_to_string(ce->proc);
defer (gb_string_free(proc_str));
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);
isize operand_index = 0;
for (; operand_index < param_count; operand_index++) {
Type *arg_type = sig_params[operand_index]->type;
Operand o = operands[operand_index];
if (variadic) {
o = operands[operand_index];
}
check_assignment(c, &o, arg_type, make_string("argument"), true);
}
if (variadic) {
@@ -3320,18 +3327,18 @@ void check_call_arguments(Checker *c, Operand *operand, Type *proc_type, AstNode
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];
for (; operand_index < operands.count; operand_index++) {
Operand o = operands[operand_index];
if (vari_expand) {
variadic_expand = true;
t = slice;
if (i != param_count) {
error(ast_node_token(o->expr),
if (operand_index != 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);
check_assignment(c, &o, t, make_string("argument"), true);
}
}
}
@@ -3574,10 +3581,14 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
fields_visited[sel.index[0]] = true;
check_expr(c, o, fv->value);
if (base_type(field->type) == t_any) {
is_constant = false;
}
if (is_constant) {
is_constant = o->mode == Addressing_Constant;
}
check_assignment(c, o, field->type, make_string("structure literal"));
}
} else {
@@ -3596,6 +3607,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
break;
}
if (base_type(field->type) == t_any) {
is_constant = false;
}
if (is_constant) {
is_constant = o->mode == Addressing_Constant;
}
@@ -3632,15 +3646,18 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
isize index = 0;
isize elem_count = cl->elems.count;
if (base_type(elem_type) == t_any) {
is_constant = false;
}
for (; index < elem_count; index++) {
AstNode *e = cl->elems[index];
if (e->kind == AstNode_FieldValue) {
error(ast_node_token(e),
"`field = value` is only allowed in structure literals");
"`field = value` is only allowed in struct literals");
continue;
}
if (t->kind == Type_Array &&
t->Array.count >= 0 &&
index >= t->Array.count) {
@@ -3660,8 +3677,9 @@ ExprKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *type_hint
is_constant = operand.mode == Addressing_Constant;
}
}
if (max < index)
if (max < index) {
max = index;
}
if (t->kind == Type_Vector) {
if (t->Vector.count > 1 && gb_is_between(index, 2, t->Vector.count-1)) {
+3 -6
View File
@@ -145,12 +145,10 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
case Basic_i16: ssa_fprintf(f, "i16"); break;
case Basic_i32: ssa_fprintf(f, "i32"); break;
case Basic_i64: ssa_fprintf(f, "i64"); break;
// case Basic_i128: ssa_fprintf(f, "i128"); break;
case Basic_u8: ssa_fprintf(f, "i8"); break;
case Basic_u16: ssa_fprintf(f, "i16"); break;
case Basic_u32: ssa_fprintf(f, "i32"); break;
case Basic_u64: ssa_fprintf(f, "i64"); break;
// case Basic_u128: ssa_fprintf(f, "i128"); break;
case Basic_f32: ssa_fprintf(f, "float"); break;
case Basic_f64: ssa_fprintf(f, "double"); break;
case Basic_rawptr: ssa_fprintf(f, "%%..rawptr"); break;
@@ -176,12 +174,11 @@ void ssa_print_type(ssaFileBuffer *f, ssaModule *m, Type *t) {
ssa_print_type(f, m, t->Array.elem);
ssa_fprintf(f, "]");
break;
case Type_Vector: {
// TODO(bill): actually do correctly
case Type_Vector:
ssa_fprintf(f, "<%lld x ", t->Vector.count);
ssa_print_type(f, m, t->Vector.elem);
ssa_fprintf(f, ">");
} break;
break;
case Type_Slice:
ssa_fprintf(f, "{");
ssa_print_type(f, m, t->Slice.elem);
@@ -278,7 +275,7 @@ void ssa_print_compound_element(ssaFileBuffer *f, ssaModule *m, ExactValue v, Ty
ssa_fprintf(f, " ");
}
if (v.kind == ExactValue_Invalid) {
if (v.kind == ExactValue_Invalid || base_type(elem_type) == t_any) {
ssa_fprintf(f, "zeroinitializer");
} else if (v.kind == ExactValue_String) {
// HACK NOTE(bill): This is a hack but it works because strings are created at the very end
+23 -12
View File
@@ -1418,6 +1418,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
proc->curr_block = proc->decl_block;
ssa_emit_jump(proc, proc->entry_block);
#if 0
ssa_optimize_blocks(proc);
ssa_build_referrers(proc);
ssa_build_dom_tree(proc);
@@ -1428,7 +1429,7 @@ void ssa_end_procedure_body(ssaProcedure *proc) {
// [ ] Local stored once? Replace loads with dominating store
// [ ] Convert to phi nodes
ssa_opt_mem2reg(proc);
#endif
// Number registers
i32 reg_index = 0;
@@ -1923,6 +1924,7 @@ ssaValue *ssa_emit_conv(ssaProcedure *proc, ssaValue *value, Type *t, b32 is_arg
ev = exact_value_to_float(ev);
} else if (is_type_string(dst)) {
// Handled elsewhere
GB_ASSERT(ev.kind == ExactValue_String);
} else if (is_type_integer(dst)) {
ev = exact_value_to_integer(ev);
} else if (is_type_pointer(dst)) {
@@ -2479,7 +2481,10 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
case Type_Slice: et = bt->Slice.elem; break;
}
auto is_elem_const = [](ssaModule *m, AstNode *elem) -> b32 {
auto is_elem_const = [](ssaModule *m, AstNode *elem, Type *elem_type) -> b32 {
if (base_type(elem_type) == t_any) {
return false;
}
if (elem->kind == AstNode_FieldValue) {
elem = elem->FieldValue.value;
}
@@ -2495,7 +2500,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssaValue *result = ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr));
for_array(index, cl->elems) {
AstNode *elem = cl->elems[index];
if (is_elem_const(proc->module, elem)) {
if (is_elem_const(proc->module, elem, et)) {
continue;
}
ssaValue *field_elem = ssa_build_expr(proc, elem);
@@ -2526,9 +2531,6 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
for_array(field_index, cl->elems) {
AstNode *elem = cl->elems[field_index];
if (is_elem_const(proc->module, elem)) {
continue;
}
ssaValue *field_expr = NULL;
Entity *field = NULL;
@@ -2538,17 +2540,23 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ast_node(fv, FieldValue, elem);
Selection sel = lookup_field(proc->module->allocator, bt, fv->field->Ident.string, false);
index = sel.index[0];
field_expr = ssa_build_expr(proc, fv->value);
elem = fv->value;
} else {
TypeAndValue *tav = type_and_value_of_expression(proc->module->info, elem);
Selection sel = lookup_field(proc->module->allocator, bt, st->fields_in_src_order[field_index]->token.string, false);
index = sel.index[0];
field_expr = ssa_build_expr(proc, elem);
}
field = st->fields[index];
if (is_elem_const(proc->module, elem, field->type)) {
continue;
}
field_expr = ssa_build_expr(proc, elem);
GB_ASSERT(ssa_type(field_expr)->kind != Type_Tuple);
field = st->fields[index];
Type *ft = field->type;
ssaValue *fv = ssa_emit_conv(proc, field_expr, ft);
@@ -2562,7 +2570,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_store(proc, v, ssa_add_module_constant(proc->module, type, make_exact_value_compound(expr)));
for_array(i, cl->elems) {
AstNode *elem = cl->elems[i];
if (is_elem_const(proc->module, elem)) {
if (is_elem_const(proc->module, elem, et)) {
continue;
}
ssaValue *field_expr = ssa_build_expr(proc, elem);
@@ -2587,7 +2595,7 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
for_array(i, cl->elems) {
AstNode *elem = cl->elems[i];
if (is_elem_const(proc->module,elem)) {
if (is_elem_const(proc->module, elem, et)) {
continue;
}
@@ -3034,12 +3042,15 @@ ssaValue *ssa_build_single_expr(ssaProcedure *proc, AstNode *expr, TypeAndValue
ssa_emit_store(proc, ssa_emit_struct_gep(proc, slice, v_two32, t_int), len);
}
if (args[0]->kind == ssaValue_Constant) {
auto *c = &args[0]->Constant;
gb_printf_err("%s %d\n", type_to_string(c->type), c->value.kind);
}
arg_count = type->param_count;
args[arg_count-1] = ssa_emit_load(proc, slice);
}
return ssa_emit_call(proc, value, args, arg_count);
case_end;