authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-07 15:11:20-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2016-02-07 15:11:20-07:00
log26ea20d88fb1b201546e29058ac4aa5d4760a577
tree9e6af6c20faa376f6ecfdd775950b8d29b4dea45
parent049e9e581933921f2aaa1e60a8082c49fac236b2

implement @const_eval

closes #73

5 files changed, 36 insertions(+), 1 deletions(-)

src/all_types.hpp+1
...@@ -1033,6 +1033,7 @@ enum BuiltinFnId {...@@ -1033,6 +1033,7 @@ enum BuiltinFnId {
1033 BuiltinFnIdCDefine,1033 BuiltinFnIdCDefine,
1034 BuiltinFnIdCUndef,1034 BuiltinFnIdCUndef,
1035 BuiltinFnIdCompileVar,1035 BuiltinFnIdCompileVar,
1036 BuiltinFnIdConstEval,
1036};1037};
10371038
1038struct BuiltinFnEntry {1039struct BuiltinFnEntry {
src/analyze.cpp+19-1
...@@ -4127,8 +4127,26 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry...@@ -4127,8 +4127,26 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
4127 buf_sprintf("unrecognized compile variable: '%s'", buf_ptr(&var_name)));4127 buf_sprintf("unrecognized compile variable: '%s'", buf_ptr(&var_name)));
4128 return g->builtin_types.entry_invalid;4128 return g->builtin_types.entry_invalid;
4129 }4129 }
4130 }
4131 case BuiltinFnIdConstEval:
4132 {
4133 AstNode **expr_node = node->data.fn_call_expr.params.at(0)->parent_field;
4134 TypeTableEntry *resolved_type = analyze_expression(g, import, context, expected_type, *expr_node);
4135 if (resolved_type->id == TypeTableEntryIdInvalid) {
4136 return resolved_type;
4137 }
41304138
4131 break;4139 ConstExprValue *const_expr_val = &get_resolved_expr(*expr_node)->const_val;
4140
4141 if (!const_expr_val->ok) {
4142 add_node_error(g, *expr_node, buf_sprintf("unable to evaluate constant expression"));
4143 return resolved_type;
4144 }
4145
4146 ConstExprValue *const_val = &get_resolved_expr(node)->const_val;
4147 *const_val = *const_expr_val;
4148
4149 return resolved_type;
4132 }4150 }
41334151
4134 }4152 }
src/codegen.cpp+2
...@@ -310,6 +310,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {...@@ -310,6 +310,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
310 case BuiltinFnIdMaxValue:310 case BuiltinFnIdMaxValue:
311 case BuiltinFnIdMemberCount:311 case BuiltinFnIdMemberCount:
312 case BuiltinFnIdCompileVar:312 case BuiltinFnIdCompileVar:
313 case BuiltinFnIdConstEval:
313 // caught by constant expression eval codegen314 // caught by constant expression eval codegen
314 zig_unreachable();315 zig_unreachable();
315 }316 }
...@@ -3513,6 +3514,7 @@ static void define_builtin_fns(CodeGen *g) {...@@ -3513,6 +3514,7 @@ static void define_builtin_fns(CodeGen *g) {
3513 create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2);3514 create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2);
3514 create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1);3515 create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1);
3515 create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileVar, "compile_var", 1);3516 create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileVar, "compile_var", 1);
3517 create_builtin_fn_with_arg_count(g, BuiltinFnIdConstEval, "const_eval", 1);
3516}3518}
35173519
35183520
test/run_tests.cpp+7
...@@ -2020,6 +2020,13 @@ fn func() -> bogus {}...@@ -2020,6 +2020,13 @@ fn func() -> bogus {}
2020 add_compile_fail_case("bogus compile var", R"SOURCE(2020 add_compile_fail_case("bogus compile var", R"SOURCE(
2021const x = @compile_var("bogus");2021const x = @compile_var("bogus");
2022 )SOURCE", 1, ".tmp_source.zig:2:24: error: unrecognized compile variable: 'bogus'");2022 )SOURCE", 1, ".tmp_source.zig:2:24: error: unrecognized compile variable: 'bogus'");
2023
2024
2025 add_compile_fail_case("@const_eval", R"SOURCE(
2026fn a(x: i32) {
2027 const y = @const_eval(x);
2028}
2029 )SOURCE", 1, ".tmp_source.zig:3:27: error: unable to evaluate constant expression");
2023}2030}
20242031
2025//////////////////////////////////////////////////////////////////////////////2032//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+7
...@@ -233,3 +233,10 @@ fn const_expr_eval_on_single_expr_blocks_fn(x: i32, b: bool) -> i32 {...@@ -233,3 +233,10 @@ fn const_expr_eval_on_single_expr_blocks_fn(x: i32, b: bool) -> i32 {
233233
234 return result;234 return result;
235}235}
236
237
238#attribute("test")
239fn builtin_const_eval() {
240 const x : i32 = @const_eval(1 + 2 + 3);
241 if (x != @const_eval(6)) unreachable{};
242}