using CanonSharp.Pascal.Parser; using CanonSharp.Pascal.SyntaxTree; using CanonSharp.Tests.Utils; namespace CanonSharp.Tests.ParserTests; public class StatementParserTests : GrammarParserTestBase { [Fact] public void StatementTest1() { AssignNode node = RunParser(GrammarParser.StatementParser(), "temp := 1"); Assert.Equal("temp", node.Variable.Identifier.LiteralValue); Assert.Equal(1, node.Expression.Convert().Value); } [Fact] public void IfTest1() { IfNode node = RunParser(GrammarParser.IfParser(), """ if i = 1 then a := a + 1 else a := a + 2 """); Assert.NotNull(node.ElseStatement); BinaryOperatorNode condition = node.Condition.Convert(); Assert.Equal(BinaryOperatorType.Equal, condition.OperatorType); AssignNode statement = node.Statement.Convert(); Assert.Equal("a", statement.Variable.Identifier.LiteralValue); AssignNode elseStatement = node.Statement.Convert(); Assert.Equal("a", elseStatement.Variable.Identifier.LiteralValue); } [Fact] public void IfTest2() { IfNode node = RunParser(GrammarParser.IfParser(), """ if i = 1 then if i = 2 then a := a + 1 else a := a + 2 """); Assert.Null(node.ElseStatement); IfNode subIfNode = node.Statement.Convert(); Assert.NotNull(subIfNode.ElseStatement); } [Fact] public void ForTest1() { ForNode node = RunParser(GrammarParser.ForParser(), """ for i := 1 to 10 do a := a + i """); Assert.Equal("i", node.Identifier.LiteralValue); Assert.Equal(1, node.LeftCondition.Convert().Value); Assert.Equal(10, node.RightCondition.Convert().Value); AssignNode assignNode = node.Statement.Convert(); Assert.Equal("a", assignNode.Variable.Identifier.LiteralValue); } [Fact] public void WhileTest1() { WhileNode node = RunParser(GrammarParser.WhileParser(), """ while c >= 1 do a := a + 1; """); BinaryOperatorNode binaryOperatorNode = node.Condition.Convert(); Assert.Equal(BinaryOperatorType.GreaterEqual, binaryOperatorNode.OperatorType); AssignNode assignNode = node.Statement.Convert(); Assert.Equal("a", assignNode.Variable.Identifier.LiteralValue); } [Fact] public void ProcedureCallTest1() { ProcedureCallNode node = RunParser(GrammarParser.ProcedureCallParser(), "test()"); Assert.Equal("test", node.Identifier.LiteralValue); Assert.Empty(node.Parameters); node = RunParser(GrammarParser.ProcedureCallParser(), "test"); Assert.Equal("test", node.Identifier.LiteralValue); Assert.Empty(node.Parameters); } [Fact] public void ProcedureCallTest2() { ProcedureCallNode node = RunParser(GrammarParser.ProcedureCallParser(), "test(1 + 1, true)"); Assert.Equal(2, node.Parameters.Count); BinaryOperatorNode firstParameter = node.Parameters[0].Convert(); Assert.Equal(BinaryOperatorType.Add, firstParameter.OperatorType); BooleanValueNode secondParameter = node.Parameters[1].Convert(); Assert.True(secondParameter.Value); } [Fact] public void ProcedureCallTest3() { ProcedureCallNode node = RunParser(GrammarParser.ProcedureCallParser(), "test(1 * + 1, test2[0])"); Assert.Equal(2, node.Parameters.Count); VariableNode secondParameter = node.Parameters[1].Convert(); Assert.Equal("test2", secondParameter.Identifier.LiteralValue); Assert.Single(secondParameter.Indexers); } [Theory] [InlineData(""" begin temp := 1 + 1; flag := true and false; end """)] [InlineData(""" begin temp := 1 + 1; flag := true and false end """)] public void CompoundStatementTest1(string input) { BlockNode node = RunParser(GrammarParser.CompoundStatementParser(), input); Assert.Equal(2, node.Statements.Count); AssignNode assignNode = node.Statements[0].Convert(); Assert.Equal("temp", assignNode.Variable.Identifier.LiteralValue); assignNode = node.Statements[1].Convert(); Assert.Equal("flag", assignNode.Variable.Identifier.LiteralValue); } [Fact] public void CompoundStatementTest2() { BlockNode node = RunParser(GrammarParser.CompoundStatementParser(), "begin end"); Assert.Empty(node.Statements); } [Fact] public void ProgramHeadTest1() { ProgramHead head = RunParser(GrammarParser.ProgramHeadParser(), "program main"); Assert.Equal("main", head.ProgramName.LiteralValue); } [Theory] [InlineData(""" begin temp := 1 + 1; flag := true and false; end """)] [InlineData(""" begin temp := 1 + 1; flag := true and false end """)] public void ProgramBodyTest1(string input) { BlockNode node = RunParser(GrammarParser.ProgramBodyParser(), input).MainBlock; Assert.Equal(2, node.Statements.Count); AssignNode assignNode = node.Statements[0].Convert(); Assert.Equal("temp", assignNode.Variable.Identifier.LiteralValue); assignNode = node.Statements[1].Convert(); Assert.Equal("flag", assignNode.Variable.Identifier.LiteralValue); } }