| ... | @@ -56,7 +56,8 @@ pub const ResultLoc = union(enum) { | ... | @@ -56,7 +56,8 @@ pub const ResultLoc = union(enum) { |
| 56 | }; | 56 | }; |
| 57 | | 57 | |
| 58 | pub fn typeExpr(mod: *Module, scope: *Scope, type_node: ast.Node.Index) 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 tree = scope.tree(); |
| | 60 | const type_src = token_starts[tree.firstToken(type_node)]; |
| 60 | const type_type = try addZIRInstConst(mod, scope, type_src, .{ | 61 | const type_type = try addZIRInstConst(mod, scope, type_src, .{ |
| 61 | .ty = Type.initTag(.type), | 62 | .ty = Type.initTag(.type), |
| 62 | .val = Value.initTag(.type_type), | 63 | .val = Value.initTag(.type_type), |
| ... | @@ -258,18 +259,23 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In | ... | @@ -258,18 +259,23 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 258 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), | 259 | .array_cat => return simpleBinOp(mod, scope, rl, node, .array_cat), |
| 259 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), | 260 | .array_mult => return simpleBinOp(mod, scope, rl, node, .array_mul), |
| 260 | | 261 | |
| 261 | .bool_and => return boolBinOp(mod, scope, rl, node), | 262 | .bool_and => return boolBinOp(mod, scope, rl, node, true), |
| 262 | .bool_or => return boolBinOp(mod, scope, rl, node), | 263 | .bool_or => return boolBinOp(mod, scope, rl, node, false), |
| 263 | | 264 | |
| 264 | .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)), | 265 | .bool_not => return rvalue(mod, scope, rl, try boolNot(mod, scope, node)), |
| 265 | .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)), | 266 | .bit_not => return rvalue(mod, scope, rl, try bitNot(mod, scope, node)), |
| 266 | .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)), | 267 | .negation => return rvalue(mod, scope, rl, try negation(mod, scope, node, .sub)), |
| 267 | .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)), | 268 | .negation_wrap => return rvalue(mod, scope, rl, try negation(mod, scope, node, .subwrap)), |
| 268 | | 269 | |
| 269 | .identifier => return try identifier(mod, scope, rl, node), | 270 | .identifier => return identifier(mod, scope, rl, node), |
| 270 | .@"asm" => return rvalue(mod, scope, rl, try assembly(mod, scope, node)), | 271 | |
| 271 | .string_literal => return rvalue(mod, scope, rl, try stringLiteral(mod, scope, node)), | 272 | .asm_simple => return assembly(mod, scope, rl, tree.asmSimple(node)), |
| 272 | .integer_literal => return rvalue(mod, scope, rl, try integerLiteral(mod, scope, node)), | 273 | .@"asm" => return assembly(mod, scope, rl, tree.asmFull(node)), |
| | 274 | |
| | 275 | .string_literal => return stringLiteral(mod, scope, rl, node), |
| | 276 | .multiline_string_literal => return multilineStringLiteral(mod, scope, rl, node), |
| | 277 | |
| | 278 | .integer_literal => return integerLiteral(mod, scope, rl, node), |
| 273 | .builtin_call => return builtinCall(mod, scope, rl, node), | 279 | .builtin_call => return builtinCall(mod, scope, rl, node), |
| 274 | .call => return callExpr(mod, scope, rl, node), | 280 | .call => return callExpr(mod, scope, rl, node), |
| 275 | .@"unreachable" => return unreach(mod, scope, node), | 281 | .@"unreachable" => return unreach(mod, scope, node), |
| ... | @@ -285,7 +291,22 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In | ... | @@ -285,7 +291,22 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 285 | .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)), | 291 | .null_literal => return rvalue(mod, scope, rl, try nullLiteral(mod, scope, node)), |
| 286 | .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)), | 292 | .optional_type => return rvalue(mod, scope, rl, try optionalType(mod, scope, node)), |
| 287 | .unwrap_optional => return unwrapOptional(mod, scope, rl, node), | 293 | .unwrap_optional => return unwrapOptional(mod, scope, rl, node), |
| 288 | .block => return rvalueVoid(mod, scope, rl, node, try blockExpr(mod, scope, node)), | 294 | |
| | 295 | .block_two, .block_two_semicolon => { |
| | 296 | const statements = [2]ast.Node.Index{ node_datas[node].lhs, node_datas[node].rhs }; |
| | 297 | if (node_datas[node].lhs == 0) { |
| | 298 | return blockExpr(mod, scope, rl, node, statements[0..0]); |
| | 299 | } else if (node_datas[node].rhs == 0) { |
| | 300 | return blockExpr(mod, scope, rl, node, statements[0..1]); |
| | 301 | } else { |
| | 302 | return blockExpr(mod, scope, rl, node, statements[0..2]); |
| | 303 | } |
| | 304 | }, |
| | 305 | .block, .block_semicolon => { |
| | 306 | const statements = tree.extra_data[node_datas[node].lhs..node_datas[node].rhs]; |
| | 307 | return blockExpr(mod, scope, rl, node, statements); |
| | 308 | }, |
| | 309 | |
| 289 | .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block), | 310 | .labeled_block => return labeledBlockExpr(mod, scope, rl, node, .block), |
| 290 | .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)), | 311 | .@"break" => return rvalue(mod, scope, rl, try breakExpr(mod, scope, node)), |
| 291 | .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)), | 312 | .@"continue" => return rvalue(mod, scope, rl, try continueExpr(mod, scope, node)), |
| ... | @@ -293,7 +314,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In | ... | @@ -293,7 +314,6 @@ pub fn expr(mod: *Module, scope: *Scope, rl: ResultLoc, node: ast.Node.Index) In |
| 293 | .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)), | 314 | .array_type => return rvalue(mod, scope, rl, try arrayType(mod, scope, node)), |
| 294 | .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)), | 315 | .array_type_sentinel => return rvalue(mod, scope, rl, try arrayTypeSentinel(mod, scope, node)), |
| 295 | .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)), | 316 | .enum_literal => return rvalue(mod, scope, rl, try enumLiteral(mod, scope, node)), |
| 296 | .MultilineStringLiteral => return rvalue(mod, scope, rl, try multilineStrLiteral(mod, scope, node)), | | |
| 297 | .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)), | 317 | .char_literal => return rvalue(mod, scope, rl, try charLiteral(mod, scope, node)), |
| 298 | .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)), | 318 | .slice_type => return rvalue(mod, scope, rl, try sliceType(mod, scope, node)), |
| 299 | .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)), | 319 | .error_union => return rvalue(mod, scope, rl, try typeInixOp(mod, scope, node, .error_union_type)), |
| ... | @@ -343,10 +363,17 @@ pub fn comptimeExpr( | ... | @@ -343,10 +363,17 @@ pub fn comptimeExpr( |
| 343 | return expr(mod, parent_scope, rl, node); | 363 | return expr(mod, parent_scope, rl, node); |
| 344 | } | 364 | } |
| 345 | | 365 | |
| | 366 | const tree = parent_scope.tree(); |
| | 367 | const main_tokens = tree.nodes.items(.main_token); |
| | 368 | const token_tags = tree.tokens.items(.tag); |
| | 369 | |
| 346 | // Optimization for labeled blocks: don't need to have 2 layers of blocks, | 370 | // Optimization for labeled blocks: don't need to have 2 layers of blocks, |
| 347 | // we can reuse the existing one. | 371 | // we can reuse the existing one. |
| 348 | if (node.castTag(.labeled_block)) |block_node| { | 372 | const lbrace = main_tokens[node]; |
| 349 | return labeledBlockExpr(mod, parent_scope, rl, block_node, .block_comptime); | 373 | if (token_tags[lbrace - 1] == .colon and |
| | 374 | token_tags[lbrace - 2] == .identifier) |
| | 375 | { |
| | 376 | return labeledBlockExpr(mod, parent_scope, rl, node, .block_comptime); |
| 350 | } | 377 | } |
| 351 | | 378 | |
| 352 | // Make a scope to collect generated instructions in the sub-expression. | 379 | // Make a scope to collect generated instructions in the sub-expression. |
| ... | @@ -363,11 +390,7 @@ pub fn comptimeExpr( | ... | @@ -363,11 +390,7 @@ pub fn comptimeExpr( |
| 363 | // instruction is the block's result value. | 390 | // instruction is the block's result value. |
| 364 | _ = try expr(mod, &block_scope.base, rl, node); | 391 | _ = try expr(mod, &block_scope.base, rl, node); |
| 365 | | 392 | |
| 366 | const tree = parent_scope.tree(); | 393 | const src = token_starts[tree.firstToken(node)]; |
| 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; | | |
| 370 | | | |
| 371 | const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{ | 394 | const block = try addZIRInstBlock(mod, parent_scope, src, .block_comptime_flat, .{ |
| 372 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), | 395 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), |
| 373 | }); | 396 | }); |
| ... | @@ -375,15 +398,13 @@ pub fn comptimeExpr( | ... | @@ -375,15 +398,13 @@ pub fn comptimeExpr( |
| 375 | return &block.base; | 398 | return &block.base; |
| 376 | } | 399 | } |
| 377 | | 400 | |
| 378 | fn breakExpr( | 401 | fn breakExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 379 | mod: *Module, | | |
| 380 | parent_scope: *Scope, | | |
| 381 | node: *ast.Node.ControlFlowExpression, | | |
| 382 | ) InnerError!*zir.Inst { | | |
| 383 | const tree = parent_scope.tree(); | 402 | const tree = parent_scope.tree(); |
| 384 | const node_datas = tree.nodes.items(.data); | 403 | const node_datas = tree.nodes.items(.data); |
| 385 | const main_tokens = tree.nodes.items(.main_token); | 404 | const main_tokens = tree.nodes.items(.main_token); |
| 386 | const src = tree.token_locs[node.ltoken].start; | 405 | const src = token_starts[main_tokens[node]]; |
| | 406 | const break_label = node_datas[node].lhs; |
| | 407 | const rhs = node_datas[node].rhs; |
| 387 | | 408 | |
| 388 | // Look for the label in the scope. | 409 | // Look for the label in the scope. |
| 389 | var scope = parent_scope; | 410 | var scope = parent_scope; |
| ... | @@ -393,7 +414,7 @@ fn breakExpr( | ... | @@ -393,7 +414,7 @@ fn breakExpr( |
| 393 | const gen_zir = scope.cast(Scope.GenZIR).?; | 414 | const gen_zir = scope.cast(Scope.GenZIR).?; |
| 394 | | 415 | |
| 395 | const block_inst = blk: { | 416 | const block_inst = blk: { |
| 396 | if (node.getLabel()) |break_label| { | 417 | if (break_label != 0) { |
| 397 | if (gen_zir.label) |*label| { | 418 | if (gen_zir.label) |*label| { |
| 398 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { | 419 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| 399 | label.used = true; | 420 | label.used = true; |
| ... | @@ -407,11 +428,11 @@ fn breakExpr( | ... | @@ -407,11 +428,11 @@ fn breakExpr( |
| 407 | continue; | 428 | continue; |
| 408 | }; | 429 | }; |
| 409 | | 430 | |
| 410 | const rhs = node.getRHS() orelse { | 431 | if (rhs == 0) { |
| 411 | return addZirInstTag(mod, parent_scope, src, .break_void, .{ | 432 | return addZirInstTag(mod, parent_scope, src, .break_void, .{ |
| 412 | .block = block_inst, | 433 | .block = block_inst, |
| 413 | }); | 434 | }); |
| 414 | }; | 435 | } |
| 415 | gen_zir.break_count += 1; | 436 | gen_zir.break_count += 1; |
| 416 | const prev_rvalue_rl_count = gen_zir.rvalue_rl_count; | 437 | const prev_rvalue_rl_count = gen_zir.rvalue_rl_count; |
| 417 | const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs); | 438 | const operand = try expr(mod, parent_scope, gen_zir.break_result_loc, rhs); |
| ... | @@ -435,7 +456,7 @@ fn breakExpr( | ... | @@ -435,7 +456,7 @@ fn breakExpr( |
| 435 | }, | 456 | }, |
| 436 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 457 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 437 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 458 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 438 | else => if (node.getLabel()) |break_label| { | 459 | else => if (break_label != 0) { |
| 439 | const label_name = try mod.identifierTokenString(parent_scope, break_label); | 460 | const label_name = try mod.identifierTokenString(parent_scope, break_label); |
| 440 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); | 461 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); |
| 441 | } else { | 462 | } else { |
| ... | @@ -445,11 +466,12 @@ fn breakExpr( | ... | @@ -445,11 +466,12 @@ fn breakExpr( |
| 445 | } | 466 | } |
| 446 | } | 467 | } |
| 447 | | 468 | |
| 448 | fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowExpression) InnerError!*zir.Inst { | 469 | fn continueExpr(mod: *Module, parent_scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 449 | const tree = parent_scope.tree(); | 470 | const tree = parent_scope.tree(); |
| 450 | const node_datas = tree.nodes.items(.data); | 471 | const node_datas = tree.nodes.items(.data); |
| 451 | const main_tokens = tree.nodes.items(.main_token); | 472 | const main_tokens = tree.nodes.items(.main_token); |
| 452 | const src = tree.token_locs[node.ltoken].start; | 473 | const src = token_starts[main_tokens[node]]; |
| | 474 | const break_label = node_datas[node].lhs; |
| 453 | | 475 | |
| 454 | // Look for the label in the scope. | 476 | // Look for the label in the scope. |
| 455 | var scope = parent_scope; | 477 | var scope = parent_scope; |
| ... | @@ -461,7 +483,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE | ... | @@ -461,7 +483,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 461 | scope = gen_zir.parent; | 483 | scope = gen_zir.parent; |
| 462 | continue; | 484 | continue; |
| 463 | }; | 485 | }; |
| 464 | if (node.getLabel()) |break_label| blk: { | 486 | if (break_label != 0) blk: { |
| 465 | if (gen_zir.label) |*label| { | 487 | if (gen_zir.label) |*label| { |
| 466 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { | 488 | if (try tokenIdentEql(mod, parent_scope, label.token, break_label)) { |
| 467 | label.used = true; | 489 | label.used = true; |
| ... | @@ -479,7 +501,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE | ... | @@ -479,7 +501,7 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 479 | }, | 501 | }, |
| 480 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, | 502 | .local_val => scope = scope.cast(Scope.LocalVal).?.parent, |
| 481 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, | 503 | .local_ptr => scope = scope.cast(Scope.LocalPtr).?.parent, |
| 482 | else => if (node.getLabel()) |break_label| { | 504 | else => if (break_label != 0) { |
| 483 | const label_name = try mod.identifierTokenString(parent_scope, break_label); | 505 | const label_name = try mod.identifierTokenString(parent_scope, break_label); |
| 484 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); | 506 | return mod.failTok(parent_scope, break_label, "label not found: '{s}'", .{label_name}); |
| 485 | } else { | 507 | } else { |
| ... | @@ -489,11 +511,18 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE | ... | @@ -489,11 +511,18 @@ fn continueExpr(mod: *Module, parent_scope: *Scope, node: *ast.Node.ControlFlowE |
| 489 | } | 511 | } |
| 490 | } | 512 | } |
| 491 | | 513 | |
| 492 | pub fn blockExpr(mod: *Module, parent_scope: *Scope, block_node: *ast.Node.block) InnerError!void { | 514 | pub fn blockExpr( |
| | 515 | mod: *Module, |
| | 516 | scope: *Scope, |
| | 517 | rl: ResultLoc, |
| | 518 | block_node: ast.Node.Index, |
| | 519 | statements: []const ast.Node.Index, |
| | 520 | ) InnerError!void { |
| 493 | const tracy = trace(@src()); | 521 | const tracy = trace(@src()); |
| 494 | defer tracy.end(); | 522 | defer tracy.end(); |
| 495 | | 523 | |
| 496 | try blockExprStmts(mod, parent_scope, &block_node.base, block_node.statements()); | 524 | try blockExprStmts(mod, scope, &block_node.base, statements); |
| | 525 | return rvalueVoid(mod, scope, rl, block_node, {}); |
| 497 | } | 526 | } |
| 498 | | 527 | |
| 499 | fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIndex) !void { | 528 | fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIndex) !void { |
| ... | @@ -508,8 +537,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn | ... | @@ -508,8 +537,8 @@ fn checkLabelRedefinition(mod: *Module, parent_scope: *Scope, label: ast.TokenIn |
| 508 | const tree = parent_scope.tree(); | 537 | const tree = parent_scope.tree(); |
| 509 | const node_datas = tree.nodes.items(.data); | 538 | const node_datas = tree.nodes.items(.data); |
| 510 | const main_tokens = tree.nodes.items(.main_token); | 539 | const main_tokens = tree.nodes.items(.main_token); |
| 511 | const label_src = tree.token_locs[label].start; | 540 | const label_src = token_starts[label]; |
| 512 | const prev_label_src = tree.token_locs[prev_label.token].start; | 541 | const prev_label_src = token_starts[prev_label.token]; |
| 513 | | 542 | |
| 514 | const label_name = try mod.identifierTokenString(parent_scope, label); | 543 | const label_name = try mod.identifierTokenString(parent_scope, label); |
| 515 | const msg = msg: { | 544 | const msg = msg: { |
| ... | @@ -556,7 +585,7 @@ fn labeledBlockExpr( | ... | @@ -556,7 +585,7 @@ fn labeledBlockExpr( |
| 556 | const tree = parent_scope.tree(); | 585 | const tree = parent_scope.tree(); |
| 557 | const node_datas = tree.nodes.items(.data); | 586 | const node_datas = tree.nodes.items(.data); |
| 558 | const main_tokens = tree.nodes.items(.main_token); | 587 | const main_tokens = tree.nodes.items(.main_token); |
| 559 | const src = tree.token_locs[block_node.lbrace].start; | 588 | const src = token_starts[block_node.lbrace]; |
| 560 | | 589 | |
| 561 | try checkLabelRedefinition(mod, parent_scope, block_node.label); | 590 | try checkLabelRedefinition(mod, parent_scope, block_node.label); |
| 562 | | 591 | |
| ... | @@ -595,7 +624,7 @@ fn labeledBlockExpr( | ... | @@ -595,7 +624,7 @@ fn labeledBlockExpr( |
| 595 | try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements()); | 624 | try blockExprStmts(mod, &block_scope.base, &block_node.base, block_node.statements()); |
| 596 | | 625 | |
| 597 | if (!block_scope.label.?.used) { | 626 | if (!block_scope.label.?.used) { |
| 598 | return mod.fail(parent_scope, tree.token_locs[block_node.label].start, "unused block label", .{}); | 627 | return mod.fail(parent_scope, token_starts[block_node.label], "unused block label", .{}); |
| 599 | } | 628 | } |
| 600 | | 629 | |
| 601 | try gen_zir.instructions.append(mod.gpa, &block_inst.base); | 630 | try gen_zir.instructions.append(mod.gpa, &block_inst.base); |
| ... | @@ -647,7 +676,7 @@ fn blockExprStmts( | ... | @@ -647,7 +676,7 @@ fn blockExprStmts( |
| 647 | | 676 | |
| 648 | var scope = parent_scope; | 677 | var scope = parent_scope; |
| 649 | for (statements) |statement| { | 678 | for (statements) |statement| { |
| 650 | const src = tree.token_locs[statement.firstToken()].start; | 679 | const src = token_starts[statement.firstToken()]; |
| 651 | _ = try addZIRNoOp(mod, scope, src, .dbg_stmt); | 680 | _ = try addZIRNoOp(mod, scope, src, .dbg_stmt); |
| 652 | switch (statement.tag) { | 681 | switch (statement.tag) { |
| 653 | .var_decl => { | 682 | .var_decl => { |
| ... | @@ -694,7 +723,7 @@ fn varDecl( | ... | @@ -694,7 +723,7 @@ fn varDecl( |
| 694 | const tree = scope.tree(); | 723 | const tree = scope.tree(); |
| 695 | const node_datas = tree.nodes.items(.data); | 724 | const node_datas = tree.nodes.items(.data); |
| 696 | const main_tokens = tree.nodes.items(.main_token); | 725 | const main_tokens = tree.nodes.items(.main_token); |
| 697 | const name_src = tree.token_locs[node.name_token].start; | 726 | const name_src = token_starts[node.name_token]; |
| 698 | const ident_name = try mod.identifierTokenString(scope, node.name_token); | 727 | const ident_name = try mod.identifierTokenString(scope, node.name_token); |
| 699 | | 728 | |
| 700 | // Local variables shadowing detection, including function parameters. | 729 | // Local variables shadowing detection, including function parameters. |
| ... | @@ -911,34 +940,46 @@ fn assignOp( | ... | @@ -911,34 +940,46 @@ fn assignOp( |
| 911 | _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result); | 940 | _ = try addZIRBinOp(mod, scope, src, .store, lhs_ptr, result); |
| 912 | } | 941 | } |
| 913 | | 942 | |
| 914 | fn boolNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { | 943 | fn boolNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 915 | const tree = scope.tree(); | 944 | const tree = scope.tree(); |
| 916 | const src = tree.token_locs[node.op_token].start; | 945 | const node_datas = tree.nodes.items(.data); |
| | 946 | const main_tokens = tree.nodes.items(.main_token); |
| | 947 | |
| | 948 | const src = token_starts[main_tokens[node]]; |
| 917 | const bool_type = try addZIRInstConst(mod, scope, src, .{ | 949 | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| 918 | .ty = Type.initTag(.type), | 950 | .ty = Type.initTag(.type), |
| 919 | .val = Value.initTag(.bool_type), | 951 | .val = Value.initTag(.bool_type), |
| 920 | }); | 952 | }); |
| 921 | const operand = try expr(mod, scope, .{ .ty = bool_type }, node.rhs); | 953 | const operand = try expr(mod, scope, .{ .ty = bool_type }, node_datas[node].lhs); |
| 922 | return addZIRUnOp(mod, scope, src, .bool_not, operand); | 954 | return addZIRUnOp(mod, scope, src, .bool_not, operand); |
| 923 | } | 955 | } |
| 924 | | 956 | |
| 925 | fn bitNot(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { | 957 | fn bitNot(mod: *Module, scope: *Scope, node: ast.Node.Index) InnerError!*zir.Inst { |
| 926 | const tree = scope.tree(); | 958 | const tree = scope.tree(); |
| 927 | const src = tree.token_locs[node.op_token].start; | 959 | const node_datas = tree.nodes.items(.data); |
| 928 | const operand = try expr(mod, scope, .none, node.rhs); | 960 | const main_tokens = tree.nodes.items(.main_token); |
| | 961 | |
| | 962 | const src = token_starts[main_tokens[node]]; |
| | 963 | const operand = try expr(mod, scope, .none, node_datas[node].lhs); |
| 929 | return addZIRUnOp(mod, scope, src, .bit_not, operand); | 964 | return addZIRUnOp(mod, scope, src, .bit_not, operand); |
| 930 | } | 965 | } |
| 931 | | 966 | |
| 932 | fn negation(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst { | 967 | fn negation( |
| | 968 | mod: *Module, |
| | 969 | scope: *Scope, |
| | 970 | node: ast.Node.Index, |
| | 971 | op_inst_tag: zir.Inst.Tag, |
| | 972 | ) InnerError!*zir.Inst { |
| 933 | const tree = scope.tree(); | 973 | const tree = scope.tree(); |
| 934 | const src = tree.token_locs[node.op_token].start; | 974 | const node_datas = tree.nodes.items(.data); |
| | 975 | const main_tokens = tree.nodes.items(.main_token); |
| 935 | | 976 | |
| | 977 | const src = token_starts[main_tokens[node]]; |
| 936 | const lhs = try addZIRInstConst(mod, scope, src, .{ | 978 | const lhs = try addZIRInstConst(mod, scope, src, .{ |
| 937 | .ty = Type.initTag(.comptime_int), | 979 | .ty = Type.initTag(.comptime_int), |
| 938 | .val = Value.initTag(.zero), | 980 | .val = Value.initTag(.zero), |
| 939 | }); | 981 | }); |
| 940 | const rhs = try expr(mod, scope, .none, node.rhs); | 982 | const rhs = try expr(mod, scope, .none, node_datas[node].lhs); |
| 941 | | | |
| 942 | return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); | 983 | return addZIRBinOp(mod, scope, src, op_inst_tag, lhs, rhs); |
| 943 | } | 984 | } |
| 944 | | 985 | |
| ... | @@ -948,20 +989,20 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE | ... | @@ -948,20 +989,20 @@ fn addressOf(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerE |
| 948 | | 989 | |
| 949 | fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { | 990 | fn optionalType(mod: *Module, scope: *Scope, node: *ast.Node.SimplePrefixOp) InnerError!*zir.Inst { |
| 950 | const tree = scope.tree(); | 991 | const tree = scope.tree(); |
| 951 | const src = tree.token_locs[node.op_token].start; | 992 | const src = token_starts[node.op_token]; |
| 952 | const operand = try typeExpr(mod, scope, node.rhs); | 993 | const operand = try typeExpr(mod, scope, node.rhs); |
| 953 | return addZIRUnOp(mod, scope, src, .optional_type, operand); | 994 | return addZIRUnOp(mod, scope, src, .optional_type, operand); |
| 954 | } | 995 | } |
| 955 | | 996 | |
| 956 | fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst { | 997 | fn sliceType(mod: *Module, scope: *Scope, node: *ast.Node.slice_type) InnerError!*zir.Inst { |
| 957 | const tree = scope.tree(); | 998 | const tree = scope.tree(); |
| 958 | const src = tree.token_locs[node.op_token].start; | 999 | const src = token_starts[node.op_token]; |
| 959 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice); | 1000 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, .Slice); |
| 960 | } | 1001 | } |
| 961 | | 1002 | |
| 962 | fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst { | 1003 | fn ptrType(mod: *Module, scope: *Scope, node: *ast.Node.PtrType) InnerError!*zir.Inst { |
| 963 | const tree = scope.tree(); | 1004 | const tree = scope.tree(); |
| 964 | const src = tree.token_locs[node.op_token].start; | 1005 | const src = token_starts[node.op_token]; |
| 965 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) { | 1006 | return ptrSliceType(mod, scope, src, &node.ptr_info, node.rhs, switch (tree.token_ids[node.op_token]) { |
| 966 | .Asterisk, .AsteriskAsterisk => .One, | 1007 | .Asterisk, .AsteriskAsterisk => .One, |
| 967 | // TODO stage1 type inference bug | 1008 | // TODO stage1 type inference bug |
| ... | @@ -1018,7 +1059,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, | ... | @@ -1018,7 +1059,7 @@ fn ptrSliceType(mod: *Module, scope: *Scope, src: usize, ptr_info: *ast.PtrInfo, |
| 1018 | | 1059 | |
| 1019 | fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst { | 1060 | fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst { |
| 1020 | const tree = scope.tree(); | 1061 | const tree = scope.tree(); |
| 1021 | const src = tree.token_locs[node.op_token].start; | 1062 | const src = token_starts[node.op_token]; |
| 1022 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1063 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1023 | .ty = Type.initTag(.type), | 1064 | .ty = Type.initTag(.type), |
| 1024 | .val = Value.initTag(.usize_type), | 1065 | .val = Value.initTag(.usize_type), |
| ... | @@ -1033,7 +1074,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst | ... | @@ -1033,7 +1074,7 @@ fn arrayType(mod: *Module, scope: *Scope, node: *ast.Node.array_type) !*zir.Inst |
| 1033 | | 1074 | |
| 1034 | fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst { | 1075 | fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sentinel) !*zir.Inst { |
| 1035 | const tree = scope.tree(); | 1076 | const tree = scope.tree(); |
| 1036 | const src = tree.token_locs[node.op_token].start; | 1077 | const src = token_starts[node.op_token]; |
| 1037 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1078 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1038 | .ty = Type.initTag(.type), | 1079 | .ty = Type.initTag(.type), |
| 1039 | .val = Value.initTag(.usize_type), | 1080 | .val = Value.initTag(.usize_type), |
| ... | @@ -1054,7 +1095,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sen | ... | @@ -1054,7 +1095,7 @@ fn arrayTypeSentinel(mod: *Module, scope: *Scope, node: *ast.Node.array_type_sen |
| 1054 | | 1095 | |
| 1055 | fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst { | 1096 | fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) InnerError!*zir.Inst { |
| 1056 | const tree = scope.tree(); | 1097 | const tree = scope.tree(); |
| 1057 | const src = tree.token_locs[node.anyframe_token].start; | 1098 | const src = token_starts[node.anyframe_token]; |
| 1058 | if (node.result) |some| { | 1099 | if (node.result) |some| { |
| 1059 | const return_type = try typeExpr(mod, scope, some.return_type); | 1100 | const return_type = try typeExpr(mod, scope, some.return_type); |
| 1060 | return addZIRUnOp(mod, scope, src, .anyframe_type, return_type); | 1101 | return addZIRUnOp(mod, scope, src, .anyframe_type, return_type); |
| ... | @@ -1068,7 +1109,7 @@ fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) Inne | ... | @@ -1068,7 +1109,7 @@ fn anyFrameType(mod: *Module, scope: *Scope, node: *ast.Node.anyframe_type) Inne |
| 1068 | | 1109 | |
| 1069 | fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst { | 1110 | fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_inst_tag: zir.Inst.Tag) InnerError!*zir.Inst { |
| 1070 | const tree = scope.tree(); | 1111 | const tree = scope.tree(); |
| 1071 | const src = tree.token_locs[node.op_token].start; | 1112 | const src = token_starts[node.op_token]; |
| 1072 | const error_set = try typeExpr(mod, scope, node.lhs); | 1113 | const error_set = try typeExpr(mod, scope, node.lhs); |
| 1073 | const payload = try typeExpr(mod, scope, node.rhs); | 1114 | const payload = try typeExpr(mod, scope, node.rhs); |
| 1074 | return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload); | 1115 | return addZIRBinOp(mod, scope, src, op_inst_tag, error_set, payload); |
| ... | @@ -1076,7 +1117,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins | ... | @@ -1076,7 +1117,7 @@ fn typeInixOp(mod: *Module, scope: *Scope, node: *ast.Node.SimpleInfixOp, op_ins |
| 1076 | | 1117 | |
| 1077 | fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst { | 1118 | fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir.Inst { |
| 1078 | const tree = scope.tree(); | 1119 | const tree = scope.tree(); |
| 1079 | const src = tree.token_locs[node.name].start; | 1120 | const src = token_starts[node.name]; |
| 1080 | const name = try mod.identifierTokenString(scope, node.name); | 1121 | const name = try mod.identifierTokenString(scope, node.name); |
| 1081 | | 1122 | |
| 1082 | return addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{}); | 1123 | return addZIRInst(mod, scope, src, zir.Inst.EnumLiteral, .{ .name = name }, .{}); |
| ... | @@ -1084,7 +1125,7 @@ fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir. | ... | @@ -1084,7 +1125,7 @@ fn enumLiteral(mod: *Module, scope: *Scope, node: *ast.Node.enum_literal) !*zir. |
| 1084 | | 1125 | |
| 1085 | fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { | 1126 | fn unwrapOptional(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { |
| 1086 | const tree = scope.tree(); | 1127 | const tree = scope.tree(); |
| 1087 | const src = tree.token_locs[node.rtoken].start; | 1128 | const src = token_starts[node.rtoken]; |
| 1088 | | 1129 | |
| 1089 | const operand = try expr(mod, scope, rl, node.lhs); | 1130 | const operand = try expr(mod, scope, rl, node.lhs); |
| 1090 | const op: zir.Inst.Tag = switch (rl) { | 1131 | const op: zir.Inst.Tag = switch (rl) { |
| ... | @@ -1100,7 +1141,7 @@ fn containerField( | ... | @@ -1100,7 +1141,7 @@ fn containerField( |
| 1100 | node: *ast.Node.ContainerField, | 1141 | node: *ast.Node.ContainerField, |
| 1101 | ) InnerError!*zir.Inst { | 1142 | ) InnerError!*zir.Inst { |
| 1102 | const tree = scope.tree(); | 1143 | const tree = scope.tree(); |
| 1103 | const src = tree.token_locs[node.firstToken()].start; | 1144 | const src = token_starts[tree.firstToken(node)]; |
| 1104 | const name = try mod.identifierTokenString(scope, node.name_token); | 1145 | const name = try mod.identifierTokenString(scope, node.name_token); |
| 1105 | | 1146 | |
| 1106 | if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) { | 1147 | if (node.comptime_token == null and node.value_expr == null and node.align_expr == null) { |
| ... | @@ -1133,7 +1174,7 @@ fn containerField( | ... | @@ -1133,7 +1174,7 @@ fn containerField( |
| 1133 | | 1174 | |
| 1134 | fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst { | 1175 | fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.ContainerDecl) InnerError!*zir.Inst { |
| 1135 | const tree = scope.tree(); | 1176 | const tree = scope.tree(); |
| 1136 | const src = tree.token_locs[node.kind_token].start; | 1177 | const src = token_starts[node.kind_token]; |
| 1137 | | 1178 | |
| 1138 | var gen_scope: Scope.GenZIR = .{ | 1179 | var gen_scope: Scope.GenZIR = .{ |
| 1139 | .parent = scope, | 1180 | .parent = scope, |
| ... | @@ -1278,7 +1319,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con | ... | @@ -1278,7 +1319,7 @@ fn containerDecl(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.Con |
| 1278 | | 1319 | |
| 1279 | fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst { | 1320 | fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) InnerError!*zir.Inst { |
| 1280 | const tree = scope.tree(); | 1321 | const tree = scope.tree(); |
| 1281 | const src = tree.token_locs[node.error_token].start; | 1322 | const src = token_starts[node.error_token]; |
| 1282 | const decls = node.decls(); | 1323 | const decls = node.decls(); |
| 1283 | const fields = try scope.arena().alloc([]const u8, decls.len); | 1324 | const fields = try scope.arena().alloc([]const u8, decls.len); |
| 1284 | | 1325 | |
| ... | @@ -1292,7 +1333,7 @@ fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) Inn | ... | @@ -1292,7 +1333,7 @@ fn errorSetDecl(mod: *Module, scope: *Scope, node: *ast.Node.error_set_decl) Inn |
| 1292 | | 1333 | |
| 1293 | fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { | 1334 | fn errorType(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError!*zir.Inst { |
| 1294 | const tree = scope.tree(); | 1335 | const tree = scope.tree(); |
| 1295 | const src = tree.token_locs[node.token].start; | 1336 | const src = token_starts[node.token]; |
| 1296 | return addZIRInstConst(mod, scope, src, .{ | 1337 | return addZIRInstConst(mod, scope, src, .{ |
| 1297 | .ty = Type.initTag(.type), | 1338 | .ty = Type.initTag(.type), |
| 1298 | .val = Value.initTag(.anyerror_type), | 1339 | .val = Value.initTag(.anyerror_type), |
| ... | @@ -1370,7 +1411,7 @@ fn orelseCatchExpr( | ... | @@ -1370,7 +1411,7 @@ fn orelseCatchExpr( |
| 1370 | payload_node: ?*ast.Node, | 1411 | payload_node: ?*ast.Node, |
| 1371 | ) InnerError!*zir.Inst { | 1412 | ) InnerError!*zir.Inst { |
| 1372 | const tree = scope.tree(); | 1413 | const tree = scope.tree(); |
| 1373 | const src = tree.token_locs[op_token].start; | 1414 | const src = token_starts[op_token]; |
| 1374 | | 1415 | |
| 1375 | var block_scope: Scope.GenZIR = .{ | 1416 | var block_scope: Scope.GenZIR = .{ |
| 1376 | .parent = scope, | 1417 | .parent = scope, |
| ... | @@ -1544,7 +1585,7 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as | ... | @@ -1544,7 +1585,7 @@ fn tokenIdentEql(mod: *Module, scope: *Scope, token1: ast.TokenIndex, token2: as |
| 1544 | | 1585 | |
| 1545 | pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst { | 1586 | pub fn field(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.SimpleInfixOp) InnerError!*zir.Inst { |
| 1546 | const tree = scope.tree(); | 1587 | const tree = scope.tree(); |
| 1547 | const src = tree.token_locs[node.op_token].start; | 1588 | const src = token_starts[node.op_token]; |
| 1548 | // TODO custom AST node for field access so that we don't have to go through a node cast here | 1589 | // TODO custom AST node for field access so that we don't have to go through a node cast here |
| 1549 | const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token); | 1590 | const field_name = try mod.identifierTokenString(scope, node.rhs.castTag(.identifier).?.token); |
| 1550 | if (rl == .ref) { | 1591 | if (rl == .ref) { |
| ... | @@ -1568,7 +1609,7 @@ fn namedField( | ... | @@ -1568,7 +1609,7 @@ fn namedField( |
| 1568 | try ensureBuiltinParamCount(mod, scope, call, 2); | 1609 | try ensureBuiltinParamCount(mod, scope, call, 2); |
| 1569 | | 1610 | |
| 1570 | const tree = scope.tree(); | 1611 | const tree = scope.tree(); |
| 1571 | const src = tree.token_locs[call.builtin_token].start; | 1612 | const src = token_starts[call.builtin_token]; |
| 1572 | const params = call.params(); | 1613 | const params = call.params(); |
| 1573 | | 1614 | |
| 1574 | const string_type = try addZIRInstConst(mod, scope, src, .{ | 1615 | const string_type = try addZIRInstConst(mod, scope, src, .{ |
| ... | @@ -1591,7 +1632,7 @@ fn namedField( | ... | @@ -1591,7 +1632,7 @@ fn namedField( |
| 1591 | | 1632 | |
| 1592 | fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst { | 1633 | fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array_access) InnerError!*zir.Inst { |
| 1593 | const tree = scope.tree(); | 1634 | const tree = scope.tree(); |
| 1594 | const src = tree.token_locs[node.rtoken].start; | 1635 | const src = token_starts[node.rtoken]; |
| 1595 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1636 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1596 | .ty = Type.initTag(.type), | 1637 | .ty = Type.initTag(.type), |
| 1597 | .val = Value.initTag(.usize_type), | 1638 | .val = Value.initTag(.usize_type), |
| ... | @@ -1612,7 +1653,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array | ... | @@ -1612,7 +1653,7 @@ fn arrayAccess(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.array |
| 1612 | | 1653 | |
| 1613 | fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst { | 1654 | fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir.Inst { |
| 1614 | const tree = scope.tree(); | 1655 | const tree = scope.tree(); |
| 1615 | const src = tree.token_locs[node.rtoken].start; | 1656 | const src = token_starts[node.rtoken]; |
| 1616 | | 1657 | |
| 1617 | const usize_type = try addZIRInstConst(mod, scope, src, .{ | 1658 | const usize_type = try addZIRInstConst(mod, scope, src, .{ |
| 1618 | .ty = Type.initTag(.type), | 1659 | .ty = Type.initTag(.type), |
| ... | @@ -1642,7 +1683,7 @@ fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir | ... | @@ -1642,7 +1683,7 @@ fn sliceExpr(mod: *Module, scope: *Scope, node: *ast.Node.slice) InnerError!*zir |
| 1642 | | 1683 | |
| 1643 | fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { | 1684 | fn deref(mod: *Module, scope: *Scope, node: *ast.Node.SimpleSuffixOp) InnerError!*zir.Inst { |
| 1644 | const tree = scope.tree(); | 1685 | const tree = scope.tree(); |
| 1645 | const src = tree.token_locs[node.rtoken].start; | 1686 | const src = token_starts[node.rtoken]; |
| 1646 | const lhs = try expr(mod, scope, .none, node.lhs); | 1687 | const lhs = try expr(mod, scope, .none, node.lhs); |
| 1647 | return addZIRUnOp(mod, scope, src, .deref, lhs); | 1688 | return addZIRUnOp(mod, scope, src, .deref, lhs); |
| 1648 | } | 1689 | } |
| ... | @@ -1669,13 +1710,14 @@ fn boolBinOp( | ... | @@ -1669,13 +1710,14 @@ fn boolBinOp( |
| 1669 | mod: *Module, | 1710 | mod: *Module, |
| 1670 | scope: *Scope, | 1711 | scope: *Scope, |
| 1671 | rl: ResultLoc, | 1712 | rl: ResultLoc, |
| 1672 | infix_node: *ast.Node.SimpleInfixOp, | 1713 | infix_node: ast.Node.Index, |
| | 1714 | is_bool_and: bool, |
| 1673 | ) InnerError!*zir.Inst { | 1715 | ) InnerError!*zir.Inst { |
| 1674 | const tree = scope.tree(); | 1716 | const tree = scope.tree(); |
| 1675 | const node_datas = tree.nodes.items(.data); | 1717 | const node_datas = tree.nodes.items(.data); |
| 1676 | const main_tokens = tree.nodes.items(.main_token); | 1718 | const main_tokens = tree.nodes.items(.main_token); |
| 1677 | | 1719 | |
| 1678 | const src = tree.token_locs[infix_node.op_token].start; | 1720 | const src = token_starts[main_tokens[infix_node]]; |
| 1679 | const bool_type = try addZIRInstConst(mod, scope, src, .{ | 1721 | const bool_type = try addZIRInstConst(mod, scope, src, .{ |
| 1680 | .ty = Type.initTag(.type), | 1722 | .ty = Type.initTag(.type), |
| 1681 | .val = Value.initTag(.bool_type), | 1723 | .val = Value.initTag(.bool_type), |
| ... | @@ -1690,7 +1732,7 @@ fn boolBinOp( | ... | @@ -1690,7 +1732,7 @@ fn boolBinOp( |
| 1690 | }; | 1732 | }; |
| 1691 | defer block_scope.instructions.deinit(mod.gpa); | 1733 | defer block_scope.instructions.deinit(mod.gpa); |
| 1692 | | 1734 | |
| 1693 | const lhs = try expr(mod, scope, .{ .ty = bool_type }, infix_node.lhs); | 1735 | const lhs = try expr(mod, scope, .{ .ty = bool_type }, node_datas[infix_node].lhs); |
| 1694 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ | 1736 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, src, zir.Inst.CondBr, .{ |
| 1695 | .condition = lhs, | 1737 | .condition = lhs, |
| 1696 | .then_body = undefined, // populated below | 1738 | .then_body = undefined, // populated below |
| ... | @@ -1710,7 +1752,7 @@ fn boolBinOp( | ... | @@ -1710,7 +1752,7 @@ fn boolBinOp( |
| 1710 | }; | 1752 | }; |
| 1711 | defer rhs_scope.instructions.deinit(mod.gpa); | 1753 | defer rhs_scope.instructions.deinit(mod.gpa); |
| 1712 | | 1754 | |
| 1713 | const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, infix_node.rhs); | 1755 | const rhs = try expr(mod, &rhs_scope.base, .{ .ty = bool_type }, node_datas[infix_node].rhs); |
| 1714 | _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ | 1756 | _ = try addZIRInst(mod, &rhs_scope.base, src, zir.Inst.Break, .{ |
| 1715 | .block = block, | 1757 | .block = block, |
| 1716 | .operand = rhs, | 1758 | .operand = rhs, |
| ... | @@ -1725,7 +1767,6 @@ fn boolBinOp( | ... | @@ -1725,7 +1767,6 @@ fn boolBinOp( |
| 1725 | }; | 1767 | }; |
| 1726 | defer const_scope.instructions.deinit(mod.gpa); | 1768 | defer const_scope.instructions.deinit(mod.gpa); |
| 1727 | | 1769 | |
| 1728 | const is_bool_and = infix_node.base.tag == .bool_and; | | |
| 1729 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ | 1770 | _ = try addZIRInst(mod, &const_scope.base, src, zir.Inst.Break, .{ |
| 1730 | .block = block, | 1771 | .block = block, |
| 1731 | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ | 1772 | .operand = try addZIRInstConst(mod, &const_scope.base, src, .{ |
| ... | @@ -1843,7 +1884,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") | ... | @@ -1843,7 +1884,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") |
| 1843 | const tree = scope.tree(); | 1884 | const tree = scope.tree(); |
| 1844 | const node_datas = tree.nodes.items(.data); | 1885 | const node_datas = tree.nodes.items(.data); |
| 1845 | const main_tokens = tree.nodes.items(.main_token); | 1886 | const main_tokens = tree.nodes.items(.main_token); |
| 1846 | const if_src = tree.token_locs[if_node.if_token].start; | 1887 | const if_src = token_starts[if_node.if_token]; |
| 1847 | const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition); | 1888 | const cond = try cond_kind.cond(mod, &block_scope, if_src, if_node.condition); |
| 1848 | | 1889 | |
| 1849 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, if_src, zir.Inst.CondBr, .{ | 1890 | const condbr = try addZIRInstSpecial(mod, &block_scope.base, if_src, zir.Inst.CondBr, .{ |
| ... | @@ -1856,7 +1897,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") | ... | @@ -1856,7 +1897,7 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") |
| 1856 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), | 1897 | .instructions = try block_scope.arena.dupe(*zir.Inst, block_scope.instructions.items), |
| 1857 | }); | 1898 | }); |
| 1858 | | 1899 | |
| 1859 | const then_src = tree.token_locs[if_node.body.lastToken()].start; | 1900 | const then_src = token_starts[if_node.body.lastToken()]; |
| 1860 | var then_scope: Scope.GenZIR = .{ | 1901 | var then_scope: Scope.GenZIR = .{ |
| 1861 | .parent = scope, | 1902 | .parent = scope, |
| 1862 | .decl = block_scope.decl, | 1903 | .decl = block_scope.decl, |
| ... | @@ -1887,14 +1928,14 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") | ... | @@ -1887,14 +1928,14 @@ fn ifExpr(mod: *Module, scope: *Scope, rl: ResultLoc, if_node: *ast.Node.@"if") |
| 1887 | var else_src: usize = undefined; | 1928 | var else_src: usize = undefined; |
| 1888 | var else_sub_scope: *Module.Scope = undefined; | 1929 | var else_sub_scope: *Module.Scope = undefined; |
| 1889 | const else_result: ?*zir.Inst = if (if_node.@"else") |else_node| blk: { | 1930 | const else_result: ?*zir.Inst = if (if_node.@"else") |else_node| blk: { |
| 1890 | else_src = tree.token_locs[else_node.body.lastToken()].start; | 1931 | else_src = token_starts[else_node.body.lastToken()]; |
| 1891 | // declare payload to the then_scope | 1932 | // declare payload to the then_scope |
| 1892 | else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); | 1933 | else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); |
| 1893 | | 1934 | |
| 1894 | block_scope.break_count += 1; | 1935 | block_scope.break_count += 1; |
| 1895 | break :blk try expr(mod, else_sub_scope, block_scope.break_result_loc, else_node.body); | 1936 | break :blk try expr(mod, else_sub_scope, block_scope.break_result_loc, else_node.body); |
| 1896 | } else blk: { | 1937 | } else blk: { |
| 1897 | else_src = tree.token_locs[if_node.lastToken()].start; | 1938 | else_src = token_starts[if_node.lastToken()]; |
| 1898 | else_sub_scope = &else_scope.base; | 1939 | else_sub_scope = &else_scope.base; |
| 1899 | break :blk null; | 1940 | break :blk null; |
| 1900 | }; | 1941 | }; |
| ... | @@ -1981,7 +2022,7 @@ fn whileExpr( | ... | @@ -1981,7 +2022,7 @@ fn whileExpr( |
| 1981 | const tree = scope.tree(); | 2022 | const tree = scope.tree(); |
| 1982 | const node_datas = tree.nodes.items(.data); | 2023 | const node_datas = tree.nodes.items(.data); |
| 1983 | const main_tokens = tree.nodes.items(.main_token); | 2024 | const main_tokens = tree.nodes.items(.main_token); |
| 1984 | const while_src = tree.token_locs[while_node.while_token].start; | 2025 | const while_src = token_starts[while_node.while_token]; |
| 1985 | const void_type = try addZIRInstConst(mod, scope, while_src, .{ | 2026 | const void_type = try addZIRInstConst(mod, scope, while_src, .{ |
| 1986 | .ty = Type.initTag(.type), | 2027 | .ty = Type.initTag(.type), |
| 1987 | .val = Value.initTag(.void_type), | 2028 | .val = Value.initTag(.void_type), |
| ... | @@ -2028,7 +2069,7 @@ fn whileExpr( | ... | @@ -2028,7 +2069,7 @@ fn whileExpr( |
| 2028 | }); | 2069 | }); |
| 2029 | } | 2070 | } |
| 2030 | | 2071 | |
| 2031 | const then_src = tree.token_locs[while_node.body.lastToken()].start; | 2072 | const then_src = token_starts[while_node.body.lastToken()]; |
| 2032 | var then_scope: Scope.GenZIR = .{ | 2073 | var then_scope: Scope.GenZIR = .{ |
| 2033 | .parent = &continue_scope.base, | 2074 | .parent = &continue_scope.base, |
| 2034 | .decl = continue_scope.decl, | 2075 | .decl = continue_scope.decl, |
| ... | @@ -2055,19 +2096,19 @@ fn whileExpr( | ... | @@ -2055,19 +2096,19 @@ fn whileExpr( |
| 2055 | | 2096 | |
| 2056 | var else_src: usize = undefined; | 2097 | var else_src: usize = undefined; |
| 2057 | const else_result: ?*zir.Inst = if (while_node.@"else") |else_node| blk: { | 2098 | const else_result: ?*zir.Inst = if (while_node.@"else") |else_node| blk: { |
| 2058 | else_src = tree.token_locs[else_node.body.lastToken()].start; | 2099 | else_src = token_starts[else_node.body.lastToken()]; |
| 2059 | // declare payload to the then_scope | 2100 | // declare payload to the then_scope |
| 2060 | const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); | 2101 | const else_sub_scope = try cond_kind.elseSubScope(mod, &else_scope, else_src, else_node.payload); |
| 2061 | | 2102 | |
| 2062 | loop_scope.break_count += 1; | 2103 | loop_scope.break_count += 1; |
| 2063 | break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body); | 2104 | break :blk try expr(mod, else_sub_scope, loop_scope.break_result_loc, else_node.body); |
| 2064 | } else blk: { | 2105 | } else blk: { |
| 2065 | else_src = tree.token_locs[while_node.lastToken()].start; | 2106 | else_src = token_starts[while_node.lastToken()]; |
| 2066 | break :blk null; | 2107 | break :blk null; |
| 2067 | }; | 2108 | }; |
| 2068 | if (loop_scope.label) |some| { | 2109 | if (loop_scope.label) |some| { |
| 2069 | if (!some.used) { | 2110 | if (!some.used) { |
| 2070 | return mod.fail(scope, tree.token_locs[some.token].start, "unused while label", .{}); | 2111 | return mod.fail(scope, token_starts[some.token], "unused while label", .{}); |
| 2071 | } | 2112 | } |
| 2072 | } | 2113 | } |
| 2073 | return finishThenElseBlock( | 2114 | return finishThenElseBlock( |
| ... | @@ -2105,7 +2146,7 @@ fn forExpr( | ... | @@ -2105,7 +2146,7 @@ fn forExpr( |
| 2105 | const tree = scope.tree(); | 2146 | const tree = scope.tree(); |
| 2106 | const node_datas = tree.nodes.items(.data); | 2147 | const node_datas = tree.nodes.items(.data); |
| 2107 | const main_tokens = tree.nodes.items(.main_token); | 2148 | const main_tokens = tree.nodes.items(.main_token); |
| 2108 | const for_src = tree.token_locs[for_node.for_token].start; | 2149 | const for_src = token_starts[for_node.for_token]; |
| 2109 | const index_ptr = blk: { | 2150 | const index_ptr = blk: { |
| 2110 | const usize_type = try addZIRInstConst(mod, scope, for_src, .{ | 2151 | const usize_type = try addZIRInstConst(mod, scope, for_src, .{ |
| 2111 | .ty = Type.initTag(.type), | 2152 | .ty = Type.initTag(.type), |
| ... | @@ -2121,7 +2162,7 @@ fn forExpr( | ... | @@ -2121,7 +2162,7 @@ fn forExpr( |
| 2121 | break :blk index_ptr; | 2162 | break :blk index_ptr; |
| 2122 | }; | 2163 | }; |
| 2123 | const array_ptr = try expr(mod, scope, .ref, for_node.array_expr); | 2164 | const array_ptr = try expr(mod, scope, .ref, for_node.array_expr); |
| 2124 | const cond_src = tree.token_locs[for_node.array_expr.firstToken()].start; | 2165 | const cond_src = token_starts[for_node.array_expr.firstToken()]; |
| 2125 | const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr); | 2166 | const len = try addZIRUnOp(mod, scope, cond_src, .indexable_ptr_len, array_ptr); |
| 2126 | | 2167 | |
| 2127 | var loop_scope: Scope.GenZIR = .{ | 2168 | var loop_scope: Scope.GenZIR = .{ |
| ... | @@ -2191,7 +2232,7 @@ fn forExpr( | ... | @@ -2191,7 +2232,7 @@ fn forExpr( |
| 2191 | } | 2232 | } |
| 2192 | | 2233 | |
| 2193 | // while body | 2234 | // while body |
| 2194 | const then_src = tree.token_locs[for_node.body.lastToken()].start; | 2235 | const then_src = token_starts[for_node.body.lastToken()]; |
| 2195 | var then_scope: Scope.GenZIR = .{ | 2236 | var then_scope: Scope.GenZIR = .{ |
| 2196 | .parent = &cond_scope.base, | 2237 | .parent = &cond_scope.base, |
| 2197 | .decl = cond_scope.decl, | 2238 | .decl = cond_scope.decl, |
| ... | @@ -2215,7 +2256,7 @@ fn forExpr( | ... | @@ -2215,7 +2256,7 @@ fn forExpr( |
| 2215 | const index_symbol_node = payload.index_symbol orelse | 2256 | const index_symbol_node = payload.index_symbol orelse |
| 2216 | break :blk &then_scope.base; | 2257 | break :blk &then_scope.base; |
| 2217 | | 2258 | |
| 2218 | const index_name = tree.tokenSlice(index_symbol_node.firstToken()); | 2259 | const index_name = tree.tokenSlice(tree.firstToken(index_symbol_node)); |
| 2219 | if (mem.eql(u8, index_name, "_")) { | 2260 | if (mem.eql(u8, index_name, "_")) { |
| 2220 | break :blk &then_scope.base; | 2261 | break :blk &then_scope.base; |
| 2221 | } | 2262 | } |
| ... | @@ -2244,16 +2285,16 @@ fn forExpr( | ... | @@ -2244,16 +2285,16 @@ fn forExpr( |
| 2244 | | 2285 | |
| 2245 | var else_src: usize = undefined; | 2286 | var else_src: usize = undefined; |
| 2246 | const else_result: ?*zir.Inst = if (for_node.@"else") |else_node| blk: { | 2287 | const else_result: ?*zir.Inst = if (for_node.@"else") |else_node| blk: { |
| 2247 | else_src = tree.token_locs[else_node.body.lastToken()].start; | 2288 | else_src = token_starts[else_node.body.lastToken()]; |
| 2248 | loop_scope.break_count += 1; | 2289 | loop_scope.break_count += 1; |
| 2249 | break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body); | 2290 | break :blk try expr(mod, &else_scope.base, loop_scope.break_result_loc, else_node.body); |
| 2250 | } else blk: { | 2291 | } else blk: { |
| 2251 | else_src = tree.token_locs[for_node.lastToken()].start; | 2292 | else_src = token_starts[for_node.lastToken()]; |
| 2252 | break :blk null; | 2293 | break :blk null; |
| 2253 | }; | 2294 | }; |
| 2254 | if (loop_scope.label) |some| { | 2295 | if (loop_scope.label) |some| { |
| 2255 | if (!some.used) { | 2296 | if (!some.used) { |
| 2256 | return mod.fail(scope, tree.token_locs[some.token].start, "unused for label", .{}); | 2297 | return mod.fail(scope, token_starts[some.token], "unused for label", .{}); |
| 2257 | } | 2298 | } |
| 2258 | } | 2299 | } |
| 2259 | return finishThenElseBlock( | 2300 | return finishThenElseBlock( |
| ... | @@ -2299,7 +2340,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2299,7 +2340,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2299 | const tree = scope.tree(); | 2340 | const tree = scope.tree(); |
| 2300 | const node_datas = tree.nodes.items(.data); | 2341 | const node_datas = tree.nodes.items(.data); |
| 2301 | const main_tokens = tree.nodes.items(.main_token); | 2342 | const main_tokens = tree.nodes.items(.main_token); |
| 2302 | const switch_src = tree.token_locs[switch_node.switch_token].start; | 2343 | const switch_src = token_starts[switch_node.switch_token]; |
| 2303 | const use_ref = switchCaseUsesRef(switch_node); | 2344 | const use_ref = switchCaseUsesRef(switch_node); |
| 2304 | | 2345 | |
| 2305 | var block_scope: Scope.GenZIR = .{ | 2346 | var block_scope: Scope.GenZIR = .{ |
| ... | @@ -2322,7 +2363,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2322,7 +2363,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2322 | var simple_case_count: usize = 0; | 2363 | var simple_case_count: usize = 0; |
| 2323 | for (switch_node.cases()) |uncasted_case| { | 2364 | for (switch_node.cases()) |uncasted_case| { |
| 2324 | const case = uncasted_case.castTag(.switch_case).?; | 2365 | const case = uncasted_case.castTag(.switch_case).?; |
| 2325 | const case_src = tree.token_locs[case.firstToken()].start; | 2366 | const case_src = token_starts[case.firstToken()]; |
| 2326 | assert(case.items_len != 0); | 2367 | assert(case.items_len != 0); |
| 2327 | | 2368 | |
| 2328 | // Check for else/_ prong, those are handled last. | 2369 | // Check for else/_ prong, those are handled last. |
| ... | @@ -2389,7 +2430,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2389,7 +2430,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2389 | if (getRangeNode(item)) |range| { | 2430 | if (getRangeNode(item)) |range| { |
| 2390 | const start = try comptimeExpr(mod, &block_scope.base, .none, range.lhs); | 2431 | const start = try comptimeExpr(mod, &block_scope.base, .none, range.lhs); |
| 2391 | const end = try comptimeExpr(mod, &block_scope.base, .none, range.rhs); | 2432 | const end = try comptimeExpr(mod, &block_scope.base, .none, range.rhs); |
| 2392 | const range_src = tree.token_locs[range.op_token].start; | 2433 | const range_src = token_starts[range.op_token]; |
| 2393 | const range_inst = try addZIRBinOp(mod, &block_scope.base, range_src, .switch_range, start, end); | 2434 | const range_inst = try addZIRBinOp(mod, &block_scope.base, range_src, .switch_range, start, end); |
| 2394 | try items.append(range_inst); | 2435 | try items.append(range_inst); |
| 2395 | } else { | 2436 | } else { |
| ... | @@ -2447,7 +2488,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2447,7 +2488,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2447 | var case_index: usize = 0; | 2488 | var case_index: usize = 0; |
| 2448 | for (switch_node.cases()) |uncasted_case| { | 2489 | for (switch_node.cases()) |uncasted_case| { |
| 2449 | const case = uncasted_case.castTag(.switch_case).?; | 2490 | const case = uncasted_case.castTag(.switch_case).?; |
| 2450 | const case_src = tree.token_locs[case.firstToken()].start; | 2491 | const case_src = token_starts[case.firstToken()]; |
| 2451 | // reset without freeing to reduce allocations. | 2492 | // reset without freeing to reduce allocations. |
| 2452 | case_scope.instructions.items.len = 0; | 2493 | case_scope.instructions.items.len = 0; |
| 2453 | | 2494 | |
| ... | @@ -2485,7 +2526,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node | ... | @@ -2485,7 +2526,7 @@ fn switchExpr(mod: *Module, scope: *Scope, rl: ResultLoc, switch_node: *ast.Node |
| 2485 | var any_ok: ?*zir.Inst = null; | 2526 | var any_ok: ?*zir.Inst = null; |
| 2486 | for (case.items()) |item| { | 2527 | for (case.items()) |item| { |
| 2487 | if (getRangeNode(item)) |range| { | 2528 | if (getRangeNode(item)) |range| { |
| 2488 | const range_src = tree.token_locs[range.op_token].start; | 2529 | const range_src = token_starts[range.op_token]; |
| 2489 | const range_inst = items.items[items_index].castTag(.switch_range).?; | 2530 | const range_inst = items.items[items_index].castTag(.switch_range).?; |
| 2490 | items_index += 1; | 2531 | items_index += 1; |
| 2491 | | 2532 | |
| ... | @@ -2565,7 +2606,7 @@ fn switchCaseExpr( | ... | @@ -2565,7 +2606,7 @@ fn switchCaseExpr( |
| 2565 | const tree = scope.tree(); | 2606 | const tree = scope.tree(); |
| 2566 | const node_datas = tree.nodes.items(.data); | 2607 | const node_datas = tree.nodes.items(.data); |
| 2567 | const main_tokens = tree.nodes.items(.main_token); | 2608 | const main_tokens = tree.nodes.items(.main_token); |
| 2568 | const case_src = tree.token_locs[case.firstToken()].start; | 2609 | const case_src = token_starts[case.firstToken()]; |
| 2569 | const sub_scope = blk: { | 2610 | const sub_scope = blk: { |
| 2570 | const uncasted_payload = case.payload orelse break :blk scope; | 2611 | const uncasted_payload = case.payload orelse break :blk scope; |
| 2571 | const payload = uncasted_payload.castTag(.PointerPayload).?; | 2612 | const payload = uncasted_payload.castTag(.PointerPayload).?; |
| ... | @@ -2593,7 +2634,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE | ... | @@ -2593,7 +2634,7 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE |
| 2593 | const tree = scope.tree(); | 2634 | const tree = scope.tree(); |
| 2594 | const node_datas = tree.nodes.items(.data); | 2635 | const node_datas = tree.nodes.items(.data); |
| 2595 | const main_tokens = tree.nodes.items(.main_token); | 2636 | const main_tokens = tree.nodes.items(.main_token); |
| 2596 | const src = tree.token_locs[cfe.ltoken].start; | 2637 | const src = token_starts[cfe.ltoken]; |
| 2597 | if (cfe.getRHS()) |rhs_node| { | 2638 | if (cfe.getRHS()) |rhs_node| { |
| 2598 | if (nodeMayNeedMemoryLocation(rhs_node, scope)) { | 2639 | if (nodeMayNeedMemoryLocation(rhs_node, scope)) { |
| 2599 | const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr); | 2640 | const ret_ptr = try addZIRNoOp(mod, scope, src, .ret_ptr); |
| ... | @@ -2609,17 +2650,24 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE | ... | @@ -2609,17 +2650,24 @@ fn ret(mod: *Module, scope: *Scope, cfe: *ast.Node.ControlFlowExpression) InnerE |
| 2609 | } | 2650 | } |
| 2610 | } | 2651 | } |
| 2611 | | 2652 | |
| 2612 | fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneToken) InnerError!*zir.Inst { | 2653 | fn identifier( |
| | 2654 | mod: *Module, |
| | 2655 | scope: *Scope, |
| | 2656 | rl: ResultLoc, |
| | 2657 | ident: ast.Node.Index, |
| | 2658 | ) InnerError!*zir.Inst { |
| 2613 | const tracy = trace(@src()); | 2659 | const tracy = trace(@src()); |
| 2614 | defer tracy.end(); | 2660 | defer tracy.end(); |
| 2615 | | 2661 | |
| 2616 | const tree = scope.tree(); | 2662 | const tree = scope.tree(); |
| 2617 | const node_datas = tree.nodes.items(.data); | 2663 | const node_datas = tree.nodes.items(.data); |
| 2618 | const main_tokens = tree.nodes.items(.main_token); | 2664 | const main_tokens = tree.nodes.items(.main_token); |
| 2619 | const ident_name = try mod.identifierTokenString(scope, ident.token); | 2665 | |
| 2620 | const src = tree.token_locs[ident.token].start; | 2666 | const ident_token = main_tokens[ident]; |
| | 2667 | const ident_name = try mod.identifierTokenString(scope, ident_token); |
| | 2668 | const src = token_starts[ident_token]; |
| 2621 | if (mem.eql(u8, ident_name, "_")) { | 2669 | if (mem.eql(u8, ident_name, "_")) { |
| 2622 | return mod.failNode(scope, &ident.base, "TODO implement '_' identifier", .{}); | 2670 | return mod.failNode(scope, ident, "TODO implement '_' identifier", .{}); |
| 2623 | } | 2671 | } |
| 2624 | | 2672 | |
| 2625 | if (getSimplePrimitiveValue(ident_name)) |typed_value| { | 2673 | if (getSimplePrimitiveValue(ident_name)) |typed_value| { |
| ... | @@ -2634,7 +2682,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo | ... | @@ -2634,7 +2682,7 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 2634 | const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) { | 2682 | const bit_count = std.fmt.parseInt(u16, ident_name[1..], 10) catch |err| switch (err) { |
| 2635 | error.Overflow => return mod.failNode( | 2683 | error.Overflow => return mod.failNode( |
| 2636 | scope, | 2684 | scope, |
| 2637 | &ident.base, | 2685 | ident, |
| 2638 | "primitive integer type '{s}' exceeds maximum bit width of 65535", | 2686 | "primitive integer type '{s}' exceeds maximum bit width of 65535", |
| 2639 | .{ident_name}, | 2687 | .{ident_name}, |
| 2640 | ), | 2688 | ), |
| ... | @@ -2698,64 +2746,91 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo | ... | @@ -2698,64 +2746,91 @@ fn identifier(mod: *Module, scope: *Scope, rl: ResultLoc, ident: *ast.Node.OneTo |
| 2698 | } | 2746 | } |
| 2699 | } | 2747 | } |
| 2700 | | 2748 | |
| 2701 | return mod.failNode(scope, &ident.base, "use of undeclared identifier '{s}'", .{ident_name}); | 2749 | return mod.failNode(scope, ident, "use of undeclared identifier '{s}'", .{ident_name}); |
| 2702 | } | 2750 | } |
| 2703 | | 2751 | |
| 2704 | fn stringLiteral(mod: *Module, scope: *Scope, str_lit: *ast.Node.OneToken) InnerError!*zir.Inst { | 2752 | fn stringLiteral( |
| | 2753 | mod: *Module, |
| | 2754 | scope: *Scope, |
| | 2755 | rl: ResultLoc, |
| | 2756 | str_lit: ast.Node.Index, |
| | 2757 | ) InnerError!*zir.Inst { |
| 2705 | const tree = scope.tree(); | 2758 | const tree = scope.tree(); |
| 2706 | const node_datas = tree.nodes.items(.data); | 2759 | const node_datas = tree.nodes.items(.data); |
| 2707 | const main_tokens = tree.nodes.items(.main_token); | 2760 | const main_tokens = tree.nodes.items(.main_token); |
| 2708 | const unparsed_bytes = tree.tokenSlice(str_lit.token); | 2761 | |
| | 2762 | const str_lit_token = main_tokens[str_lit]; |
| | 2763 | const unparsed_bytes = tree.tokenSlice(str_lit_token); |
| 2709 | const arena = scope.arena(); | 2764 | const arena = scope.arena(); |
| 2710 | | 2765 | |
| 2711 | var bad_index: usize = undefined; | 2766 | var bad_index: usize = undefined; |
| 2712 | const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) { | 2767 | const bytes = std.zig.parseStringLiteral(arena, unparsed_bytes, &bad_index) catch |err| switch (err) { |
| 2713 | error.InvalidCharacter => { | 2768 | error.InvalidCharacter => { |
| 2714 | const bad_byte = unparsed_bytes[bad_index]; | 2769 | const bad_byte = unparsed_bytes[bad_index]; |
| 2715 | const src = tree.token_locs[str_lit.token].start; | 2770 | const src = token_starts[str_lit_token]; |
| 2716 | return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte}); | 2771 | return mod.fail(scope, src + bad_index, "invalid string literal character: '{c}'\n", .{bad_byte}); |
| 2717 | }, | 2772 | }, |
| 2718 | else => |e| return e, | 2773 | else => |e| return e, |
| 2719 | }; | 2774 | }; |
| 2720 | | 2775 | |
| 2721 | const src = tree.token_locs[str_lit.token].start; | 2776 | const src = token_starts[str_lit_token]; |
| 2722 | return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); | 2777 | const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); |
| | 2778 | return rvalue(mod, scope, rl, str_inst); |
| 2723 | } | 2779 | } |
| 2724 | | 2780 | |
| 2725 | fn multilineStrLiteral(mod: *Module, scope: *Scope, node: *ast.Node.MultilineStringLiteral) !*zir.Inst { | 2781 | fn multilineStringLiteral( |
| | 2782 | mod: *Module, |
| | 2783 | scope: *Scope, |
| | 2784 | rl: ResultLoc, |
| | 2785 | str_lit: ast.Node.Index, |
| | 2786 | ) InnerError!*zir.Inst { |
| 2726 | const tree = scope.tree(); | 2787 | const tree = scope.tree(); |
| 2727 | const node_datas = tree.nodes.items(.data); | 2788 | const node_datas = tree.nodes.items(.data); |
| 2728 | const main_tokens = tree.nodes.items(.main_token); | 2789 | const main_tokens = tree.nodes.items(.main_token); |
| 2729 | const lines = node.linesConst(); | | |
| 2730 | const src = tree.token_locs[lines[0]].start; | | |
| 2731 | | 2790 | |
| 2732 | // line lengths and new lines | 2791 | const start = node_datas[node].lhs; |
| 2733 | var len = lines.len - 1; | 2792 | const end = node_datas[node].rhs; |
| 2734 | for (lines) |line| { | | |
| 2735 | // 2 for the '//' + 1 for '\n' | | |
| 2736 | len += tree.tokenSlice(line).len - 3; | | |
| 2737 | } | | |
| 2738 | | 2793 | |
| 2739 | const bytes = try scope.arena().alloc(u8, len); | 2794 | // Count the number of bytes to allocate. |
| 2740 | var i: usize = 0; | 2795 | const len: usize = len: { |
| 2741 | for (lines) |line, line_i| { | 2796 | var tok_i = start; |
| 2742 | if (line_i != 0) { | 2797 | var len: usize = 0; |
| 2743 | bytes[i] = '\n'; | 2798 | while (tok_i <= end) : (tok_i += 1) { |
| 2744 | i += 1; | 2799 | // 2 for the '//' + 1 for '\n' |
| | 2800 | len += tree.tokenSlice(tok_i).len - 3; |
| 2745 | } | 2801 | } |
| 2746 | const slice = tree.tokenSlice(line); | 2802 | break :len len; |
| 2747 | mem.copy(u8, bytes[i..], slice[2 .. slice.len - 1]); | 2803 | }; |
| 2748 | i += slice.len - 3; | 2804 | const bytes = try scope.arena().alloc(u8, len); |
| 2749 | } | 2805 | // First line: do not append a newline. |
| 2750 | | 2806 | var byte_i: usize = 0; |
| 2751 | return addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); | 2807 | var tok_i = start; |
| | 2808 | { |
| | 2809 | const slice = tree.tokenSlice(tok_i); |
| | 2810 | const line_bytes = slice[2 .. slice.len - 1]; |
| | 2811 | mem.copy(u8, bytes[byte_i..], line_bytes); |
| | 2812 | byte_i += line_bytes.len; |
| | 2813 | tok_i += 1; |
| | 2814 | } |
| | 2815 | // Following lines: each line prepends a newline. |
| | 2816 | while (tok_i <= end) : (tok_i += 1) { |
| | 2817 | bytes[byte_i] = '\n'; |
| | 2818 | byte_i += 1; |
| | 2819 | const slice = tree.tokenSlice(tok_i); |
| | 2820 | const line_bytes = slice[2 .. slice.len - 1]; |
| | 2821 | mem.copy(u8, bytes[byte_i..], line_bytes); |
| | 2822 | byte_i += line_bytes.len; |
| | 2823 | } |
| | 2824 | const src = token_starts[start]; |
| | 2825 | const str_inst = try addZIRInst(mod, scope, src, zir.Inst.Str, .{ .bytes = bytes }, .{}); |
| | 2826 | return rvalue(mod, scope, rl, str_inst); |
| 2752 | } | 2827 | } |
| 2753 | | 2828 | |
| 2754 | fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst { | 2829 | fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst { |
| 2755 | const tree = scope.tree(); | 2830 | const tree = scope.tree(); |
| 2756 | const node_datas = tree.nodes.items(.data); | 2831 | const node_datas = tree.nodes.items(.data); |
| 2757 | const main_tokens = tree.nodes.items(.main_token); | 2832 | const main_tokens = tree.nodes.items(.main_token); |
| 2758 | const src = tree.token_locs[node.token].start; | 2833 | const src = token_starts[node.token]; |
| 2759 | const slice = tree.tokenSlice(node.token); | 2834 | const slice = tree.tokenSlice(node.token); |
| 2760 | | 2835 | |
| 2761 | var bad_index: usize = undefined; | 2836 | var bad_index: usize = undefined; |
| ... | @@ -2772,13 +2847,19 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst | ... | @@ -2772,13 +2847,19 @@ fn charLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) !*zir.Inst |
| 2772 | }); | 2847 | }); |
| 2773 | } | 2848 | } |
| 2774 | | 2849 | |
| 2775 | fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) InnerError!*zir.Inst { | 2850 | fn integerLiteral( |
| | 2851 | mod: *Module, |
| | 2852 | scope: *Scope, |
| | 2853 | rl: ResultLoc, |
| | 2854 | int_lit: ast.Node.Index, |
| | 2855 | ) InnerError!*zir.Inst { |
| 2776 | const arena = scope.arena(); | 2856 | const arena = scope.arena(); |
| 2777 | const tree = scope.tree(); | 2857 | const tree = scope.tree(); |
| 2778 | const node_datas = tree.nodes.items(.data); | | |
| 2779 | const main_tokens = tree.nodes.items(.main_token); | 2858 | const main_tokens = tree.nodes.items(.main_token); |
| 2780 | const prefixed_bytes = tree.tokenSlice(int_lit.token); | 2859 | |
| 2781 | const base = if (mem.startsWith(u8, prefixed_bytes, "0x")) | 2860 | const int_token = main_tokens[int_lit]; |
| | 2861 | const prefixed_bytes = tree.tokenSlice(int_token); |
| | 2862 | const base: u8 = if (mem.startsWith(u8, prefixed_bytes, "0x")) |
| 2782 | 16 | 2863 | 16 |
| 2783 | else if (mem.startsWith(u8, prefixed_bytes, "0o")) | 2864 | else if (mem.startsWith(u8, prefixed_bytes, "0o")) |
| 2784 | 8 | 2865 | 8 |
| ... | @@ -2793,13 +2874,14 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne | ... | @@ -2793,13 +2874,14 @@ fn integerLiteral(mod: *Module, scope: *Scope, int_lit: *ast.Node.OneToken) Inne |
| 2793 | prefixed_bytes[2..]; | 2874 | prefixed_bytes[2..]; |
| 2794 | | 2875 | |
| 2795 | if (std.fmt.parseInt(u64, bytes, base)) |small_int| { | 2876 | if (std.fmt.parseInt(u64, bytes, base)) |small_int| { |
| 2796 | const src = tree.token_locs[int_lit.token].start; | 2877 | const src = token_starts[int_token]; |
| 2797 | return addZIRInstConst(mod, scope, src, .{ | 2878 | const result = try addZIRInstConst(mod, scope, src, .{ |
| 2798 | .ty = Type.initTag(.comptime_int), | 2879 | .ty = Type.initTag(.comptime_int), |
| 2799 | .val = try Value.Tag.int_u64.create(arena, small_int), | 2880 | .val = try Value.Tag.int_u64.create(arena, small_int), |
| 2800 | }); | 2881 | }); |
| | 2882 | return rvalue(mod, scope, rl, result); |
| 2801 | } else |err| { | 2883 | } else |err| { |
| 2802 | return mod.failTok(scope, int_lit.token, "TODO implement int literals that don't fit in a u64", .{}); | 2884 | return mod.failTok(scope, int_token, "TODO implement int literals that don't fit in a u64", .{}); |
| 2803 | } | 2885 | } |
| 2804 | } | 2886 | } |
| 2805 | | 2887 | |
| ... | @@ -2816,7 +2898,7 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne | ... | @@ -2816,7 +2898,7 @@ fn floatLiteral(mod: *Module, scope: *Scope, float_lit: *ast.Node.OneToken) Inne |
| 2816 | const float_number = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) { | 2898 | const float_number = std.fmt.parseFloat(f128, bytes) catch |e| switch (e) { |
| 2817 | error.InvalidCharacter => unreachable, // validated by tokenizer | 2899 | error.InvalidCharacter => unreachable, // validated by tokenizer |
| 2818 | }; | 2900 | }; |
| 2819 | const src = tree.token_locs[float_lit.token].start; | 2901 | const src = token_starts[float_lit.token]; |
| 2820 | return addZIRInstConst(mod, scope, src, .{ | 2902 | return addZIRInstConst(mod, scope, src, .{ |
| 2821 | .ty = Type.initTag(.comptime_float), | 2903 | .ty = Type.initTag(.comptime_float), |
| 2822 | .val = try Value.Tag.float_128.create(arena, float_number), | 2904 | .val = try Value.Tag.float_128.create(arena, float_number), |
| ... | @@ -2828,7 +2910,7 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro | ... | @@ -2828,7 +2910,7 @@ fn undefLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerErro |
| 2828 | const tree = scope.tree(); | 2910 | const tree = scope.tree(); |
| 2829 | const node_datas = tree.nodes.items(.data); | 2911 | const node_datas = tree.nodes.items(.data); |
| 2830 | const main_tokens = tree.nodes.items(.main_token); | 2912 | const main_tokens = tree.nodes.items(.main_token); |
| 2831 | const src = tree.token_locs[node.token].start; | 2913 | const src = token_starts[node.token]; |
| 2832 | return addZIRInstConst(mod, scope, src, .{ | 2914 | return addZIRInstConst(mod, scope, src, .{ |
| 2833 | .ty = Type.initTag(.@"undefined"), | 2915 | .ty = Type.initTag(.@"undefined"), |
| 2834 | .val = Value.initTag(.undef), | 2916 | .val = Value.initTag(.undef), |
| ... | @@ -2840,7 +2922,7 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError | ... | @@ -2840,7 +2922,7 @@ fn boolLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError |
| 2840 | const tree = scope.tree(); | 2922 | const tree = scope.tree(); |
| 2841 | const node_datas = tree.nodes.items(.data); | 2923 | const node_datas = tree.nodes.items(.data); |
| 2842 | const main_tokens = tree.nodes.items(.main_token); | 2924 | const main_tokens = tree.nodes.items(.main_token); |
| 2843 | const src = tree.token_locs[node.token].start; | 2925 | const src = token_starts[node.token]; |
| 2844 | return addZIRInstConst(mod, scope, src, .{ | 2926 | return addZIRInstConst(mod, scope, src, .{ |
| 2845 | .ty = Type.initTag(.bool), | 2927 | .ty = Type.initTag(.bool), |
| 2846 | .val = switch (tree.token_ids[node.token]) { | 2928 | .val = switch (tree.token_ids[node.token]) { |
| ... | @@ -2856,34 +2938,34 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError | ... | @@ -2856,34 +2938,34 @@ fn nullLiteral(mod: *Module, scope: *Scope, node: *ast.Node.OneToken) InnerError |
| 2856 | const tree = scope.tree(); | 2938 | const tree = scope.tree(); |
| 2857 | const node_datas = tree.nodes.items(.data); | 2939 | const node_datas = tree.nodes.items(.data); |
| 2858 | const main_tokens = tree.nodes.items(.main_token); | 2940 | const main_tokens = tree.nodes.items(.main_token); |
| 2859 | const src = tree.token_locs[node.token].start; | 2941 | const src = token_starts[node.token]; |
| 2860 | return addZIRInstConst(mod, scope, src, .{ | 2942 | return addZIRInstConst(mod, scope, src, .{ |
| 2861 | .ty = Type.initTag(.@"null"), | 2943 | .ty = Type.initTag(.@"null"), |
| 2862 | .val = Value.initTag(.null_value), | 2944 | .val = Value.initTag(.null_value), |
| 2863 | }); | 2945 | }); |
| 2864 | } | 2946 | } |
| 2865 | | 2947 | |
| 2866 | fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError!*zir.Inst { | 2948 | fn assembly(mod: *Module, scope: *Scope, rl: ResultLoc, full: ast.full.Asm) InnerError!*zir.Inst { |
| 2867 | if (asm_node.outputs.len != 0) { | | |
| 2868 | return mod.failNode(scope, &asm_node.base, "TODO implement asm with an output", .{}); | | |
| 2869 | } | | |
| 2870 | const arena = scope.arena(); | 2949 | const arena = scope.arena(); |
| 2871 | const tree = scope.tree(); | 2950 | const tree = scope.tree(); |
| 2872 | const node_datas = tree.nodes.items(.data); | 2951 | const node_datas = tree.nodes.items(.data); |
| 2873 | const main_tokens = tree.nodes.items(.main_token); | 2952 | const main_tokens = tree.nodes.items(.main_token); |
| 2874 | | 2953 | |
| 2875 | const inputs = try arena.alloc(*zir.Inst, asm_node.inputs.len); | 2954 | if (full.outputs.len != 0) { |
| 2876 | const args = try arena.alloc(*zir.Inst, asm_node.inputs.len); | 2955 | return mod.failTok(scope, full.ast.asm_token, "TODO implement asm with an output", .{}); |
| | 2956 | } |
| 2877 | | 2957 | |
| 2878 | const src = tree.token_locs[asm_node.asm_token].start; | 2958 | const inputs = try arena.alloc(*zir.Inst, full.inputs.len); |
| | 2959 | const args = try arena.alloc(*zir.Inst, full.inputs.len); |
| 2879 | | 2960 | |
| | 2961 | const src = token_starts[full.ast.asm_token]; |
| 2880 | const str_type = try addZIRInstConst(mod, scope, src, .{ | 2962 | const str_type = try addZIRInstConst(mod, scope, src, .{ |
| 2881 | .ty = Type.initTag(.type), | 2963 | .ty = Type.initTag(.type), |
| 2882 | .val = Value.initTag(.const_slice_u8_type), | 2964 | .val = Value.initTag(.const_slice_u8_type), |
| 2883 | }); | 2965 | }); |
| 2884 | const str_type_rl: ResultLoc = .{ .ty = str_type }; | 2966 | const str_type_rl: ResultLoc = .{ .ty = str_type }; |
| 2885 | | 2967 | |
| 2886 | for (asm_node.inputs) |input, i| { | 2968 | for (full.inputs) |input, i| { |
| 2887 | // TODO semantically analyze constraints | 2969 | // TODO semantically analyze constraints |
| 2888 | inputs[i] = try expr(mod, scope, str_type_rl, input.constraint); | 2970 | inputs[i] = try expr(mod, scope, str_type_rl, input.constraint); |
| 2889 | args[i] = try expr(mod, scope, .none, input.expr); | 2971 | args[i] = try expr(mod, scope, .none, input.expr); |
| ... | @@ -2894,15 +2976,15 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError! | ... | @@ -2894,15 +2976,15 @@ fn assembly(mod: *Module, scope: *Scope, asm_node: *ast.Node.@"asm") InnerError! |
| 2894 | .val = Value.initTag(.void_type), | 2976 | .val = Value.initTag(.void_type), |
| 2895 | }); | 2977 | }); |
| 2896 | const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{ | 2978 | const asm_inst = try addZIRInst(mod, scope, src, zir.Inst.@"asm", .{ |
| 2897 | .asm_source = try expr(mod, scope, str_type_rl, asm_node.template), | 2979 | .asm_source = try expr(mod, scope, str_type_rl, full.ast.template), |
| 2898 | .return_type = return_type, | 2980 | .return_type = return_type, |
| 2899 | }, .{ | 2981 | }, .{ |
| 2900 | .@"volatile" = asm_node.volatile_token != null, | 2982 | .@"volatile" = full.volatile_token != null, |
| 2901 | //.clobbers = TODO handle clobbers | 2983 | //.clobbers = TODO handle clobbers |
| 2902 | .inputs = inputs, | 2984 | .inputs = inputs, |
| 2903 | .args = args, | 2985 | .args = args, |
| 2904 | }); | 2986 | }); |
| 2905 | return asm_inst; | 2987 | return rvalue(mod, scope, rl, asm_inst); |
| 2906 | } | 2988 | } |
| 2907 | | 2989 | |
| 2908 | fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void { | 2990 | fn ensureBuiltinParamCount(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call, count: u32) !void { |
| ... | @@ -2924,7 +3006,7 @@ fn simpleCast( | ... | @@ -2924,7 +3006,7 @@ fn simpleCast( |
| 2924 | const tree = scope.tree(); | 3006 | const tree = scope.tree(); |
| 2925 | const node_datas = tree.nodes.items(.data); | 3007 | const node_datas = tree.nodes.items(.data); |
| 2926 | const main_tokens = tree.nodes.items(.main_token); | 3008 | const main_tokens = tree.nodes.items(.main_token); |
| 2927 | const src = tree.token_locs[call.builtin_token].start; | 3009 | const src = token_starts[call.builtin_token]; |
| 2928 | const params = call.params(); | 3010 | const params = call.params(); |
| 2929 | const dest_type = try typeExpr(mod, scope, params[0]); | 3011 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 2930 | const rhs = try expr(mod, scope, .none, params[1]); | 3012 | const rhs = try expr(mod, scope, .none, params[1]); |
| ... | @@ -2938,7 +3020,7 @@ fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerErro | ... | @@ -2938,7 +3020,7 @@ fn ptrToInt(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerErro |
| 2938 | const tree = scope.tree(); | 3020 | const tree = scope.tree(); |
| 2939 | const node_datas = tree.nodes.items(.data); | 3021 | const node_datas = tree.nodes.items(.data); |
| 2940 | const main_tokens = tree.nodes.items(.main_token); | 3022 | const main_tokens = tree.nodes.items(.main_token); |
| 2941 | const src = tree.token_locs[call.builtin_token].start; | 3023 | const src = token_starts[call.builtin_token]; |
| 2942 | return addZIRUnOp(mod, scope, src, .ptrtoint, operand); | 3024 | return addZIRUnOp(mod, scope, src, .ptrtoint, operand); |
| 2943 | } | 3025 | } |
| 2944 | | 3026 | |
| ... | @@ -2952,7 +3034,7 @@ fn as( | ... | @@ -2952,7 +3034,7 @@ fn as( |
| 2952 | const tree = scope.tree(); | 3034 | const tree = scope.tree(); |
| 2953 | const node_datas = tree.nodes.items(.data); | 3035 | const node_datas = tree.nodes.items(.data); |
| 2954 | const main_tokens = tree.nodes.items(.main_token); | 3036 | const main_tokens = tree.nodes.items(.main_token); |
| 2955 | const src = tree.token_locs[call.builtin_token].start; | 3037 | const src = token_starts[call.builtin_token]; |
| 2956 | const params = call.params(); | 3038 | const params = call.params(); |
| 2957 | const dest_type = try typeExpr(mod, scope, params[0]); | 3039 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 2958 | switch (rl) { | 3040 | switch (rl) { |
| ... | @@ -3028,7 +3110,7 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_c | ... | @@ -3028,7 +3110,7 @@ fn bitCast(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_c |
| 3028 | const tree = scope.tree(); | 3110 | const tree = scope.tree(); |
| 3029 | const node_datas = tree.nodes.items(.data); | 3111 | const node_datas = tree.nodes.items(.data); |
| 3030 | const main_tokens = tree.nodes.items(.main_token); | 3112 | const main_tokens = tree.nodes.items(.main_token); |
| 3031 | const src = tree.token_locs[call.builtin_token].start; | 3113 | const src = token_starts[call.builtin_token]; |
| 3032 | const params = call.params(); | 3114 | const params = call.params(); |
| 3033 | const dest_type = try typeExpr(mod, scope, params[0]); | 3115 | const dest_type = try typeExpr(mod, scope, params[0]); |
| 3034 | switch (rl) { | 3116 | switch (rl) { |
| ... | @@ -3074,7 +3156,7 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError! | ... | @@ -3074,7 +3156,7 @@ fn import(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerError! |
| 3074 | const tree = scope.tree(); | 3156 | const tree = scope.tree(); |
| 3075 | const node_datas = tree.nodes.items(.data); | 3157 | const node_datas = tree.nodes.items(.data); |
| 3076 | const main_tokens = tree.nodes.items(.main_token); | 3158 | const main_tokens = tree.nodes.items(.main_token); |
| 3077 | const src = tree.token_locs[call.builtin_token].start; | 3159 | const src = token_starts[call.builtin_token]; |
| 3078 | const params = call.params(); | 3160 | const params = call.params(); |
| 3079 | const target = try expr(mod, scope, .none, params[0]); | 3161 | const target = try expr(mod, scope, .none, params[0]); |
| 3080 | return addZIRUnOp(mod, scope, src, .import, target); | 3162 | return addZIRUnOp(mod, scope, src, .import, target); |
| ... | @@ -3085,7 +3167,7 @@ fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) Inner | ... | @@ -3085,7 +3167,7 @@ fn compileError(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) Inner |
| 3085 | const tree = scope.tree(); | 3167 | const tree = scope.tree(); |
| 3086 | const node_datas = tree.nodes.items(.data); | 3168 | const node_datas = tree.nodes.items(.data); |
| 3087 | const main_tokens = tree.nodes.items(.main_token); | 3169 | const main_tokens = tree.nodes.items(.main_token); |
| 3088 | const src = tree.token_locs[call.builtin_token].start; | 3170 | const src = token_starts[call.builtin_token]; |
| 3089 | const params = call.params(); | 3171 | const params = call.params(); |
| 3090 | const target = try expr(mod, scope, .none, params[0]); | 3172 | const target = try expr(mod, scope, .none, params[0]); |
| 3091 | return addZIRUnOp(mod, scope, src, .compile_error, target); | 3173 | return addZIRUnOp(mod, scope, src, .compile_error, target); |
| ... | @@ -3096,7 +3178,7 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) | ... | @@ -3096,7 +3178,7 @@ fn setEvalBranchQuota(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) |
| 3096 | const tree = scope.tree(); | 3178 | const tree = scope.tree(); |
| 3097 | const node_datas = tree.nodes.items(.data); | 3179 | const node_datas = tree.nodes.items(.data); |
| 3098 | const main_tokens = tree.nodes.items(.main_token); | 3180 | const main_tokens = tree.nodes.items(.main_token); |
| 3099 | const src = tree.token_locs[call.builtin_token].start; | 3181 | const src = token_starts[call.builtin_token]; |
| 3100 | const params = call.params(); | 3182 | const params = call.params(); |
| 3101 | const u32_type = try addZIRInstConst(mod, scope, src, .{ | 3183 | const u32_type = try addZIRInstConst(mod, scope, src, .{ |
| 3102 | .ty = Type.initTag(.type), | 3184 | .ty = Type.initTag(.type), |
| ... | @@ -3111,7 +3193,7 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_ca | ... | @@ -3111,7 +3193,7 @@ fn typeOf(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.builtin_ca |
| 3111 | const node_datas = tree.nodes.items(.data); | 3193 | const node_datas = tree.nodes.items(.data); |
| 3112 | const main_tokens = tree.nodes.items(.main_token); | 3194 | const main_tokens = tree.nodes.items(.main_token); |
| 3113 | const arena = scope.arena(); | 3195 | const arena = scope.arena(); |
| 3114 | const src = tree.token_locs[call.builtin_token].start; | 3196 | const src = token_starts[call.builtin_token]; |
| 3115 | const params = call.params(); | 3197 | const params = call.params(); |
| 3116 | if (params.len < 1) { | 3198 | if (params.len < 1) { |
| 3117 | return mod.failTok(scope, call.builtin_token, "expected at least 1 argument, found 0", .{}); | 3199 | return mod.failTok(scope, call.builtin_token, "expected at least 1 argument, found 0", .{}); |
| ... | @@ -3129,7 +3211,7 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerEr | ... | @@ -3129,7 +3211,7 @@ fn compileLog(mod: *Module, scope: *Scope, call: *ast.Node.builtin_call) InnerEr |
| 3129 | const node_datas = tree.nodes.items(.data); | 3211 | const node_datas = tree.nodes.items(.data); |
| 3130 | const main_tokens = tree.nodes.items(.main_token); | 3212 | const main_tokens = tree.nodes.items(.main_token); |
| 3131 | const arena = scope.arena(); | 3213 | const arena = scope.arena(); |
| 3132 | const src = tree.token_locs[call.builtin_token].start; | 3214 | const src = token_starts[call.builtin_token]; |
| 3133 | const params = call.params(); | 3215 | const params = call.params(); |
| 3134 | var targets = try arena.alloc(*zir.Inst, params.len); | 3216 | var targets = try arena.alloc(*zir.Inst, params.len); |
| 3135 | for (params) |param, param_i| | 3217 | for (params) |param, param_i| |
| ... | @@ -3161,7 +3243,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.built | ... | @@ -3161,7 +3243,7 @@ fn builtinCall(mod: *Module, scope: *Scope, rl: ResultLoc, call: *ast.Node.built |
| 3161 | } else if (mem.eql(u8, builtin_name, "@TypeOf")) { | 3243 | } else if (mem.eql(u8, builtin_name, "@TypeOf")) { |
| 3162 | return typeOf(mod, scope, rl, call); | 3244 | return typeOf(mod, scope, rl, call); |
| 3163 | } else if (mem.eql(u8, builtin_name, "@breakpoint")) { | 3245 | } else if (mem.eql(u8, builtin_name, "@breakpoint")) { |
| 3164 | const src = tree.token_locs[call.builtin_token].start; | 3246 | const src = token_starts[call.builtin_token]; |
| 3165 | return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint)); | 3247 | return rvalue(mod, scope, rl, try addZIRNoOp(mod, scope, src, .breakpoint)); |
| 3166 | } else if (mem.eql(u8, builtin_name, "@import")) { | 3248 | } else if (mem.eql(u8, builtin_name, "@import")) { |
| 3167 | return rvalue(mod, scope, rl, try import(mod, scope, call)); | 3249 | return rvalue(mod, scope, rl, try import(mod, scope, call)); |
| ... | @@ -3187,7 +3269,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In | ... | @@ -3187,7 +3269,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In |
| 3187 | const param_nodes = node.params(); | 3269 | const param_nodes = node.params(); |
| 3188 | const args = try scope.getGenZIR().arena.alloc(*zir.Inst, param_nodes.len); | 3270 | const args = try scope.getGenZIR().arena.alloc(*zir.Inst, param_nodes.len); |
| 3189 | for (param_nodes) |param_node, i| { | 3271 | for (param_nodes) |param_node, i| { |
| 3190 | const param_src = tree.token_locs[param_node.firstToken()].start; | 3272 | const param_src = token_starts[tree.firstToken(param_node)]; |
| 3191 | const param_type = try addZIRInst(mod, scope, param_src, zir.Inst.ParamType, .{ | 3273 | const param_type = try addZIRInst(mod, scope, param_src, zir.Inst.ParamType, .{ |
| 3192 | .func = lhs, | 3274 | .func = lhs, |
| 3193 | .arg_index = i, | 3275 | .arg_index = i, |
| ... | @@ -3195,7 +3277,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In | ... | @@ -3195,7 +3277,7 @@ fn callExpr(mod: *Module, scope: *Scope, rl: ResultLoc, node: *ast.Node.call) In |
| 3195 | args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node); | 3277 | args[i] = try expr(mod, scope, .{ .ty = param_type }, param_node); |
| 3196 | } | 3278 | } |
| 3197 | | 3279 | |
| 3198 | const src = tree.token_locs[node.lhs.firstToken()].start; | 3280 | const src = token_starts[node.lhs.firstToken()]; |
| 3199 | const result = try addZIRInst(mod, scope, src, zir.Inst.Call, .{ | 3281 | const result = try addZIRInst(mod, scope, src, zir.Inst.Call, .{ |
| 3200 | .func = lhs, | 3282 | .func = lhs, |
| 3201 | .args = args, | 3283 | .args = args, |
| ... | @@ -3208,7 +3290,7 @@ fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerE | ... | @@ -3208,7 +3290,7 @@ fn unreach(mod: *Module, scope: *Scope, unreach_node: *ast.Node.OneToken) InnerE |
| 3208 | const tree = scope.tree(); | 3290 | const tree = scope.tree(); |
| 3209 | const node_datas = tree.nodes.items(.data); | 3291 | const node_datas = tree.nodes.items(.data); |
| 3210 | const main_tokens = tree.nodes.items(.main_token); | 3292 | const main_tokens = tree.nodes.items(.main_token); |
| 3211 | const src = tree.token_locs[unreach_node.token].start; | 3293 | const src = token_starts[unreach_node.token]; |
| 3212 | return addZIRNoOp(mod, scope, src, .unreachable_safe); | 3294 | return addZIRNoOp(mod, scope, src, .unreachable_safe); |
| 3213 | } | 3295 | } |
| 3214 | | 3296 | |
| ... | @@ -3528,6 +3610,8 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr | ... | @@ -3528,6 +3610,8 @@ fn rvalue(mod: *Module, scope: *Scope, rl: ResultLoc, result: *zir.Inst) InnerEr |
| 3528 | } | 3610 | } |
| 3529 | } | 3611 | } |
| 3530 | | 3612 | |
| | 3613 | /// TODO when reworking ZIR memory layout, make the void value correspond to a hard coded |
| | 3614 | /// index; that way this does not actually need to allocate anything. |
| 3531 | fn rvalueVoid( | 3615 | fn rvalueVoid( |
| 3532 | mod: *Module, | 3616 | mod: *Module, |
| 3533 | scope: *Scope, | 3617 | scope: *Scope, |