| author | |
| committer | |
| log | 6ff996f60fa4e26e8dc5a8556986b5caa3eb1021 |
| tree | d38579da50304852f292f7ccb555bef87562ba43 |
| parent | 50310cf9df75217cba0edf2420a8af8d560d4b3e |
5 files changed, 75 insertions(+), 0 deletions(-)
src/all_types.hpp+1| ... | @@ -1139,6 +1139,7 @@ enum BuiltinFnId { | ... | @@ -1139,6 +1139,7 @@ enum BuiltinFnId { |
| 1139 | BuiltinFnIdFence, | 1139 | BuiltinFnIdFence, |
| 1140 | BuiltinFnIdDivExact, | 1140 | BuiltinFnIdDivExact, |
| 1141 | BuiltinFnIdTruncate, | 1141 | BuiltinFnIdTruncate, |
| 1142 | BuiltinFnIdIntType, | ||
| 1142 | }; | 1143 | }; |
| 1143 | 1144 | ||
| 1144 | struct BuiltinFnEntry { | 1145 | struct BuiltinFnEntry { |
src/analyze.cpp+48| ... | @@ -4790,6 +4790,52 @@ static TypeTableEntry *analyze_compile_err(CodeGen *g, ImportTableEntry *import, | ... | @@ -4790,6 +4790,52 @@ static TypeTableEntry *analyze_compile_err(CodeGen *g, ImportTableEntry *import, |
| 4790 | return g->builtin_types.entry_invalid; | 4790 | return g->builtin_types.entry_invalid; |
| 4791 | } | 4791 | } |
| 4792 | 4792 | ||
| 4793 | static TypeTableEntry *analyze_int_type(CodeGen *g, ImportTableEntry *import, | ||
| 4794 | BlockContext *context, AstNode *node) | ||
| 4795 | { | ||
| 4796 | AstNode **is_signed_node = &node->data.fn_call_expr.params.at(0); | ||
| 4797 | AstNode **bit_count_node = &node->data.fn_call_expr.params.at(1); | ||
| 4798 | AstNode **is_wrap_node = &node->data.fn_call_expr.params.at(2); | ||
| 4799 | |||
| 4800 | TypeTableEntry *bool_type = g->builtin_types.entry_bool; | ||
| 4801 | TypeTableEntry *usize_type = g->builtin_types.entry_usize; | ||
| 4802 | TypeTableEntry *is_signed_type = analyze_expression(g, import, context, bool_type, *is_signed_node); | ||
| 4803 | TypeTableEntry *bit_count_type = analyze_expression(g, import, context, usize_type, *bit_count_node); | ||
| 4804 | TypeTableEntry *is_wrap_type = analyze_expression(g, import, context, bool_type, *is_wrap_node); | ||
| 4805 | |||
| 4806 | if (is_signed_type->id == TypeTableEntryIdInvalid || | ||
| 4807 | bit_count_type->id == TypeTableEntryIdInvalid || | ||
| 4808 | is_wrap_type->id == TypeTableEntryIdInvalid) | ||
| 4809 | { | ||
| 4810 | return g->builtin_types.entry_invalid; | ||
| 4811 | } | ||
| 4812 | |||
| 4813 | ConstExprValue *is_signed_val = &get_resolved_expr(*is_signed_node)->const_val; | ||
| 4814 | ConstExprValue *bit_count_val = &get_resolved_expr(*bit_count_node)->const_val; | ||
| 4815 | ConstExprValue *is_wrap_val = &get_resolved_expr(*is_wrap_node)->const_val; | ||
| 4816 | |||
| 4817 | AstNode *bad_node = nullptr; | ||
| 4818 | if (!is_signed_val->ok) { | ||
| 4819 | bad_node = *is_signed_node; | ||
| 4820 | } else if (!bit_count_val->ok) { | ||
| 4821 | bad_node = *bit_count_node; | ||
| 4822 | } else if (!is_wrap_val->ok) { | ||
| 4823 | bad_node = *is_wrap_node; | ||
| 4824 | } | ||
| 4825 | if (bad_node) { | ||
| 4826 | add_node_error(g, bad_node, buf_sprintf("unable to evaluate constant expression")); | ||
| 4827 | return g->builtin_types.entry_invalid; | ||
| 4828 | } | ||
| 4829 | |||
| 4830 | bool depends_on_compile_var = is_signed_val->depends_on_compile_var || | ||
| 4831 | bit_count_val->depends_on_compile_var || is_wrap_val->depends_on_compile_var; | ||
| 4832 | |||
| 4833 | TypeTableEntry *int_type = get_int_type(g, is_signed_val->data.x_bool, is_wrap_val->data.x_bool, | ||
| 4834 | bit_count_val->data.x_bignum.data.x_uint); | ||
| 4835 | return resolve_expr_const_val_as_type(g, node, int_type, depends_on_compile_var); | ||
| 4836 | |||
| 4837 | } | ||
| 4838 | |||
| 4793 | static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, | 4839 | static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry *import, BlockContext *context, |
| 4794 | TypeTableEntry *expected_type, AstNode *node) | 4840 | TypeTableEntry *expected_type, AstNode *node) |
| 4795 | { | 4841 | { |
| ... | @@ -5136,6 +5182,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry | ... | @@ -5136,6 +5182,8 @@ static TypeTableEntry *analyze_builtin_fn_call_expr(CodeGen *g, ImportTableEntry |
| 5136 | return analyze_truncate(g, import, context, node); | 5182 | return analyze_truncate(g, import, context, node); |
| 5137 | case BuiltinFnIdCompileErr: | 5183 | case BuiltinFnIdCompileErr: |
| 5138 | return analyze_compile_err(g, import, context, node); | 5184 | return analyze_compile_err(g, import, context, node); |
| 5185 | case BuiltinFnIdIntType: | ||
| 5186 | return analyze_int_type(g, import, context, node); | ||
| 5139 | } | 5187 | } |
| 5140 | zig_unreachable(); | 5188 | zig_unreachable(); |
| 5141 | } | 5189 | } |
src/codegen.cpp+2| ... | @@ -540,6 +540,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { | ... | @@ -540,6 +540,7 @@ static LLVMValueRef gen_builtin_fn_call_expr(CodeGen *g, AstNode *node) { |
| 540 | case BuiltinFnIdImport: | 540 | case BuiltinFnIdImport: |
| 541 | case BuiltinFnIdCImport: | 541 | case BuiltinFnIdCImport: |
| 542 | case BuiltinFnIdCompileErr: | 542 | case BuiltinFnIdCompileErr: |
| 543 | case BuiltinFnIdIntType: | ||
| 543 | zig_unreachable(); | 544 | zig_unreachable(); |
| 544 | case BuiltinFnIdCtz: | 545 | case BuiltinFnIdCtz: |
| 545 | case BuiltinFnIdClz: | 546 | case BuiltinFnIdClz: |
| ... | @@ -4657,6 +4658,7 @@ static void define_builtin_fns(CodeGen *g) { | ... | @@ -4657,6 +4658,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4657 | create_builtin_fn_with_arg_count(g, BuiltinFnIdDivExact, "div_exact", 2); | 4658 | create_builtin_fn_with_arg_count(g, BuiltinFnIdDivExact, "div_exact", 2); |
| 4658 | create_builtin_fn_with_arg_count(g, BuiltinFnIdTruncate, "truncate", 2); | 4659 | create_builtin_fn_with_arg_count(g, BuiltinFnIdTruncate, "truncate", 2); |
| 4659 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compile_err", 1); | 4660 | create_builtin_fn_with_arg_count(g, BuiltinFnIdCompileErr, "compile_err", 1); |
| 4661 | create_builtin_fn_with_arg_count(g, BuiltinFnIdIntType, "int_type", 3); | ||
| 4660 | } | 4662 | } |
| 4661 | 4663 | ||
| 4662 | static void init(CodeGen *g, Buf *source_path) { | 4664 | static void init(CodeGen *g, Buf *source_path) { |
src/eval.cpp+1| ... | @@ -834,6 +834,7 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_ | ... | @@ -834,6 +834,7 @@ static bool eval_fn_call_builtin(EvalFn *ef, AstNode *node, ConstExprValue *out_ |
| 834 | case BuiltinFnIdFrameAddress: | 834 | case BuiltinFnIdFrameAddress: |
| 835 | case BuiltinFnIdReturnAddress: | 835 | case BuiltinFnIdReturnAddress: |
| 836 | case BuiltinFnIdCompileErr: | 836 | case BuiltinFnIdCompileErr: |
| 837 | case BuiltinFnIdIntType: | ||
| 837 | zig_unreachable(); | 838 | zig_unreachable(); |
| 838 | } | 839 | } |
| 839 | 840 |
test/self_hosted.zig+23| ... | @@ -1689,3 +1689,26 @@ struct DivResult { | ... | @@ -1689,3 +1689,26 @@ struct DivResult { |
| 1689 | quotient: u64, | 1689 | quotient: u64, |
| 1690 | remainder: u64, | 1690 | remainder: u64, |
| 1691 | } | 1691 | } |
| 1692 | |||
| 1693 | #attribute("test") | ||
| 1694 | fn int_type_builtin() { | ||
| 1695 | assert(@int_type(true, 8, false) == i8); | ||
| 1696 | assert(@int_type(true, 16, false) == i16); | ||
| 1697 | assert(@int_type(true, 32, false) == i32); | ||
| 1698 | assert(@int_type(true, 64, false) == i64); | ||
| 1699 | |||
| 1700 | assert(@int_type(false, 8, false) == u8); | ||
| 1701 | assert(@int_type(false, 16, false) == u16); | ||
| 1702 | assert(@int_type(false, 32, false) == u32); | ||
| 1703 | assert(@int_type(false, 64, false) == u64); | ||
| 1704 | |||
| 1705 | assert(@int_type(true, 8, true) == i8w); | ||
| 1706 | assert(@int_type(true, 16, true) == i16w); | ||
| 1707 | assert(@int_type(true, 32, true) == i32w); | ||
| 1708 | assert(@int_type(true, 64, true) == i64w); | ||
| 1709 | |||
| 1710 | assert(@int_type(false, 8, true) == u8w); | ||
| 1711 | assert(@int_type(false, 16, true) == u16w); | ||
| 1712 | assert(@int_type(false, 32, true) == u32w); | ||
| 1713 | assert(@int_type(false, 64, true) == u64w); | ||
| 1714 | } |