diff --git a/src/parser/expr_cursor.rs b/src/parser/expr_cursor.rs index ce2006a7..b6cf8aa4 100644 --- a/src/parser/expr_cursor.rs +++ b/src/parser/expr_cursor.rs @@ -116,12 +116,12 @@ impl ExprParserWithCursor { /// 乗算式をパース fn parse_multiplicative_expr(cursor: &mut TokenCursor) -> Result { - let mut left = Self::parse_postfix_expr(cursor)?; + let mut left = Self::parse_unary_expr(cursor)?; while let Some(op) = Self::match_multiplicative_op(cursor) { let op_line = cursor.current().line; cursor.advance(); - let right = Self::parse_postfix_expr(cursor)?; + let right = Self::parse_unary_expr(cursor)?; left = ASTNode::BinaryOp { operator: op, left: Box::new(left), @@ -133,6 +133,34 @@ impl ExprParserWithCursor { Ok(left) } + /// 単項演算子(- / not) + fn parse_unary_expr(cursor: &mut TokenCursor) -> Result { + // match式は旧系にあるが、ここでは単項の最小対応に限定 + match &cursor.current().token_type { + TokenType::MINUS => { + let op_line = cursor.current().line; + cursor.advance(); + let operand = Self::parse_unary_expr(cursor)?; + Ok(ASTNode::UnaryOp { + operator: crate::ast::UnaryOperator::Minus, + operand: Box::new(operand), + span: Span::new(op_line, 0, op_line, 0), + }) + } + TokenType::NOT => { + let op_line = cursor.current().line; + cursor.advance(); + let operand = Self::parse_unary_expr(cursor)?; + Ok(ASTNode::UnaryOp { + operator: crate::ast::UnaryOperator::Not, + operand: Box::new(operand), + span: Span::new(op_line, 0, op_line, 0), + }) + } + _ => Self::parse_postfix_expr(cursor), + } + } + /// 後置(フィールドアクセス・関数/メソッド呼び出し)をパース fn parse_postfix_expr(cursor: &mut TokenCursor) -> Result { let mut expr = Self::parse_primary_expr(cursor)?; diff --git a/tools/smokes/v2/profiles/integration/parity/vm_llvm_precedence_arith.sh b/tools/smokes/v2/profiles/integration/parity/vm_llvm_precedence_arith.sh new file mode 100644 index 00000000..771f3a77 --- /dev/null +++ b/tools/smokes/v2/profiles/integration/parity/vm_llvm_precedence_arith.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# vm_llvm_precedence_arith.sh - arithmetic precedence parity (1 + 2 * 3 == 7, (1+2)*3==9) + +source "$(dirname "$0")/../../../lib/test_runner.sh" +source "$(dirname "$0")/../../../lib/result_checker.sh" + +require_env || exit 2 +preflight_plugins || exit 2 + +test_vm_llvm_precedence_arith() { + local code='print(1 + 2 * 3)\nprint((1 + 2) * 3)' + check_parity -c "$code" "vm_llvm_precedence_arith" +} + +run_test "vm_llvm_precedence_arith" test_vm_llvm_precedence_arith + diff --git a/tools/smokes/v2/profiles/integration/parity/vm_llvm_unary_not.sh b/tools/smokes/v2/profiles/integration/parity/vm_llvm_unary_not.sh new file mode 100644 index 00000000..aa223a14 --- /dev/null +++ b/tools/smokes/v2/profiles/integration/parity/vm_llvm_unary_not.sh @@ -0,0 +1,16 @@ +#!/bin/bash +# vm_llvm_unary_not.sh - unary 'not' parity + +source "$(dirname "$0")/../../../lib/test_runner.sh" +source "$(dirname "$0")/../../../lib/result_checker.sh" + +require_env || exit 2 +preflight_plugins || exit 2 + +test_vm_llvm_unary_not() { + local code='print(not false)' + check_parity -c "$code" "vm_llvm_unary_not" +} + +run_test "vm_llvm_unary_not" test_vm_llvm_unary_not +