From e5b17580107ad0783b7f07de100aeb9ccf175603 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Jan 2017 23:20:53 -0500 Subject: [PATCH] remove staticEval builtin in favor of comptime expression --- doc/langref.md | 7 ----- src/all_types.hpp | 10 +------ src/analyze.cpp | 2 +- src/codegen.cpp | 2 -- src/ir.cpp | 66 +++++------------------------------------ src/ir_print.cpp | 9 ------ test/cases/array.zig | 2 +- test/cases/generics.zig | 2 +- test/cases/math.zig | 4 +-- test/cases/misc.zig | 6 ++-- test/run_tests.cpp | 6 ---- 11 files changed, 16 insertions(+), 100 deletions(-) diff --git a/doc/langref.md b/doc/langref.md index fe89db0ec4..94ef5cc972 100644 --- a/doc/langref.md +++ b/doc/langref.md @@ -551,13 +551,6 @@ Build scripts can set additional compile variables of any name and type. The result of this function is a compile time constant that is marked as depending on a compile variable. -### @staticEval(expression) -> @typeOf(expression) - -This function wraps an expression and generates a compile error if the -expression is not known at compile time. - -The result of the function is the result of the expression. - ### @generatedCode(expression) -> @typeOf(expression) This function wraps an expression and returns the result of the expression diff --git a/src/all_types.hpp b/src/all_types.hpp index 61f7d7cc8b..a12444eb4c 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1058,7 +1058,6 @@ enum BuiltinFnId { BuiltinFnIdCUndef, BuiltinFnIdCompileVar, BuiltinFnIdCompileErr, - BuiltinFnIdStaticEval, BuiltinFnIdGeneratedCode, BuiltinFnIdCtz, BuiltinFnIdClz, @@ -1373,7 +1372,7 @@ struct ScopeLoop { }; // This scope is created for a comptime expression. -// NodeTypeCompTime +// NodeTypeCompTime, NodeTypeSwitchExpr struct ScopeCompTime { Scope base; }; @@ -1454,7 +1453,6 @@ enum IrInstructionId { IrInstructionIdEnumTag, IrInstructionIdClz, IrInstructionIdCtz, - IrInstructionIdStaticEval, IrInstructionIdGeneratedCode, IrInstructionIdImport, IrInstructionIdCImport, @@ -1867,12 +1865,6 @@ struct IrInstructionEnumTag { IrInstruction *value; }; -struct IrInstructionStaticEval { - IrInstruction base; - - IrInstruction *value; -}; - struct IrInstructionGeneratedCode { IrInstruction base; diff --git a/src/analyze.cpp b/src/analyze.cpp index 3308901628..1e83a51b5b 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -139,7 +139,7 @@ ScopeFnDef *create_fndef_scope(AstNode *node, Scope *parent, FnTableEntry *fn_en } Scope *create_comptime_scope(AstNode *node, Scope *parent) { - assert(node->type == NodeTypeCompTime); + assert(node->type == NodeTypeCompTime || node->type == NodeTypeSwitchExpr); ScopeCompTime *scope = allocate(1); init_scope(&scope->base, ScopeIdCompTime, node, parent); return &scope->base; diff --git a/src/codegen.cpp b/src/codegen.cpp index 5d1f52fb0f..6d67eec838 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -2261,7 +2261,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdCompileVar: case IrInstructionIdSizeOf: case IrInstructionIdSwitchTarget: - case IrInstructionIdStaticEval: case IrInstructionIdContainerInitFields: case IrInstructionIdMinValue: case IrInstructionIdMaxValue: @@ -3640,7 +3639,6 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdCDefine, "cDefine", 2); create_builtin_fn(g, BuiltinFnIdCUndef, "cUndef", 1); create_builtin_fn(g, BuiltinFnIdCompileVar, "compileVar", 1); - create_builtin_fn(g, BuiltinFnIdStaticEval, "staticEval", 1); create_builtin_fn(g, BuiltinFnIdGeneratedCode, "generatedCode", 1); create_builtin_fn(g, BuiltinFnIdCtz, "ctz", 1); create_builtin_fn(g, BuiltinFnIdClz, "clz", 1); diff --git a/src/ir.cpp b/src/ir.cpp index 9842d2f3ad..f516da8c15 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -315,10 +315,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTag *) { return IrInstructionIdEnumTag; } -static constexpr IrInstructionId ir_instruction_id(IrInstructionStaticEval *) { - return IrInstructionIdStaticEval; -} - static constexpr IrInstructionId ir_instruction_id(IrInstructionGeneratedCode *) { return IrInstructionIdGeneratedCode; } @@ -1403,15 +1399,6 @@ static IrInstruction *ir_build_enum_tag_from(IrBuilder *irb, IrInstruction *old_ return new_instruction; } -static IrInstruction *ir_build_static_eval(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { - IrInstructionStaticEval *instruction = ir_build_instruction(irb, scope, source_node); - instruction->value = value; - - ir_ref_instruction(value, irb->current_basic_block); - - return &instruction->base; -} - static IrInstruction *ir_build_generated_code(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *value) { @@ -2300,13 +2287,6 @@ static IrInstruction *ir_instruction_ctz_get_dep(IrInstructionCtz *instruction, } } -static IrInstruction *ir_instruction_staticeval_get_dep(IrInstructionStaticEval *instruction, size_t index) { - switch (index) { - case 0: return instruction->value; - default: return nullptr; - } -} - static IrInstruction *ir_instruction_generatedcode_get_dep(IrInstructionGeneratedCode *instruction, size_t index) { switch (index) { case 0: return instruction->value; @@ -2711,8 +2691,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t return ir_instruction_clz_get_dep((IrInstructionClz *) instruction, index); case IrInstructionIdCtz: return ir_instruction_ctz_get_dep((IrInstructionCtz *) instruction, index); - case IrInstructionIdStaticEval: - return ir_instruction_staticeval_get_dep((IrInstructionStaticEval *) instruction, index); case IrInstructionIdGeneratedCode: return ir_instruction_generatedcode_get_dep((IrInstructionGeneratedCode *) instruction, index); case IrInstructionIdImport: @@ -3727,15 +3705,6 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return ir_build_clz(irb, scope, node, arg0_value); } - case BuiltinFnIdStaticEval: - { - AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) - return arg0_value; - - return ir_build_static_eval(irb, scope, node, arg0_value); - } case BuiltinFnIdGeneratedCode: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); @@ -4731,6 +4700,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ZigList incoming_blocks = {0}; ZigList check_ranges = {0}; + Scope *comptime_scope = create_comptime_scope(node, scope); AstNode *else_prong = nullptr; for (size_t prong_i = 0; prong_i < prong_count; prong_i += 1) { AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i); @@ -4764,11 +4734,11 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * AstNode *start_node = item_node->data.switch_range.start; AstNode *end_node = item_node->data.switch_range.end; - IrInstruction *start_value = ir_gen_node(irb, start_node, scope); + IrInstruction *start_value = ir_gen_node(irb, start_node, comptime_scope); if (start_value == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; - IrInstruction *end_value = ir_gen_node(irb, end_node, scope); + IrInstruction *end_value = ir_gen_node(irb, end_node, comptime_scope); if (end_value == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; @@ -4776,13 +4746,10 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * check_range->start = start_value; check_range->end = end_value; - IrInstruction *start_value_const = ir_build_static_eval(irb, scope, start_node, start_value); - IrInstruction *end_value_const = ir_build_static_eval(irb, scope, start_node, end_value); - IrInstruction *lower_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpGreaterOrEq, - target_value, start_value_const, false); + target_value, start_value, false); IrInstruction *upper_range_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpCmpLessOrEq, - target_value, end_value_const, false); + target_value, end_value, false); IrInstruction *both_ok = ir_build_bin_op(irb, scope, item_node, IrBinOpBoolAnd, lower_range_ok, upper_range_ok, false); if (ok_bit) { @@ -4791,7 +4758,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ok_bit = both_ok; } } else { - IrInstruction *item_value = ir_gen_node(irb, item_node, scope); + IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); if (item_value == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; @@ -4833,7 +4800,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * AstNode *item_node = prong_node->data.switch_prong.items.at(item_i); assert(item_node->type != NodeTypeSwitchRange); - IrInstruction *item_value = ir_gen_node(irb, item_node, scope); + IrInstruction *item_value = ir_gen_node(irb, item_node, comptime_scope); if (item_value == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; @@ -9660,22 +9627,6 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag(IrAnalyze *ira, IrInstruc return new_instruction->value.type; } -static TypeTableEntry *ir_analyze_instruction_static_eval(IrAnalyze *ira, - IrInstructionStaticEval *static_eval_instruction) -{ - IrInstruction *value = static_eval_instruction->value->other; - if (value->value.type->id == TypeTableEntryIdInvalid) - return ira->codegen->builtin_types.entry_invalid; - - ConstExprValue *val = ir_resolve_const(ira, value, UndefBad); - if (!val) - return ira->codegen->builtin_types.entry_invalid; - - ConstExprValue *out_val = ir_build_const_from(ira, &static_eval_instruction->base, val->depends_on_compile_var); - *out_val = *val; - return value->value.type; -} - static TypeTableEntry *ir_analyze_instruction_generated_code(IrAnalyze *ira, IrInstructionGeneratedCode *instruction) { IrInstruction *value = instruction->value->other; if (value->value.type->id == TypeTableEntryIdInvalid) @@ -11379,8 +11330,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi return ir_analyze_instruction_switch_var(ira, (IrInstructionSwitchVar *)instruction); case IrInstructionIdEnumTag: return ir_analyze_instruction_enum_tag(ira, (IrInstructionEnumTag *)instruction); - case IrInstructionIdStaticEval: - return ir_analyze_instruction_static_eval(ira, (IrInstructionStaticEval *)instruction); case IrInstructionIdGeneratedCode: return ir_analyze_instruction_generated_code(ira, (IrInstructionGeneratedCode *)instruction); case IrInstructionIdImport: @@ -11591,7 +11540,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdSwitchVar: case IrInstructionIdSwitchTarget: case IrInstructionIdEnumTag: - case IrInstructionIdStaticEval: case IrInstructionIdGeneratedCode: case IrInstructionIdRef: case IrInstructionIdMinValue: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 1598d69491..418b4b5e7c 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -486,12 +486,6 @@ static void ir_print_enum_tag(IrPrint *irp, IrInstructionEnumTag *instruction) { ir_print_other_instruction(irp, instruction->value); } -static void ir_print_static_eval(IrPrint *irp, IrInstructionStaticEval *instruction) { - fprintf(irp->f, "@staticEval("); - ir_print_other_instruction(irp, instruction->value); - fprintf(irp->f, ")"); -} - static void ir_print_generated_code(IrPrint *irp, IrInstructionGeneratedCode *instruction) { fprintf(irp->f, "@generatedCode("); ir_print_other_instruction(irp, instruction->value); @@ -938,9 +932,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdEnumTag: ir_print_enum_tag(irp, (IrInstructionEnumTag *)instruction); break; - case IrInstructionIdStaticEval: - ir_print_static_eval(irp, (IrInstructionStaticEval *)instruction); - break; case IrInstructionIdGeneratedCode: ir_print_generated_code(irp, (IrInstructionGeneratedCode *)instruction); break; diff --git a/test/cases/array.zig b/test/cases/array.zig index f29d36b680..79dcf21407 100644 --- a/test/cases/array.zig +++ b/test/cases/array.zig @@ -49,7 +49,7 @@ fn arrayLiteral() { fn arrayDotLenConstExpr() { @setFnTest(this); - assert(@staticEval(some_array.len) == 4); + assert(comptime {some_array.len == 4}); } const ArrayDotLenConstExpr = struct { diff --git a/test/cases/generics.zig b/test/cases/generics.zig index 76bb9fe5ef..069b468966 100644 --- a/test/cases/generics.zig +++ b/test/cases/generics.zig @@ -13,7 +13,7 @@ fn max(comptime T: type, a: T, b: T) -> T { } fn add(comptime a: i32, b: i32) -> i32 { - return @staticEval(a) + b; + return comptime {a} + b; } const the_max = max(u32, 1234, 5678); diff --git a/test/cases/math.zig b/test/cases/math.zig index 370c78c613..7dde0bf62c 100644 --- a/test/cases/math.zig +++ b/test/cases/math.zig @@ -172,8 +172,8 @@ const DivResult = struct { fn binaryNot() { @setFnTest(this); - assert(@staticEval(~u16(0b1010101010101010) == 0b0101010101010101)); - assert(@staticEval(~u64(2147483647) == 18446744071562067968)); + assert(comptime {~u16(0b1010101010101010) == 0b0101010101010101}); + assert(comptime {~u64(2147483647) == 18446744071562067968}); testBinaryNot(0b1010101010101010); } diff --git a/test/cases/misc.zig b/test/cases/misc.zig index 6ae56a5b9a..64482cf427 100644 --- a/test/cases/misc.zig +++ b/test/cases/misc.zig @@ -174,8 +174,8 @@ fn memcpyAndMemsetIntrinsics() { fn builtinStaticEval() { @setFnTest(this); - const x : i32 = @staticEval(1 + 2 + 3); - assert(x == @staticEval(6)); + const x : i32 = comptime {1 + 2 + 3}; + assert(x == comptime 6); } fn slicing() { @@ -201,7 +201,7 @@ fn constantEqualFunctionPointers() { @setFnTest(this); const alias = emptyFn; - assert(@staticEval(emptyFn == alias)); + assert(comptime {emptyFn == alias}); } fn emptyFn() {} diff --git a/test/run_tests.cpp b/test/run_tests.cpp index 3450845d55..19d36d2565 100644 --- a/test/run_tests.cpp +++ b/test/run_tests.cpp @@ -1116,12 +1116,6 @@ const x = @compileVar("bogus"); )SOURCE", 1, ".tmp_source.zig:2:23: error: unrecognized compile variable: 'bogus'"); - add_compile_fail_case("@staticEval", R"SOURCE( -fn a(x: i32) { - const y = @staticEval(x); -} - )SOURCE", 1, ".tmp_source.zig:3:27: error: unable to evaluate constant expression"); - add_compile_fail_case("non constant expression in array size outside function", R"SOURCE( const Foo = struct { y: [get()]u8,