aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/check_expr.cpp2
-rw-r--r--src/check_stmt.cpp76
-rw-r--r--src/checker.cpp4
-rw-r--r--src/ir.cpp19
4 files changed, 11 insertions, 90 deletions
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index fae38fa01..ef43812c0 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -6739,7 +6739,7 @@ bool check_range(CheckerContext *c, Ast *node, Operand *x, Operand *y, ExactValu
}
if (inline_for_depth_) *inline_for_depth_ = inline_for_depth;
- } else {
+ } else if (inline_for_depth_ != nullptr) {
error(ie->op, "Interval expressions must be constant");
return false;
}
diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp
index d4398664b..2bf82facd 100644
--- a/src/check_stmt.cpp
+++ b/src/check_stmt.cpp
@@ -1476,80 +1476,14 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
if (is_ast_range(expr)) {
ast_node(ie, BinaryExpr, expr);
- Operand x = {Addressing_Invalid};
- Operand y = {Addressing_Invalid};
-
- check_expr(ctx, &x, ie->left);
- if (x.mode == Addressing_Invalid) {
- goto skip_expr_range_stmt;
- }
- check_expr(ctx, &y, ie->right);
- if (y.mode == Addressing_Invalid) {
- goto skip_expr_range_stmt;
- }
-
- convert_to_typed(ctx, &x, y.type);
- if (x.mode == Addressing_Invalid) {
- goto skip_expr_range_stmt;
- }
- convert_to_typed(ctx, &y, x.type);
- if (y.mode == Addressing_Invalid) {
- goto skip_expr_range_stmt;
- }
-
- convert_to_typed(ctx, &x, default_type(y.type));
- if (x.mode == Addressing_Invalid) {
- goto skip_expr_range_stmt;
- }
- convert_to_typed(ctx, &y, default_type(x.type));
- if (y.mode == Addressing_Invalid) {
- goto skip_expr_range_stmt;
- }
-
- if (!are_types_identical(x.type, y.type)) {
- if (x.type != t_invalid &&
- y.type != t_invalid) {
- gbString xt = type_to_string(x.type);
- gbString yt = type_to_string(y.type);
- gbString expr_str = expr_to_string(x.expr);
- error(ie->op, "Mismatched types in interval expression '%s' : '%s' vs '%s'", expr_str, xt, yt);
- gb_string_free(expr_str);
- gb_string_free(yt);
- gb_string_free(xt);
- }
- goto skip_expr_range_stmt;
- }
+ Operand x = {};
+ Operand y = {};
- Type *type = x.type;
- if (!is_type_integer(type) && !is_type_float(type) && !is_type_pointer(type) && !is_type_enum(type)) {
- error(ie->op, "Only numerical and pointer types are allowed within interval expressions");
+ bool ok = check_range(ctx, expr, &x, &y, nullptr);
+ if (!ok) {
goto skip_expr_range_stmt;
}
-
- if (x.mode == Addressing_Constant &&
- y.mode == Addressing_Constant) {
- ExactValue a = x.value;
- ExactValue b = y.value;
-
- GB_ASSERT(are_types_identical(x.type, y.type));
-
- TokenKind op = Token_Lt;
- switch (ie->op.kind) {
- case Token_Ellipsis: op = Token_LtEq; break;
- case Token_RangeHalf: op = Token_Lt; break;
- default: error(ie->op, "Invalid range operator"); break;
- }
- bool ok = compare_exact_values(op, a, b);
- if (!ok) {
- // TODO(bill): Better error message
- error(ie->op, "Invalid interval range");
- goto skip_expr_range_stmt;
- }
- }
-
- add_type_and_value(&ctx->checker->info, ie->left, x.mode, x.type, x.value);
- add_type_and_value(&ctx->checker->info, ie->right, y.mode, y.type, y.value);
- val0 = type;
+ val0 = x.type;
val1 = t_int;
} else {
Operand operand = {Addressing_Invalid};
diff --git a/src/checker.cpp b/src/checker.cpp
index 4490caa69..8ba45a799 100644
--- a/src/checker.cpp
+++ b/src/checker.cpp
@@ -1033,7 +1033,9 @@ void add_type_and_value(CheckerInfo *i, Ast *expr, AddressingMode mode, Type *ty
expr->tav.mode = mode;
expr->tav.type = type;
- expr->tav.value = value;
+ if (mode == Addressing_Constant || mode == Addressing_Invalid) {
+ expr->tav.value = value;
+ }
}
void add_entity_definition(CheckerInfo *i, Ast *identifier, Entity *entity) {
diff --git a/src/ir.cpp b/src/ir.cpp
index 8d5587341..d7db09180 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -6613,22 +6613,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
GB_ASSERT(tv.mode != Addressing_Invalid);
GB_ASSERT(tv.mode != Addressing_Type);
- #if 0
- if (tv.mode == Addressing_Type) {
- // // TODO(bill): Handle this correctly
- #if 0
- i32 entry_index = ir_type_info_index(proc->module->info, tv.type, false);
- if (entry_index >= 0) {
- return ir_get_type_info_ptr(proc, tv.type);
- // i32 id = entry_index+1;
- // return ir_value_constant(t_int, exact_value_i64(id));
- }
- #endif
- // return v_raw_nil;
- return ir_value_nil(tv.type);
- }
- #endif
-
if (tv.value.kind != ExactValue_Invalid) {
// NOTE(bill): Edge case
if (tv.value.kind != ExactValue_Compound &&
@@ -8686,7 +8670,8 @@ void ir_build_range_interval(irProcedure *proc, AstBinaryExpr *node, Type *val_t
upper = ir_build_expr(proc, node->right);
- irValue *cond = ir_emit_comp(proc, op, ir_emit_load(proc, value), upper);
+ irValue *curr_value = ir_emit_load(proc, value);
+ irValue *cond = ir_emit_comp(proc, op, curr_value, upper);
ir_emit_if(proc, cond, body, done);
ir_start_block(proc, body);