Browse Source

Disable for in over cstring

gingerBill 7 years ago
parent
commit
e5735af6d6
3 changed files with 34 additions and 6 deletions
  1. 1 1
      src/check_stmt.cpp
  2. 12 0
      src/exact_value.cpp
  3. 21 5
      src/ir.cpp

+ 1 - 1
src/check_stmt.cpp

@@ -1389,7 +1389,7 @@ void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
 				Type *t = base_type(type_deref(operand.type));
 				switch (t->kind) {
 				case Type_Basic:
-					if (is_type_string(t)) {
+					if (is_type_string(t) && t->Basic.kind != Basic_cstring) {
 						val0 = t_rune;
 						val1 = t_int;
 						add_package_dependency(ctx, "runtime", "__string_decode_rune");

+ 12 - 0
src/exact_value.cpp

@@ -141,6 +141,8 @@ ExactValue exact_value_integer_from_string(String const &string) {
 	return result;
 }
 
+
+
 f64 float_from_string(String string) {
 	isize i = 0;
 	u8 *str = string.text;
@@ -296,6 +298,16 @@ ExactValue exact_value_to_integer(ExactValue v) {
 	return r;
 }
 
+i64 exact_value_to_i64(ExactValue v) {
+	v = exact_value_to_integer(v);
+	i64 result = 0;
+	if (v.kind == ExactValue_Integer) {
+		return big_int_to_i64(&v.value_integer);
+	}
+	return result;
+}
+
+
 ExactValue exact_value_to_float(ExactValue v) {
 	switch (v.kind) {
 	case ExactValue_Integer:

+ 21 - 5
src/ir.cpp

@@ -4872,8 +4872,6 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
 			Ast *ue_expr = unparen_expr(ue->expr);
 			if (ue_expr->kind == Ast_TypeAssertion) {
 				gbAllocator a = ir_allocator();
-
-
 				GB_ASSERT(is_type_pointer(tv.type));
 
 				ast_node(ta, TypeAssertion, ue_expr);
@@ -4935,10 +4933,25 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
 				} else {
 					GB_PANIC("TODO(bill): type assertion %s", type_to_string(type));
 				}
-
+			} else if (ue_expr->kind == Ast_IndexExpr) {
+			#if 0
+				ast_node(ie, IndexExpr, ue_expr);
+				if (is_type_slice(ie->expr->tav.type)) {
+					auto tav = ie->index->tav;
+					if (tav.mode == Addressing_Constant) {
+						if (exact_value_to_i64(tav.value) == 0) {
+							irValue *s = ir_build_expr(proc, ie->expr);
+							if (is_type_pointer(ir_type(s))) {
+								s = ir_emit_load(proc, s);
+							}
+							return ir_slice_elem(proc, s);
+						}
+					}
+				}
+			#endif
 			}
 
-			return ir_emit_ptr_offset(proc, ir_build_addr_ptr(proc, ue->expr), v_zero); // Make a copy of the pointer
+			return ir_build_addr_ptr(proc, ue->expr);
 		}
 		default:
 			return ir_emit_unary_arith(proc, ue->op.kind, ir_build_expr(proc, ue->expr), tv.type);
@@ -6455,6 +6468,7 @@ void ir_build_range_string(irProcedure *proc, irValue *expr, Type *val_type,
 	if (done_) *done_ = done;
 }
 
+
 void ir_build_range_interval(irProcedure *proc, AstBinaryExpr *node, Type *val_type,
                              irValue **val_, irValue **idx_, irBlock **loop_, irBlock **done_) {
 	// TODO(bill): How should the behaviour work for lower and upper bounds checking for iteration?
@@ -6988,10 +7002,12 @@ void ir_build_stmt_internal(irProcedure *proc, Ast *node) {
 					string = ir_emit_load(proc, string);
 				}
 				if (is_type_untyped(expr_type)) {
-					irValue *s = ir_add_local_generated(proc, t_string);
+					irValue *s = ir_add_local_generated(proc, default_type(ir_type(string)));
 					ir_emit_store(proc, s, string);
 					string = ir_emit_load(proc, s);
 				}
+				Type *t = base_type(ir_type(string));
+				GB_ASSERT(!is_type_cstring(t));
 				ir_build_range_string(proc, string, val0_type, &val, &key, &loop, &done);
 				break;
 			}