using CanonSharp.Pascal.Parser; using CanonSharp.Pascal.SyntaxTree; using CanonSharp.Tests.Utils; namespace CanonSharp.Tests.ParserTests; public sealed class ExpressionParserTests : GrammarParserTestBase { [Fact] public void BoolTest() { BooleanValueNode node = RunParser(GrammarParser.FactorParser(), "false"); Assert.False(node.Value); node = RunParser(GrammarParser.FactorParser(), "true"); Assert.True(node.Value); } [Fact] public void NumberTest() { IntegerValueNode integerValueNode = RunParser(GrammarParser.FactorParser(), "123456"); Assert.Equal(123456, integerValueNode.Value); FloatValueNode floatValueNode = RunParser(GrammarParser.FactorParser(), "123.456"); Assert.Equal(123.456, floatValueNode.Value); } [Fact] public void UnaryOperatorTest() { UnaryOperatorNode node = RunParser(GrammarParser.FactorParser(), "- 123"); Assert.Equal(UnaryOperatorType.Minus, node.OperatorType); Assert.Equal(123, node.Node.Convert().Value); node = RunParser(GrammarParser.FactorParser(), "+ 100.5"); Assert.Equal(UnaryOperatorType.Plus, node.OperatorType); Assert.Equal(100.5, node.Node.Convert().Value); } [Fact] public void IdentifierTest() { VariableNode node = RunParser(GrammarParser.VariableParser(), "temp"); Assert.Equal("temp", node.Identifier.LiteralValue); } [Fact] public void ArrayIdentifierTest() { VariableNode node = RunParser(GrammarParser.VariableParser(), "a[0]"); Assert.Equal("a", node.Identifier.LiteralValue); Assert.Single(node.Indexers); Assert.Equal(0, node.Indexers.First().Convert().Value); node = RunParser(GrammarParser.VariableParser(), "a[i + 1]"); Assert.Equal("a", node.Identifier.LiteralValue); Assert.Single(node.Indexers); BinaryOperatorNode binaryOperatorNode = node.Indexers.First().Convert(); Assert.Equal(BinaryOperatorType.Add, binaryOperatorNode.OperatorType); Assert.Equal("i", binaryOperatorNode.Left.Convert().Identifier.LiteralValue); Assert.Equal(1, binaryOperatorNode.Right.Convert().Value); node = RunParser(GrammarParser.VariableParser(), "a[b[i + 1] - 10, c]"); Assert.Equal("a", node.Identifier.LiteralValue); Assert.Equal(2, node.Indexers.Count); VariableNode secondNode = node.Indexers[1].Convert(); Assert.Equal("c", secondNode.Identifier.LiteralValue); Assert.Empty(secondNode.Indexers); BinaryOperatorNode firstNode = node.Indexers[0].Convert(); Assert.Equal(BinaryOperatorType.Subtract, firstNode.OperatorType); Assert.Equal(10, firstNode.Right.Convert().Value); VariableNode variableNode = firstNode.Left.Convert(); Assert.Equal("b", variableNode.Identifier.LiteralValue); Assert.Single(variableNode.Indexers); binaryOperatorNode = variableNode.Indexers[0].Convert(); Assert.Equal(BinaryOperatorType.Add, binaryOperatorNode.OperatorType); Assert.Equal("i", binaryOperatorNode.Left.Convert().Identifier.LiteralValue); Assert.Equal(1, binaryOperatorNode.Right.Convert().Value); } [Fact] public void ProcedureCallTest() { ProcedureCallNode node = RunParser(GrammarParser.FactorParser(), "test(1)"); Assert.Equal("test", node.Identifier.LiteralValue); Assert.Single(node.Parameters); Assert.Equal(1, node.Parameters[0].Convert().Value); node = RunParser(GrammarParser.FactorParser(), "test()"); Assert.Equal("test", node.Identifier.LiteralValue); Assert.Empty(node.Parameters); VariableNode variableNode = RunParser(GrammarParser.FactorParser(), "test"); Assert.Equal("test", variableNode.Identifier.LiteralValue); Assert.Empty(variableNode.Indexers); } [Fact] public void SingleTermTest() { VariableNode node = RunParser(GrammarParser.TermParser(), "temp"); Assert.Equal("temp", node.Identifier.LiteralValue); UnaryOperatorNode unaryOperatorNode = RunParser(GrammarParser.TermParser(), "- 123"); Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType); Assert.Equal(123, unaryOperatorNode.Node.Convert().Value); unaryOperatorNode = RunParser(GrammarParser.TermParser(), "+ 100.5"); Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType); Assert.Equal(100.5, unaryOperatorNode.Node.Convert().Value); } [Fact] public void MultiplyTermTest1() { BinaryOperatorNode node = RunParser(GrammarParser.TermParser(), "10 / 2"); Assert.Equal(BinaryOperatorType.Divide, node.OperatorType); Assert.Equal(10, node.Left.Convert().Value); Assert.Equal(2, node.Right.Convert().Value); } [Fact] public void MultiplyTermTest2() { BinaryOperatorNode node = RunParser(GrammarParser.TermParser(), "10 div 2"); Assert.Equal(BinaryOperatorType.IntegerDivide, node.OperatorType); Assert.Equal(10, node.Left.Convert().Value); Assert.Equal(2, node.Right.Convert().Value); } [Fact] public void MultiplyTermTest3() { BinaryOperatorNode node = RunParser(GrammarParser.TermParser(), "temp * 2 div 3"); Assert.Equal(BinaryOperatorType.IntegerDivide, node.OperatorType); Assert.Equal(3, node.Right.Convert().Value); BinaryOperatorNode leftNode = node.Left.Convert(); Assert.Equal(BinaryOperatorType.Multiply, leftNode.OperatorType); Assert.Equal("temp", leftNode.Left.Convert().Identifier.LiteralValue); Assert.Equal(2, leftNode.Right.Convert().Value); } [Fact] public void SimpleExpressionTest1() { VariableNode node = RunParser(GrammarParser.SimpleExpressionParser(), "temp"); Assert.Equal("temp", node.Identifier.LiteralValue); UnaryOperatorNode unaryOperatorNode = RunParser(GrammarParser.SimpleExpressionParser(), "- 123"); Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType); Assert.Equal(123, unaryOperatorNode.Node.Convert().Value); unaryOperatorNode = RunParser(GrammarParser.SimpleExpressionParser(), "+ 100.5"); Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType); Assert.Equal(100.5, unaryOperatorNode.Node.Convert().Value); } [Fact] public void SimpleExpressionTest2() { BinaryOperatorNode node = RunParser(GrammarParser.SimpleExpressionParser(), "1 + 1"); Assert.Equal(BinaryOperatorType.Add, node.OperatorType); Assert.Equal(1, node.Left.Convert().Value); Assert.Equal(1, node.Right.Convert().Value); node = RunParser(GrammarParser.SimpleExpressionParser(), "1 + 1 - 2"); Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType); Assert.Equal(2, node.Right.Convert().Value); BinaryOperatorNode leftNode = node.Left.Convert(); Assert.Equal(BinaryOperatorType.Add, leftNode.OperatorType); Assert.Equal(1, leftNode.Left.Convert().Value); Assert.Equal(1, leftNode.Right.Convert().Value); } [Fact] public void SimpleExpressionTest3() { BinaryOperatorNode node = RunParser(GrammarParser.SimpleExpressionParser(), "1 - 2 * 5"); Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType); Assert.Equal(1, node.Left.Convert().Value); BinaryOperatorNode rightNode = node.Right.Convert(); Assert.Equal(BinaryOperatorType.Multiply, rightNode.OperatorType); Assert.Equal(2, rightNode.Left.Convert().Value); Assert.Equal(5, rightNode.Right.Convert().Value); } [Fact] public void SimpleExpressionTest4() { BinaryOperatorNode node = RunParser(GrammarParser.SimpleExpressionParser(), "1 + +1"); Assert.Equal(BinaryOperatorType.Add, node.OperatorType); Assert.Equal(1, node.Left.Convert().Value); UnaryOperatorNode unaryOperatorNode = node.Right.Convert(); Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType); Assert.Equal(1, unaryOperatorNode.Node.Convert().Value); node = RunParser(GrammarParser.SimpleExpressionParser(), "1 - -1"); Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType); Assert.Equal(1, node.Left.Convert().Value); unaryOperatorNode = node.Right.Convert(); Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType); Assert.Equal(1, unaryOperatorNode.Node.Convert().Value); node = RunParser(GrammarParser.SimpleExpressionParser(), "+ 1 - - 1"); Assert.Equal(BinaryOperatorType.Subtract, node.OperatorType); unaryOperatorNode = node.Left.Convert(); Assert.Equal(UnaryOperatorType.Plus, unaryOperatorNode.OperatorType); Assert.Equal(1, unaryOperatorNode.Node.Convert().Value); unaryOperatorNode = node.Right.Convert(); Assert.Equal(UnaryOperatorType.Minus, unaryOperatorNode.OperatorType); Assert.Equal(1, unaryOperatorNode.Node.Convert().Value); } [Fact] public void SimpleExpressionTest5() { BinaryOperatorNode node = RunParser(GrammarParser.SimpleExpressionParser(), "true and temp or temp and false"); Assert.Equal(BinaryOperatorType.Or, node.OperatorType); BinaryOperatorNode left = node.Left.Convert(); Assert.Equal(BinaryOperatorType.And, left.OperatorType); BinaryOperatorNode right = node.Right.Convert(); Assert.Equal(BinaryOperatorType.And, right.OperatorType); } [Fact] public void ExpressionTest1() { BinaryOperatorNode node = RunParser(GrammarParser.ExpressionParser(), "true and temp or temp and false"); Assert.Equal(BinaryOperatorType.Or, node.OperatorType); BinaryOperatorNode left = node.Left.Convert(); Assert.Equal(BinaryOperatorType.And, left.OperatorType); BinaryOperatorNode right = node.Right.Convert(); Assert.Equal(BinaryOperatorType.And, right.OperatorType); } [Fact] public void ExpressionTest2() { BinaryOperatorNode node = RunParser(GrammarParser.ExpressionParser(), "2 >= 1"); Assert.Equal(BinaryOperatorType.GreaterEqual, node.OperatorType); Assert.Equal(2, node.Left.Convert().Value); Assert.Equal(1, node.Right.Convert().Value); } [Fact] public void ExpressionTest3() { BinaryOperatorNode node = RunParser(GrammarParser.ExpressionParser(), "(1 + 1) * 2"); Assert.Equal(BinaryOperatorType.Multiply, node.OperatorType); Assert.Equal(2, node.Right.Convert().Value); node = node.Left.Convert(); Assert.Equal(BinaryOperatorType.Add, node.OperatorType); Assert.Equal(1, node.Left.Convert().Value); Assert.Equal(1, node.Right.Convert().Value); } [Fact] public void ExpressionsTest1() { List nodes = RunParser(GrammarParser.ExpressionsParser(), "1 + 1, 2 * 3"); Assert.Equal(BinaryOperatorType.Add, nodes[0].OperatorType); Assert.Equal(BinaryOperatorType.Multiply, nodes[1].OperatorType); } [Fact] public void VariableTest1() { VariableNode node = RunParser(GrammarParser.VariableParser(), "temp"); Assert.Equal("temp", node.Identifier.LiteralValue); } }