authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-23 00:34:47-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-01-23 00:34:59-07:00
loga922d5d42a3ba9bbded0740e1eb3246e7b57ad2a
treef62821f2a88dd807ca28362379cd4b1e01974275
parent1543043bf5b5633de485dccee88872a3d4f6c454

implement literal error values

See #23

4 files changed, 60 insertions(+), 5 deletions(-)

src/all_types.hpp+2
...@@ -310,6 +310,7 @@ enum CastOp {...@@ -310,6 +310,7 @@ enum CastOp {
310 CastOpToUnknownSizeArray,310 CastOpToUnknownSizeArray,
311 CastOpMaybeWrap,311 CastOpMaybeWrap,
312 CastOpPointerReinterpret,312 CastOpPointerReinterpret,
313 CastOpErrToInt,
313};314};
314315
315struct AstNodeFnCallExpr {316struct AstNodeFnCallExpr {
...@@ -999,6 +1000,7 @@ struct CodeGen {...@@ -999,6 +1000,7 @@ struct CodeGen {
999 bool error_during_imports;1000 bool error_during_imports;
1000 uint32_t next_node_index;1001 uint32_t next_node_index;
1001 uint32_t next_error_index;1002 uint32_t next_error_index;
1003 TypeTableEntry *err_tag_type;
1002};1004};
10031005
1004struct VariableTableEntry {1006struct VariableTableEntry {
src/analyze.cpp+29-5
...@@ -233,11 +233,10 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {...@@ -233,11 +233,10 @@ static TypeTableEntry *get_error_type(CodeGen *g, TypeTableEntry *child_type) {
233 entry->data.error.child_type = child_type;233 entry->data.error.child_type = child_type;
234234
235 if (child_type->size_in_bits == 0) {235 if (child_type->size_in_bits == 0) {
236 TypeTableEntry *tag_type = get_smallest_unsigned_int_type(g, g->next_error_index);236 entry->type_ref = g->err_tag_type->type_ref;
237 entry->type_ref = tag_type->type_ref;237 entry->size_in_bits = g->err_tag_type->size_in_bits;
238 entry->size_in_bits = tag_type->size_in_bits;238 entry->align_in_bits = g->err_tag_type->align_in_bits;
239 entry->align_in_bits = tag_type->align_in_bits;239 entry->di_type = g->err_tag_type->di_type;
240 entry->di_type = tag_type->di_type;
241240
242 } else {241 } else {
243 zig_panic("TODO get_error_type non-void");242 zig_panic("TODO get_error_type non-void");
...@@ -2869,6 +2868,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex...@@ -2869,6 +2868,10 @@ static void eval_const_expr_implicit_cast(CodeGen *g, AstNode *node, AstNode *ex
2869 const_val->data.x_maybe = other_val;2868 const_val->data.x_maybe = other_val;
2870 const_val->ok = true;2869 const_val->ok = true;
2871 break;2870 break;
2871 case CastOpErrToInt:
2872 bignum_init_unsigned(&const_val->data.x_bignum, other_val->data.x_err->value);
2873 const_val->ok = true;
2874 break;
2872 }2875 }
2873}2876}
28742877
...@@ -2975,6 +2978,24 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B...@@ -2975,6 +2978,24 @@ static TypeTableEntry *analyze_cast_expr(CodeGen *g, ImportTableEntry *import, B
2975 }2978 }
2976 }2979 }
29772980
2981 // explicit cast from %void to integer type which can fit it
2982 if (actual_type->id == TypeTableEntryIdError &&
2983 actual_type->data.error.child_type->size_in_bits == 0 &&
2984 wanted_type->id == TypeTableEntryIdInt)
2985 {
2986 BigNum bn;
2987 bignum_init_unsigned(&bn, g->next_error_index);
2988 if (bignum_fits_in_bits(&bn, wanted_type->size_in_bits, wanted_type->data.integral.is_signed)) {
2989 node->data.fn_call_expr.cast_op = CastOpErrToInt;
2990 eval_const_expr_implicit_cast(g, node, expr_node);
2991 return wanted_type;
2992 } else {
2993 add_node_error(g, node,
2994 buf_sprintf("too many error values to fit in '%s'", buf_ptr(&wanted_type->name)));
2995 return g->builtin_types.entry_invalid;
2996 }
2997 }
2998
2978 add_node_error(g, node,2999 add_node_error(g, node,
2979 buf_sprintf("invalid cast from type '%s' to '%s'",3000 buf_sprintf("invalid cast from type '%s' to '%s'",
2980 buf_ptr(&actual_type->name),3001 buf_ptr(&actual_type->name),
...@@ -4353,6 +4374,9 @@ void semantic_analyze(CodeGen *g) {...@@ -4353,6 +4374,9 @@ void semantic_analyze(CodeGen *g) {
4353 }4374 }
4354 }4375 }
4355 }4376 }
4377
4378 g->err_tag_type = get_smallest_unsigned_int_type(g, g->next_error_index);
4379
4356 {4380 {
4357 auto it = g->import_table.entry_iterator();4381 auto it = g->import_table.entry_iterator();
4358 for (;;) {4382 for (;;) {
src/codegen.cpp+13
...@@ -284,6 +284,13 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {...@@ -284,6 +284,13 @@ static LLVMValueRef gen_cast_expr(CodeGen *g, AstNode *node) {
284 zig_unreachable();284 zig_unreachable();
285 case CastOpNoop:285 case CastOpNoop:
286 return expr_val;286 return expr_val;
287 case CastOpErrToInt:
288 assert(actual_type->id == TypeTableEntryIdError);
289 if (actual_type->data.error.child_type->size_in_bits == 0) {
290 return expr_val;
291 } else {
292 zig_panic("TODO");
293 }
287 case CastOpMaybeWrap:294 case CastOpMaybeWrap:
288 {295 {
289 assert(cast_expr->tmp_ptr);296 assert(cast_expr->tmp_ptr);
...@@ -2122,6 +2129,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE...@@ -2122,6 +2129,12 @@ static LLVMValueRef gen_const_val(CodeGen *g, TypeTableEntry *type_entry, ConstE
2122 } else {2129 } else {
2123 return global_value;2130 return global_value;
2124 }2131 }
2132 } else if (type_entry->id == TypeTableEntryIdError) {
2133 if (type_entry->data.error.child_type->size_in_bits == 0) {
2134 return LLVMConstInt(g->err_tag_type->type_ref, const_val->data.x_err->value, false);
2135 } else {
2136 zig_panic("TODO");
2137 }
2125 } else {2138 } else {
2126 zig_unreachable();2139 zig_unreachable();
2127 }2140 }
test/run_tests.cpp+16
...@@ -1258,6 +1258,22 @@ pub fn main(args: [][]u8) i32 => {...@@ -1258,6 +1258,22 @@ pub fn main(args: [][]u8) i32 => {
1258}1258}
1259 )SOURCE", "OK\n");1259 )SOURCE", "OK\n");
12601260
1261 add_simple_case("error values", R"SOURCE(
1262import "std.zig";
1263%.err1;
1264%.err2;
1265pub fn main(args: [][]u8) i32 => {
1266 const a = i32(%.err1);
1267 const b = i32(%.err2);
1268 if (a == b) {
1269 print_str("BAD\n");
1270 }
1271
1272 print_str("OK\n");
1273 return 0;
1274}
1275 )SOURCE", "OK\n");
1276
1261}1277}
12621278
12631279