예제 #1
0
        public void ReplacePushAndPopWithUnary()
        {
            var cu = new CompilationUnit().AddStatements(new Statement[]
            {
                new MethodInvocation("Push").AddArgument(0.ToLiteral()).ToStatement(),
                new MethodInvocation("Push").AddArgument(false.ToLiteral()).ToStatement(),
                new JumpStatement(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not), 0)
            });
            var expectedCu = new CompilationUnit().AddStatements(new Statement[]
            {
                new JumpStatement(new UnaryExpression(false.ToLiteral(), Operator.Not), 0)
            });

            var actualCu = new ReplacePushAndPop().Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #2
0
        public void ReplaceVariables()
        {
            var cu = new CompilationUnit().AddStatements(new []
            {
                new BinaryExpression(
                    new ElementAccess("Variables", 0), Operator.Assignment, new ElementAccess("Variables", 1)).ToStatement()
            });
            var expectedCu = new CompilationUnit().AddStatements(new []
            {
                new BinaryExpression(
                    new ElementAccess("Variables", 0), Operator.Assignment, new ElementAccess("Variables", 1)).ToStatement()
            });
            var resolver = new ResolveAllTypesOfVariables(8);
            var actualCu = resolver.Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #3
0
        public void ReplacePushAndPopWithJump()
        {
            var cu = new CompilationUnit().AddStatements(new []
            {
                new MethodInvocation("Push").AddArgument(true.ToLiteral()).ToStatement(0, 5),
                new JumpStatement(new ElementAccess("Bits", 0), 15, 5, 10),
                new MethodInvocation("Print").AddArgument(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not)).ToStatement(10, 15),
                new MethodInvocation("Print").AddArgument(new MethodInvocation("Pop")).ToStatement(15, 20)
            });
            var expectedCu = new CompilationUnit().AddStatements(new []
            {
                new JumpStatement(new ElementAccess("Bits", 0), 15, 5, 10),
                new MethodInvocation("Print").AddArgument(new UnaryExpression(true.ToLiteral(), Operator.Not)).ToStatement(10, 15),
                new MethodInvocation("Print").AddArgument(true.ToLiteral()).ToStatement(15, 20)
            });

            var actualCu = new ReplacePushAndPop().Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #4
0
        public void ReplacePushAndPopWithMultiPops()
        {
            var cu = new CompilationUnit().AddStatements(new []
            {
                new MethodInvocation("Push").AddArgument(0.ToLiteral()).ToStatement(),
                new MethodInvocation("Push").AddArgument(1.ToLiteral()).ToStatement(),
                new MethodInvocation("Push").AddArgument(2.ToLiteral()).ToStatement(),
                new MethodInvocation("Print").AddArgument(
                    new MethodInvocation("Pop").AddArgument(5.ToLiteral())).ToStatement()
            });
            var expectedCu = new CompilationUnit().AddStatements(new []
            {
                new MethodInvocation("Print").AddArguments(
                    new ArrayLiteralExpression(new[] { 2.ToLiteral(), 1.ToLiteral(), 0.ToLiteral() })).ToStatement()
            });

            var actualCu = new ReplacePushAndPop().Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #5
0
        public void ReplacePushAndPopWithPushRecurse()
        {
            var cu = new CompilationUnit().AddStatements(new Statement[]
            {
                new MethodInvocation("Push").AddArgument(1.ToLiteral()).ToStatement(),
                new MethodInvocation("Push").AddArgument(2.ToLiteral()).ToStatement(),
                new MethodInvocation("Push").AddArgument(new BinaryExpression(
                                                             new MethodInvocation("Pop"), Operator.Equals, new MethodInvocation("Pop"))).ToStatement(),
                new MethodInvocation("Print").AddArguments(new MethodInvocation("Pop")).ToStatement()
            });
            var expectedCu = new CompilationUnit().AddStatements(new Statement[]
            {
                new MethodInvocation("Print").AddArgument(
                    new BinaryExpression(2.ToLiteral(), Operator.Equals, 1.ToLiteral())).ToStatement()
            });

            var actualCu = new ReplacePushAndPop().Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #6
0
        public void ReplaceJumpToGoToIfNecessary()
        {
            var cu = new CompilationUnit().AddStatements(new Statement[]
            {
                new JumpStatement(false.ToLiteral(), 10)
                {
                    StartOffset = 0, EndOffset = 5
                },
                new ExpressionStatement(
                    new MethodInvocation("Print").AddArgument("Var1 is lower or equals to 0".ToLiteral()))
                {
                    StartOffset = 5, EndOffset = 10
                },
                new ExpressionStatement(
                    new MethodInvocation("Print").AddArgument("End".ToLiteral()))
                {
                    StartOffset = 10, EndOffset = 15
                }
            });
            var expectedCu = new CompilationUnit().AddStatements(new Statement[]
            {
                new JumpStatement(false.ToLiteral(), 10)
                {
                    StartOffset = 0, EndOffset = 5
                },
                new ExpressionStatement(
                    new MethodInvocation("Print").AddArgument("Var1 is lower or equals to 0".ToLiteral()))
                {
                    StartOffset = 5, EndOffset = 10
                },
                new ExpressionStatement(
                    new MethodInvocation("Print").AddArgument("End".ToLiteral()))
                {
                    StartOffset = 10, EndOffset = 15
                }
            });

            var actualCu = new ReplaceJumpToGoTo().Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #7
0
        public void ResolveVariable()
        {
            var cu = new CompilationUnit().AddStatements(new []
            {
                new BinaryExpression(CreateVariable(1), Operator.Assignment, CreateVariable(2)).ToStatement(),
                new BinaryExpression(CreateVariable(1), Operator.Assignment, CreateVariable(3)).ToStatement()
            });

            var knownVariables = new Dictionary <int, string> {
                { 1, "Foo1" }, { 2, "Foo2" }
            };
            var resolver = new ResolveVariables(knownVariables);
            var actualCu = resolver.Replace(cu);

            var expectedCu = new CompilationUnit().AddStatements(new []
            {
                new BinaryExpression(new SimpleName("Foo1"), Operator.Assignment, new SimpleName("Foo2")).ToStatement(),
                new BinaryExpression(new SimpleName("Foo1"), Operator.Assignment, CreateVariable(3)).ToStatement()
            });

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #8
0
        public void ReplacePushAndPopWithPushDup()
        {
            var cu = new CompilationUnit().AddStatements(new Statement[]
            {
                new MethodInvocation("Push").AddArgument(new ElementAccess("Variables", 1073741827)).ToStatement(),
                new MethodInvocation("Dup").AddArgument(new MethodInvocation("Pop")).ToStatement(),
                new MethodInvocation("Push").AddArgument(0.ToLiteral()).ToStatement(),
                new MethodInvocation("Push").AddArgument(
                    new BinaryExpression(
                        new MethodInvocation("Pop"), Operator.Equals, new MethodInvocation("Pop"))).ToStatement(),
                new JumpStatement(new MethodInvocation("Pop"), 33)
            });
            var expectedCu = new CompilationUnit().AddStatements(new Statement[]
            {
                new JumpStatement(new BinaryExpression(
                                      0.ToLiteral(), Operator.Equals, new ElementAccess("Variables", 1073741827)), 33)
            });

            var actualCu = new ReplacePushAndPop().Replace(cu);

            AstHelper.AstEquals(expectedCu, actualCu);
        }
예제 #9
0
        public void ReplaceJumpToIfWithRealExample()
        {
            // cu =
            //            [   0,   5]  Push(156)
            //            [   5,  10]  Push(108)
            //            [  10,  15]  Variables[301] = Pop()
            //            [  15,  16]  StopObjectCode()
            //            [  16,  21]  Push(Bits[563])
            //            [  21,  22]  Push(!Pop())
            //            [  22,  27]  jump 48 if !Pop()
            //            [  27,  32]  Push(972)
            //            [  32,  37]  Push(972)
            //            [  37,  42]  Push(354)
            //            [  42,  43]  LoadRoomWithEgo(Pop(), Pop(), Pop(), Pop())
            //            [  43,  48]  jump 96 if True
            //            [  48,  53]  Push(Bits[9])
            //            [  53,  54]  Push(!Pop())
            //            [  54,  59]  Push(Bits[8])
            //            [  59,  60]  Push(!Pop())
            //            [  60,  61]  Push(Pop() & Pop())
            //            [  61,  66]  jump 80 if !Pop()
            //            [  66,  71]  Push(5)
            //            [  71,  76]  Push(1)
            //            [  76,  77]  CutScene(Pop(25))
            //            [  77,  79]  WaitForCamera()
            //            [  79,  80]  EndCutScene()
            //            [  80,  85]  Push(0)
            //            [  85,  90]  Push(351)
            //            [  90,  95]  Push(0)
            //            [  95,  96]  StartScript(Pop(), Pop(), Pop(25))
            //            [  96,  97]  StopObjectCode()

            var cu = new CompilationUnit().AddStatements(new Statement[]
            {
                new MethodInvocation("Push").AddArgument(156).ToStatement(0, 5),
                new MethodInvocation("Push").AddArgument(108).ToStatement(5, 10),
                new BinaryExpression(new ElementAccess("Variables", 301), Operator.Assignment, new MethodInvocation("Pop")).ToStatement(10, 15),
                new MethodInvocation("StopObjectCode").ToStatement(15, 16),
                new MethodInvocation("Push").AddArgument(new ElementAccess("Bits", 563)).ToStatement(16, 21),
                new MethodInvocation("Push").AddArgument(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not)).ToStatement(21, 22),
                new JumpStatement(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not), 48, 22, 27),
                new MethodInvocation("Push").AddArgument(972).ToStatement(27, 32),
                new MethodInvocation("Push").AddArgument(972).ToStatement(32, 37),
                new MethodInvocation("Push").AddArgument(354).ToStatement(37, 42),
                new MethodInvocation("LoadRoomWithEgo").AddArguments(new MethodInvocation("Pop"), new MethodInvocation("Pop"), new MethodInvocation("Pop"), new MethodInvocation("Pop")).ToStatement(42, 43),
                new JumpStatement(true.ToLiteral(), 96, 43, 48),
                new MethodInvocation("Push").AddArgument(new ElementAccess("Bits", 9)).ToStatement(48, 53),
                new MethodInvocation("Push").AddArgument(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not)).ToStatement(53, 54),
                new MethodInvocation("Push").AddArgument(new ElementAccess("Bits", 8)).ToStatement(54, 59),
                new MethodInvocation("Push").AddArgument(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not)).ToStatement(59, 60),
                new MethodInvocation("Push").AddArgument(new BinaryExpression(new MethodInvocation("Pop"), Operator.And, new MethodInvocation("Pop"))).ToStatement(60, 61),
                new JumpStatement(new UnaryExpression(new MethodInvocation("Pop"), Operator.Not), 80, 61, 66),
                new MethodInvocation("Push").AddArgument(5).ToStatement(66, 71),
                new MethodInvocation("Push").AddArgument(1).ToStatement(71, 76),
                new MethodInvocation("CutScene").AddArgument(new MethodInvocation("Pop").AddArgument(25)).ToStatement(76, 77),
                new MethodInvocation("WaitForCamera").ToStatement(77, 79),
                new MethodInvocation("EndCutScene").ToStatement(79, 80),
                new MethodInvocation("Push").AddArgument(0).ToStatement(80, 85),
                new MethodInvocation("Push").AddArgument(351).ToStatement(85, 90),
                new MethodInvocation("Push").AddArgument(0).ToStatement(90, 95),
                new MethodInvocation("StartScript").AddArguments(new MethodInvocation("Pop"), new MethodInvocation("Pop"), new MethodInvocation("Pop").AddArgument(25)).ToStatement(95, 96),
                new MethodInvocation("StopObjectCode").ToStatement(96, 97),
            });


            // expectedCu =
            //            [   0,   5]  Push(156)
            //            [   5,  10]  Push(108)
            //            [  10,  15]  Variables[301] = Pop()
            //            [  15,  16]  StopObjectCode()
            //            [  16,  21]  Push(Bits[563])
            //            [  21,  22]  Push(!Pop())
            //            [  22,  27]  if (!Pop())
            //                         {
            //            [  27,  32]    Push(972)
            //            [  32,  37]    Push(972)
            //            [  37,  42]    Push(354)
            //            [  42,  43]    LoadRoomWithEgo(Pop(), Pop(), Pop(), Pop())
            //            [  43,  48]    goto label_96
            //                         }
            //            [  48,  53]  Push(Bits[9])
            //            [  53,  54]  Push(!Pop())
            //            [  54,  59]  Push(Bits[8])
            //            [  59,  60]  Push(!Pop())
            //            [  60,  61]  Push(Pop() & Pop())
            //            [  61,  66]  if !Pop()
            //                         {
            //            [  66,  71]    Push(5)
            //            [  71,  76]    Push(1)
            //            [  76,  77]    CutScene(Pop(25))
            //            [  77,  79]    WaitForCamera()
            //            [  79,  80]    EndCutScene()
            //                         }
            //            [  80,  85]  Push(0)
            //            [  85,  90]  Push(351)
            //            [  90,  95]  Push(0)
            //            [  95,  96]  StartScript(Pop(), Pop(), Pop(25))
            // label_96:
            //            [  96,  97]  StopObjectCode()

            var replacers = new IAstReplacer[]
            {
                new ReplacePushAndPop(),
                new ResolveAllTypesOfVariables(8),
                new ReplaceJumpToIf(),
                new ReplaceJumpToWhile(),
                new ReplaceJumpToGoTo()
            };

            Array.ForEach(replacers, r => cu = r.Replace(cu));

            Console.WriteLine(AstHelper.ToString(cu, true));
        }
예제 #10
0
        public void ReplaceJumpToIfWithRealExample2()
        {
            // cu =
            //[0,65]{
            //[0, 3]  jump 59 if !ActiveObject.Locked
            //[3, 7]  Variables[1] = Actors[VariableEgo].GetBitVar(1)
            //[7,12]  jump 25 if Variables[1] != 1
            //[12,19] PrintEgo("Easy!")
            //[19,22] jump 59 if True
            //[22,25] jump 56 if True
            //[25,56] PrintEgo("I can't budge it. It's rusted shut.")
            //[56,59] jump 64 if True
            //[59,60] ActiveObject.State8 = True
            //[60,62] Objects[213].State8 = True
            //[62,64] StartSound(7)
            //[64,65] StopObjectCode()
            //[ 0,65]
            //    }

            var cu = new CompilationUnit().AddStatements(new Statement[]
            {
                new JumpStatement(new UnaryExpression(new MemberAccess("ActiveObject", "Locked"), Operator.Not), 59, 0, 3),
                new BinaryExpression(new ElementAccess("Variables", 1), Operator.Assignment,
                                     new MethodInvocation(new MemberAccess(new ElementAccess("Actors", "VariableEgo"), "GetBitVar")).AddArgument(1)).ToStatement(3, 7),
                new JumpStatement(new BinaryExpression(new ElementAccess("Variables", 1), Operator.Inequals, 1.ToLiteral()), 25, 7, 12),
                new MethodInvocation("PrintEgo").AddArgument("Easy!").ToStatement(12, 19),
                new JumpStatement(true.ToLiteral(), 59, 19, 22),
                new JumpStatement(true.ToLiteral(), 56, 19, 22),
                new MethodInvocation("PrintEgo").AddArgument("I can't budge it. It's rusted shut.!").ToStatement(256, 56),
                new JumpStatement(true.ToLiteral(), 64, 56, 59),
                new BinaryExpression(new MemberAccess("ActiveObject", "State8"), Operator.Assignment, true.ToLiteral()).ToStatement(59, 60),
                new BinaryExpression(new ElementAccess("Objects", 213), Operator.Assignment, true.ToLiteral()).ToStatement(60, 62),
                new MethodInvocation("StartSound").AddArgument(7).ToStatement(62, 64),
                new MethodInvocation("StopObjectCode").ToStatement(64, 65)
            });

            // expectedCu =
            //  if ActiveObject.Locked
            //  {
            //      Variables[1] = Actors[VariableEgo].GetBitVar(1)
            //      if Variables[1] == 1
            //      {
            //          PrintEgo("Easy!")
            //      }
            //      else
            //      {
            //          PrintEgo("I can't budge it. It's rusted shut.")
            //          StopObjectCode();
            //      }
            //  }
            //  ActiveObject.State8 = True
            //  213.State8 = True
            //  StartSound(7)
            //  StopObjectCode()

            var expectedCu = new CompilationUnit().AddStatements(new Statement[]
            {
                new IfStatement(new MemberAccess("ActiveObject", "Locked")).SetTrueStatement(
                    new BinaryExpression(new ElementAccess("Variables", 1), Operator.Assignment,
                                         new MethodInvocation(new MemberAccess(new ElementAccess("Actors", "VariableEgo"), "GetBitVar")).AddArgument(1)).ToStatement(),
                    new IfStatement(new BinaryExpression(new ElementAccess("Variables", 1), Operator.Equals, 1.ToLiteral()))
                    .SetTrueStatement(new MethodInvocation("PrintEgo").AddArgument("Easy!").ToStatement())
                    .SetFalseStatement(
                        new MethodInvocation("PrintEgo").AddArgument("I can't budge it. It's rusted shut.!").ToStatement(),
                        new MethodInvocation("StopObjectCode").ToStatement())),
                new BinaryExpression(new MemberAccess("ActiveObject", "State8"), Operator.Assignment, true.ToLiteral()).ToStatement(),
                new BinaryExpression(new ElementAccess("Objects", 213), Operator.Assignment, true.ToLiteral()).ToStatement(),
                new MethodInvocation("StartSound").AddArgument(7).ToStatement(),
                new MethodInvocation("StopObjectCode").ToStatement()
            });

            var actualCu = new ReplaceJumpToIf().Replace(cu);

            Console.WriteLine(AstHelper.ToString(actualCu, false));

            AstHelper.AstEquals(expectedCu, actualCu);
        }