| ... | @@ -55,7 +55,7 @@ pub const ResultLoc = union(enum) { | ... | @@ -55,7 +55,7 @@ pub const ResultLoc = union(enum) { |
| 55 | }; | 55 | }; |
| 56 | }; | 56 | }; |
| 57 | | 57 | |
| 58 | pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*zir.Inst { | 58 | pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) InnerError!*zir.Inst { |
| 59 | const type_src = scope.tree().token_locs[type_node.firstToken()].start; | 59 | const type_src = scope.tree().token_locs[type_node.firstToken()].start; |
| 60 | const type_type = try addZIRInstConst(mod, scope, type_src, .{ | 60 | const type_type = try addZIRInstConst(mod, scope, type_src, .{ |
| 61 | .ty = Type.initTag(.type), | 61 | .ty = Type.initTag(.type), |
| ... | @@ -65,134 +65,133 @@ pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*z | ... | @@ -65,134 +65,133 @@ pub fn typeExpr(mod: *Module, scope: *Scope, type_node: *ast.Node) InnerError!*z |
| 65 | return expr(mod, scope, type_rl, type_node); | 65 | return expr(mod, scope, type_rl, type_node); |
| 66 | } | 66 | } |
| 67 | | 67 | |
| 68 | fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst { | 68 | fn lvalExpr(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 69 | switch (node.tag) { | 69 | const tree = scope.tree(); |
| 70 | .Root => unreachable, | 70 | const node_tags = tree.nodes.items(.tag); |
| 71 | .Use => unreachable, | 71 | const main_tokens = tree.nodes.items(.main_token); |
| 72 | .TestDecl => unreachable, | 72 | switch (node_tags[node]) { |
| 73 | .DocComment => unreachable, | 73 | .root => unreachable, |
| 74 | .VarDecl => unreachable, | 74 | .@"usingnamespace" => unreachable, |
| 75 | .SwitchCase => unreachable, | 75 | .test_decl => unreachable, |
| 76 | .SwitchElse => unreachable, | 76 | .doc_comment => unreachable, |
| 77 | .Else => unreachable, | 77 | .var_decl => unreachable, |
| 78 | .Payload => unreachable, | 78 | .switch_case => unreachable, |
| 79 | .PointerPayload => unreachable, | 79 | .switch_else => unreachable, |
| 80 | .PointerIndexPayload => unreachable, | 80 | .container_field_init => unreachable, |
| 81 | .ErrorTag => unreachable, | 81 | .container_field_align => unreachable, |
| 82 | .FieldInitializer => unreachable, | 82 | .container_field => unreachable, |
| 83 | .ContainerField => unreachable, | 83 | |
| 84 | | 84 | .assign, |
| 85 | .Assign, | 85 | .assign_bit_and, |
| 86 | .AssignBitAnd, | 86 | .assign_bit_or, |
| 87 | .AssignBitOr, | 87 | .assign_bit_shift_left, |
| 88 | .AssignBitShiftLeft, | 88 | .assign_bit_shift_right, |
| 89 | .AssignBitShiftRight, | 89 | .assign_bit_xor, |
| 90 | .AssignBitXor, | 90 | .assign_div, |
| 91 | .AssignDiv, | 91 | .assign_sub, |
| 92 | .AssignSub, | 92 | .assign_sub_wrap, |
| 93 | .AssignSubWrap, | 93 | .assign_mod, |
| 94 | .AssignMod, | 94 | .assign_add, |
| 95 | .AssignAdd, | 95 | .assign_add_wrap, |
| 96 | .AssignAddWrap, | 96 | .assign_mul, |
| 97 | .AssignMul, | 97 | .assign_mul_wrap, |
| 98 | .AssignMulWrap, | 98 | .add, |
| 99 | .Add, | 99 | .add_wrap, |
| 100 | .AddWrap, | 100 | .sub, |
| 101 | .Sub, | 101 | .sub_wrap, |
| 102 | .SubWrap, | 102 | .mul, |
| 103 | .Mul, | 103 | .mul_wrap, |
| 104 | .MulWrap, | 104 | .div, |
| 105 | .Div, | 105 | .mod, |
| 106 | .Mod, | 106 | .bit_and, |
| 107 | .BitAnd, | 107 | .bit_or, |
| 108 | .BitOr, | 108 | .bit_shift_left, |
| 109 | .BitShiftLeft, | 109 | .bit_shift_right, |
| 110 | .BitShiftRight, | 110 | .bit_xor, |
| 111 | .BitXor, | 111 | .bang_equal, |
| 112 | .BangEqual, | 112 | .equal_equal, |
| 113 | .EqualEqual, | 113 | .greater_than, |
| 114 | .GreaterThan, | 114 | .greater_or_equal, |
| 115 | .GreaterOrEqual, | 115 | .less_than, |
| 116 | .LessThan, | 116 | .less_or_equal, |
| 117 | .LessOrEqual, | 117 | .array_cat, |
| 118 | .ArrayCat, | 118 | .array_mult, |
| 119 | .ArrayMult, | 119 | .bool_and, |
| 120 | .BoolAnd, | 120 | .bool_or, |
| 121 | .BoolOr, | 121 | .@"asm", |
| 122 | .Asm, | 122 | .string_literal, |
| 123 | .StringLiteral, | 123 | .integer_literal, |
| 124 | .IntegerLiteral, | 124 | .call, |
| 125 | .Call, | 125 | .@"unreachable", |
| 126 | .Unreachable, | 126 | .@"return", |
| 127 | .Return, | 127 | .@"if", |
| 128 | .If, | 128 | .@"while", |
| 129 | .While, | 129 | .bool_not, |
| 130 | .BoolNot, | 130 | .address_of, |
| 131 | .AddressOf, | 131 | .float_literal, |
| 132 | .FloatLiteral, | 132 | .undefined_literal, |
| 133 | .UndefinedLiteral, | 133 | .bool_literal, |
| 134 | .BoolLiteral, | 134 | .null_literal, |
| 135 | .NullLiteral, | 135 | .optional_type, |
| 136 | .OptionalType, | 136 | .block, |
| 137 | .Block, | 137 | .labeled_block, |
| 138 | .LabeledBlock, | 138 | .@"break", |
| 139 | .Break, | | |
| 140 | .PtrType, | 139 | .PtrType, |
| 141 | .ArrayType, | 140 | .array_type, |
| 142 | .ArrayTypeSentinel, | 141 | .array_type_sentinel, |
| 143 | .EnumLiteral, | 142 | .enum_literal, |
| 144 | .MultilineStringLiteral, | 143 | .MultilineStringLiteral, |
| 145 | .CharLiteral, | 144 | .char_literal, |
| 146 | .Defer, | 145 | .@"defer", |
| 147 | .Catch, | 146 | .@"catch", |
| 148 | .ErrorUnion, | 147 | .error_union, |
| 149 | .MergeErrorSets, | 148 | .merge_error_sets, |
| 150 | .Range, | 149 | .range, |
| 151 | .Await, | 150 | .@"await", |
| 152 | .BitNot, | 151 | .bit_not, |
| 153 | .Negation, | 152 | .negation, |
| 154 | .NegationWrap, | 153 | .negation_wrap, |
| 155 | .Resume, | 154 | .@"resume", |
| 156 | .Try, | 155 | .@"try", |
| 157 | .SliceType, | 156 | .slice_type, |
| 158 | .Slice, | 157 | .slice, |
| 159 | .ArrayInitializer, | 158 | .ArrayInitializer, |
| 160 | .ArrayInitializerDot, | 159 | .ArrayInitializerDot, |
| 161 | .StructInitializer, | 160 | .StructInitializer, |
| 162 | .StructInitializerDot, | 161 | .StructInitializerDot, |
| 163 | .Switch, | 162 | .@"switch", |
| 164 | .For, | 163 | .@"for", |
| 165 | .Suspend, | 164 | .@"suspend", |
| 166 | .Continue, | 165 | .@"continue", |
| 167 | .AnyType, | 166 | .@"anytype", |
| 168 | .ErrorType, | 167 | .error_type, |
| 169 | .FnProto, | 168 | .FnProto, |
| 170 | .AnyFrameType, | 169 | .anyframe_type, |
| 171 | .ErrorSetDecl, | 170 | .error_set_decl, |
| 172 | .ContainerDecl, | 171 | .ContainerDecl, |
| 173 | .Comptime, | 172 | .@"comptime", |
| 174 | .Nosuspend, | 173 | .@"nosuspend", |
| | 174 | .builtin_call, |
| | 175 | .builtin_call_comma, |
| 175 | => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}), | 176 | => return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}), |
| 176 | | 177 | |
| 177 | // @field can be assigned to | 178 | // `@field` can be assigned to. |
| 178 | .BuiltinCall => { | 179 | .builtin_call_two, .builtin_call_two_comma => { |
| 179 | const call = node.castTag(.BuiltinCall).?; | 180 | const builtin_token = main_tokens[node]; |
| 180 | const tree = scope.tree(); | 181 | const builtin_name = tree.tokenSlice(builtin_token); |
| 181 | const builtin_name = tree.tokenSlice(call.builtin_token); | | |
| 182 | | | |
| 183 | if (!mem.eql(u8, builtin_name, "@field")) { | 182 | if (!mem.eql(u8, builtin_name, "@field")) { |
| 184 | return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}); | 183 | return mod.failNode(scope, node, "invalid left-hand side to assignment", .{}); |
| 185 | } | 184 | } |
| 186 | }, | 185 | }, |
| 187 | | 186 | |
| 188 | // can be assigned to | 187 | // can be assigned to |
| 189 | .UnwrapOptional, | 188 | .unwrap_optional, |
| 190 | .Deref, | 189 | .deref, |
| 191 | .Period, | 190 | .period, |
| 192 | .ArrayAccess, | 191 | .array_access, |
| 193 | .Identifier, | 192 | .identifier, |
| 194 | .GroupedExpression, | 193 | .grouped_expression, |
| 195 | .OrElse, | 194 | .@"orelse", |
| 196 | => {}, | 195 | => {}, |
| 197 | } | 196 | } |
| 198 | return expr(mod, scope, .ref, node); | 197 | return expr(mod, scope, .ref, node); |
| ... | @@ -202,16 +201,16 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst { | ... | @@ -202,16 +201,16 @@ fn lvalExpr(mod: *Module, scope: *Scope, node: *ast.Node) InnerError!*zir.Inst { |
| 202 | /// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the | 201 | /// When `rl` is discard, ptr, inferred_ptr, bitcasted_ptr, or inferred_ptr, the |
| 203 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, | 202 | /// result instruction can be used to inspect whether it is isNoReturn() but that is it, |
| 204 | /// it must otherwise not be used. | 203 | /// it must otherwise not be used. |
| 205 | pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerError!*zir.Inst { | 204 | pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) InnerError!*zir.Inst { |
| 206 | switch (node.tag) { | 205 | switch (node.tag) { |
| 207 | .Root => unreachable, // Top-level declaration. | 206 | .root => unreachable, // Top-level declaration. |
| 208 | .Use => unreachable, // Top-level declaration. | 207 | .@"usingnamespace" => unreachable, // Top-level declaration. |
| 209 | .TestDecl => unreachable, // Top-level declaration. | 208 | .test_decl => unreachable, // Top-level declaration. |
| 210 | .DocComment => unreachable, // Top-level declaration. | 209 | .doc_comment => unreachable, // Top-level declaration. |
| 211 | .VarDecl => unreachable, // Handled in `blockExpr`. | 210 | .var_decl => unreachable, // Handled in `blockExpr`. |
| 212 | .SwitchCase => unreachable, // Handled in `switchExpr`. | 211 | .switch_case => unreachable, // Handled in `switchExpr`. |
| 213 | .SwitchElse => unreachable, // Handled in `switchExpr`. | 212 | .switch_else => unreachable, // Handled in `switchExpr`. |
| 214 | .Range => unreachable, // Handled in `switchExpr`. | 213 | .range => unreachable, // Handled in `switchExpr`. |
| 215 | .Else => unreachable, // Handled explicitly the control flow expression functions. | 214 | .Else => unreachable, // Handled explicitly the control flow expression functions. |
| 216 | .Payload => unreachable, // Handled explicitly. | 215 | .Payload => unreachable, // Handled explicitly. |
| 217 | .PointerPayload => unreachable, // Handled explicitly. | 216 | .PointerPayload => unreachable, // Handled explicitly. |
| ... | @@ -220,114 +219,113 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr | ... | @@ -220,114 +219,113 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node) InnerEr |
| 220 | .FieldInitializer => unreachable, // Handled explicitly. | 219 | .FieldInitializer => unreachable, // Handled explicitly. |
| 221 | .ContainerField => unreachable, // Handled explicitly. | 220 | .ContainerField => unreachable, // Handled explicitly. |
| 222 | | 221 | |
| 223 | .Assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node.castTag(.Assign).?)), | 222 | .assign => return rvalueVoid(mod, scope, rl, node, try assign(mod, scope, node)), |
| 224 | .AssignBitAnd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitAnd).?, .bit_and)), | 223 | .assign_bit_and => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_and)), |
| 225 | .AssignBitOr => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitOr).?, .bit_or)), | 224 | .assign_bit_or => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .bit_or)), |
| 226 | .AssignBitShiftLeft => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftLeft).?, .shl)), | 225 | .assign_bit_shift_left => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shl)), |
| 227 | .AssignBitShiftRight => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitShiftRight).?, .shr)), | 226 | .assign_bit_shift_right => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .shr)), |
| 228 | .AssignBitXor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignBitXor).?, .xor)), | 227 | .assign_bit_xor => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .xor)), |
| 229 | .AssignDiv => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignDiv).?, .div)), | 228 | .assign_div => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .div)), |
| 230 | .AssignSub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSub).?, .sub)), | 229 | .assign_sub => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .sub)), |
| 231 | .AssignSubWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignSubWrap).?, .subwrap)), | 230 | .assign_sub_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .subwrap)), |
| 232 | .AssignMod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMod).?, .mod_rem)), | 231 | .assign_mod => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mod_rem)), |
| 233 | .AssignAdd => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAdd).?, .add)), | 232 | .assign_add => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .add)), |
| 234 | .AssignAddWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignAddWrap).?, .addwrap)), | 233 | .assign_add_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .addwrap)), |
| 235 | .AssignMul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMul).?, .mul)), | 234 | .assign_mul => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mul)), |
| 236 | .AssignMulWrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node.castTag(.AssignMulWrap).?, .mulwrap)), | 235 | .assign_mul_wrap => return rvalueVoid(mod, scope, rl, node, try assignOp(mod, scope, node, .mulwrap)), |
| 237 | | 236 | |
| 238 | .Add => return simpleBinOp(mod, scope, rl, node.castTag(.Add).?, .add), | 237 | .add => return simpleBinOp(mod, scope, rl, node, .add), |
| 239 | .AddWrap => return simpleBinOp(mod, scope, rl, node.castTag(.AddWrap).?, .addwrap), | 238 | .add_wrap => return simpleBinOp(mod, scope, rl, node, .addwrap), |
| 240 | .Sub => return simpleBinOp(mod, scope, rl, node.castTag(.Sub).?, .sub), | 239 | .sub => return simpleBinOp(mod, scope, rl, node, .sub), |
| 241 | .SubWrap => return simpleBinOp(mod, scope, rl, node.castTag(.SubWrap).?, .subwrap), | 240 | .sub_wrap => return simpleBinOp(mod, scope, rl, node, .subwrap), |
| 242 | .Mul => return simpleBinOp(mod, scope, rl, node.castTag(.Mul).?, .mul), | 241 | .mul => return simpleBinOp(mod, scope, rl, node, .mul), |
| 243 | .MulWrap => return simpleBinOp(mod, scope, rl, node.castTag(.MulWrap).?, .mulwrap), | 242 | .mul_wrap => return simpleBinOp(mod, scope, rl, node, .mulwrap), |
| 244 | .Div => return simpleBinOp(mod, scope, rl, node.castTag(.Div).?, .div), | 243 | .div => return simpleBinOp(mod, scope, rl, node, .div), |
| 245 | .Mod => return simpleBinOp(mod, scope, rl, node.castTag(.Mod).?, .mod_rem), | 244 | .mod => return simpleBinOp(mod, scope, rl, node, .mod_rem), |
| 246 | .BitAnd => return simpleBinOp(mod, scope, rl, node.castTag(.BitAnd).?, .bit_and), | 245 | .bit_and => return simpleBinOp(mod, scope, rl, node, .bit_and), |
| 247 | .BitOr => return simpleBinOp(mod, scope, rl, node.castTag(.BitOr).?, .bit_or), | 246 | .bit_or => return simpleBinOp(mod, scope, rl, node, .bit_or), |
| 248 | .BitShiftLeft => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftLeft).?, .shl), | 247 | .bit_shift_left => return simpleBinOp(mod, scope, rl, node, .shl), |
| 249 | .BitShiftRight => return simpleBinOp(mod, scope, rl, node.castTag(.BitShiftRight).?, .shr), | 248 | .bit_shift_right => return simpleBinOp(mod, scope, rl, node, .shr), |
| 250 | .BitXor => return simpleBinOp(mod, scope, rl, node.castTag(.BitXor).?, .xor), | 249 | .bit_xor => return simpleBinOp(mod, scope, rl, node, .xor), |
| 251 | | 250 | |
| 252 | .BangEqual => return simpleBinOp(mod, scope, rl, node.castTag(.BangEqual).?, .cmp_neq), | 251 | .bang_equal => return simpleBinOp(mod, scope, rl, node, .cmp_neq), |
| 253 | .EqualEqual => return simpleBinOp(mod, scope, rl, node.castTag(.EqualEqual).?, .cmp_eq), | 252 | .equal_equal => return simpleBinOp(mod, scope, rl, node, .cmp_eq), |
| 254 | .GreaterThan => return simpleBinOp(mod, scope, rl, node.castTag(.GreaterThan).?, .cmp_gt), | 253 | .greater_than => return simpleBinOp(mod, scope, rl, node, .cmp_gt), |
| 255 | .GreaterOrEqual => return simpleBinOp(mod, scope, rl, node.castTag(.GreaterOrEqual).?, .cmp_gte), | 254 | .greater_or_equal => return simpleBinOp(mod, scope, rl, node, .cmp_gte), |
| 256 | .LessThan => return simpleBinOp(mod, scope, rl, node.castTag(.LessThan).?, .cmp_lt), | 255 | .less_than => return simpleBinOp(mod, scope, rl, node, .cmp_lt), |
| 257 | .LessOrEqual => return simpleBinOp(mod, scope, rl, node.castTag(.LessOrEqual).?, .cmp_lte), | 256 | .less_or_equal => return simpleBinOp(mod, scope, rl, node, .cmp_lte), |
| 258 | | 257 | |
| 259 | .ArrayCat => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayCat).?, .array_cat), | 258 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), |
| 260 | .ArrayMult => return simpleBinOp(mod, scope, rl, node.castTag(.ArrayMult).?, .array_mul), | 259 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), |
| 261 | | 260 | |
| 262 | .BoolAnd => return boolBinOp(mod, scope, rl, node.castTag(.BoolAnd).?), | 261 | .bool_and => return boolBinOp(mod, scope, rl, node), |
| 263 | .BoolOr => return boolBinOp(mod, scope, rl, node.castTag(.BoolOr).?), | 262 | .bool_or => return boolBinOp(mod, scope, rl, node), |
| 264 | | 263 | |
| 265 | .BoolNot => return rvalue(mod, scope, rl, try boolNot(mod, scope, node.castTag(.BoolNot).?)), | 264 | .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)), |
| 266 | .BitNot => return rvalue(mod, scope, rl, try bitNot(mod, scope, node.castTag(.BitNot).?)), | 265 | .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)), |
| 267 | .Negation => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.Negation).?, .sub)), | 266 | .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)), |
| 268 | .NegationWrap => return rvalue(mod, scope, rl, try negation(mod, scope, node.castTag(.NegationWrap).?, .subwrap)), | 267 | .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)), |
| 269 | | 268 | |
| 270 | .Identifier => return try identifier(mod, scope, rl, node.castTag(.Identifier).?), | 269 | .identifier => return try identifier(mod, scope, rl, node), |
| 271 | .Asm => return rvalue(mod, scope, rl, try assembly(mod, scope, node.castTag(.Asm).?)), | 270 | .@"asm" => return rvalue(mod, scope, rl, try assembly(mod, scope, node)), |
| 272 | .StringLiteral => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node.castTag(.StringLiteral).?)), | 271 | .string_literal => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node)), |
| 273 | .IntegerLiteral => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node.castTag(.IntegerLiteral).?)), | 272 | .integer_literal => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node)), |
| 274 | .BuiltinCall => return builtinCall(mod, scope, rl, node.castTag(.BuiltinCall).?), | 273 | .builtin_call => return builtinCall(mod, scope, rl, node), |
| 275 | .Call => return callExpr(mod, scope, rl, node.castTag(.Call).?), | 274 | .call => return callExpr(mod, scope, rl, node), |
| 276 | .Unreachable => return unreach(mod, scope, node.castTag(.Unreachable).?), | 275 | .@"unreachable" => return unreach(mod, scope, node), |
| 277 | .Return => return ret(mod, scope, node.castTag(.Return).?), | 276 | .@"return" => return ret(mod, scope, node), |
| 278 | .If => return ifExpr(mod, scope, rl, node.castTag(.If).?), | 277 | .@"if" => return ifExpr(mod, scope, rl, node), |
| 279 | .While => return whileExpr(mod, scope, rl, node.castTag(.While).?), | 278 | .@"while" => return whileExpr(mod, scope, rl, node), |
| 280 | .Period => return field(mod, scope, rl, node.castTag(.Period).?), | 279 | .period => return field(mod, scope, rl, node), |
| 281 | .Deref => return rvalue(mod, scope, rl, try deref(mod, scope, node.castTag(.Deref).?)), | 280 | .deref => return rvalue(mod, scope, rl, try deref(mod, scope, node)), |
| 282 | .AddressOf => return rvalue(mod, scope, rl, try addressOf(mod, scope, node.castTag(.AddressOf).?)), | 281 | .address_of => return rvalue(mod, scope, rl, try addressOf(mod, scope, node)), |
| 283 | .FloatLiteral => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node.castTag(.FloatLiteral).?)), | 282 | .float_literal => return rvalue(mod, scope, rl, try floatLiteral(mod, scope, node)), |
| 284 | .UndefinedLiteral => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node.castTag(.UndefinedLiteral).?)), | 283 | .undefined_literal => return rvalue(mod, scope, rl, try undefLiteral(mod, scope, node)), |
| 285 | .BoolLiteral => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node.castTag(.BoolLiteral).?)), | 284 | .bool_literal => return rvalue(mod, scope, rl, try boolLiteral(mod, scope, node)), |
| 286 | .NullLiteral => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node.castTag(.NullLiteral).?)), | 285 | .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)), |
| 287 | .OptionalType => return rvalue(mod, scope, rl, try optionalType(mod, scope, node.castTag(.OptionalType).?)), | 286 | .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)), |
| 288 | .UnwrapOptional => return unwrapOptional(mod, scope, rl, node.castTag(.UnwrapOptional).?), | 287 | .unwrap_optional => return unwrapOptional(mod, scope, rl, node), |
| 289 | .Block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node.castTag(.Block).?)), | 288 | .block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node)), |
| 290 | .LabeledBlock => return labeledBlockExpr(mod, scope, rl, node.castTag(.LabeledBlock).?, .block), | 289 | .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block), |
| 291 | .Break => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node.castTag(.Break).?)), | 290 | .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)), |
| 292 | .Continue => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node.castTag(.Continue).?)), | 291 | .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)), |
| 293 | .PtrType => return rvalue(mod, scope, rl, try ptrType(mod, scope, node.castTag(.PtrType).?)), | 292 | .grouped_expression => return expr(mod, scope, rl, node.expr), |
| 294 | .GroupedExpression => return expr(mod, scope, rl, node.castTag(.GroupedExpression).?.expr), | 293 | .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)), |
| 295 | .ArrayType => return rvalue(mod, scope, rl, try arrayType(mod, scope, node.castTag(.ArrayType).?)), | 294 | .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)), |
| 296 | .ArrayTypeSentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node.castTag(.ArrayTypeSentinel).?)), | 295 | .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)), |
| 297 | .EnumLiteral => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node.castTag(.EnumLiteral).?)), | 296 | .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node)), |
| 298 | .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node.castTag(.MultilineStringLiteral).?)), | 297 | .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)), |
| 299 | .CharLiteral => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node.castTag(.CharLiteral).?)), | 298 | .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)), |
| 300 | .SliceType => return rvalue(mod, scope, rl, try sliceType(mod, scope, node.castTag(.SliceType).?)), | 299 | .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)), |
| 301 | .ErrorUnion => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.ErrorUnion).?, .error_union_type)), | 300 | .merge_error_sets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .merge_error_sets)), |
| 302 | .MergeErrorSets => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node.castTag(.MergeErrorSets).?, .merge_error_sets)), | 301 | .anyframe_type => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node)), |
| 303 | .AnyFrameType => return rvalue(mod, scope, rl, try anyFrameType(mod, scope, node.castTag(.AnyFrameType).?)), | 302 | .error_set_decl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node)), |
| 304 | .ErrorSetDecl => return rvalue(mod, scope, rl, try errorSetDecl(mod, scope, node.castTag(.ErrorSetDecl).?)), | 303 | .error_type => return rvalue(mod, scope, rl, try errorType(mod, scope, node)), |
| 305 | .ErrorType => return rvalue(mod, scope, rl, try errorType(mod, scope, node.castTag(.ErrorType).?)), | 304 | .@"for" => return forExpr(mod, scope, rl, node), |
| 306 | .For => return forExpr(mod, scope, rl, node.castTag(.For).?), | 305 | .array_access => return arrayAccess(mod, scope, rl, node), |
| 307 | .ArrayAccess => return arrayAccess(mod, scope, rl, node.castTag(.ArrayAccess).?), | 306 | .slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node)), |
| 308 | .Slice => return rvalue(mod, scope, rl, try sliceExpr(mod, scope, node.castTag(.Slice).?)), | 307 | .@"catch" => return catchExpr(mod, scope, rl, node), |
| 309 | .Catch => return catchExpr(mod, scope, rl, node.castTag(.Catch).?), | 308 | .@"comptime" => return comptimeKeyword(mod, scope, rl, node), |
| 310 | .Comptime => return comptimeKeyword(mod, scope, rl, node.castTag(.Comptime).?), | 309 | .@"orelse" => return orelseExpr(mod, scope, rl, node), |
| 311 | .OrElse => return orelseExpr(mod, scope, rl, node.castTag(.OrElse).?), | 310 | .@"switch" => return switchExpr(mod, scope, rl, node), |
| 312 | .Switch => return switchExpr(mod, scope, rl, node.castTag(.Switch).?), | 311 | .ContainerDecl => return containerDecl(mod, scope, rl, node), |
| 313 | .ContainerDecl => return containerDecl(mod, scope, rl, node.castTag(.ContainerDecl).?), | 312 | |
| 314 | | 313 | .@"defer" => return mod.failNode(scope, node, "TODO implement astgen.expr for .defer", .{}), |
| 315 | .Defer => return mod.failNode(scope, node, "TODO implement astgen.expr for .Defer", .{}), | 314 | .@"await" => return mod.failNode(scope, node, "TODO implement astgen.expr for .await", .{}), |
| 316 | .Await => return mod.failNode(scope, node, "TODO implement astgen.expr for .Await", .{}), | 315 | .@"resume" => return mod.failNode(scope, node, "TODO implement astgen.expr for .resume", .{}), |
| 317 | .Resume => return mod.failNode(scope, node, "TODO implement astgen.expr for .Resume", .{}), | 316 | .@"try" => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}), |
| 318 | .Try => return mod.failNode(scope, node, "TODO implement astgen.expr for .Try", .{}), | | |
| 319 | .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}), | 317 | .ArrayInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializer", .{}), |
| 320 | .ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}), | 318 | .ArrayInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .ArrayInitializerDot", .{}), |
| 321 | .StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}), | 319 | .StructInitializer => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializer", .{}), |
| 322 | .StructInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializerDot", .{}), | 320 | .StructInitializerDot => return mod.failNode(scope, node, "TODO implement astgen.expr for .StructInitializerDot", .{}), |
| 323 | .Suspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Suspend", .{}), | 321 | .@"suspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .suspend", .{}), |
| 324 | .AnyType => return mod.failNode(scope, node, "TODO implement astgen.expr for .AnyType", .{}), | 322 | .@"anytype" => return mod.failNode(scope, node, "TODO implement astgen.expr for .anytype", .{}), |
| 325 | .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}), | 323 | .FnProto => return mod.failNode(scope, node, "TODO implement astgen.expr for .FnProto", .{}), |
| 326 | .Nosuspend => return mod.failNode(scope, node, "TODO implement astgen.expr for .Nosuspend", .{}), | 324 | .@"nosuspend" => return mod.failNode(scope, node, "TODO implement astgen.expr for .nosuspend", .{}), |
| 327 | } | 325 | } |
| 328 | } | 326 | } |
| 329 | | 327 | |
| 330 | fn comptimeKeyword(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Comptime) InnerError!*zir.Inst { | 328 | fn comptimeKeyword(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.@"comptime") InnerError!*zir.Inst { |
| 331 | const tracy = trace(@src()); | 329 | const tracy = trace(@src()); |
| 332 | defer tracy.end(); | 330 | defer tracy.end(); |
| 333 | | 331 | |
| ... | @@ -338,7 +336,7 @@ pub fn comptimeExpr( | ... | @@ -338,7 +336,7 @@ pub fn comptimeExpr( |
| 338 | mod: *Module, | 336 | mod: *Module, |
| 339 | parent_scope: *Scope, | 337 | parent_scope: *Scope, |
| 340 | rl: ResultLoc, | 338 | rl: ResultLoc, |
| 341 | node: *ast.Node, | 339 | node: ast.Node.Index, |
| 342 | ) InnerError!*zir.Inst { | 340 | ) InnerError!*zir.Inst { |
| 343 | // If we are already in a comptime scope, no need to make another one. | 341 | // If we are already in a comptime scope, no need to make another one. |
| 344 | if (parent_scope.isComptime()) { | 342 | if (parent_scope.isComptime()) { |
| ... | @@ -347,7 +345,7 @@ pub fn comptimeExpr( | ... | @@ -347,7 +345,7 @@ pub fn comptimeExpr( |
| 347 | | 345 | |
| 348 | // Optimization for labeled blocks: don't need to have 2 layers of blocks, | 346 | // Optimization for labeled blocks: don't need to have 2 layers of blocks, |
| 349 | // we can reuse the existing one. | 347 | // we can reuse the existing one. |
| 350 | if (node.castTag(.LabeledBlock)) |block_node| { | 348 | if (node.castTag(.labeled_block)) |block_node| { |
| 351 | return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime); | 349 | return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime); |
| 352 | } | 350 | } |
| 353 | | 351 | |
| ... | @@ -366,6 +364,8 @@ pub fn comptimeExpr( | ... | @@ -366,6 +364,8 @@ pub fn comptimeExpr( |
| 366 | _ = try expr(mod, &block_scope.base, rl, node); | 364 | _ = try expr(mod, &block_scope.base, rl, node); |
| 367 | | 365 | |
| 368 | const tree = parent_scope.tree(); | 366 | const tree = parent_scope.tree(); |
| | 367 | const node_datas = tree.nodes.items(.data); |
| | 368 | const main_tokens = tree.nodes.items(.main_token); |
| 369 | const src = tree.token_locs[node.firstToken()].start; | 369 | const src = tree.token_locs[node.firstToken()].start; |
| 370 | | 370 | |
| 371 | const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{ | 371 | const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{ |
| ... | @@ -381,6 +381,8 @@ fn breakExpr( | ... | @@ -381,6 +381,8 @@ fn breakExpr( |
| 381 | node: *ast.Node.ControlFlowExpression, | 381 | node: *ast.Node.ControlFlowExpression, |
| 382 | ) InnerError!*zir.Inst { | 382 | ) InnerError!*zir.Inst { |
| 383 | const tree = parent_scope.tree(); | 383 | const tree = parent_scope.tree(); |
| | 384 | const node_datas = tree.nodes.items(.data); |
| | 385 | const main_tokens = tree.nodes.items(.main_token); |
| 384 | const src = tree.token_locs[node.ltoken].start; | 386 | const src = tree.token_locs[node.ltoken].start; |
| 385 | | 387 | |
| 386 | // Look for the label in the scope. | 388 | // Look for the label in the scope. |
| ... | @@ -445,6 +447,8 @@ fn breakExpr( | ... | @@ -445,6 +447,8 @@ fn breakExpr( |
| 445 | | 447 | |
| 446 | fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst { | 448 | fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst { |
| 447 | const tree = parent_scope.tree(); | 449 | const tree = parent_scope.tree(); |
| | 450 | const node_datas = tree.nodes.items(.data); |
| | 451 | const main_tokens = tree.nodes.items(.main_token); |
| 448 | const src = tree.token_locs[node.ltoken].start; | 452 | const src = tree.token_locs[node.ltoken].start; |
| 449 | | 453 | |
| 450 | // Look for the label in the scope. | 454 | // Look for the label in the scope. |
| ... | @@ -485,7 +489,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE | ... | @@ -485,7 +489,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 485 | } | 489 | } |
| 486 | } | 490 | } |
| 487 | | 491 | |
| 488 | pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.Block) InnerError!void { | 492 | pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.block) InnerError!void { |
| 489 | const tracy = trace(@src()); | 493 | const tracy = trace(@src()); |
| 490 | defer tracy.end(); | 494 | defer tracy.end(); |
| 491 | | 495 | |
| ... | @@ -502,6 +506,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn | ... | @@ -502,6 +506,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn |
| 502 | if (gen_zir.label) |prev_label| { | 506 | if (gen_zir.label) |prev_label| { |
| 503 | if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) { | 507 | if (try tokenIdentEql(mod, parent_scope, label, prev_label.token)) { |
| 504 | const tree = parent_scope.tree(); | 508 | const tree = parent_scope.tree(); |
| | 509 | const node_datas = tree.nodes.items(.data); |
| | 510 | const main_tokens = tree.nodes.items(.main_token); |
| 505 | const label_src = tree.token_locs[label].start; | 511 | const label_src = tree.token_locs[label].start; |
| 506 | const prev_label_src = tree.token_locs[prev_label.token].start; | 512 | const prev_label_src = tree.token_locs[prev_label.token].start; |
| 507 | | 513 | |
| ... | @@ -539,7 +545,7 @@ fn labeledBlockExpr( | ... | @@ -539,7 +545,7 @@ fn labeledBlockExpr( |
| 539 | mod: *Module, | 545 | mod: *Module, |
| 540 | parent_scope: *Scope, | 546 | parent_scope: *Scope, |
| 541 | rl: ResultLoc, | 547 | rl: ResultLoc, |
| 542 | block_node: *ast.Node.LabeledBlock, | 548 | block_node: *ast.Node.labeled_block, |
| 543 | zir_tag: zir.Inst.Tag, | 549 | zir_tag: zir.Inst.Tag, |
| 544 | ) InnerError!*zir.Inst { | 550 | ) InnerError!*zir.Inst { |
| 545 | const tracy = trace(@src()); | 551 | const tracy = trace(@src()); |
| ... | @@ -548,6 +554,8 @@ fn labeledBlockExpr( | ... | @@ -548,6 +554,8 @@ fn labeledBlockExpr( |
| 548 | assert(zir_tag == .block or zir_tag == .block_comptime); | 554 | assert(zir_tag == .block or zir_tag == .block_comptime); |
| 549 | | 555 | |
| 550 | const tree = parent_scope.tree(); | 556 | const tree = parent_scope.tree(); |
| | 557 | const node_datas = tree.nodes.items(.data); |
| | 558 | const main_tokens = tree.nodes.items(.main_token); |
| 551 | const src = tree.token_locs[block_node.lbrace].start; | 559 | const src = tree.token_locs[block_node.lbrace].start; |
| 552 | | 560 | |
| 553 | try checkLabelRedefinition(mod, parent_scope, block_node.label); | 561 | try checkLabelRedefinition(mod, parent_scope, block_node.label); |
| ... | @@ -627,10 +635,12 @@ fn labeledBlockExpr( | ... | @@ -627,10 +635,12 @@ fn labeledBlockExpr( |
| 627 | fn blockExprStmts( | 635 | fn blockExprStmts( |
| 628 | mod: *Module, | 636 | mod: *Module, |
| 629 | parent_scope: *Scope, | 637 | parent_scope: *Scope, |
| 630 | node: *ast.Node, | 638 | node: ast.Node.Index, |
| 631 | statements: []*ast.Node, | 639 | statements: []const ast.Node.Index, |
| 632 | ) !void { | 640 | ) !void { |
| 633 | const tree = parent_scope.tree(); | 641 | const tree = parent_scope.tree(); |
| | 642 | const node_datas = tree.nodes.items(.data); |
| | 643 | const main_tokens = tree.nodes.items(.main_token); |
| 634 | | 644 | |
| 635 | var block_arena = std.heap.ArenaAllocator.init(mod.gpa); | 645 | var block_arena = std.heap.ArenaAllocator.init(mod.gpa); |
| 636 | defer block_arena.deinit(); | 646 | defer block_arena.deinit(); |
| ... | @@ -640,24 +650,24 @@ fn blockExprStmts( | ... | @@ -640,24 +650,24 @@ fn blockExprStmts( |
| 640 | const src = tree.token_locs[statement.firstToken()].start; | 650 | const src = tree.token_locs[statement.firstToken()].start; |
| 641 | _ = try addZIRNoOp(mod, scope, src, .dbg_stmt); | 651 | _ = try addZIRNoOp(mod, scope, src, .dbg_stmt); |
| 642 | switch (statement.tag) { | 652 | switch (statement.tag) { |
| 643 | .VarDecl => { | 653 | .var_decl => { |
| 644 | const var_decl_node = statement.castTag(.VarDecl).?; | 654 | const var_decl_node = statement.castTag(.var_decl).?; |
| 645 | scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator); | 655 | scope = try varDecl(mod, scope, var_decl_node, &block_arena.allocator); |
| 646 | }, | 656 | }, |
| 647 | .Assign => try assign(mod, scope, statement.castTag(.Assign).?), | 657 | .assign => try assign(mod, scope, statement), |
| 648 | .AssignBitAnd => try assignOp(mod, scope, statement.castTag(.AssignBitAnd).?, .bit_and), | 658 | .assign_bit_and => try assignOp(mod, scope, statement, .bit_and), |
| 649 | .AssignBitOr => try assignOp(mod, scope, statement.castTag(.AssignBitOr).?, .bit_or), | 659 | .assign_bit_or => try assignOp(mod, scope, statement, .bit_or), |
| 650 | .AssignBitShiftLeft => try assignOp(mod, scope, statement.castTag(.AssignBitShiftLeft).?, .shl), | 660 | .assign_bit_shift_left => try assignOp(mod, scope, statement, .shl), |
| 651 | .AssignBitShiftRight => try assignOp(mod, scope, statement.castTag(.AssignBitShiftRight).?, .shr), | 661 | .assign_bit_shift_right => try assignOp(mod, scope, statement, .shr), |
| 652 | .AssignBitXor => try assignOp(mod, scope, statement.castTag(.AssignBitXor).?, .xor), | 662 | .assign_bit_xor => try assignOp(mod, scope, statement, .xor), |
| 653 | .AssignDiv => try assignOp(mod, scope, statement.castTag(.AssignDiv).?, .div), | 663 | .assign_div => try assignOp(mod, scope, statement, .div), |
| 654 | .AssignSub => try assignOp(mod, scope, statement.castTag(.AssignSub).?, .sub), | 664 | .assign_sub => try assignOp(mod, scope, statement, .sub), |
| 655 | .AssignSubWrap => try assignOp(mod, scope, statement.castTag(.AssignSubWrap).?, .subwrap), | 665 | .assign_sub_wrap => try assignOp(mod, scope, statement, .subwrap), |
| 656 | .AssignMod => try assignOp(mod, scope, statement.castTag(.AssignMod).?, .mod_rem), | 666 | .assign_mod => try assignOp(mod, scope, statement, .mod_rem), |
| 657 | .AssignAdd => try assignOp(mod, scope, statement.castTag(.AssignAdd).?, .add), | 667 | .assign_add => try assignOp(mod, scope, statement, .add), |
| 658 | .AssignAddWrap => try assignOp(mod, scope, statement.castTag(.AssignAddWrap).?, .addwrap), | 668 | .assign_add_wrap => try assignOp(mod, scope, statement, .addwrap), |
| 659 | .AssignMul => try assignOp(mod, scope, statement.castTag(.AssignMul).?, .mul), | 669 | .assign_mul => try assignOp(mod, scope, statement, .mul), |
| 660 | .AssignMulWrap => try assignOp(mod, scope, statement.castTag(.AssignMulWrap).?, .mulwrap), | 670 | .assign_mul_wrap => try assignOp(mod, scope, statement, .mulwrap), |
| 661 | | 671 | |
| 662 | else => { | 672 | else => { |
| 663 | const possibly_unused_result = try expr(mod, scope, .none, statement); | 673 | const possibly_unused_result = try expr(mod, scope, .none, statement); |
| ... | @@ -672,7 +682,7 @@ fn blockExprStmts( | ... | @@ -672,7 +682,7 @@ fn blockExprStmts( |
| 672 | fn varDecl( | 682 | fn varDecl( |
| 673 | mod: *Module, | 683 | mod: *Module, |
| 674 | scope: *Scope, | 684 | scope: *Scope, |
| 675 | node: *ast.Node.VarDecl, | 685 | node: *ast.Node.var_decl, |
| 676 | block_arena: *Allocator, | 686 | block_arena: *Allocator, |
| 677 | ) InnerError!*Scope { | 687 | ) InnerError!*Scope { |
| 678 | if (node.getComptimeToken()) |comptime_token| { | 688 | if (node.getComptimeToken()) |comptime_token| { |
| ... | @@ -682,6 +692,8 @@ fn varDecl( | ... | @@ -682,6 +692,8 @@ fn varDecl( |
| 682 | return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{}); | 692 | return mod.failNode(scope, align_node, "TODO implement alignment on locals", .{}); |
| 683 | } | 693 | } |
| 684 | const tree = scope.tree(); | 694 | const tree = scope.tree(); |
| | 695 | const node_datas = tree.nodes.items(.data); |
| | 696 | const main_tokens = tree.nodes.items(.main_token); |
| 685 | const name_src = tree.token_locs[node.name_token].start; | 697 | const name_src = tree.token_locs[node.name_token].start; |
| 686 | const ident_name = try mod.identifierTokenString(scope, node.name_token); | 698 | const ident_name = try mod.identifierTokenString(scope, node.name_token); |
| 687 | | 699 | |
| ... | @@ -733,7 +745,7 @@ fn varDecl( | ... | @@ -733,7 +745,7 @@ fn varDecl( |
| 733 | return mod.fail(scope, name_src, "variables must be initialized", .{}); | 745 | return mod.fail(scope, name_src, "variables must be initialized", .{}); |
| 734 | | 746 | |
| 735 | switch (tree.token_ids[node.mut_token]) { | 747 | switch (tree.token_ids[node.mut_token]) { |
| 736 | .Keyword_const => { | 748 | .keyword_const => { |
| 737 | // Depending on the type of AST the initialization expression is, we may need an lvalue | 749 | // Depending on the type of AST the initialization expression is, we may need an lvalue |
| 738 | // or an rvalue as a result location. If it is an rvalue, we can use the instruction as | 750 | // or an rvalue as a result location. If it is an rvalue, we can use the instruction as |
| 739 | // the variable, no memory location needed. | 751 | // the variable, no memory location needed. |
| ... | @@ -834,7 +846,7 @@ fn varDecl( | ... | @@ -834,7 +846,7 @@ fn varDecl( |
| 834 | }; | 846 | }; |
| 835 | return &sub_scope.base; | 847 | return &sub_scope.base; |
| 836 | }, | 848 | }, |
| 837 | .Keyword_var => { | 849 | .keyword_var => { |
| 838 | var resolve_inferred_alloc: ?*zir.Inst = null; | 850 | var resolve_inferred_alloc: ?*zir.Inst = null; |
| 839 | const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: { | 851 | const var_data: struct { result_loc: ResultLoc, alloc: *zir.Inst } = if (node.getTypeNode()) |type_node| a: { |
| 840 | const type_inst = try typeExpr(mod, scope, type_node); | 852 | const type_inst = try typeExpr(mod, scope, type_node); |
| ... | @@ -862,33 +874,39 @@ fn varDecl( | ... | @@ -862,33 +874,39 @@ fn varDecl( |
| 862 | } | 874 | } |
| 863 | } | 875 | } |
| 864 | | 876 | |
| 865 | fn assign(mod: *Module, scope: *Scope, infix_node: *ast.Node.SimpleInfixOp) InnerError!void { | 877 | fn assign(mod: *Module, scope: *Scope, infix_node: ast.Node.Index) InnerError!void { |
| 866 | if (infix_node.lhs.castTag(.Identifier)) |ident| { | 878 | const tree = scope.tree(); |
| 867 | // This intentionally does not support @"_" syntax. | 879 | const node_datas = tree.nodes.items(.data); |
| 868 | const ident_name = scope.tree().tokenSlice(ident.token); | 880 | const main_tokens = tree.nodes.items(.main_token); |
| | 881 | const lhs = node_datas[infix_node].lhs; |
| | 882 | const rhs = node_datas[infix_node].rhs; |
| | 883 | if (node_tags[lhs] == .identifier) { |
| | 884 | // This intentionally does not support `@"_"` syntax. |
| | 885 | const ident_name = tree.tokenSlice(main_tokens[lhs]); |
| 869 | if (mem.eql(u8, ident_name, "_")) { | 886 | if (mem.eql(u8, ident_name, "_")) { |
| 870 | _ = try expr(mod, scope, .discard, infix_node.rhs); | 887 | _ = try expr(mod, scope, .discard, infix_node.rhs); |
| 871 | return; | 888 | return; |
| 872 | } | 889 | } |
| 873 | } | 890 | } |
| 874 | const lvalue = try lvalExpr(mod, scope, infix_node.lhs); | 891 | const lvalue = try lvalExpr(mod, scope, lhs); |
| 875 | _ = try expr(mod, scope, .{ .ptr = lvalue }, infix_node.rhs); | 892 | _ = try expr(mod, scope, .{ .ptr = lvalue }, rhs); |
| 876 | } | 893 | } |
| 877 | | 894 | |
| 878 | fn assignOp( | 895 | fn assignOp( |
| 879 | mod: *Module, | 896 | mod: *Module, |
| 880 | scope: *Scope, | 897 | scope: *Scope, |
| 881 | infix_node: *ast.Node.SimpleInfixOp, | 898 | infix_node: ast.Node.Index, |
| 882 | op_inst_tag: zir.Inst.Tag, | 899 | op_inst_tag: zir.Inst.Tag, |
| 883 | ) InnerError!void { | 900 | ) InnerError!void { |
| 884 | const lhs_ptr = try lvalExpr(mod, scope, infix_node.lhs); | | |
| 885 | const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr); | | |
| 886 | const lhs_type = try addZIRUnOp(mod, scope, lhs_ptr.src, .typeof, lhs); | | |
| 887 | const rhs = try expr(mod, scope, .{ .ty = lhs_type }, infix_node.rhs); | | |
| 888 | | | |
| 889 | const tree = scope.tree(); | 901 | const tree = scope.tree(); |
| 890 | const src = tree.token_locs[infix_node.op_token].start; | 902 | const node_datas = tree.nodes.items(.data); |
| | 903 | const main_tokens = tree.nodes.items(.main_token); |
| 891 | | 904 | |
| | 905 | const lhs_ptr = try lvalExpr(mod, scope, node_datas[infix_node].lhs); |
| | 906 | const lhs = try addZIRUnOp(mod, scope, lhs_ptr.src, .deref, lhs_ptr); |
| | 907 | const lhs_type = try addZIRUnOp(mod, scope, lhs_ptr.src, .typeof, lhs); |
| | 908 | const rhs = try expr(mod, scope, .{ .ty = lhs_type }, node_datas[infix_node].rhs); |
| | 909 | const src = token_starts[main_tokens[infix_node]]; |
| 892 | const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); | 910 | const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); |
| 893 | _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result); | 911 | _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result); |
| 894 | } | 912 | } |
| ... | @@ -935,7 +953,7 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn | ... | @@ -935,7 +953,7 @@ fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) Inn |
| 935 | return addZIRUnOp(mod, scope, src, .optional_type, operand); | 953 | return addZIRUnOp(mod, scope, src, .optional_type, operand); |
| 936 | } | 954 | } |
| 937 | | 955 | |
| 938 | fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.SliceType) InnerError!*zir.Inst { | 956 | fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst { |
| 939 | const tree = scope.tree(); | 957 | const tree = scope.tree(); |
| 940 | const src = tree.token_locs[node.op_token].start; | 958 | const src = tree.token_locs[node.op_token].start; |
| 941 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice); | 959 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice); |
| ... | @@ -948,7 +966,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir | ... | @@ -948,7 +966,7 @@ fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir |
| 948 | .Asterisk, .AsteriskAsterisk => .One, | 966 | .Asterisk, .AsteriskAsterisk => .One, |
| 949 | // TODO stage1 type inference bug | 967 | // TODO stage1 type inference bug |
| 950 | .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) { | 968 | .LBracket => @as(std.builtin.TypeInfo.Pointer.Size, switch (tree.token_ids[node.op_token + 2]) { |
| 951 | .Identifier => .C, | 969 | .identifier => .C, |
| 952 | else => .Many, | 970 | else => .Many, |
| 953 | }), | 971 | }), |
| 954 | else => unreachable, | 972 | else => unreachable, |
| ... | @@ -998,7 +1016,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, | ... | @@ -998,7 +1016,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, |
| 998 | return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args); | 1016 | return addZIRInst(mod, scope, src, zir.Inst.PtrType, .{ .child_type = child_type }, kw_args); |
| 999 | } | 1017 | } |
| 1000 | | 1018 | |
| 1001 | fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst { | 1019 | fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst { |
| 1002 | const tree = scope.tree(); | 1020 | const tree = scope.tree(); |
| 1003 | const src = tree.token_locs[node.op_token].start; | 1021 | const src = tree.token_locs[node.op_token].start; |
| 1004 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1022 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| ... | @@ -1013,7 +1031,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst | ... | @@ -1013,7 +1031,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.ArrayType) !*zir.Inst |
| 1013 | return addZIRBinOp(mod, scope, src, .array_type, len, elem_type); | 1031 | return addZIRBinOp(mod, scope, src, .array_type, len, elem_type); |
| 1014 | } | 1032 | } |
| 1015 | | 1033 | |
| 1016 | fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSentinel) !*zir.Inst { | 1034 | fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst { |
| 1017 | const tree = scope.tree(); | 1035 | const tree = scope.tree(); |
| 1018 | const src = tree.token_locs[node.op_token].start; | 1036 | const src = tree.token_locs[node.op_token].start; |
| 1019 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1037 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| ... | @@ -1034,7 +1052,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti | ... | @@ -1034,7 +1052,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.ArrayTypeSenti |
| 1034 | }, .{}); | 1052 | }, .{}); |
| 1035 | } | 1053 | } |
| 1036 | | 1054 | |
| 1037 | fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.AnyFrameType) InnerError!*zir.Inst { | 1055 | fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst { |
| 1038 | const tree = scope.tree(); | 1056 | const tree = scope.tree(); |
| 1039 | const src = tree.token_locs[node.anyframe_token].start; | 1057 | const src = tree.token_locs[node.anyframe_token].start; |
| 1040 | if (node.result) |some| { | 1058 | if (node.result) |some| { |
| ... | @@ -1056,7 +1074,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins | ... | @@ -1056,7 +1074,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins |
| 1056 | return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload); | 1074 | return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload); |
| 1057 | } | 1075 | } |
| 1058 | | 1076 | |
| 1059 | fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.EnumLiteral) !*zir.Inst { | 1077 | fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst { |
| 1060 | const tree = scope.tree(); | 1078 | const tree = scope.tree(); |
| 1061 | const src = tree.token_locs[node.name].start; | 1079 | const src = tree.token_locs[node.name].start; |
| 1062 | const name = try mod.identifierTokenString(scope, node.name); | 1080 | const name = try mod.identifierTokenString(scope, node.name); |
| ... | @@ -1141,13 +1159,13 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con | ... | @@ -1141,13 +1159,13 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1141 | | 1159 | |
| 1142 | var layout: std.builtin.TypeInfo.ContainerLayout = .Auto; | 1160 | var layout: std.builtin.TypeInfo.ContainerLayout = .Auto; |
| 1143 | if (node.layout_token) |some| switch (tree.token_ids[some]) { | 1161 | if (node.layout_token) |some| switch (tree.token_ids[some]) { |
| 1144 | .Keyword_extern => layout = .Extern, | 1162 | .keyword_extern => layout = .Extern, |
| 1145 | .Keyword_packed => layout = .Packed, | 1163 | .keyword_packed => layout = .Packed, |
| 1146 | else => unreachable, | 1164 | else => unreachable, |
| 1147 | }; | 1165 | }; |
| 1148 | | 1166 | |
| 1149 | const container_type = switch (tree.token_ids[node.kind_token]) { | 1167 | const container_type = switch (tree.token_ids[node.kind_token]) { |
| 1150 | .Keyword_enum => blk: { | 1168 | .keyword_enum => blk: { |
| 1151 | const tag_type: ?*zir.Inst = switch (node.init_arg_expr) { | 1169 | const tag_type: ?*zir.Inst = switch (node.init_arg_expr) { |
| 1152 | .Type => |t| try typeExpr(mod, &gen_scope.base, t), | 1170 | .Type => |t| try typeExpr(mod, &gen_scope.base, t), |
| 1153 | .None => null, | 1171 | .None => null, |
| ... | @@ -1174,7 +1192,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con | ... | @@ -1174,7 +1192,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1174 | }; | 1192 | }; |
| 1175 | break :blk Type.initPayload(&enum_type.base); | 1193 | break :blk Type.initPayload(&enum_type.base); |
| 1176 | }, | 1194 | }, |
| 1177 | .Keyword_struct => blk: { | 1195 | .keyword_struct => blk: { |
| 1178 | assert(node.init_arg_expr == .None); | 1196 | assert(node.init_arg_expr == .None); |
| 1179 | const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{ | 1197 | const inst = try addZIRInst(mod, &gen_scope.base, src, zir.Inst.StructType, .{ |
| 1180 | .fields = try arena.dupe(*zir.Inst, fields.items), | 1198 | .fields = try arena.dupe(*zir.Inst, fields.items), |
| ... | @@ -1196,7 +1214,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con | ... | @@ -1196,7 +1214,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1196 | }; | 1214 | }; |
| 1197 | break :blk Type.initPayload(&struct_type.base); | 1215 | break :blk Type.initPayload(&struct_type.base); |
| 1198 | }, | 1216 | }, |
| 1199 | .Keyword_union => blk: { | 1217 | .keyword_union => blk: { |
| 1200 | const init_inst = switch (node.init_arg_expr) { | 1218 | const init_inst = switch (node.init_arg_expr) { |
| 1201 | .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null, | 1219 | .Enum => |e| if (e) |t| try typeExpr(mod, &gen_scope.base, t) else null, |
| 1202 | .None => null, | 1220 | .None => null, |
| ... | @@ -1229,7 +1247,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con | ... | @@ -1229,7 +1247,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1229 | }; | 1247 | }; |
| 1230 | break :blk Type.initPayload(&union_type.base); | 1248 | break :blk Type.initPayload(&union_type.base); |
| 1231 | }, | 1249 | }, |
| 1232 | .Keyword_opaque => blk: { | 1250 | .keyword_opaque => blk: { |
| 1233 | if (fields.items.len > 0) { | 1251 | if (fields.items.len > 0) { |
| 1234 | return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{}); | 1252 | return mod.fail(scope, fields.items[0].src, "opaque types cannot have fields", .{}); |
| 1235 | } | 1253 | } |
| ... | @@ -1258,7 +1276,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con | ... | @@ -1258,7 +1276,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1258 | } | 1276 | } |
| 1259 | } | 1277 | } |
| 1260 | | 1278 | |
| 1261 | fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.ErrorSetDecl) InnerError!*zir.Inst { | 1279 | fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst { |
| 1262 | const tree = scope.tree(); | 1280 | const tree = scope.tree(); |
| 1263 | const src = tree.token_locs[node.error_token].start; | 1281 | const src = tree.token_locs[node.error_token].start; |
| 1264 | const decls = node.decls(); | 1282 | const decls = node.decls(); |
| ... | @@ -1281,7 +1299,7 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!* | ... | @@ -1281,7 +1299,7 @@ fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!* |
| 1281 | }); | 1299 | }); |
| 1282 | } | 1300 | } |
| 1283 | | 1301 | |
| 1284 | fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Catch) InnerError!*zir.Inst { | 1302 | fn catchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.@"catch") InnerError!*zir.Inst { |
| 1285 | switch (rl) { | 1303 | switch (rl) { |
| 1286 | .ref => return orelseCatchExpr( | 1304 | .ref => return orelseCatchExpr( |
| 1287 | mod, | 1305 | mod, |
| ... | @@ -1528,7 +1546,7 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleI | ... | @@ -1528,7 +1546,7 @@ pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleI |
| 1528 | const tree = scope.tree(); | 1546 | const tree = scope.tree(); |
| 1529 | const src = tree.token_locs[node.op_token].start; | 1547 | const src = tree.token_locs[node.op_token].start; |
| 1530 | // TODO custom AST node for field access so that we don't have to go through a node cast here | 1548 | // TODO custom AST node for field access so that we don't have to go through a node cast here |
| 1531 | const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.Identifier).?.token); | 1549 | const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token); |
| 1532 | if (rl == .ref) { | 1550 | if (rl == .ref) { |
| 1533 | return addZirInstTag(mod, scope, src, .field_ptr, .{ | 1551 | return addZirInstTag(mod, scope, src, .field_ptr, .{ |
| 1534 | .object = try expr(mod, scope, .ref, node.lhs), | 1552 | .object = try expr(mod, scope, .ref, node.lhs), |
| ... | @@ -1545,7 +1563,7 @@ fn namedField( | ... | @@ -1545,7 +1563,7 @@ fn namedField( |
| 1545 | mod: *Module, | 1563 | mod: *Module, |
| 1546 | scope: *Scope, | 1564 | scope: *Scope, |
| 1547 | rl: ResultLoc, | 1565 | rl: ResultLoc, |
| 1548 | call: *ast.Node.BuiltinCall, | 1566 | call: *ast.Node.builtin_call, |
| 1549 | ) InnerError!*zir.Inst { | 1567 | ) InnerError!*zir.Inst { |
| 1550 | try ensureBuiltinParamCount(mod, scope, call, 2); | 1568 | try ensureBuiltinParamCount(mod, scope, call, 2); |
| 1551 | | 1569 | |
| ... | @@ -1571,7 +1589,7 @@ fn namedField( | ... | @@ -1571,7 +1589,7 @@ fn namedField( |
| 1571 | })); | 1589 | })); |
| 1572 | } | 1590 | } |
| 1573 | | 1591 | |
| 1574 | fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ArrayAccess) InnerError!*zir.Inst { | 1592 | fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst { |
| 1575 | const tree = scope.tree(); | 1593 | const tree = scope.tree(); |
| 1576 | const src = tree.token_locs[node.rtoken].start; | 1594 | const src = tree.token_locs[node.rtoken].start; |
| 1577 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1595 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| ... | @@ -1592,7 +1610,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array | ... | @@ -1592,7 +1610,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Array |
| 1592 | })); | 1610 | })); |
| 1593 | } | 1611 | } |
| 1594 | | 1612 | |
| 1595 | fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.Slice) InnerError!*zir.Inst { | 1613 | fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst { |
| 1596 | const tree = scope.tree(); | 1614 | const tree = scope.tree(); |
| 1597 | const src = tree.token_locs[node.rtoken].start; | 1615 | const src = tree.token_locs[node.rtoken].start; |
| 1598 | | 1616 | |
| ... | @@ -1633,15 +1651,16 @@ fn simpleBinOp( | ... | @@ -1633,15 +1651,16 @@ fn simpleBinOp( |
| 1633 | mod: *Module, | 1651 | mod: *Module, |
| 1634 | scope: *Scope, | 1652 | scope: *Scope, |
| 1635 | rl: ResultLoc, | 1653 | rl: ResultLoc, |
| 1636 | infix_node: *ast.Node.SimpleInfixOp, | 1654 | infix_node: ast.Node.Index, |
| 1637 | op_inst_tag: zir.Inst.Tag, | 1655 | op_inst_tag: zir.Inst.Tag, |
| 1638 | ) InnerError!*zir.Inst { | 1656 | ) InnerError!*zir.Inst { |
| 1639 | const tree = scope.tree(); | 1657 | const tree = scope.tree(); |
| 1640 | const src = tree.token_locs[infix_node.op_token].start; | 1658 | const node_datas = tree.nodes.items(.data); |
| 1641 | | 1659 | const main_tokens = tree.nodes.items(.main_token); |
| 1642 | const lhs = try expr(mod, scope, .none, infix_node.lhs); | | |
| 1643 | const rhs = try expr(mod, scope, .none, infix_node.rhs); | | |
| 1644 | | 1660 | |
| | 1661 | const lhs = try expr(mod, scope, .none, node_datas[infix_node].lhs); |
| | 1662 | const rhs = try expr(mod, scope, .none, node_datas[infix_node].rhs); |
| | 1663 | const src = token_starts[main_tokens[infix_node]]; |
| 1645 | const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); | 1664 | const result = try addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); |
| 1646 | return rvalue(mod, scope, rl, result); | 1665 | return rvalue(mod, scope, rl, result); |
| 1647 | } | 1666 | } |
| ... | @@ -1653,6 +1672,9 @@ fn boolBinOp( | ... | @@ -1653,6 +1672,9 @@ fn boolBinOp( |
| 1653 | infix_node: *ast.Node.SimpleInfixOp, | 1672 | infix_node: *ast.Node.SimpleInfixOp, |
| 1654 | ) InnerError!*zir.Inst { | 1673 | ) InnerError!*zir.Inst { |
| 1655 | const tree = scope.tree(); | 1674 | const tree = scope.tree(); |
| | 1675 | const node_datas = tree.nodes.items(.data); |
| | 1676 | const main_tokens = tree.nodes.items(.main_token); |
| | 1677 | |
| 1656 | const src = tree.token_locs[infix_node.op_token].start; | 1678 | const src = tree.token_locs[infix_node.op_token].start; |
| 1657 | const bool_type = try addZIRInstConst(mod, scope, src, .{ | 1679 | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| 1658 | .ty = Type.initTag(.type), | 1680 | .ty = Type.initTag(.type), |
| ... | @@ -1703,7 +1725,7 @@ fn boolBinOp( | ... | @@ -1703,7 +1725,7 @@ fn boolBinOp( |
| 1703 | }; | 1725 | }; |
| 1704 | defer const_scope.instructions.deinit(mod.gpa); | 1726 | defer const_scope.instructions.deinit(mod.gpa); |
| 1705 | | 1727 | |
| 1706 | const is_bool_and = infix_node.base.tag == .BoolAnd; | 1728 | const is_bool_and = infix_node.base.tag == .bool_and; |
| 1707 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ | 1729 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ |
| 1708 | .block = block, | 1730 | .block = block, |
| 1709 | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ | 1731 | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ |
| ... | @@ -1769,7 +1791,7 @@ const CondKind = union(enum) { | ... | @@ -1769,7 +1791,7 @@ const CondKind = union(enum) { |
| 1769 | return &then_scope.base; | 1791 | return &then_scope.base; |
| 1770 | }; | 1792 | }; |
| 1771 | const is_ptr = payload.ptr_token != null; | 1793 | const is_ptr = payload.ptr_token != null; |
| 1772 | const ident_node = payload.value_symbol.castTag(.Identifier).?; | 1794 | const ident_node = payload.value_symbol.castTag(.identifier).?; |
| 1773 | | 1795 | |
| 1774 | // This intentionally does not support @"_" syntax. | 1796 | // This intentionally does not support @"_" syntax. |
| 1775 | const ident_name = then_scope.base.tree().tokenSlice(ident_node.token); | 1797 | const ident_name = then_scope.base.tree().tokenSlice(ident_node.token); |
| ... | @@ -1788,7 +1810,7 @@ const CondKind = union(enum) { | ... | @@ -1788,7 +1810,7 @@ const CondKind = union(enum) { |
| 1788 | const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .err_union_payload_unsafe_ptr, self.err_union.?); | 1810 | const payload_ptr = try addZIRUnOp(mod, &else_scope.base, src, .err_union_payload_unsafe_ptr, self.err_union.?); |
| 1789 | | 1811 | |
| 1790 | const payload = payload_node.?.castTag(.Payload).?; | 1812 | const payload = payload_node.?.castTag(.Payload).?; |
| 1791 | const ident_node = payload.error_symbol.castTag(.Identifier).?; | 1813 | const ident_node = payload.error_symbol.castTag(.identifier).?; |
| 1792 | | 1814 | |
| 1793 | // This intentionally does not support @"_" syntax. | 1815 | // This intentionally does not support @"_" syntax. |
| 1794 | const ident_name = else_scope.base.tree().tokenSlice(ident_node.token); | 1816 | const ident_name = else_scope.base.tree().tokenSlice(ident_node.token); |
| ... | @@ -1800,7 +1822,7 @@ const CondKind = union(enum) { | ... | @@ -1800,7 +1822,7 @@ const CondKind = union(enum) { |
| 1800 | } | 1822 | } |
| 1801 | }; | 1823 | }; |
| 1802 | | 1824 | |
| 1803 | fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) InnerError!*zir.Inst { | 1825 | fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") InnerError!*zir.Inst { |
| 1804 | var cond_kind: CondKind = .bool; | 1826 | var cond_kind: CondKind = .bool; |
| 1805 | if (if_node.payload) |_| cond_kind = .{ .optional = null }; | 1827 | if (if_node.payload) |_| cond_kind = .{ .optional = null }; |
| 1806 | if (if_node.@"else") |else_node| { | 1828 | if (if_node.@"else") |else_node| { |
| ... | @@ -1819,6 +1841,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn | ... | @@ -1819,6 +1841,8 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.If) Inn |
| 1819 | defer block_scope.instructions.deinit(mod.gpa); | 1841 | defer block_scope.instructions.deinit(mod.gpa); |
| 1820 | | 1842 | |
| 1821 | const tree = scope.tree(); | 1843 | const tree = scope.tree(); |
| | 1844 | const node_datas = tree.nodes.items(.data); |
| | 1845 | const main_tokens = tree.nodes.items(.main_token); |
| 1822 | const if_src = tree.token_locs[if_node.if_token].start; | 1846 | const if_src = tree.token_locs[if_node.if_token].start; |
| 1823 | const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition); | 1847 | const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition); |
| 1824 | | 1848 | |
| ... | @@ -1918,7 +1942,7 @@ fn whileExpr( | ... | @@ -1918,7 +1942,7 @@ fn whileExpr( |
| 1918 | mod: *Module, | 1942 | mod: *Module, |
| 1919 | scope: *Scope, | 1943 | scope: *Scope, |
| 1920 | rl: ResultLoc, | 1944 | rl: ResultLoc, |
| 1921 | while_node: *ast.Node.While, | 1945 | while_node: *ast.Node.@"while", |
| 1922 | ) InnerError!*zir.Inst { | 1946 | ) InnerError!*zir.Inst { |
| 1923 | var cond_kind: CondKind = .bool; | 1947 | var cond_kind: CondKind = .bool; |
| 1924 | if (while_node.payload) |_| cond_kind = .{ .optional = null }; | 1948 | if (while_node.payload) |_| cond_kind = .{ .optional = null }; |
| ... | @@ -1955,6 +1979,8 @@ fn whileExpr( | ... | @@ -1955,6 +1979,8 @@ fn whileExpr( |
| 1955 | defer continue_scope.instructions.deinit(mod.gpa); | 1979 | defer continue_scope.instructions.deinit(mod.gpa); |
| 1956 | | 1980 | |
| 1957 | const tree = scope.tree(); | 1981 | const tree = scope.tree(); |
| | 1982 | const node_datas = tree.nodes.items(.data); |
| | 1983 | const main_tokens = tree.nodes.items(.main_token); |
| 1958 | const while_src = tree.token_locs[while_node.while_token].start; | 1984 | const while_src = tree.token_locs[while_node.while_token].start; |
| 1959 | const void_type = try addZIRInstConst(mod, scope, while_src, .{ | 1985 | const void_type = try addZIRInstConst(mod, scope, while_src, .{ |
| 1960 | .ty = Type.initTag(.type), | 1986 | .ty = Type.initTag(.type), |
| ... | @@ -2066,7 +2092,7 @@ fn forExpr( | ... | @@ -2066,7 +2092,7 @@ fn forExpr( |
| 2066 | mod: *Module, | 2092 | mod: *Module, |
| 2067 | scope: *Scope, | 2093 | scope: *Scope, |
| 2068 | rl: ResultLoc, | 2094 | rl: ResultLoc, |
| 2069 | for_node: *ast.Node.For, | 2095 | for_node: *ast.Node.@"for", |
| 2070 | ) InnerError!*zir.Inst { | 2096 | ) InnerError!*zir.Inst { |
| 2071 | if (for_node.label) |label| { | 2097 | if (for_node.label) |label| { |
| 2072 | try checkLabelRedefinition(mod, scope, label); | 2098 | try checkLabelRedefinition(mod, scope, label); |
| ... | @@ -2077,6 +2103,8 @@ fn forExpr( | ... | @@ -2077,6 +2103,8 @@ fn forExpr( |
| 2077 | | 2103 | |
| 2078 | // setup variables and constants | 2104 | // setup variables and constants |
| 2079 | const tree = scope.tree(); | 2105 | const tree = scope.tree(); |
| | 2106 | const node_datas = tree.nodes.items(.data); |
| | 2107 | const main_tokens = tree.nodes.items(.main_token); |
| 2080 | const for_src = tree.token_locs[for_node.for_token].start; | 2108 | const for_src = tree.token_locs[for_node.for_token].start; |
| 2081 | const index_ptr = blk: { | 2109 | const index_ptr = blk: { |
| 2082 | const usize_type = try addZIRInstConst(mod, scope, for_src, .{ | 2110 | const usize_type = try addZIRInstConst(mod, scope, for_src, .{ |
| ... | @@ -2246,9 +2274,9 @@ fn forExpr( | ... | @@ -2246,9 +2274,9 @@ fn forExpr( |
| 2246 | ); | 2274 | ); |
| 2247 | } | 2275 | } |
| 2248 | | 2276 | |
| 2249 | fn switchCaseUsesRef(node: *ast.Node.Switch) bool { | 2277 | fn switchCaseUsesRef(node: *ast.Node.@"switch") bool { |
| 2250 | for (node.cases()) |uncasted_case| { | 2278 | for (node.cases()) |uncasted_case| { |
| 2251 | const case = uncasted_case.castTag(.SwitchCase).?; | 2279 | const case = uncasted_case.castTag(.switch_case).?; |
| 2252 | const uncasted_payload = case.payload orelse continue; | 2280 | const uncasted_payload = case.payload orelse continue; |
| 2253 | const payload = uncasted_payload.castTag(.PointerPayload).?; | 2281 | const payload = uncasted_payload.castTag(.PointerPayload).?; |
| 2254 | if (payload.ptr_token) |_| return true; | 2282 | if (payload.ptr_token) |_| return true; |
| ... | @@ -2260,15 +2288,17 @@ fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp { | ... | @@ -2260,15 +2288,17 @@ fn getRangeNode(node: *ast.Node) ?*ast.Node.SimpleInfixOp { |
| 2260 | var cur = node; | 2288 | var cur = node; |
| 2261 | while (true) { | 2289 | while (true) { |
| 2262 | switch (cur.tag) { | 2290 | switch (cur.tag) { |
| 2263 | .Range => return @fieldParentPtr(ast.Node.SimpleInfixOp, "base", cur), | 2291 | .range => return @fieldParentPtr(ast.Node.SimpleInfixOp, "base", cur), |
| 2264 | .GroupedExpression => cur = @fieldParentPtr(ast.Node.GroupedExpression, "base", cur).expr, | 2292 | .grouped_expression => cur = @fieldParentPtr(ast.Node.grouped_expression, "base", cur).expr, |
| 2265 | else => return null, | 2293 | else => return null, |
| 2266 | } | 2294 | } |
| 2267 | } | 2295 | } |
| 2268 | } | 2296 | } |
| 2269 | | 2297 | |
| 2270 | fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node.Switch) InnerError!*zir.Inst { | 2298 | fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node.@"switch") InnerError!*zir.Inst { |
| 2271 | const tree = scope.tree(); | 2299 | const tree = scope.tree(); |
| | 2300 | const node_datas = tree.nodes.items(.data); |
| | 2301 | const main_tokens = tree.nodes.items(.main_token); |
| 2272 | const switch_src = tree.token_locs[switch_node.switch_token].start; | 2302 | const switch_src = tree.token_locs[switch_node.switch_token].start; |
| 2273 | const use_ref = switchCaseUsesRef(switch_node); | 2303 | const use_ref = switchCaseUsesRef(switch_node); |
| 2274 | | 2304 | |
| ... | @@ -2291,12 +2321,12 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2291,12 +2321,12 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2291 | var first_range: ?*zir.Inst = null; | 2321 | var first_range: ?*zir.Inst = null; |
| 2292 | var simple_case_count: usize = 0; | 2322 | var simple_case_count: usize = 0; |
| 2293 | for (switch_node.cases()) |uncasted_case| { | 2323 | for (switch_node.cases()) |uncasted_case| { |
| 2294 | const case = uncasted_case.castTag(.SwitchCase).?; | 2324 | const case = uncasted_case.castTag(.switch_case).?; |
| 2295 | const case_src = tree.token_locs[case.firstToken()].start; | 2325 | const case_src = tree.token_locs[case.firstToken()].start; |
| 2296 | assert(case.items_len != 0); | 2326 | assert(case.items_len != 0); |
| 2297 | | 2327 | |
| 2298 | // Check for else/_ prong, those are handled last. | 2328 | // Check for else/_ prong, those are handled last. |
| 2299 | if (case.items_len == 1 and case.items()[0].tag == .SwitchElse) { | 2329 | if (case.items_len == 1 and case.items()[0].tag == .switch_else) { |
| 2300 | if (else_src) |src| { | 2330 | if (else_src) |src| { |
| 2301 | const msg = msg: { | 2331 | const msg = msg: { |
| 2302 | const msg = try mod.errMsg( | 2332 | const msg = try mod.errMsg( |
| ... | @@ -2313,7 +2343,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2313,7 +2343,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2313 | } | 2343 | } |
| 2314 | else_src = case_src; | 2344 | else_src = case_src; |
| 2315 | continue; | 2345 | continue; |
| 2316 | } else if (case.items_len == 1 and case.items()[0].tag == .Identifier and | 2346 | } else if (case.items_len == 1 and case.items()[0].tag == .identifier and |
| 2317 | mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_")) | 2347 | mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_")) |
| 2318 | { | 2348 | { |
| 2319 | if (underscore_src) |src| { | 2349 | if (underscore_src) |src| { |
| ... | @@ -2412,20 +2442,20 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2412,20 +2442,20 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2412 | defer else_scope.instructions.deinit(mod.gpa); | 2442 | defer else_scope.instructions.deinit(mod.gpa); |
| 2413 | | 2443 | |
| 2414 | // Now generate all but the special cases | 2444 | // Now generate all but the special cases |
| 2415 | var special_case: ?*ast.Node.SwitchCase = null; | 2445 | var special_case: ?*ast.Node.switch_case = null; |
| 2416 | var items_index: usize = 0; | 2446 | var items_index: usize = 0; |
| 2417 | var case_index: usize = 0; | 2447 | var case_index: usize = 0; |
| 2418 | for (switch_node.cases()) |uncasted_case| { | 2448 | for (switch_node.cases()) |uncasted_case| { |
| 2419 | const case = uncasted_case.castTag(.SwitchCase).?; | 2449 | const case = uncasted_case.castTag(.switch_case).?; |
| 2420 | const case_src = tree.token_locs[case.firstToken()].start; | 2450 | const case_src = tree.token_locs[case.firstToken()].start; |
| 2421 | // reset without freeing to reduce allocations. | 2451 | // reset without freeing to reduce allocations. |
| 2422 | case_scope.instructions.items.len = 0; | 2452 | case_scope.instructions.items.len = 0; |
| 2423 | | 2453 | |
| 2424 | // Check for else/_ prong, those are handled last. | 2454 | // Check for else/_ prong, those are handled last. |
| 2425 | if (case.items_len == 1 and case.items()[0].tag == .SwitchElse) { | 2455 | if (case.items_len == 1 and case.items()[0].tag == .switch_else) { |
| 2426 | special_case = case; | 2456 | special_case = case; |
| 2427 | continue; | 2457 | continue; |
| 2428 | } else if (case.items_len == 1 and case.items()[0].tag == .Identifier and | 2458 | } else if (case.items_len == 1 and case.items()[0].tag == .identifier and |
| 2429 | mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_")) | 2459 | mem.eql(u8, tree.tokenSlice(case.items()[0].firstToken()), "_")) |
| 2430 | { | 2460 | { |
| 2431 | special_case = case; | 2461 | special_case = case; |
| ... | @@ -2528,11 +2558,13 @@ fn switchCaseExpr( | ... | @@ -2528,11 +2558,13 @@ fn switchCaseExpr( |
| 2528 | scope: *Scope, | 2558 | scope: *Scope, |
| 2529 | rl: ResultLoc, | 2559 | rl: ResultLoc, |
| 2530 | block: *zir.Inst.Block, | 2560 | block: *zir.Inst.Block, |
| 2531 | case: *ast.Node.SwitchCase, | 2561 | case: *ast.Node.switch_case, |
| 2532 | target: *zir.Inst, | 2562 | target: *zir.Inst, |
| 2533 | target_ptr: ?*zir.Inst, | 2563 | target_ptr: ?*zir.Inst, |
| 2534 | ) !void { | 2564 | ) !void { |
| 2535 | const tree = scope.tree(); | 2565 | const tree = scope.tree(); |
| | 2566 | const node_datas = tree.nodes.items(.data); |
| | 2567 | const main_tokens = tree.nodes.items(.main_token); |
| 2536 | const case_src = tree.token_locs[case.firstToken()].start; | 2568 | const case_src = tree.token_locs[case.firstToken()].start; |
| 2537 | const sub_scope = blk: { | 2569 | const sub_scope = blk: { |
| 2538 | const uncasted_payload = case.payload orelse break :blk scope; | 2570 | const uncasted_payload = case.payload orelse break :blk scope; |
| ... | @@ -2559,6 +2591,8 @@ fn switchCaseExpr( | ... | @@ -2559,6 +2591,8 @@ fn switchCaseExpr( |
| 2559 | | 2591 | |
| 2560 | fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst { | 2592 | fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst { |
| 2561 | const tree = scope.tree(); | 2593 | const tree = scope.tree(); |
| | 2594 | const node_datas = tree.nodes.items(.data); |
| | 2595 | const main_tokens = tree.nodes.items(.main_token); |
| 2562 | const src = tree.token_locs[cfe.ltoken].start; | 2596 | const src = tree.token_locs[cfe.ltoken].start; |
| 2563 | if (cfe.getRHS()) |rhs_node| { | 2597 | if (cfe.getRHS()) |rhs_node| { |
| 2564 | if (nodeMayNeedMemoryLocation(rhs_node, scope)) { | 2598 | if (nodeMayNeedMemoryLocation(rhs_node, scope)) { |
| ... | @@ -2580,6 +2614,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo | ... | @@ -2580,6 +2614,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 2580 | defer tracy.end(); | 2614 | defer tracy.end(); |
| 2581 | | 2615 | |
| 2582 | const tree = scope.tree(); | 2616 | const tree = scope.tree(); |
| | 2617 | const node_datas = tree.nodes.items(.data); |
| | 2618 | const main_tokens = tree.nodes.items(.main_token); |
| 2583 | const ident_name = try mod.identifierTokenString(scope, ident.token); | 2619 | const ident_name = try mod.identifierTokenString(scope, ident.token); |
| 2584 | const src = tree.token_locs[ident.token].start; | 2620 | const src = tree.token_locs[ident.token].start; |
| 2585 | if (mem.eql(u8, ident_name, "_")) { | 2621 | if (mem.eql(u8, ident_name, "_")) { |
| ... | @@ -2667,6 +2703,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo | ... | @@ -2667,6 +2703,8 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 2667 | | 2703 | |
| 2668 | fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst { | 2704 | fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2669 | const tree = scope.tree(); | 2705 | const tree = scope.tree(); |
| | 2706 | const node_datas = tree.nodes.items(.data); |
| | 2707 | const main_tokens = tree.nodes.items(.main_token); |
| 2670 | const unparsed_bytes = tree.tokenSlice(str_lit.token); | 2708 | const unparsed_bytes = tree.tokenSlice(str_lit.token); |
| 2671 | const arena = scope.arena(); | 2709 | const arena = scope.arena(); |
| 2672 | | 2710 | |
| ... | @@ -2686,6 +2724,8 @@ fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) Inner | ... | @@ -2686,6 +2724,8 @@ fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) Inner |
| 2686 | | 2724 | |
| 2687 | fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst { | 2725 | fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst { |
| 2688 | const tree = scope.tree(); | 2726 | const tree = scope.tree(); |
| | 2727 | const node_datas = tree.nodes.items(.data); |
| | 2728 | const main_tokens = tree.nodes.items(.main_token); |
| 2689 | const lines = node.linesConst(); | 2729 | const lines = node.linesConst(); |
| 2690 | const src = tree.token_locs[lines[0]].start; | 2730 | const src = tree.token_locs[lines[0]].start; |
| 2691 | | 2731 | |
| ... | @@ -2713,6 +2753,8 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr | ... | @@ -2713,6 +2753,8 @@ fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStr |
| 2713 | | 2753 | |
| 2714 | fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst { | 2754 | fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst { |
| 2715 | const tree = scope.tree(); | 2755 | const tree = scope.tree(); |
| | 2756 | const node_datas = tree.nodes.items(.data); |
| | 2757 | const main_tokens = tree.nodes.items(.main_token); |
| 2716 | const src = tree.token_locs[node.token].start; | 2758 | const src = tree.token_locs[node.token].start; |
| 2717 | const slice = tree.tokenSlice(node.token); | 2759 | const slice = tree.tokenSlice(node.token); |
| 2718 | | 2760 | |
| ... | @@ -2733,6 +2775,8 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst | ... | @@ -2733,6 +2775,8 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst |
| 2733 | fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst { | 2775 | fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2734 | const arena = scope.arena(); | 2776 | const arena = scope.arena(); |
| 2735 | const tree = scope.tree(); | 2777 | const tree = scope.tree(); |
| | 2778 | const node_datas = tree.nodes.items(.data); |
| | 2779 | const main_tokens = tree.nodes.items(.main_token); |
| 2736 | const prefixed_bytes = tree.tokenSlice(int_lit.token); | 2780 | const prefixed_bytes = tree.tokenSlice(int_lit.token); |
| 2737 | const base = if (mem.startsWith(u8, prefixed_bytes, "0x")) | 2781 | const base = if (mem.startsWith(u8, prefixed_bytes, "0x")) |
| 2738 | 16 | 2782 | 16 |
| ... | @@ -2762,6 +2806,8 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne | ... | @@ -2762,6 +2806,8 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne |
| 2762 | fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) InnerError!*zir.Inst { | 2806 | fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2763 | const arena = scope.arena(); | 2807 | const arena = scope.arena(); |
| 2764 | const tree = scope.tree(); | 2808 | const tree = scope.tree(); |
| | 2809 | const node_datas = tree.nodes.items(.data); |
| | 2810 | const main_tokens = tree.nodes.items(.main_token); |
| 2765 | const bytes = tree.tokenSlice(float_lit.token); | 2811 | const bytes = tree.tokenSlice(float_lit.token); |
| 2766 | if (bytes.len > 2 and bytes[1] == 'x') { | 2812 | if (bytes.len > 2 and bytes[1] == 'x') { |
| 2767 | return mod.failTok(scope, float_lit.token, "TODO hex floats", .{}); | 2813 | return mod.failTok(scope, float_lit.token, "TODO hex floats", .{}); |
| ... | @@ -2780,6 +2826,8 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne | ... | @@ -2780,6 +2826,8 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne |
| 2780 | fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { | 2826 | fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2781 | const arena = scope.arena(); | 2827 | const arena = scope.arena(); |
| 2782 | const tree = scope.tree(); | 2828 | const tree = scope.tree(); |
| | 2829 | const node_datas = tree.nodes.items(.data); |
| | 2830 | const main_tokens = tree.nodes.items(.main_token); |
| 2783 | const src = tree.token_locs[node.token].start; | 2831 | const src = tree.token_locs[node.token].start; |
| 2784 | return addZIRInstConst(mod, scope, src, .{ | 2832 | return addZIRInstConst(mod, scope, src, .{ |
| 2785 | .ty = Type.initTag(.@"undefined"), | 2833 | .ty = Type.initTag(.@"undefined"), |
| ... | @@ -2790,12 +2838,14 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro | ... | @@ -2790,12 +2838,14 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro |
| 2790 | fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { | 2838 | fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2791 | const arena = scope.arena(); | 2839 | const arena = scope.arena(); |
| 2792 | const tree = scope.tree(); | 2840 | const tree = scope.tree(); |
| | 2841 | const node_datas = tree.nodes.items(.data); |
| | 2842 | const main_tokens = tree.nodes.items(.main_token); |
| 2793 | const src = tree.token_locs[node.token].start; | 2843 | const src = tree.token_locs[node.token].start; |
| 2794 | return addZIRInstConst(mod, scope, src, .{ | 2844 | return addZIRInstConst(mod, scope, src, .{ |
| 2795 | .ty = Type.initTag(.bool), | 2845 | .ty = Type.initTag(.bool), |
| 2796 | .val = switch (tree.token_ids[node.token]) { | 2846 | .val = switch (tree.token_ids[node.token]) { |
| 2797 | .Keyword_true => Value.initTag(.bool_true), | 2847 | .keyword_true => Value.initTag(.bool_true), |
| 2798 | .Keyword_false => Value.initTag(.bool_false), | 2848 | .keyword_false => Value.initTag(.bool_false), |
| 2799 | else => unreachable, | 2849 | else => unreachable, |
| 2800 | }, | 2850 | }, |
| 2801 | }); | 2851 | }); |
| ... | @@ -2804,6 +2854,8 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError | ... | @@ -2804,6 +2854,8 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError |
| 2804 | fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { | 2854 | fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 2805 | const arena = scope.arena(); | 2855 | const arena = scope.arena(); |
| 2806 | const tree = scope.tree(); | 2856 | const tree = scope.tree(); |
| | 2857 | const node_datas = tree.nodes.items(.data); |
| | 2858 | const main_tokens = tree.nodes.items(.main_token); |
| 2807 | const src = tree.token_locs[node.token].start; | 2859 | const src = tree.token_locs[node.token].start; |
| 2808 | return addZIRInstConst(mod, scope, src, .{ | 2860 | return addZIRInstConst(mod, scope, src, .{ |
| 2809 | .ty = Type.initTag(.@"null"), | 2861 | .ty = Type.initTag(.@"null"), |
| ... | @@ -2811,12 +2863,14 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError | ... | @@ -2811,12 +2863,14 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError |
| 2811 | }); | 2863 | }); |
| 2812 | } | 2864 | } |
| 2813 | | 2865 | |
| 2814 | fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zir.Inst { | 2866 | fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!*zir.Inst { |
| 2815 | if (asm_node.outputs.len != 0) { | 2867 | if (asm_node.outputs.len != 0) { |
| 2816 | return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{}); | 2868 | return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{}); |
| 2817 | } | 2869 | } |
| 2818 | const arena = scope.arena(); | 2870 | const arena = scope.arena(); |
| 2819 | const tree = scope.tree(); | 2871 | const tree = scope.tree(); |
| | 2872 | const node_datas = tree.nodes.items(.data); |
| | 2873 | const main_tokens = tree.nodes.items(.main_token); |
| 2820 | | 2874 | |
| 2821 | const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len); | 2875 | const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len); |
| 2822 | const args = try arena.alloc(*zir.Inst, asm_node.inputs.len); | 2876 | const args = try arena.alloc(*zir.Inst, asm_node.inputs.len); |
| ... | @@ -2839,7 +2893,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi | ... | @@ -2839,7 +2893,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi |
| 2839 | .ty = Type.initTag(.type), | 2893 | .ty = Type.initTag(.type), |
| 2840 | .val = Value.initTag(.void_type), | 2894 | .val = Value.initTag(.void_type), |
| 2841 | }); | 2895 | }); |
| 2842 | const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.Asm, .{ | 2896 | const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{ |
| 2843 | .asm_source = try expr(mod, scope, str_type_rl, asm_node.template), | 2897 | .asm_source = try expr(mod, scope, str_type_rl, asm_node.template), |
| 2844 | .return_type = return_type, | 2898 | .return_type = return_type, |
| 2845 | }, .{ | 2899 | }, .{ |
| ... | @@ -2851,7 +2905,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi | ... | @@ -2851,7 +2905,7 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.Asm) InnerError!*zi |
| 2851 | return asm_inst; | 2905 | return asm_inst; |
| 2852 | } | 2906 | } |
| 2853 | | 2907 | |
| 2854 | fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall, count: u32) !void { | 2908 | fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void { |
| 2855 | if (call.params_len == count) | 2909 | if (call.params_len == count) |
| 2856 | return; | 2910 | return; |
| 2857 | | 2911 | |
| ... | @@ -2863,11 +2917,13 @@ fn simpleCast( | ... | @@ -2863,11 +2917,13 @@ fn simpleCast( |
| 2863 | mod: *Module, | 2917 | mod: *Module, |
| 2864 | scope: *Scope, | 2918 | scope: *Scope, |
| 2865 | rl: ResultLoc, | 2919 | rl: ResultLoc, |
| 2866 | call: *ast.Node.BuiltinCall, | 2920 | call: *ast.Node.builtin_call, |
| 2867 | inst_tag: zir.Inst.Tag, | 2921 | inst_tag: zir.Inst.Tag, |
| 2868 | ) InnerError!*zir.Inst { | 2922 | ) InnerError!*zir.Inst { |
| 2869 | try ensureBuiltinParamCount(mod, scope, call, 2); | 2923 | try ensureBuiltinParamCount(mod, scope, call, 2); |
| 2870 | const tree = scope.tree(); | 2924 | const tree = scope.tree(); |
| | 2925 | const node_datas = tree.nodes.items(.data); |
| | 2926 | const main_tokens = tree.nodes.items(.main_token); |
| 2871 | const src = tree.token_locs[call.builtin_token].start; | 2927 | const src = tree.token_locs[call.builtin_token].start; |
| 2872 | const params = call.params(); | 2928 | const params = call.params(); |
| 2873 | const dest_type = try typeExpr(mod, scope, params[0]); | 2929 | const dest_type = try typeExpr(mod, scope, params[0]); |
| ... | @@ -2876,10 +2932,12 @@ fn simpleCast( | ... | @@ -2876,10 +2932,12 @@ fn simpleCast( |
| 2876 | return rvalue(mod, scope, rl, result); | 2932 | return rvalue(mod, scope, rl, result); |
| 2877 | } | 2933 | } |
| 2878 | | 2934 | |
| 2879 | fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 2935 | fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 2880 | try ensureBuiltinParamCount(mod, scope, call, 1); | 2936 | try ensureBuiltinParamCount(mod, scope, call, 1); |
| 2881 | const operand = try expr(mod, scope, .none, call.params()[0]); | 2937 | const operand = try expr(mod, scope, .none, call.params()[0]); |
| 2882 | const tree = scope.tree(); | 2938 | const tree = scope.tree(); |
| | 2939 | const node_datas = tree.nodes.items(.data); |
| | 2940 | const main_tokens = tree.nodes.items(.main_token); |
| 2883 | const src = tree.token_locs[call.builtin_token].start; | 2941 | const src = tree.token_locs[call.builtin_token].start; |
| 2884 | return addZIRUnOp(mod, scope, src, .ptrtoint, operand); | 2942 | return addZIRUnOp(mod, scope, src, .ptrtoint, operand); |
| 2885 | } | 2943 | } |
| ... | @@ -2888,10 +2946,12 @@ fn as( | ... | @@ -2888,10 +2946,12 @@ fn as( |
| 2888 | mod: *Module, | 2946 | mod: *Module, |
| 2889 | scope: *Scope, | 2947 | scope: *Scope, |
| 2890 | rl: ResultLoc, | 2948 | rl: ResultLoc, |
| 2891 | call: *ast.Node.BuiltinCall, | 2949 | call: *ast.Node.builtin_call, |
| 2892 | ) InnerError!*zir.Inst { | 2950 | ) InnerError!*zir.Inst { |
| 2893 | try ensureBuiltinParamCount(mod, scope, call, 2); | 2951 | try ensureBuiltinParamCount(mod, scope, call, 2); |
| 2894 | const tree = scope.tree(); | 2952 | const tree = scope.tree(); |
| | 2953 | const node_datas = tree.nodes.items(.data); |
| | 2954 | const main_tokens = tree.nodes.items(.main_token); |
| 2895 | const src = tree.token_locs[call.builtin_token].start; | 2955 | const src = tree.token_locs[call.builtin_token].start; |
| 2896 | const params = call.params(); | 2956 | const params = call.params(); |
| 2897 | const dest_type = try typeExpr(mod, scope, params[0]); | 2957 | const dest_type = try typeExpr(mod, scope, params[0]); |
| ... | @@ -2963,9 +3023,11 @@ fn asRlPtr( | ... | @@ -2963,9 +3023,11 @@ fn asRlPtr( |
| 2963 | } | 3023 | } |
| 2964 | } | 3024 | } |
| 2965 | | 3025 | |
| 2966 | fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3026 | fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 2967 | try ensureBuiltinParamCount(mod, scope, call, 2); | 3027 | try ensureBuiltinParamCount(mod, scope, call, 2); |
| 2968 | const tree = scope.tree(); | 3028 | const tree = scope.tree(); |
| | 3029 | const node_datas = tree.nodes.items(.data); |
| | 3030 | const main_tokens = tree.nodes.items(.main_token); |
| 2969 | const src = tree.token_locs[call.builtin_token].start; | 3031 | const src = tree.token_locs[call.builtin_token].start; |
| 2970 | const params = call.params(); | 3032 | const params = call.params(); |
| 2971 | const dest_type = try typeExpr(mod, scope, params[0]); | 3033 | const dest_type = try typeExpr(mod, scope, params[0]); |
| ... | @@ -3007,27 +3069,33 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa | ... | @@ -3007,27 +3069,33 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCa |
| 3007 | } | 3069 | } |
| 3008 | } | 3070 | } |
| 3009 | | 3071 | |
| 3010 | fn import(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3072 | fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 3011 | try ensureBuiltinParamCount(mod, scope, call, 1); | 3073 | try ensureBuiltinParamCount(mod, scope, call, 1); |
| 3012 | const tree = scope.tree(); | 3074 | const tree = scope.tree(); |
| | 3075 | const node_datas = tree.nodes.items(.data); |
| | 3076 | const main_tokens = tree.nodes.items(.main_token); |
| 3013 | const src = tree.token_locs[call.builtin_token].start; | 3077 | const src = tree.token_locs[call.builtin_token].start; |
| 3014 | const params = call.params(); | 3078 | const params = call.params(); |
| 3015 | const target = try expr(mod, scope, .none, params[0]); | 3079 | const target = try expr(mod, scope, .none, params[0]); |
| 3016 | return addZIRUnOp(mod, scope, src, .import, target); | 3080 | return addZIRUnOp(mod, scope, src, .import, target); |
| 3017 | } | 3081 | } |
| 3018 | | 3082 | |
| 3019 | fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3083 | fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 3020 | try ensureBuiltinParamCount(mod, scope, call, 1); | 3084 | try ensureBuiltinParamCount(mod, scope, call, 1); |
| 3021 | const tree = scope.tree(); | 3085 | const tree = scope.tree(); |
| | 3086 | const node_datas = tree.nodes.items(.data); |
| | 3087 | const main_tokens = tree.nodes.items(.main_token); |
| 3022 | const src = tree.token_locs[call.builtin_token].start; | 3088 | const src = tree.token_locs[call.builtin_token].start; |
| 3023 | const params = call.params(); | 3089 | const params = call.params(); |
| 3024 | const target = try expr(mod, scope, .none, params[0]); | 3090 | const target = try expr(mod, scope, .none, params[0]); |
| 3025 | return addZIRUnOp(mod, scope, src, .compile_error, target); | 3091 | return addZIRUnOp(mod, scope, src, .compile_error, target); |
| 3026 | } | 3092 | } |
| 3027 | | 3093 | |
| 3028 | fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3094 | fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 3029 | try ensureBuiltinParamCount(mod, scope, call, 1); | 3095 | try ensureBuiltinParamCount(mod, scope, call, 1); |
| 3030 | const tree = scope.tree(); | 3096 | const tree = scope.tree(); |
| | 3097 | const node_datas = tree.nodes.items(.data); |
| | 3098 | const main_tokens = tree.nodes.items(.main_token); |
| 3031 | const src = tree.token_locs[call.builtin_token].start; | 3099 | const src = tree.token_locs[call.builtin_token].start; |
| 3032 | const params = call.params(); | 3100 | const params = call.params(); |
| 3033 | const u32_type = try addZIRInstConst(mod, scope, src, .{ | 3101 | const u32_type = try addZIRInstConst(mod, scope, src, .{ |
| ... | @@ -3038,8 +3106,10 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) | ... | @@ -3038,8 +3106,10 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) |
| 3038 | return addZIRUnOp(mod, scope, src, .set_eval_branch_quota, quota); | 3106 | return addZIRUnOp(mod, scope, src, .set_eval_branch_quota, quota); |
| 3039 | } | 3107 | } |
| 3040 | | 3108 | |
| 3041 | fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3109 | fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 3042 | const tree = scope.tree(); | 3110 | const tree = scope.tree(); |
| | 3111 | const node_datas = tree.nodes.items(.data); |
| | 3112 | const main_tokens = tree.nodes.items(.main_token); |
| 3043 | const arena = scope.arena(); | 3113 | const arena = scope.arena(); |
| 3044 | const src = tree.token_locs[call.builtin_token].start; | 3114 | const src = tree.token_locs[call.builtin_token].start; |
| 3045 | const params = call.params(); | 3115 | const params = call.params(); |
| ... | @@ -3054,8 +3124,10 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCal | ... | @@ -3054,8 +3124,10 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCal |
| 3054 | items[param_i] = try expr(mod, scope, .none, param); | 3124 | items[param_i] = try expr(mod, scope, .none, param); |
| 3055 | return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{})); | 3125 | return rvalue(mod, scope, rl, try addZIRInst(mod, scope, src, zir.Inst.TypeOfPeer, .{ .items = items }, .{})); |
| 3056 | } | 3126 | } |
| 3057 | fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3127 | fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 3058 | const tree = scope.tree(); | 3128 | const tree = scope.tree(); |
| | 3129 | const node_datas = tree.nodes.items(.data); |
| | 3130 | const main_tokens = tree.nodes.items(.main_token); |
| 3059 | const arena = scope.arena(); | 3131 | const arena = scope.arena(); |
| 3060 | const src = tree.token_locs[call.builtin_token].start; | 3132 | const src = tree.token_locs[call.builtin_token].start; |
| 3061 | const params = call.params(); | 3133 | const params = call.params(); |
| ... | @@ -3065,8 +3137,10 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerErr | ... | @@ -3065,8 +3137,10 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.BuiltinCall) InnerErr |
| 3065 | return addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{}); | 3137 | return addZIRInst(mod, scope, src, zir.Inst.CompileLog, .{ .to_log = targets }, .{}); |
| 3066 | } | 3138 | } |
| 3067 | | 3139 | |
| 3068 | fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.BuiltinCall) InnerError!*zir.Inst { | 3140 | fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_call) InnerError!*zir.Inst { |
| 3069 | const tree = scope.tree(); | 3141 | const tree = scope.tree(); |
| | 3142 | const node_datas = tree.nodes.items(.data); |
| | 3143 | const main_tokens = tree.nodes.items(.main_token); |
| 3070 | const builtin_name = tree.tokenSlice(call.builtin_token); | 3144 | const builtin_name = tree.tokenSlice(call.builtin_token); |
| 3071 | | 3145 | |
| 3072 | // We handle the different builtins manually because they have different semantics depending | 3146 | // We handle the different builtins manually because they have different semantics depending |
| ... | @@ -3104,8 +3178,10 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built | ... | @@ -3104,8 +3178,10 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.Built |
| 3104 | } | 3178 | } |
| 3105 | } | 3179 | } |
| 3106 | | 3180 | |
| 3107 | fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) InnerError!*zir.Inst { | 3181 | fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) InnerError!*zir.Inst { |
| 3108 | const tree = scope.tree(); | 3182 | const tree = scope.tree(); |
| | 3183 | const node_datas = tree.nodes.items(.data); |
| | 3184 | const main_tokens = tree.nodes.items(.main_token); |
| 3109 | const lhs = try expr(mod, scope, .none, node.lhs); | 3185 | const lhs = try expr(mod, scope, .none, node.lhs); |
| 3110 | | 3186 | |
| 3111 | const param_nodes = node.params(); | 3187 | const param_nodes = node.params(); |
| ... | @@ -3130,6 +3206,8 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) In | ... | @@ -3130,6 +3206,8 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Call) In |
| 3130 | | 3206 | |
| 3131 | fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerError!*zir.Inst { | 3207 | fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 3132 | const tree = scope.tree(); | 3208 | const tree = scope.tree(); |
| | 3209 | const node_datas = tree.nodes.items(.data); |
| | 3210 | const main_tokens = tree.nodes.items(.main_token); |
| 3133 | const src = tree.token_locs[unreach_node.token].start; | 3211 | const src = tree.token_locs[unreach_node.token].start; |
| 3134 | return addZIRNoOp(mod, scope, src, .unreachable_safe); | 3212 | return addZIRNoOp(mod, scope, src, .unreachable_safe); |
| 3135 | } | 3213 | } |
| ... | @@ -3176,11 +3254,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { | ... | @@ -3176,11 +3254,11 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { |
| 3176 | while (true) { | 3254 | while (true) { |
| 3177 | switch (node.tag) { | 3255 | switch (node.tag) { |
| 3178 | .Root, | 3256 | .Root, |
| 3179 | .Use, | 3257 | .@"usingnamespace", |
| 3180 | .TestDecl, | 3258 | .test_decl, |
| 3181 | .DocComment, | 3259 | .doc_comment, |
| 3182 | .SwitchCase, | 3260 | .switch_case, |
| 3183 | .SwitchElse, | 3261 | .switch_else, |
| 3184 | .Else, | 3262 | .Else, |
| 3185 | .Payload, | 3263 | .Payload, |
| 3186 | .PointerPayload, | 3264 | .PointerPayload, |
| ... | @@ -3190,97 +3268,97 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { | ... | @@ -3190,97 +3268,97 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { |
| 3190 | .FieldInitializer, | 3268 | .FieldInitializer, |
| 3191 | => unreachable, | 3269 | => unreachable, |
| 3192 | | 3270 | |
| 3193 | .Return, | 3271 | .@"return", |
| 3194 | .Break, | 3272 | .@"break", |
| 3195 | .Continue, | 3273 | .@"continue", |
| 3196 | .BitNot, | 3274 | .bit_not, |
| 3197 | .BoolNot, | 3275 | .bool_not, |
| 3198 | .VarDecl, | 3276 | .var_decl, |
| 3199 | .Defer, | 3277 | .@"defer", |
| 3200 | .AddressOf, | 3278 | .address_of, |
| 3201 | .OptionalType, | 3279 | .optional_type, |
| 3202 | .Negation, | 3280 | .negation, |
| 3203 | .NegationWrap, | 3281 | .negation_wrap, |
| 3204 | .Resume, | 3282 | .@"resume", |
| 3205 | .ArrayType, | 3283 | .array_type, |
| 3206 | .ArrayTypeSentinel, | 3284 | .array_type_sentinel, |
| 3207 | .PtrType, | 3285 | .PtrType, |
| 3208 | .SliceType, | 3286 | .slice_type, |
| 3209 | .Suspend, | 3287 | .@"suspend", |
| 3210 | .AnyType, | 3288 | .@"anytype", |
| 3211 | .ErrorType, | 3289 | .error_type, |
| 3212 | .FnProto, | 3290 | .FnProto, |
| 3213 | .AnyFrameType, | 3291 | .anyframe_type, |
| 3214 | .IntegerLiteral, | 3292 | .integer_literal, |
| 3215 | .FloatLiteral, | 3293 | .float_literal, |
| 3216 | .EnumLiteral, | 3294 | .enum_literal, |
| 3217 | .StringLiteral, | 3295 | .string_literal, |
| 3218 | .MultilineStringLiteral, | 3296 | .MultilineStringLiteral, |
| 3219 | .CharLiteral, | 3297 | .char_literal, |
| 3220 | .BoolLiteral, | 3298 | .bool_literal, |
| 3221 | .NullLiteral, | 3299 | .null_literal, |
| 3222 | .UndefinedLiteral, | 3300 | .undefined_literal, |
| 3223 | .Unreachable, | 3301 | .@"unreachable", |
| 3224 | .Identifier, | 3302 | .identifier, |
| 3225 | .ErrorSetDecl, | 3303 | .error_set_decl, |
| 3226 | .ContainerDecl, | 3304 | .ContainerDecl, |
| 3227 | .Asm, | 3305 | .@"asm", |
| 3228 | .Add, | 3306 | .add, |
| 3229 | .AddWrap, | 3307 | .add_wrap, |
| 3230 | .ArrayCat, | 3308 | .array_cat, |
| 3231 | .ArrayMult, | 3309 | .array_mult, |
| 3232 | .Assign, | 3310 | .assign, |
| 3233 | .AssignBitAnd, | 3311 | .assign_bit_and, |
| 3234 | .AssignBitOr, | 3312 | .assign_bit_or, |
| 3235 | .AssignBitShiftLeft, | 3313 | .assign_bit_shift_left, |
| 3236 | .AssignBitShiftRight, | 3314 | .assign_bit_shift_right, |
| 3237 | .AssignBitXor, | 3315 | .assign_bit_xor, |
| 3238 | .AssignDiv, | 3316 | .assign_div, |
| 3239 | .AssignSub, | 3317 | .assign_sub, |
| 3240 | .AssignSubWrap, | 3318 | .assign_sub_wrap, |
| 3241 | .AssignMod, | 3319 | .assign_mod, |
| 3242 | .AssignAdd, | 3320 | .assign_add, |
| 3243 | .AssignAddWrap, | 3321 | .assign_add_wrap, |
| 3244 | .AssignMul, | 3322 | .assign_mul, |
| 3245 | .AssignMulWrap, | 3323 | .assign_mul_wrap, |
| 3246 | .BangEqual, | 3324 | .bang_equal, |
| 3247 | .BitAnd, | 3325 | .bit_and, |
| 3248 | .BitOr, | 3326 | .bit_or, |
| 3249 | .BitShiftLeft, | 3327 | .bit_shift_left, |
| 3250 | .BitShiftRight, | 3328 | .bit_shift_right, |
| 3251 | .BitXor, | 3329 | .bit_xor, |
| 3252 | .BoolAnd, | 3330 | .bool_and, |
| 3253 | .BoolOr, | 3331 | .bool_or, |
| 3254 | .Div, | 3332 | .div, |
| 3255 | .EqualEqual, | 3333 | .equal_equal, |
| 3256 | .ErrorUnion, | 3334 | .error_union, |
| 3257 | .GreaterOrEqual, | 3335 | .greater_or_equal, |
| 3258 | .GreaterThan, | 3336 | .greater_than, |
| 3259 | .LessOrEqual, | 3337 | .less_or_equal, |
| 3260 | .LessThan, | 3338 | .less_than, |
| 3261 | .MergeErrorSets, | 3339 | .merge_error_sets, |
| 3262 | .Mod, | 3340 | .mod, |
| 3263 | .Mul, | 3341 | .mul, |
| 3264 | .MulWrap, | 3342 | .mul_wrap, |
| 3265 | .Range, | 3343 | .range, |
| 3266 | .Period, | 3344 | .period, |
| 3267 | .Sub, | 3345 | .sub, |
| 3268 | .SubWrap, | 3346 | .sub_wrap, |
| 3269 | .Slice, | 3347 | .slice, |
| 3270 | .Deref, | 3348 | .deref, |
| 3271 | .ArrayAccess, | 3349 | .array_access, |
| 3272 | .Block, | 3350 | .block, |
| 3273 | => return false, | 3351 | => return false, |
| 3274 | | 3352 | |
| 3275 | // Forward the question to a sub-expression. | 3353 | // Forward the question to a sub-expression. |
| 3276 | .GroupedExpression => node = node.castTag(.GroupedExpression).?.expr, | 3354 | .grouped_expression => node = node.castTag(.grouped_expression).?.expr, |
| 3277 | .Try => node = node.castTag(.Try).?.rhs, | 3355 | .@"try" => node = node.castTag(.@"try").?.rhs, |
| 3278 | .Await => node = node.castTag(.Await).?.rhs, | 3356 | .@"await" => node = node.castTag(.@"await").?.rhs, |
| 3279 | .Catch => node = node.castTag(.Catch).?.rhs, | 3357 | .@"catch" => node = node.castTag(.@"catch").?.rhs, |
| 3280 | .OrElse => node = node.castTag(.OrElse).?.rhs, | 3358 | .@"orelse" => node = node.castTag(.@"orelse").?.rhs, |
| 3281 | .Comptime => node = node.castTag(.Comptime).?.expr, | 3359 | .@"comptime" => node = node.castTag(.@"comptime").?.expr, |
| 3282 | .Nosuspend => node = node.castTag(.Nosuspend).?.expr, | 3360 | .@"nosuspend" => node = node.castTag(.@"nosuspend").?.expr, |
| 3283 | .UnwrapOptional => node = node.castTag(.UnwrapOptional).?.lhs, | 3361 | .unwrap_optional => node = node.castTag(.unwrap_optional).?.lhs, |
| 3284 | | 3362 | |
| 3285 | // True because these are exactly the expressions we need memory locations for. | 3363 | // True because these are exactly the expressions we need memory locations for. |
| 3286 | .ArrayInitializer, | 3364 | .ArrayInitializer, |
| ... | @@ -3291,14 +3369,14 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { | ... | @@ -3291,14 +3369,14 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { |
| 3291 | | 3369 | |
| 3292 | // True because depending on comptime conditions, sub-expressions | 3370 | // True because depending on comptime conditions, sub-expressions |
| 3293 | // may be the kind that need memory locations. | 3371 | // may be the kind that need memory locations. |
| 3294 | .While, | 3372 | .@"while", |
| 3295 | .For, | 3373 | .@"for", |
| 3296 | .Switch, | 3374 | .@"switch", |
| 3297 | .Call, | 3375 | .call, |
| 3298 | .LabeledBlock, | 3376 | .labeled_block, |
| 3299 | => return true, | 3377 | => return true, |
| 3300 | | 3378 | |
| 3301 | .BuiltinCall => { | 3379 | .builtin_call => { |
| 3302 | @setEvalBranchQuota(5000); | 3380 | @setEvalBranchQuota(5000); |
| 3303 | const builtin_needs_mem_loc = std.ComptimeStringMap(bool, .{ | 3381 | const builtin_needs_mem_loc = std.ComptimeStringMap(bool, .{ |
| 3304 | .{ "@addWithOverflow", false }, | 3382 | .{ "@addWithOverflow", false }, |
| ... | @@ -3404,12 +3482,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { | ... | @@ -3404,12 +3482,12 @@ fn nodeMayNeedMemoryLocation(start_node: *ast.Node, scope: *Scope) bool { |
| 3404 | .{ "@TypeOf", false }, | 3482 | .{ "@TypeOf", false }, |
| 3405 | .{ "@unionInit", true }, | 3483 | .{ "@unionInit", true }, |
| 3406 | }); | 3484 | }); |
| 3407 | const name = scope.tree().tokenSlice(node.castTag(.BuiltinCall).?.builtin_token); | 3485 | const name = scope.tree().tokenSlice(node.castTag(.builtin_call).?.builtin_token); |
| 3408 | return builtin_needs_mem_loc.get(name).?; | 3486 | return builtin_needs_mem_loc.get(name).?; |
| 3409 | }, | 3487 | }, |
| 3410 | | 3488 | |
| 3411 | // Depending on AST properties, they may need memory locations. | 3489 | // Depending on AST properties, they may need memory locations. |
| 3412 | .If => return node.castTag(.If).?.@"else" != null, | 3490 | .@"if" => return node.castTag(.@"if").?.@"else" != null, |
| 3413 | } | 3491 | } |
| 3414 | } | 3492 | } |
| 3415 | } | 3493 | } |
| ... | @@ -3450,8 +3528,17 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr | ... | @@ -3450,8 +3528,17 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr |
| 3450 | } | 3528 | } |
| 3451 | } | 3529 | } |
| 3452 | | 3530 | |
| 3453 | fn rvalueVoid(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node, result: void) InnerError!*zir.Inst { | 3531 | fn rvalueVoid( |
| 3454 | const src = scope.tree().token_locs[node.firstToken()].start; | 3532 | mod: *Module, |
| | 3533 | scope: *Scope, |
| | 3534 | rl: ResultLoc, |
| | 3535 | node: ast.Node.Index, |
| | 3536 | result: void, |
| | 3537 | ) InnerError!*zir.Inst { |
| | 3538 | const tree = scope.tree(); |
| | 3539 | const node_datas = tree.nodes.items(.data); |
| | 3540 | const main_tokens = tree.nodes.items(.main_token); |
| | 3541 | const src = tree.tokens.items(.start)[tree.firstToken(node)]; |
| 3455 | const void_inst = try addZIRInstConst(mod, scope, src, .{ | 3542 | const void_inst = try addZIRInstConst(mod, scope, src, .{ |
| 3456 | .ty = Type.initTag(.void), | 3543 | .ty = Type.initTag(.void), |
| 3457 | .val = Value.initTag(.void_value), | 3544 | .val = Value.initTag(.void_value), |