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 {
10331033 BuiltinFnIdCDefine,
10341034 BuiltinFnIdCUndef,
10351035 BuiltinFnIdCompileVar,
1036 BuiltinFnIdConstEval,
10361037};
10371038
10381039struct BuiltinFnEntry {
src/analyze.cpp+19-1
......@@ -4127,8 +4127,26 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry
41274127 buf_sprintf("unrecognized compile variable: '%s'", buf_ptr(&var_name)));
41284128 return g->builtin_types.entry_invalid;
41294129 }
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;
41324150 }
41334151
41344152 }
src/codegen.cpp+2
......@@ -310,6 +310,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) {
310310 case BuiltinFnIdMaxValue:
311311 case BuiltinFnIdMemberCount:
312312 case BuiltinFnIdCompileVar:
313 case BuiltinFnIdConstEval:
313314 // caught by constant expression eval codegen
314315 zig_unreachable();
315316 }
......@@ -3513,6 +3514,7 @@ static void define_builtin_fns(CodeGen *g) {
35133514 create_builtin_fn_with_arg_count(g, BuiltinFnIdCDefine, "c_define", 2);
35143515 create_builtin_fn_with_arg_count(g, BuiltinFnIdCUndef, "c_undef", 1);
35153516 create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileVar, "compile_var", 1);
3517 create_builtin_fn_with_arg_count(g, BuiltinFnIdConstEval, "const_eval", 1);
35163518}
35173519
35183520
test/run_tests.cpp+7
......@@ -2020,6 +2020,13 @@ fn func() -> bogus {}
20202020 add_compile_fail_case("bogus compile var", R"SOURCE(
20212021const x = @compile_var("bogus");
20222022 )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");
20232030}
20242031
20252032//////////////////////////////////////////////////////////////////////////////
test/self_hosted.zig+7
......@@ -233,3 +233,10 @@ fn const_expr_eval_on_single_expr_blocks_fn(x: i32, b: bool) -> i32 {
233233
234234 return result;
235235}
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}