| ... | @@ -694,11 +694,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -694,11 +694,11 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 694 | .bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and), | 694 | .bool_and => return boolBinOp(gz, scope, rl, node, .bool_br_and), |
| 695 | .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or), | 695 | .bool_or => return boolBinOp(gz, scope, rl, node, .bool_br_or), |
| 696 | | 696 | |
| 697 | .bool_not => return boolNot(gz, scope, rl, node), | 697 | .bool_not => return simpleUnOp(gz, scope, rl, node, bool_rl, node_datas[node].lhs, .bool_not), |
| 698 | .bit_not => return bitNot(gz, scope, rl, node), | 698 | .bit_not => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .bit_not), |
| 699 | | 699 | |
| 700 | .negation => return negation(gz, scope, rl, node, .negate), | 700 | .negation => return negation(gz, scope, rl, node), |
| 701 | .negation_wrap => return negation(gz, scope, rl, node, .negate_wrap), | 701 | .negation_wrap => return simpleUnOp(gz, scope, rl, node, .none, node_datas[node].lhs, .negate_wrap), |
| 702 | | 702 | |
| 703 | .identifier => return identifier(gz, scope, rl, node), | 703 | .identifier => return identifier(gz, scope, rl, node), |
| 704 | | 704 | |
| ... | @@ -748,7 +748,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr | ... | @@ -748,7 +748,7 @@ fn expr(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerEr |
| 748 | }, | 748 | }, |
| 749 | .@"return" => return ret(gz, scope, node), | 749 | .@"return" => return ret(gz, scope, node), |
| 750 | .field_access => return fieldAccess(gz, scope, rl, node), | 750 | .field_access => return fieldAccess(gz, scope, rl, node), |
| 751 | .float_literal => return floatLiteral(gz, rl, node), | 751 | .float_literal => return floatLiteral(gz, rl, node, .positive), |
| 752 | | 752 | |
| 753 | .if_simple => return ifExpr(gz, scope, rl.br(), node, tree.ifSimple(node)), | 753 | .if_simple => return ifExpr(gz, scope, rl.br(), node, tree.ifSimple(node)), |
| 754 | .@"if" => return ifExpr(gz, scope, rl.br(), node, tree.ifFull(node)), | 754 | .@"if" => return ifExpr(gz, scope, rl.br(), node, tree.ifFull(node)), |
| ... | @@ -3029,42 +3029,6 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE | ... | @@ -3029,42 +3029,6 @@ fn assignShiftSat(gz: *GenZir, scope: *Scope, infix_node: Ast.Node.Index) InnerE |
| 3029 | _ = try gz.addBin(.store, lhs_ptr, result); | 3029 | _ = try gz.addBin(.store, lhs_ptr, result); |
| 3030 | } | 3030 | } |
| 3031 | | 3031 | |
| 3032 | fn boolNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | | |
| 3033 | const astgen = gz.astgen; | | |
| 3034 | const tree = astgen.tree; | | |
| 3035 | const node_datas = tree.nodes.items(.data); | | |
| 3036 | | | |
| 3037 | const operand = try expr(gz, scope, bool_rl, node_datas[node].lhs); | | |
| 3038 | const result = try gz.addUnNode(.bool_not, operand, node); | | |
| 3039 | return rvalue(gz, rl, result, node); | | |
| 3040 | } | | |
| 3041 | | | |
| 3042 | fn bitNot(gz: *GenZir, scope: *Scope, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | | |
| 3043 | const astgen = gz.astgen; | | |
| 3044 | const tree = astgen.tree; | | |
| 3045 | const node_datas = tree.nodes.items(.data); | | |
| 3046 | | | |
| 3047 | const operand = try expr(gz, scope, .none, node_datas[node].lhs); | | |
| 3048 | const result = try gz.addUnNode(.bit_not, operand, node); | | |
| 3049 | return rvalue(gz, rl, result, node); | | |
| 3050 | } | | |
| 3051 | | | |
| 3052 | fn negation( | | |
| 3053 | gz: *GenZir, | | |
| 3054 | scope: *Scope, | | |
| 3055 | rl: ResultLoc, | | |
| 3056 | node: Ast.Node.Index, | | |
| 3057 | tag: Zir.Inst.Tag, | | |
| 3058 | ) InnerError!Zir.Inst.Ref { | | |
| 3059 | const astgen = gz.astgen; | | |
| 3060 | const tree = astgen.tree; | | |
| 3061 | const node_datas = tree.nodes.items(.data); | | |
| 3062 | | | |
| 3063 | const operand = try expr(gz, scope, .none, node_datas[node].lhs); | | |
| 3064 | const result = try gz.addUnNode(tag, operand, node); | | |
| 3065 | return rvalue(gz, rl, result, node); | | |
| 3066 | } | | |
| 3067 | | | |
| 3068 | fn ptrType( | 3032 | fn ptrType( |
| 3069 | gz: *GenZir, | 3033 | gz: *GenZir, |
| 3070 | scope: *Scope, | 3034 | scope: *Scope, |
| ... | @@ -6728,14 +6692,16 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Z | ... | @@ -6728,14 +6692,16 @@ fn integerLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Z |
| 6728 | return rvalue(gz, rl, result, node); | 6692 | return rvalue(gz, rl, result, node); |
| 6729 | } | 6693 | } |
| 6730 | | 6694 | |
| 6731 | fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir.Inst.Ref { | 6695 | const Sign = enum { negative, positive }; |
| | 6696 | |
| | 6697 | fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index, sign: Sign) InnerError!Zir.Inst.Ref { |
| 6732 | const astgen = gz.astgen; | 6698 | const astgen = gz.astgen; |
| 6733 | const tree = astgen.tree; | 6699 | const tree = astgen.tree; |
| 6734 | const main_tokens = tree.nodes.items(.main_token); | 6700 | const main_tokens = tree.nodes.items(.main_token); |
| 6735 | | 6701 | |
| 6736 | const main_token = main_tokens[node]; | 6702 | const main_token = main_tokens[node]; |
| 6737 | const bytes = tree.tokenSlice(main_token); | 6703 | const bytes = tree.tokenSlice(main_token); |
| 6738 | const float_number: f128 = if (bytes.len > 2 and bytes[1] == 'x') hex: { | 6704 | const unsigned_float_number: f128 = if (bytes.len > 2 and bytes[1] == 'x') hex: { |
| 6739 | assert(bytes[0] == '0'); // validated by tokenizer | 6705 | assert(bytes[0] == '0'); // validated by tokenizer |
| 6740 | break :hex std.fmt.parseHexFloat(f128, bytes) catch |err| switch (err) { | 6706 | break :hex std.fmt.parseHexFloat(f128, bytes) catch |err| switch (err) { |
| 6741 | error.InvalidCharacter => unreachable, // validated by tokenizer | 6707 | error.InvalidCharacter => unreachable, // validated by tokenizer |
| ... | @@ -6744,6 +6710,10 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir | ... | @@ -6744,6 +6710,10 @@ fn floatLiteral(gz: *GenZir, rl: ResultLoc, node: Ast.Node.Index) InnerError!Zir |
| 6744 | } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) { | 6710 | } else std.fmt.parseFloat(f128, bytes) catch |err| switch (err) { |
| 6745 | error.InvalidCharacter => unreachable, // validated by tokenizer | 6711 | error.InvalidCharacter => unreachable, // validated by tokenizer |
| 6746 | }; | 6712 | }; |
| | 6713 | const float_number = switch (sign) { |
| | 6714 | .negative => -unsigned_float_number, |
| | 6715 | .positive => unsigned_float_number, |
| | 6716 | }; |
| 6747 | // If the value fits into a f64 without losing any precision, store it that way. | 6717 | // If the value fits into a f64 without losing any precision, store it that way. |
| 6748 | @setFloatMode(.Strict); | 6718 | @setFloatMode(.Strict); |
| 6749 | const smaller_float = @floatCast(f64, float_number); | 6719 | const smaller_float = @floatCast(f64, float_number); |
| ... | @@ -7651,6 +7621,29 @@ fn simpleUnOp( | ... | @@ -7651,6 +7621,29 @@ fn simpleUnOp( |
| 7651 | return rvalue(gz, rl, result, node); | 7621 | return rvalue(gz, rl, result, node); |
| 7652 | } | 7622 | } |
| 7653 | | 7623 | |
| | 7624 | fn negation( |
| | 7625 | gz: *GenZir, |
| | 7626 | scope: *Scope, |
| | 7627 | rl: ResultLoc, |
| | 7628 | node: Ast.Node.Index, |
| | 7629 | ) InnerError!Zir.Inst.Ref { |
| | 7630 | const astgen = gz.astgen; |
| | 7631 | const tree = astgen.tree; |
| | 7632 | const node_tags = tree.nodes.items(.tag); |
| | 7633 | const node_datas = tree.nodes.items(.data); |
| | 7634 | |
| | 7635 | // Check for float literal as the sub-expression because we want to preserve |
| | 7636 | // its negativity rather than having it go through comptime subtraction. |
| | 7637 | const operand_node = node_datas[node].lhs; |
| | 7638 | if (node_tags[operand_node] == .float_literal) { |
| | 7639 | return floatLiteral(gz, rl, operand_node, .negative); |
| | 7640 | } |
| | 7641 | |
| | 7642 | const operand = try expr(gz, scope, .none, operand_node); |
| | 7643 | const result = try gz.addUnNode(.negate, operand, node); |
| | 7644 | return rvalue(gz, rl, result, node); |
| | 7645 | } |
| | 7646 | |
| 7654 | fn cmpxchg( | 7647 | fn cmpxchg( |
| 7655 | gz: *GenZir, | 7648 | gz: *GenZir, |
| 7656 | scope: *Scope, | 7649 | scope: *Scope, |