| author | |
| committer | |
| log | 623741171629055a22a35bb8278d81a81dcffbde |
| tree | da0cc10fd43c5d167edc59dc587dba1befbb08b4 |
| parent | 01f066de379caf545ec65c572f75cc1ed1312799 |
...of special syntax.
partially reverts 41144a8566a6fbd779403f6b69424bb640c94a7f
closes #3069 files changed, 56 insertions(+), 169 deletions(-)
doc/langref.md+3-6| ... | ... | @@ -79,7 +79,7 @@ SwitchProng = (list(SwitchItem, ",") | "else") "=>" option("|" option("*") Symbo |
| 79 | 79 | |
| 80 | 80 | SwitchItem = Expression | (Expression "..." Expression) |
| 81 | 81 | |
| 82 | ForExpression(body) = "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body)) | |
| 82 | ForExpression(body) = option("inline") "for" "(" Expression ")" option("|" option("*") Symbol option("," Symbol) "|") body option("else" BlockExpression(body)) | |
| 83 | 83 | |
| 84 | 84 | BoolOrExpression = BoolAndExpression "or" BoolOrExpression | BoolAndExpression |
| 85 | 85 | |
| ... | ... | @@ -95,7 +95,7 @@ TryExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") |
| 95 | 95 | |
| 96 | 96 | TestExpression(body) = "if" "(" Expression ")" option("|" option("*") Symbol "|") body option("else" BlockExpression(body)) |
| 97 | 97 | |
| 98 | WhileExpression(body) = "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body)) | |
| 98 | WhileExpression(body) = option("inline") "while" "(" Expression ")" option("|" option("*") Symbol "|") option(":" "(" Expression ")") body option("else" option("|" Symbol "|") BlockExpression(body)) | |
| 99 | 99 | |
| 100 | 100 | BoolAndExpression = ComparisonExpression "and" BoolAndExpression | ComparisonExpression |
| 101 | 101 | |
| ... | ... | @@ -125,9 +125,7 @@ MultiplyOperator = "*" | "/" | "%" | "**" | "*%" |
| 125 | 125 | |
| 126 | 126 | PrefixOpExpression = PrefixOp PrefixOpExpression | SuffixOpExpression |
| 127 | 127 | |
| 128 | SuffixOpExpression = InlineExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 129 | ||
| 130 | InlineExpression = option("inline") PrimaryExpression | |
| 128 | SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 131 | 129 | |
| 132 | 130 | FieldAccessExpression = "." Symbol |
| 133 | 131 | |
| ... | ... | @@ -161,7 +159,6 @@ ContainerDecl = option("extern" | "packed") ("struct" | "enum" | "union") "{" ma |
| 161 | 159 | ## Operator Precedence |
| 162 | 160 | |
| 163 | 161 | ``` |
| 164 | inline x | |
| 165 | 162 | x() x[] x.y |
| 166 | 163 | !x -x -%x ~x *x &x ?x %x %%x ??x |
| 167 | 164 | x{} |
src/all_types.hpp+1-15| ... | ... | @@ -175,7 +175,6 @@ struct ConstErrValue { |
| 175 | 175 | struct ConstBoundFnValue { |
| 176 | 176 | FnTableEntry *fn; |
| 177 | 177 | IrInstruction *first_arg; |
| 178 | bool is_inline; | |
| 179 | 178 | }; |
| 180 | 179 | |
| 181 | 180 | struct ConstArgTuple { |
| ... | ... | @@ -209,7 +208,6 @@ enum RuntimeHintPtr { |
| 209 | 208 | |
| 210 | 209 | struct ConstFn { |
| 211 | 210 | FnTableEntry *fn_entry; |
| 212 | bool is_inline; | |
| 213 | 211 | }; |
| 214 | 212 | |
| 215 | 213 | struct ConstExprValue { |
| ... | ... | @@ -379,7 +377,6 @@ enum NodeType { |
| 379 | 377 | NodeTypeVarLiteral, |
| 380 | 378 | NodeTypeTryExpr, |
| 381 | 379 | NodeTypeTestExpr, |
| 382 | NodeTypeInlineExpr, | |
| 383 | 380 | }; |
| 384 | 381 | |
| 385 | 382 | struct AstNodeRoot { |
| ... | ... | @@ -796,10 +793,6 @@ struct AstNodeErrorType { |
| 796 | 793 | struct AstNodeVarLiteral { |
| 797 | 794 | }; |
| 798 | 795 | |
| 799 | struct AstNodeInlineExpr { | |
| 800 | AstNode *body; | |
| 801 | }; | |
| 802 | ||
| 803 | 796 | struct AstNode { |
| 804 | 797 | enum NodeType type; |
| 805 | 798 | size_t line; |
| ... | ... | @@ -857,7 +850,6 @@ struct AstNode { |
| 857 | 850 | AstNodeArrayType array_type; |
| 858 | 851 | AstNodeErrorType error_type; |
| 859 | 852 | AstNodeVarLiteral var_literal; |
| 860 | AstNodeInlineExpr inline_expr; | |
| 861 | 853 | } data; |
| 862 | 854 | }; |
| 863 | 855 | |
| ... | ... | @@ -1214,6 +1206,7 @@ enum BuiltinFnId { |
| 1214 | 1206 | BuiltinFnIdEnumTagName, |
| 1215 | 1207 | BuiltinFnIdFieldParentPtr, |
| 1216 | 1208 | BuiltinFnIdOffsetOf, |
| 1209 | BuiltinFnIdInlineCall, | |
| 1217 | 1210 | }; |
| 1218 | 1211 | |
| 1219 | 1212 | struct BuiltinFnEntry { |
| ... | ... | @@ -1791,7 +1784,6 @@ enum IrInstructionId { |
| 1791 | 1784 | IrInstructionIdDeclRef, |
| 1792 | 1785 | IrInstructionIdPanic, |
| 1793 | 1786 | IrInstructionIdEnumTagName, |
| 1794 | IrInstructionIdSetFnRefInline, | |
| 1795 | 1787 | IrInstructionIdFieldParentPtr, |
| 1796 | 1788 | IrInstructionIdOffsetOf, |
| 1797 | 1789 | }; |
| ... | ... | @@ -2532,12 +2524,6 @@ struct IrInstructionEnumTagName { |
| 2532 | 2524 | IrInstruction *target; |
| 2533 | 2525 | }; |
| 2534 | 2526 | |
| 2535 | struct IrInstructionSetFnRefInline { | |
| 2536 | IrInstruction base; | |
| 2537 | ||
| 2538 | IrInstruction *fn_ref; | |
| 2539 | }; | |
| 2540 | ||
| 2541 | 2527 | struct IrInstructionFieldParentPtr { |
| 2542 | 2528 | IrInstruction base; |
| 2543 | 2529 |
src/analyze.cpp+4-9| ... | ... | @@ -2195,7 +2195,6 @@ void scan_decls(CodeGen *g, ScopeDecls *decls_scope, AstNode *node) { |
| 2195 | 2195 | case NodeTypeVarLiteral: |
| 2196 | 2196 | case NodeTypeTryExpr: |
| 2197 | 2197 | case NodeTypeTestExpr: |
| 2198 | case NodeTypeInlineExpr: | |
| 2199 | 2198 | zig_unreachable(); |
| 2200 | 2199 | } |
| 2201 | 2200 | } |
| ... | ... | @@ -3304,8 +3303,7 @@ static uint32_t hash_const_val(ConstExprValue *const_val) { |
| 3304 | 3303 | // TODO better hashing algorithm |
| 3305 | 3304 | return 31643936; |
| 3306 | 3305 | case TypeTableEntryIdFn: |
| 3307 | return hash_ptr(const_val->data.x_fn.fn_entry) + | |
| 3308 | (const_val->data.x_fn.is_inline ? 4133894920 : 3983484790); | |
| 3306 | return 4133894920 ^ hash_ptr(const_val->data.x_fn.fn_entry); | |
| 3309 | 3307 | case TypeTableEntryIdNamespace: |
| 3310 | 3308 | return hash_ptr(const_val->data.x_import); |
| 3311 | 3309 | case TypeTableEntryIdBlock: |
| ... | ... | @@ -3756,8 +3754,7 @@ bool const_values_equal(ConstExprValue *a, ConstExprValue *b) { |
| 3756 | 3754 | case TypeTableEntryIdPureError: |
| 3757 | 3755 | return a->data.x_pure_err == b->data.x_pure_err; |
| 3758 | 3756 | case TypeTableEntryIdFn: |
| 3759 | return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry && | |
| 3760 | a->data.x_fn.is_inline == b->data.x_fn.is_inline; | |
| 3757 | return a->data.x_fn.fn_entry == b->data.x_fn.fn_entry; | |
| 3761 | 3758 | case TypeTableEntryIdBool: |
| 3762 | 3759 | return a->data.x_bool == b->data.x_bool; |
| 3763 | 3760 | case TypeTableEntryIdInt: |
| ... | ... | @@ -3997,8 +3994,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 3997 | 3994 | case TypeTableEntryIdFn: |
| 3998 | 3995 | { |
| 3999 | 3996 | FnTableEntry *fn_entry = const_val->data.x_fn.fn_entry; |
| 4000 | const char *inline_str = const_val->data.x_fn.is_inline ? "inline " : ""; | |
| 4001 | buf_appendf(buf, "%s%s", inline_str, buf_ptr(&fn_entry->symbol_name)); | |
| 3997 | buf_appendf(buf, "%s", buf_ptr(&fn_entry->symbol_name)); | |
| 4002 | 3998 | return; |
| 4003 | 3999 | } |
| 4004 | 4000 | case TypeTableEntryIdBlock: |
| ... | ... | @@ -4080,8 +4076,7 @@ void render_const_value(CodeGen *g, Buf *buf, ConstExprValue *const_val) { |
| 4080 | 4076 | case TypeTableEntryIdBoundFn: |
| 4081 | 4077 | { |
| 4082 | 4078 | FnTableEntry *fn_entry = const_val->data.x_bound_fn.fn; |
| 4083 | const char *inline_str = const_val->data.x_bound_fn.is_inline ? "inline " : ""; | |
| 4084 | buf_appendf(buf, "(%sbound fn %s)", inline_str, buf_ptr(&fn_entry->symbol_name)); | |
| 4079 | buf_appendf(buf, "(bound fn %s)", buf_ptr(&fn_entry->symbol_name)); | |
| 4085 | 4080 | return; |
| 4086 | 4081 | } |
| 4087 | 4082 | case TypeTableEntryIdStruct: |
src/ast_render.cpp-8| ... | ... | @@ -236,8 +236,6 @@ static const char *node_type_str(NodeType node_type) { |
| 236 | 236 | return "TryExpr"; |
| 237 | 237 | case NodeTypeTestExpr: |
| 238 | 238 | return "TestExpr"; |
| 239 | case NodeTypeInlineExpr: | |
| 240 | return "InlineExpr"; | |
| 241 | 239 | } |
| 242 | 240 | zig_unreachable(); |
| 243 | 241 | } |
| ... | ... | @@ -927,12 +925,6 @@ static void render_node_extra(AstRender *ar, AstNode *node, bool grouped) { |
| 927 | 925 | render_node_ungrouped(ar, node->data.unwrap_err_expr.op2); |
| 928 | 926 | break; |
| 929 | 927 | } |
| 930 | case NodeTypeInlineExpr: | |
| 931 | { | |
| 932 | fprintf(ar->f, "inline "); | |
| 933 | render_node_grouped(ar, node->data.inline_expr.body); | |
| 934 | break; | |
| 935 | } | |
| 936 | 928 | case NodeTypeFnDecl: |
| 937 | 929 | case NodeTypeParamDecl: |
| 938 | 930 | case NodeTypeErrorValueDecl: |
src/codegen.cpp+7-1| ... | ... | @@ -3017,7 +3017,6 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, |
| 3017 | 3017 | case IrInstructionIdSetGlobalLinkage: |
| 3018 | 3018 | case IrInstructionIdDeclRef: |
| 3019 | 3019 | case IrInstructionIdSwitchVar: |
| 3020 | case IrInstructionIdSetFnRefInline: | |
| 3021 | 3020 | case IrInstructionIdOffsetOf: |
| 3022 | 3021 | zig_unreachable(); |
| 3023 | 3022 | case IrInstructionIdReturn: |
| ... | ... | @@ -3596,6 +3595,7 @@ static void render_const_val_global(CodeGen *g, ConstExprValue *const_val, const |
| 3596 | 3595 | } |
| 3597 | 3596 | |
| 3598 | 3597 | static void delete_unused_builtin_fns(CodeGen *g) { |
| 3598 | // TODO get rid of this function | |
| 3599 | 3599 | auto it = g->builtin_fn_table.entry_iterator(); |
| 3600 | 3600 | for (;;) { |
| 3601 | 3601 | auto *entry = it.next(); |
| ... | ... | @@ -4330,6 +4330,7 @@ static BuiltinFnEntry *create_builtin_fn(CodeGen *g, BuiltinFnId id, const char |
| 4330 | 4330 | |
| 4331 | 4331 | static void define_builtin_fns(CodeGen *g) { |
| 4332 | 4332 | { |
| 4333 | // TODO make lazy and get rid of delete_unused_builtin_fns | |
| 4333 | 4334 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdBreakpoint, "breakpoint", 0); |
| 4334 | 4335 | builtin_fn->ref_count = 1; |
| 4335 | 4336 | |
| ... | ... | @@ -4340,6 +4341,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4340 | 4341 | g->trap_fn_val = builtin_fn->fn_val; |
| 4341 | 4342 | } |
| 4342 | 4343 | { |
| 4344 | // TODO make lazy and get rid of delete_unused_builtin_fns | |
| 4343 | 4345 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdReturnAddress, |
| 4344 | 4346 | "returnAddress", 0); |
| 4345 | 4347 | TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); |
| ... | ... | @@ -4352,6 +4354,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4352 | 4354 | g->return_address_fn_val = builtin_fn->fn_val; |
| 4353 | 4355 | } |
| 4354 | 4356 | { |
| 4357 | // TODO make lazy and get rid of delete_unused_builtin_fns | |
| 4355 | 4358 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdFrameAddress, |
| 4356 | 4359 | "frameAddress", 0); |
| 4357 | 4360 | TypeTableEntry *return_type = get_pointer_to_type(g, g->builtin_types.entry_u8, true); |
| ... | ... | @@ -4364,6 +4367,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4364 | 4367 | g->frame_address_fn_val = builtin_fn->fn_val; |
| 4365 | 4368 | } |
| 4366 | 4369 | { |
| 4370 | // TODO make lazy and get rid of delete_unused_builtin_fns | |
| 4367 | 4371 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemcpy, "memcpy", 3); |
| 4368 | 4372 | builtin_fn->ref_count = 1; |
| 4369 | 4373 | |
| ... | ... | @@ -4382,6 +4386,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4382 | 4386 | g->memcpy_fn_val = builtin_fn->fn_val; |
| 4383 | 4387 | } |
| 4384 | 4388 | { |
| 4389 | // TODO make lazy and get rid of delete_unused_builtin_fns | |
| 4385 | 4390 | BuiltinFnEntry *builtin_fn = create_builtin_fn(g, BuiltinFnIdMemset, "memset", 3); |
| 4386 | 4391 | builtin_fn->ref_count = 1; |
| 4387 | 4392 | |
| ... | ... | @@ -4443,6 +4448,7 @@ static void define_builtin_fns(CodeGen *g) { |
| 4443 | 4448 | create_builtin_fn(g, BuiltinFnIdDivFloor, "divFloor", 2); |
| 4444 | 4449 | create_builtin_fn(g, BuiltinFnIdRem, "rem", 2); |
| 4445 | 4450 | create_builtin_fn(g, BuiltinFnIdMod, "mod", 2); |
| 4451 | create_builtin_fn(g, BuiltinFnIdInlineCall, "inlineCall", SIZE_MAX); | |
| 4446 | 4452 | } |
| 4447 | 4453 | |
| 4448 | 4454 | static const char *bool_to_str(bool b) { |
src/ir.cpp+28-82| ... | ... | @@ -553,10 +553,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionEnumTagName *) { |
| 553 | 553 | return IrInstructionIdEnumTagName; |
| 554 | 554 | } |
| 555 | 555 | |
| 556 | static constexpr IrInstructionId ir_instruction_id(IrInstructionSetFnRefInline *) { | |
| 557 | return IrInstructionIdSetFnRefInline; | |
| 558 | } | |
| 559 | ||
| 560 | 556 | static constexpr IrInstructionId ir_instruction_id(IrInstructionFieldParentPtr *) { |
| 561 | 557 | return IrInstructionIdFieldParentPtr; |
| 562 | 558 | } |
| ... | ... | @@ -2142,18 +2138,6 @@ static IrInstruction *ir_build_enum_tag_name(IrBuilder *irb, Scope *scope, AstNo |
| 2142 | 2138 | return &instruction->base; |
| 2143 | 2139 | } |
| 2144 | 2140 | |
| 2145 | static IrInstruction *ir_build_set_fn_ref_inline(IrBuilder *irb, Scope *scope, AstNode *source_node, | |
| 2146 | IrInstruction *fn_ref) | |
| 2147 | { | |
| 2148 | IrInstructionSetFnRefInline *instruction = ir_build_instruction<IrInstructionSetFnRefInline>( | |
| 2149 | irb, scope, source_node); | |
| 2150 | instruction->fn_ref = fn_ref; | |
| 2151 | ||
| 2152 | ir_ref_instruction(fn_ref, irb->current_basic_block); | |
| 2153 | ||
| 2154 | return &instruction->base; | |
| 2155 | } | |
| 2156 | ||
| 2157 | 2141 | static IrInstruction *ir_build_field_parent_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, |
| 2158 | 2142 | IrInstruction *type_value, IrInstruction *field_name, IrInstruction *field_ptr, TypeStructField *field) |
| 2159 | 2143 | { |
| ... | ... | @@ -2838,13 +2822,6 @@ static IrInstruction *ir_instruction_enumtagname_get_dep(IrInstructionEnumTagNam |
| 2838 | 2822 | } |
| 2839 | 2823 | } |
| 2840 | 2824 | |
| 2841 | static IrInstruction *ir_instruction_setfnrefinline_get_dep(IrInstructionSetFnRefInline *instruction, size_t index) { | |
| 2842 | switch (index) { | |
| 2843 | case 0: return instruction->fn_ref; | |
| 2844 | default: return nullptr; | |
| 2845 | } | |
| 2846 | } | |
| 2847 | ||
| 2848 | 2825 | static IrInstruction *ir_instruction_fieldparentptr_get_dep(IrInstructionFieldParentPtr *instruction, size_t index) { |
| 2849 | 2826 | switch (index) { |
| 2850 | 2827 | case 0: return instruction->type_value; |
| ... | ... | @@ -3048,8 +3025,6 @@ static IrInstruction *ir_instruction_get_dep(IrInstruction *instruction, size_t |
| 3048 | 3025 | return ir_instruction_panic_get_dep((IrInstructionPanic *) instruction, index); |
| 3049 | 3026 | case IrInstructionIdEnumTagName: |
| 3050 | 3027 | return ir_instruction_enumtagname_get_dep((IrInstructionEnumTagName *) instruction, index); |
| 3051 | case IrInstructionIdSetFnRefInline: | |
| 3052 | return ir_instruction_setfnrefinline_get_dep((IrInstructionSetFnRefInline *) instruction, index); | |
| 3053 | 3028 | case IrInstructionIdFieldParentPtr: |
| 3054 | 3029 | return ir_instruction_fieldparentptr_get_dep((IrInstructionFieldParentPtr *) instruction, index); |
| 3055 | 3030 | case IrInstructionIdOffsetOf: |
| ... | ... | @@ -4376,6 +4351,30 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo |
| 4376 | 4351 | |
| 4377 | 4352 | return ir_build_offset_of(irb, scope, node, arg0_value, arg1_value); |
| 4378 | 4353 | } |
| 4354 | case BuiltinFnIdInlineCall: | |
| 4355 | { | |
| 4356 | if (node->data.fn_call_expr.params.length == 0) { | |
| 4357 | add_node_error(irb->codegen, node, buf_sprintf("expected at least 1 argument, found 0")); | |
| 4358 | return irb->codegen->invalid_instruction; | |
| 4359 | } | |
| 4360 | ||
| 4361 | AstNode *fn_ref_node = node->data.fn_call_expr.params.at(0); | |
| 4362 | IrInstruction *fn_ref = ir_gen_node(irb, fn_ref_node, scope); | |
| 4363 | if (fn_ref == irb->codegen->invalid_instruction) | |
| 4364 | return fn_ref; | |
| 4365 | ||
| 4366 | size_t arg_count = node->data.fn_call_expr.params.length - 1; | |
| 4367 | ||
| 4368 | IrInstruction **args = allocate<IrInstruction*>(arg_count); | |
| 4369 | for (size_t i = 0; i < arg_count; i += 1) { | |
| 4370 | AstNode *arg_node = node->data.fn_call_expr.params.at(i + 1); | |
| 4371 | args[i] = ir_gen_node(irb, arg_node, scope); | |
| 4372 | if (args[i] == irb->codegen->invalid_instruction) | |
| 4373 | return args[i]; | |
| 4374 | } | |
| 4375 | ||
| 4376 | return ir_build_call(irb, scope, node, nullptr, fn_ref, arg_count, args, false, true); | |
| 4377 | } | |
| 4379 | 4378 | } |
| 4380 | 4379 | zig_unreachable(); |
| 4381 | 4380 | } |
| ... | ... | @@ -5800,19 +5799,6 @@ static IrInstruction *ir_gen_fn_proto(IrBuilder *irb, Scope *parent_scope, AstNo |
| 5800 | 5799 | return ir_build_fn_proto(irb, parent_scope, node, param_types, return_type); |
| 5801 | 5800 | } |
| 5802 | 5801 | |
| 5803 | static IrInstruction *ir_gen_inline_expr(IrBuilder *irb, Scope *parent_scope, AstNode *node) { | |
| 5804 | assert(node->type == NodeTypeInlineExpr); | |
| 5805 | ||
| 5806 | AstNode *body_node = node->data.inline_expr.body; | |
| 5807 | ||
| 5808 | IrInstruction *fn_ptr = ir_gen_node(irb, body_node, parent_scope); | |
| 5809 | if (fn_ptr == irb->codegen->invalid_instruction) | |
| 5810 | return irb->codegen->invalid_instruction; | |
| 5811 | ||
| 5812 | return ir_build_set_fn_ref_inline(irb, parent_scope, node, fn_ptr); | |
| 5813 | } | |
| 5814 | ||
| 5815 | ||
| 5816 | 5802 | static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scope, |
| 5817 | 5803 | LVal lval) |
| 5818 | 5804 | { |
| ... | ... | @@ -5903,8 +5889,6 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop |
| 5903 | 5889 | return ir_lval_wrap(irb, scope, ir_gen_container_decl(irb, scope, node), lval); |
| 5904 | 5890 | case NodeTypeFnProto: |
| 5905 | 5891 | return ir_lval_wrap(irb, scope, ir_gen_fn_proto(irb, scope, node), lval); |
| 5906 | case NodeTypeInlineExpr: | |
| 5907 | return ir_lval_wrap(irb, scope, ir_gen_inline_expr(irb, scope, node), lval); | |
| 5908 | 5892 | case NodeTypeFnDef: |
| 5909 | 5893 | zig_panic("TODO IR gen NodeTypeFnDef"); |
| 5910 | 5894 | case NodeTypeFnDecl: |
| ... | ... | @@ -6809,7 +6793,7 @@ static TypeTableEntry *ir_resolve_type(IrAnalyze *ira, IrInstruction *type_value |
| 6809 | 6793 | return const_val->data.x_type; |
| 6810 | 6794 | } |
| 6811 | 6795 | |
| 6812 | static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value, bool *is_inline) { | |
| 6796 | static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value) { | |
| 6813 | 6797 | if (fn_value == ira->codegen->invalid_instruction) |
| 6814 | 6798 | return nullptr; |
| 6815 | 6799 | |
| ... | ... | @@ -6826,7 +6810,6 @@ static FnTableEntry *ir_resolve_fn(IrAnalyze *ira, IrInstruction *fn_value, bool |
| 6826 | 6810 | if (!const_val) |
| 6827 | 6811 | return nullptr; |
| 6828 | 6812 | |
| 6829 | *is_inline = const_val->data.x_fn.is_inline; | |
| 6830 | 6813 | return const_val->data.x_fn.fn_entry; |
| 6831 | 6814 | } |
| 6832 | 6815 | |
| ... | ... | @@ -9179,17 +9162,15 @@ static TypeTableEntry *ir_analyze_instruction_call(IrAnalyze *ira, IrInstruction |
| 9179 | 9162 | ir_link_new_instruction(cast_instruction, &call_instruction->base); |
| 9180 | 9163 | return ir_finish_anal(ira, cast_instruction->value.type); |
| 9181 | 9164 | } else if (fn_ref->value.type->id == TypeTableEntryIdFn) { |
| 9182 | bool is_inline; | |
| 9183 | FnTableEntry *fn_table_entry = ir_resolve_fn(ira, fn_ref, &is_inline); | |
| 9165 | FnTableEntry *fn_table_entry = ir_resolve_fn(ira, fn_ref); | |
| 9184 | 9166 | return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, |
| 9185 | fn_ref, nullptr, is_comptime, is_inline); | |
| 9167 | fn_ref, nullptr, is_comptime, call_instruction->is_inline); | |
| 9186 | 9168 | } else if (fn_ref->value.type->id == TypeTableEntryIdBoundFn) { |
| 9187 | 9169 | assert(fn_ref->value.special == ConstValSpecialStatic); |
| 9188 | 9170 | FnTableEntry *fn_table_entry = fn_ref->value.data.x_bound_fn.fn; |
| 9189 | 9171 | IrInstruction *first_arg_ptr = fn_ref->value.data.x_bound_fn.first_arg; |
| 9190 | bool is_inline = fn_ref->value.data.x_bound_fn.is_inline; | |
| 9191 | 9172 | return ir_analyze_fn_call(ira, call_instruction, fn_table_entry, fn_table_entry->type_entry, |
| 9192 | nullptr, first_arg_ptr, is_comptime, is_inline); | |
| 9173 | nullptr, first_arg_ptr, is_comptime, call_instruction->is_inline); | |
| 9193 | 9174 | } else { |
| 9194 | 9175 | ir_add_error_node(ira, fn_ref->source_node, |
| 9195 | 9176 | buf_sprintf("type '%s' not a function", buf_ptr(&fn_ref->value.type->name))); |
| ... | ... | @@ -11736,38 +11717,6 @@ static TypeTableEntry *ir_analyze_instruction_enum_tag_name(IrAnalyze *ira, IrIn |
| 11736 | 11717 | return result->value.type; |
| 11737 | 11718 | } |
| 11738 | 11719 | |
| 11739 | static TypeTableEntry *ir_analyze_instruction_set_fn_ref_inline(IrAnalyze *ira, | |
| 11740 | IrInstructionSetFnRefInline *instruction) | |
| 11741 | { | |
| 11742 | IrInstruction *fn_ref = instruction->fn_ref->other; | |
| 11743 | if (type_is_invalid(fn_ref->value.type)) | |
| 11744 | return ira->codegen->builtin_types.entry_invalid; | |
| 11745 | ||
| 11746 | if (fn_ref->value.type->id == TypeTableEntryIdFn) { | |
| 11747 | ConstExprValue *fn_ref_val = ir_resolve_const(ira, fn_ref, UndefBad); | |
| 11748 | if (!fn_ref_val) | |
| 11749 | return ira->codegen->builtin_types.entry_invalid; | |
| 11750 | ||
| 11751 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | |
| 11752 | *out_val = *fn_ref_val; | |
| 11753 | out_val->data.x_fn.is_inline = true; | |
| 11754 | return out_val->type; | |
| 11755 | } else if (fn_ref->value.type->id == TypeTableEntryIdBoundFn) { | |
| 11756 | ConstExprValue *fn_ref_val = ir_resolve_const(ira, fn_ref, UndefBad); | |
| 11757 | if (!fn_ref_val) | |
| 11758 | return ira->codegen->builtin_types.entry_invalid; | |
| 11759 | ||
| 11760 | ConstExprValue *out_val = ir_build_const_from(ira, &instruction->base); | |
| 11761 | *out_val = *fn_ref_val; | |
| 11762 | out_val->data.x_bound_fn.is_inline = true; | |
| 11763 | return out_val->type; | |
| 11764 | } else { | |
| 11765 | ir_add_error(ira, &instruction->base, | |
| 11766 | buf_sprintf("expected function type, found '%s'", buf_ptr(&fn_ref->value.type->name))); | |
| 11767 | return ira->codegen->builtin_types.entry_invalid; | |
| 11768 | } | |
| 11769 | } | |
| 11770 | ||
| 11771 | 11720 | static TypeTableEntry *ir_analyze_instruction_field_parent_ptr(IrAnalyze *ira, |
| 11772 | 11721 | IrInstructionFieldParentPtr *instruction) |
| 11773 | 11722 | { |
| ... | ... | @@ -13403,8 +13352,6 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi |
| 13403 | 13352 | return ir_analyze_instruction_int_to_ptr(ira, (IrInstructionIntToPtr *)instruction); |
| 13404 | 13353 | case IrInstructionIdEnumTagName: |
| 13405 | 13354 | return ir_analyze_instruction_enum_tag_name(ira, (IrInstructionEnumTagName *)instruction); |
| 13406 | case IrInstructionIdSetFnRefInline: | |
| 13407 | return ir_analyze_instruction_set_fn_ref_inline(ira, (IrInstructionSetFnRefInline *)instruction); | |
| 13408 | 13355 | case IrInstructionIdFieldParentPtr: |
| 13409 | 13356 | return ir_analyze_instruction_field_parent_ptr(ira, (IrInstructionFieldParentPtr *)instruction); |
| 13410 | 13357 | case IrInstructionIdOffsetOf: |
| ... | ... | @@ -13585,7 +13532,6 @@ bool ir_has_side_effects(IrInstruction *instruction) { |
| 13585 | 13532 | case IrInstructionIdErrName: |
| 13586 | 13533 | case IrInstructionIdTypeName: |
| 13587 | 13534 | case IrInstructionIdEnumTagName: |
| 13588 | case IrInstructionIdSetFnRefInline: | |
| 13589 | 13535 | case IrInstructionIdFieldParentPtr: |
| 13590 | 13536 | case IrInstructionIdOffsetOf: |
| 13591 | 13537 | return false; |
src/ir_print.cpp-8| ... | ... | @@ -866,11 +866,6 @@ static void ir_print_panic(IrPrint *irp, IrInstructionPanic *instruction) { |
| 866 | 866 | fprintf(irp->f, ")"); |
| 867 | 867 | } |
| 868 | 868 | |
| 869 | static void ir_print_set_fn_ref_inline(IrPrint *irp, IrInstructionSetFnRefInline *instruction) { | |
| 870 | fprintf(irp->f, "inline "); | |
| 871 | ir_print_other_instruction(irp, instruction->fn_ref); | |
| 872 | } | |
| 873 | ||
| 874 | 869 | static void ir_print_field_parent_ptr(IrPrint *irp, IrInstructionFieldParentPtr *instruction) { |
| 875 | 870 | fprintf(irp->f, "@fieldParentPtr("); |
| 876 | 871 | ir_print_other_instruction(irp, instruction->type_value); |
| ... | ... | @@ -1167,9 +1162,6 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { |
| 1167 | 1162 | case IrInstructionIdPanic: |
| 1168 | 1163 | ir_print_panic(irp, (IrInstructionPanic *)instruction); |
| 1169 | 1164 | break; |
| 1170 | case IrInstructionIdSetFnRefInline: | |
| 1171 | ir_print_set_fn_ref_inline(irp, (IrInstructionSetFnRefInline *)instruction); | |
| 1172 | break; | |
| 1173 | 1165 | case IrInstructionIdFieldParentPtr: |
| 1174 | 1166 | ir_print_field_parent_ptr(irp, (IrInstructionFieldParentPtr *)instruction); |
| 1175 | 1167 | break; |
src/parser.cpp+12-39| ... | ... | @@ -850,32 +850,7 @@ static AstNode *ast_parse_curly_suffix_expr(ParseContext *pc, size_t *token_inde |
| 850 | 850 | } |
| 851 | 851 | |
| 852 | 852 | /* |
| 853 | InlineExpression = option("inline") PrimaryExpression | |
| 854 | */ | |
| 855 | static AstNode *ast_parse_inline_expr(ParseContext *pc, size_t *token_index, bool mandatory) { | |
| 856 | Token *token = &pc->tokens->at(*token_index); | |
| 857 | ||
| 858 | if (token->id == TokenIdKeywordInline) { | |
| 859 | *token_index += 1; | |
| 860 | AstNode *primary_expr_node = ast_parse_primary_expr(pc, token_index, true); | |
| 861 | if (primary_expr_node->type == NodeTypeWhileExpr) { | |
| 862 | primary_expr_node->data.while_expr.is_inline = true; | |
| 863 | return primary_expr_node; | |
| 864 | } else if (primary_expr_node->type == NodeTypeForExpr) { | |
| 865 | primary_expr_node->data.for_expr.is_inline = true; | |
| 866 | return primary_expr_node; | |
| 867 | } else { | |
| 868 | AstNode *node = ast_create_node(pc, NodeTypeInlineExpr, token); | |
| 869 | node->data.inline_expr.body = primary_expr_node; | |
| 870 | return node; | |
| 871 | } | |
| 872 | } else { | |
| 873 | return ast_parse_primary_expr(pc, token_index, mandatory); | |
| 874 | } | |
| 875 | } | |
| 876 | ||
| 877 | /* | |
| 878 | SuffixOpExpression = InlineExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 853 | SuffixOpExpression = PrimaryExpression option(FnCallExpression | ArrayAccessExpression | FieldAccessExpression | SliceExpression) | |
| 879 | 854 | FnCallExpression : token(LParen) list(Expression, token(Comma)) token(RParen) |
| 880 | 855 | ArrayAccessExpression : token(LBracket) Expression token(RBracket) |
| 881 | 856 | SliceExpression = "[" Expression "..." option(Expression) "]" |
| ... | ... | @@ -883,8 +858,8 @@ FieldAccessExpression : token(Dot) token(Symbol) |
| 883 | 858 | StructLiteralField : token(Dot) token(Symbol) token(Eq) Expression |
| 884 | 859 | */ |
| 885 | 860 | static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, bool mandatory) { |
| 886 | AstNode *inline_expr = ast_parse_inline_expr(pc, token_index, mandatory); | |
| 887 | if (!inline_expr) | |
| 861 | AstNode *primary_expr = ast_parse_primary_expr(pc, token_index, mandatory); | |
| 862 | if (!primary_expr) | |
| 888 | 863 | return nullptr; |
| 889 | 864 | |
| 890 | 865 | while (true) { |
| ... | ... | @@ -893,10 +868,10 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, |
| 893 | 868 | *token_index += 1; |
| 894 | 869 | |
| 895 | 870 | AstNode *node = ast_create_node(pc, NodeTypeFnCallExpr, first_token); |
| 896 | node->data.fn_call_expr.fn_ref_expr = inline_expr; | |
| 871 | node->data.fn_call_expr.fn_ref_expr = primary_expr; | |
| 897 | 872 | ast_parse_fn_call_param_list(pc, token_index, &node->data.fn_call_expr.params); |
| 898 | 873 | |
| 899 | inline_expr = node; | |
| 874 | primary_expr = node; | |
| 900 | 875 | } else if (first_token->id == TokenIdLBracket) { |
| 901 | 876 | *token_index += 1; |
| 902 | 877 | |
| ... | ... | @@ -908,21 +883,21 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, |
| 908 | 883 | *token_index += 1; |
| 909 | 884 | |
| 910 | 885 | AstNode *node = ast_create_node(pc, NodeTypeSliceExpr, first_token); |
| 911 | node->data.slice_expr.array_ref_expr = inline_expr; | |
| 886 | node->data.slice_expr.array_ref_expr = primary_expr; | |
| 912 | 887 | node->data.slice_expr.start = expr_node; |
| 913 | 888 | node->data.slice_expr.end = ast_parse_expression(pc, token_index, false); |
| 914 | 889 | |
| 915 | 890 | ast_eat_token(pc, token_index, TokenIdRBracket); |
| 916 | 891 | |
| 917 | inline_expr = node; | |
| 892 | primary_expr = node; | |
| 918 | 893 | } else if (ellipsis_or_r_bracket->id == TokenIdRBracket) { |
| 919 | 894 | *token_index += 1; |
| 920 | 895 | |
| 921 | 896 | AstNode *node = ast_create_node(pc, NodeTypeArrayAccessExpr, first_token); |
| 922 | node->data.array_access_expr.array_ref_expr = inline_expr; | |
| 897 | node->data.array_access_expr.array_ref_expr = primary_expr; | |
| 923 | 898 | node->data.array_access_expr.subscript = expr_node; |
| 924 | 899 | |
| 925 | inline_expr = node; | |
| 900 | primary_expr = node; | |
| 926 | 901 | } else { |
| 927 | 902 | ast_invalid_token_error(pc, first_token); |
| 928 | 903 | } |
| ... | ... | @@ -932,12 +907,12 @@ static AstNode *ast_parse_suffix_op_expr(ParseContext *pc, size_t *token_index, |
| 932 | 907 | Token *name_token = ast_eat_token(pc, token_index, TokenIdSymbol); |
| 933 | 908 | |
| 934 | 909 | AstNode *node = ast_create_node(pc, NodeTypeFieldAccessExpr, first_token); |
| 935 | node->data.field_access_expr.struct_expr = inline_expr; | |
| 910 | node->data.field_access_expr.struct_expr = primary_expr; | |
| 936 | 911 | node->data.field_access_expr.field_name = token_buf(name_token); |
| 937 | 912 | |
| 938 | inline_expr = node; | |
| 913 | primary_expr = node; | |
| 939 | 914 | } else { |
| 940 | return inline_expr; | |
| 915 | return primary_expr; | |
| 941 | 916 | } |
| 942 | 917 | } |
| 943 | 918 | } |
| ... | ... | @@ -2733,7 +2708,5 @@ void ast_visit_node_children(AstNode *node, void (*visit)(AstNode **, void *cont |
| 2733 | 2708 | case NodeTypeVarLiteral: |
| 2734 | 2709 | // none |
| 2735 | 2710 | break; |
| 2736 | case NodeTypeInlineExpr: | |
| 2737 | visit_field(&node->data.inline_expr.body, visit, context); | |
| 2738 | 2711 | } |
| 2739 | 2712 | } |
test/cases/fn.zig+1-1| ... | ... | @@ -90,7 +90,7 @@ fn fn4() -> u32 {8} |
| 90 | 90 | |
| 91 | 91 | |
| 92 | 92 | test "inline function call" { |
| 93 | assert((inline add(3, 9)) == 12); | |
| 93 | assert(@inlineCall(add, 3, 9) == 12); | |
| 94 | 94 | } |
| 95 | 95 | |
| 96 | 96 | fn add(a: i32, b: i32) -> i32 { a + b } |