expr as type; {N}bool is still causing problems

This commit is contained in:
gingerBill
2016-08-14 12:22:31 +01:00
parent c10b46af9f
commit ee00236412
11 changed files with 833 additions and 546 deletions
+137 -107
View File
@@ -384,11 +384,9 @@ Type *check_type(Checker *c, AstNode *e, Type *named_type) {
Type *elem = check_type(c, vt->elem);
Type *be = get_base_type(elem);
i64 count = check_array_count(c, vt->count);
if (!is_type_vector(be) &&
!(is_type_boolean(be) || is_type_numeric(be))) {
if (!is_type_boolean(be) && !is_type_numeric(be)) {
err_str = type_to_string(elem);
error(&c->error_collector, ast_node_token(vt->elem), "Vector element type must be a boolean, numerical, or vector. Got `%s`", err_str);
} else {
error(&c->error_collector, ast_node_token(vt->elem), "Vector element type must be numerical or a boolean. Got `%s`", err_str);
}
type = make_type_vector(c->allocator, elem, count);
set_base_type(named_type, type);
@@ -433,7 +431,7 @@ end:
b32 check_unary_op(Checker *c, Operand *o, Token op) {
// TODO(bill): Handle errors correctly
Type *type = get_base_type(base_vector_type(o->type));
Type *type = get_base_type(base_vector_type(get_base_type(o->type)));
gbString str = NULL;
defer (gb_string_free(str));
switch (op.kind) {
@@ -702,13 +700,11 @@ void check_comparison(Checker *c, Operand *x, Operand *y, Token op) {
update_expr_type(c, y->expr, default_type(y->type), true);
}
if (is_type_vector(x->type)) {
Type *vec_bool = NULL;
do {
} while (is_type_vector(x->type->vector.elem));
if (is_type_vector(get_base_type(y->type))) {
x->type = make_type_vector(c->allocator, t_bool, get_base_type(y->type)->vector.count);
} else {
x->type = t_untyped_bool;
}
x->type = t_untyped_bool;
}
void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
@@ -805,6 +801,101 @@ void check_shift(Checker *c, Operand *x, Operand *y, AstNode *node) {
x->mode = Addressing_Value;
}
b32 check_castable_to(Checker *c, Operand *operand, Type *y) {
if (check_is_assignable_to(c, operand, y))
return true;
Type *x = operand->type;
Type *xb = get_base_type(x);
Type *yb = get_base_type(y);
if (are_types_identical(xb, yb))
return true;
// Cast between booleans and integers
if (is_type_boolean(x) || is_type_integer(x)) {
if (is_type_boolean(y) || is_type_integer(y))
return true;
}
// Cast between numbers
if (is_type_integer(x) || is_type_float(x)) {
if (is_type_integer(y) || is_type_float(y))
return true;
}
// Cast between pointers
if (is_type_pointer(x)) {
if (is_type_pointer(y))
return true;
}
// untyped integers -> pointers
if (is_type_untyped(xb) && is_type_integer(xb)) {
if (is_type_pointer(yb))
return true;
}
// (u)int <-> pointer
if (is_type_pointer(xb) || is_type_int_or_uint(xb)) {
if (is_type_pointer(yb))
return true;
}
if (is_type_pointer(xb)) {
if (is_type_pointer(yb) || is_type_int_or_uint(yb))
return true;
}
// []byte/[]u8 <-> string
if (is_type_u8_slice(xb) && is_type_string(yb)) {
return true;
}
if (is_type_string(xb) && is_type_u8_slice(yb)) {
return true;
}
return false;
}
void check_cast_expr(Checker *c, Operand *operand, Type *type) {
b32 is_const_expr = operand->mode == Addressing_Constant;
b32 can_convert = false;
if (is_const_expr && is_type_constant_type(type)) {
Type *t = get_base_type(type);
if (t->kind == Type_Basic) {
if (check_value_is_expressible(c, operand->value, t, &operand->value)) {
can_convert = true;
}
}
} else if (check_castable_to(c, operand, type)) {
operand->mode = Addressing_Value;
can_convert = true;
}
if (!can_convert) {
gbString expr_str = expr_to_string(operand->expr);
gbString type_str = type_to_string(type);
defer (gb_string_free(expr_str));
defer (gb_string_free(type_str));
error(&c->error_collector, ast_node_token(operand->expr), "Cannot cast `%s` to `%s`", expr_str, type_str);
operand->mode = Addressing_Invalid;
return;
}
if (is_type_untyped(operand->type)) {
Type *final_type = type;
if (is_const_expr && !is_type_constant_type(type)) {
final_type = default_type(operand->type);
}
update_expr_type(c, operand->expr, final_type, true);
}
operand->type = type;
}
void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
GB_ASSERT(node->kind == AstNode_BinaryExpr);
Operand y_ = {}, *y = &y_;
@@ -813,6 +904,15 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
ast_node(be, BinaryExpr, node);
if (be->op.kind == Token_as) {
check_expr(c, x, be->left);
Type *cast_type = check_type(c, be->right);
if (x->mode == Addressing_Invalid)
return;
check_cast_expr(c, x, cast_type);
return;
}
check_expr(c, x, be->left);
check_expr(c, y, be->right);
if (x->mode == Addressing_Invalid) {
@@ -890,7 +990,7 @@ void check_binary_expr(Checker *c, Operand *x, AstNode *node) {
}
if (x->mode == Addressing_Constant &&
y->mode == Addressing_Constant) {
y->mode == Addressing_Constant) {
ExactValue a = x->value;
ExactValue b = y->value;
@@ -943,7 +1043,18 @@ void update_expr_type(Checker *c, AstNode *e, Type *type, b32 final) {
found->type = get_base_type(type);
map_set(&c->info.untyped, key, *found);
} else {
ExpressionInfo old = *found;
map_remove(&c->info.untyped, key);
if (old.is_lhs && !is_type_integer(type)) {
gbString expr_str = expr_to_string(e);
gbString type_str = type_to_string(type);
defer (gb_string_free(expr_str));
defer (gb_string_free(type_str));
error(&c->error_collector, ast_node_token(e), "Shifted operand %s must be an integer, got %s", expr_str, type_str);
return;
}
add_type_and_value(&c->info, e, found->mode, type, found->value);
}
}
@@ -1349,6 +1460,11 @@ b32 check_builtin_procedure(Checker *c, Operand *operand, AstNode *call, i32 id)
value = make_exact_value_integer(t->array.count);
break;
case Type_Vector:
mode = Addressing_Constant;
value = make_exact_value_integer(t->vector.count);
break;
case Type_Slice:
mode = Addressing_Value;
break;
@@ -1600,85 +1716,6 @@ ExpressionKind check_call_expr(Checker *c, Operand *operand, AstNode *call) {
return Expression_Statement;
}
b32 check_castable_to(Checker *c, Operand *operand, Type *y) {
if (check_is_assignable_to(c, operand, y))
return true;
Type *x = operand->type;
Type *xb = get_base_type(x);
Type *yb = get_base_type(y);
if (are_types_identical(xb, yb))
return true;
// Cast between numbers
if (is_type_integer(x) || is_type_float(x)) {
if (is_type_integer(y) || is_type_float(y))
return true;
}
// Cast between pointers
if (is_type_pointer(x)) {
if (is_type_pointer(y))
return true;
}
// untyped integers -> pointers
if (is_type_untyped(xb) && is_type_integer(xb)) {
if (is_type_pointer(yb))
return true;
}
// (u)int <-> pointer
if (is_type_pointer(xb) || is_type_int_or_uint(xb)) {
if (is_type_pointer(yb))
return true;
}
if (is_type_pointer(xb)) {
if (is_type_pointer(yb) || is_type_int_or_uint(yb))
return true;
}
// []byte/[]u8 <-> string
if (is_type_u8_slice(xb) && is_type_string(yb)) {
return true;
}
if (is_type_string(xb) && is_type_u8_slice(yb)) {
return true;
}
return false;
}
void check_cast_expr(Checker *c, Operand *operand, Type *type) {
b32 is_const_expr = operand->mode == Addressing_Constant;
b32 can_convert = false;
if (is_const_expr && is_type_constant_type(type)) {
Type *t = get_base_type(type);
if (t->kind == Type_Basic) {
if (check_value_is_expressible(c, operand->value, t, &operand->value)) {
can_convert = true;
}
}
} else if (check_castable_to(c, operand, type)) {
operand->mode = Addressing_Value;
can_convert = true;
}
if (!can_convert) {
gbString expr_str = expr_to_string(operand->expr);
gbString type_str = type_to_string(type);
defer (gb_string_free(expr_str));
defer (gb_string_free(type_str));
error(&c->error_collector, ast_node_token(operand->expr), "Cannot cast `%s` to `%s`", expr_str, type_str);
operand->mode = Addressing_Invalid;
return;
}
operand->type = type;
}
void check_expr_with_type_hint(Checker *c, Operand *o, AstNode *e, Type *t) {
check_expr_base(c, o, e, t);
check_not_tuple(c, o);
@@ -1924,6 +1961,15 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
o->type = t->array.elem;
break;
case Type_Vector:
valid = true;
max_count = t->vector.count;
if (o->mode != Addressing_Variable)
o->mode = Addressing_Value;
o->type = t->vector.elem;
break;
case Type_Slice:
valid = true;
o->type = t->slice.elem;
@@ -2039,15 +2085,6 @@ ExpressionKind check__expr_base(Checker *c, Operand *o, AstNode *node, Type *typ
case_end;
case_ast_node(ce, CastExpr, node);
Type *cast_type = check_type(c, ce->type);
check_expr_or_type(c, o, ce->expr);
if (o->mode != Addressing_Invalid)
check_cast_expr(c, o, cast_type);
case_end;
case_ast_node(ce, CallExpr, node);
return check_call_expr(c, o, node);
case_end;
@@ -2287,13 +2324,6 @@ gbString write_expr_to_string(gbString str, AstNode *node) {
str = gb_string_appendc(str, "]");
case_end;
case_ast_node(ce, CastExpr, node);
str = gb_string_appendc(str, "cast(");
str = write_expr_to_string(str, ce->type);
str = gb_string_appendc(str, ")");
str = write_expr_to_string(str, ce->expr);
case_end;
case_ast_node(e, Ellipsis, node);
str = gb_string_appendc(str, "..");
case_end;