示例#1
0
        public void BaZicCodeGeneratorTryCatch()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new TryCatchStatement()
                    .WithTryBody(
                        new CommentStatement("Evaluation")
                        ).WithCatchBody(
                        new ThrowStatement(new ExceptionReferenceExpression())
                        )
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    TRY
        # Evaluation
    CATCH
        THROW EXCEPTION
    END TRY
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#2
0
        /// <summary>
        /// Initializes a new instance of the <see cref="ParserResult"/> class.
        /// </summary>
        /// <param name="program">The program</param>
        /// <param name="issues">The issues</param>
        public ParserResult(BaZicProgram program, AggregateException issues)
        {
            Requires.NotNull(issues, nameof(issues));

            Program = program;
            Issues  = issues;
        }
示例#3
0
        public void BaZicCodeGeneratorInvoke()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new ExpressionStatement(new InvokeMethodExpression("Foo", true).WithParameters(new PrimitiveExpression(1), new BinaryOperatorExpression(new PrimitiveExpression(2), BinaryOperatorType.Subtraction, new PrimitiveExpression(1)))),
                    new VariableDeclaration("integer").WithDefaultValue(new PrimitiveExpression(1)),
                    new ReturnStatement(new InvokeCoreMethodExpression(new VariableReferenceExpression("integer"), "ToString", false).WithParameters(new PrimitiveExpression("X")))
                    ),
                new MethodDeclaration("Foo", true, true)
                .WithParameters(new ParameterDeclaration("arg1", true), new ParameterDeclaration("arg2"))
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    AWAIT Foo(1, 2 - 1)
    VARIABLE integer = 1
    RETURN integer.ToString(""X"")
END FUNCTION

EXTERN ASYNC FUNCTION Foo(arg1[], arg2)

END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#4
0
        /// <summary>
        /// Optimize a BaZic syntax tree.
        /// </summary>
        /// <param name="program">The syntax tree to optimize.</param>
        /// <returns>Returns a new syntax tree that is optimized.</returns>
        public BaZicProgram Optimize(BaZicProgram program)
        {
            _nameGenerator.Reset();
            _program = program;
            _methodInformations.Clear();
            _iterationEndLabels.Clear();

            foreach (var method in program.Methods)
            {
                method.WithBody(OptimizeStatementBlock(method.Statements).ToArray());
            }

            if (program is BaZicUiProgram uiProgram)
            {
                return(new BaZicUiProgram(true)
                {
                    Xaml = uiProgram.Xaml
                }
                       .WithResourceFilePaths(uiProgram.ResourceFilePaths.ToArray())
                       .WithUiEvents(uiProgram.UiEvents.ToArray())
                       .WithControlAccessors(uiProgram.UiControlAccessors.ToArray())
                       .WithAssemblies(program.Assemblies.ToArray())
                       .WithVariables(program.GlobalVariables.ToArray())
                       .WithMethods(program.Methods.ToArray()));
            }

            return(new BaZicProgram(true)
                   .WithAssemblies(program.Assemblies.ToArray())
                   .WithVariables(program.GlobalVariables.ToArray())
                   .WithMethods(program.Methods.ToArray()));
        }
示例#5
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProgramInterpreter"/> class.
 /// </summary>
 /// <param name="baZicInterpreter">The main interpreter.</param>
 /// <param name="program">The <see cref="BaZicProgram"/> to interpret.</param>
 /// <param name="executionFlowId">A GUID that defines in which callstack is linked.</param>
 internal ProgramInterpreter(BaZicInterpreterCore baZicInterpreter, BaZicProgram program, Guid executionFlowId)
     : base(baZicInterpreter, null, executionFlowId)
 {
     Requires.NotNull(program, nameof(program));
     _program   = program;
     _uiProgram = program as BaZicUiProgram;
 }
示例#6
0
        public void CSharpCodeGeneratorIndent()
        {
            var program = new BaZicProgram()
                          .WithVariables(
                new VariableDeclaration("Foo")
                ).WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("Bar", true),
                    new IterationStatement(new BinaryOperatorExpression(new VariableReferenceExpression("Foo"), BinaryOperatorType.Equality, new VariableReferenceExpression("Bar")))
                    .WithBody(
                        new ConditionStatement(new PrimitiveExpression(true))
                        .WithThenBody(
                            new CommentStatement("If true")
                            ).WithElseBody(
                            new CommentStatement("If not true")
                            )
                        )
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        private dynamic Foo = null;

        public dynamic Main(dynamic args)
        {
            try {
            dynamic Bar = null;
            while (Foo == Bar)
            {
                if (true)
                {
                    // If true
                }
                else
                {
                    // If not true
                }
            }
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#7
0
 /// <summary>
 /// Initializes a new instance of the <see cref="CompiledProgramRunner"/> class.
 /// </summary>
 /// <param name="baZicInterpreter">The <see cref="BaZicInterpreterCore"/> that called this class.</param>
 /// <param name="program">The <see cref="BaZicProgram"/> to compile and run.</param>
 /// <param name="assemblySandbox">The sandbox that contains the required assemblies.</param>
 internal CompiledProgramRunner(BaZicInterpreterCore baZicInterpreter, BaZicProgram program, AssemblySandbox assemblySandbox)
 {
     Requires.NotNull(baZicInterpreter, nameof(baZicInterpreter));
     Requires.NotNull(program, nameof(program));
     Requires.NotNull(assemblySandbox, nameof(assemblySandbox));
     _baZicInterpreter = baZicInterpreter;
     _program          = program;
     _assemblySandbox  = assemblySandbox;
 }
示例#8
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BaZicInterpreterCore"/> class.
        /// </summary>
        /// <param name="middleware">The middleware</param>
        /// <param name="assemblySandbox">The assembly sandbox.</param>
        /// <param name="program">The <see cref="BaZicProgram"/> to interpret.</param>
        private BaZicInterpreterCore(BaZicInterpreterMiddleware middleware, AssemblySandbox assemblySandbox, BaZicProgram program)
            : this(middleware, assemblySandbox)
        {
            Requires.NotNull(program, nameof(program));

            _stateChangedHistory = new List <BaZicInterpreterStateChangeEventArgs>();
            ChangeState(this, new BaZicInterpreterStateChangeEventArgs(BaZicInterpreterState.Ready));

            Program = program;
        }
示例#9
0
        public void CSharpCodeGeneratorPrimitiveValues()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("foo"),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(1)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(1.1234)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(-1.5467f)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression("Hel\"l\r\no")),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(true)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(false)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression()),
                    new VariableDeclaration("bar", true).WithDefaultValue(new PrimitiveExpression(new object[] { "Hello", new object[] { "Foo", "Bar", "Buz" } })),
                    new AssignStatement(new VariableReferenceExpression("bar"), new ArrayCreationExpression().WithValues(new PrimitiveExpression(1), new PrimitiveExpression(1.1234), new PrimitiveExpression("Hello")))
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            dynamic foo = null;
            foo = 1;
            foo = 1.1234;
            foo = -1.5467;
            foo = ""Hel\""l\r\no"";
            foo = true;
            foo = false;
            foo = null;
            dynamic bar = new BaZicProgramReleaseMode.ObservableDictionary() { ""Hello"", new BaZicProgramReleaseMode.ObservableDictionary() { ""Foo"", ""Bar"", ""Buz"" } };
            bar = new BaZicProgramReleaseMode.ObservableDictionary() { 1, 1.1234, ""Hello"" };
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#10
0
        public async Task BaZicInterpreterAssembliesLoad()
        {
            var program = new BaZicProgram();

            program.WithAssemblies("FakeAssembly, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");

            var interpreter = new BaZicInterpreter(program);
            await interpreter.StartDebugAsync(true);

            var exception = (LoadAssemblyException)interpreter.Error.Exception;

            Assert.AreEqual("FakeAssembly, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", exception.AssemblyPath);
            Assert.AreEqual("Could not load file or assembly 'FakeAssembly, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its dependencies. The system cannot find the file specified.", exception.InnerException.Message);
        }
示例#11
0
        public void BaZicCodeGeneratorCondition()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new ConditionStatement(new BinaryOperatorExpression(new BinaryOperatorExpression(new BinaryOperatorExpression(new PrimitiveExpression(1), BinaryOperatorType.LessThan, new PrimitiveExpression(2)), BinaryOperatorType.LogicalAnd, new BinaryOperatorExpression(new PrimitiveExpression(3), BinaryOperatorType.LessThan, new PrimitiveExpression(4))), BinaryOperatorType.LogicalOr, new NotOperatorExpression(new PrimitiveExpression(false))))
                    .WithThenBody(
                        new CommentStatement("If true")
                        ).WithElseBody(
                        new ConditionStatement(new BinaryOperatorExpression(new PrimitiveExpression(1), BinaryOperatorType.LessThan, new PrimitiveExpression(2)))
                        .WithThenBody(
                            new ConditionStatement(new NotOperatorExpression(new BinaryOperatorExpression(new PrimitiveExpression(1), BinaryOperatorType.LessThan, new PrimitiveExpression(2))))
                            .WithThenBody(
                                new CommentStatement("If true")
                                ).WithElseBody(
                                new CommentStatement("If not true")
                                )
                            ).WithElseBody(
                            new CommentStatement("If not true")
                            )
                        )
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    IF ((1 < 2) AND (3 < 4)) OR (NOT FALSE) THEN
        # If true
    ELSE
        IF 1 < 2 THEN
            IF NOT (1 < 2) THEN
                # If true
            ELSE
                # If not true
            END IF
        ELSE
            # If not true
        END IF
    END IF
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#12
0
        public void CSharpCodeGeneratorTryCatch()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new TryCatchStatement()
                    .WithTryBody(
                        new CommentStatement("Evaluation")
                        ).WithCatchBody(
                        new ThrowStatement(new ExceptionReferenceExpression())
                        )
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            try
            {
                // Evaluation
            }
            catch (System.Exception EXCEPTION)
            {
                throw EXCEPTION;
            }
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#13
0
        public void CSharpCodeGeneratorInvoke()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new ExpressionStatement(new InvokeMethodExpression("Foo", true).WithParameters(new PrimitiveExpression(1), new BinaryOperatorExpression(new PrimitiveExpression(2), BinaryOperatorType.Subtraction, new PrimitiveExpression(1)))),
                    new VariableDeclaration("integer").WithDefaultValue(new PrimitiveExpression(1)),
                    new ReturnStatement(new InvokeCoreMethodExpression(new VariableReferenceExpression("integer"), "ToString", false).WithParameters(new PrimitiveExpression("X")))
                    ),
                new MethodDeclaration("Foo", true, true)
                .WithParameters(new ParameterDeclaration("arg1", true), new ParameterDeclaration("arg2"))
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            Foo(1, 2 - 1).GetAwaiter().GetResult();
            dynamic integer = 1;
            return _programHelperInstance.AddUnwaitedThreadIfRequired(integer, ""ToString"", ""X"");
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }

        public async System.Threading.Tasks.Task<dynamic> Foo(dynamic arg1, dynamic arg2)
        {

            return await System.Threading.Tasks.Task.FromResult<object>(null);
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#14
0
        public void BaZicCodeGeneratorIndent()
        {
            var program = new BaZicProgram()
                          .WithVariables(
                new VariableDeclaration("Foo")
                ).WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("Bar", true),
                    new IterationStatement(new BinaryOperatorExpression(new VariableReferenceExpression("Foo"), BinaryOperatorType.Equality, new VariableReferenceExpression("Bar")))
                    .WithBody(
                        new ConditionStatement(new PrimitiveExpression(true))
                        .WithThenBody(
                            new CommentStatement("If true")
                            ).WithElseBody(
                            new CommentStatement("If not true")
                            )
                        )
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

VARIABLE Foo

EXTERN FUNCTION Main(args[])
    VARIABLE Bar[]
    DO WHILE Foo = Bar
        IF TRUE THEN
            # If true
        ELSE
            # If not true
        END IF
    LOOP
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
        public async Task VariableReferenceInterpreterVariableNotFound()
        {
            var parser = new BaZicParser();

            var inputCode = new BaZicProgram()
                            .WithMethods(new EntryPointMethod()
                                         .WithBody(
                                             new ReturnStatement(new VariableReferenceExpression("var1"))
                                             ));
            var interpreter = new BaZicInterpreter(inputCode);
            await interpreter.StartDebugAsync(true);

            var expectedLogs = @"[State] Ready
[State] Preparing
[Log] Reference assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' loaded in the application domain.
[Log] Reference assembly 'System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' loaded in the application domain.
[Log] Reference assembly 'System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' loaded in the application domain.
[Log] Reference assembly 'System.Runtime, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' loaded in the application domain.
[Log] Reference assembly 'Microsoft.CSharp, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' loaded in the application domain.
[Log] Reference assembly 'PresentationFramework, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' loaded in the application domain.
[Log] Reference assembly 'PresentationCore, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' loaded in the application domain.
[Log] Reference assembly 'WindowsBase, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' loaded in the application domain.
[Log] Declaring global variables.
[Log] Program's entry point detected.
[State] Running
[Log] Preparing to invoke the method 'Main'.
[Log] Executing the argument values of the method.
[Log] Executing an expression of type 'ArrayCreationExpression'.
[Log] The expression returned the value 'BaZicProgramReleaseMode.ObservableDictionary' (BaZicProgramReleaseMode.ObservableDictionary (length: 0)).
[Log] Invoking the synchronous method 'Main'.
[Log] Variable 'args' declared. Default value : {Null}
[Log] Variable 'args' value set to : BaZicProgramReleaseMode.ObservableDictionary (BaZicProgramReleaseMode.ObservableDictionary (length: 0))
[Log] Registering labels.
[Log] Executing a statement of type 'ReturnStatement'.
[Log] Executing an expression of type 'VariableReferenceExpression'.
[Error] The variable 'var1' does not exist or is not accessible.
";

            Assert.AreEqual(expectedLogs, interpreter.GetStateChangedHistoryString());
        }
示例#16
0
        public void BaZicCodeGeneratorPrimitiveValues()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("foo"),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(1)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(1.1234)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(-1.5467f)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression("Hel\"l\r\no")),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(true)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression(false)),
                    new AssignStatement(new VariableReferenceExpression("foo"), new PrimitiveExpression()),
                    new VariableDeclaration("bar", true).WithDefaultValue(new PrimitiveExpression(new object[] { "Hello", new object[] { "Foo", "Bar", "Buz" } })),
                    new AssignStatement(new VariableReferenceExpression("bar"), new ArrayCreationExpression().WithValues(new PrimitiveExpression(1), new PrimitiveExpression(1.1234), new PrimitiveExpression("Hello")))
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    VARIABLE foo
    foo = 1
    foo = 1.1234
    foo = -1.5467
    foo = ""Hel\""l\r\no""
    foo = TRUE
    foo = FALSE
    foo = NULL
    VARIABLE bar[] = NEW [""Hello"", NEW [""Foo"", ""Bar"", ""Buz""]]
    bar = NEW [1, 1.1234, ""Hello""]
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#17
0
        public void BaZicCodeGeneratorArrayIndexer()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("Foo", true),
                    new ReturnStatement(new ArrayIndexerExpression(new VariableReferenceExpression("Foo"), new Expression[] { new PrimitiveExpression(0) }))
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    VARIABLE Foo[]
    RETURN Foo[0]
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#18
0
        public void BaZicCodeGeneratorProperty()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("foo").WithDefaultValue(new PrimitiveExpression("Hello")),
                    new ReturnStatement(new PropertyReferenceExpression(new VariableReferenceExpression("foo"), "Length"))
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    VARIABLE foo = ""Hello""
    RETURN foo.Length
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#19
0
        public void BaZicCodeGeneratorClassReference()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("Baz", true).WithDefaultValue(new InstantiateExpression(new ClassReferenceExpression("System", "Array"))),
                    new VariableDeclaration("Boo", true).WithDefaultValue(new InstantiateExpression(new ClassReferenceExpression("System", "String")))
                    )
                );

            var code = new BaZicCodeGenerator().Generate(program);

            var expected =
                @"# BaZic code generated automatically

EXTERN FUNCTION Main(args[])
    VARIABLE Baz[] = NEW System.Array()
    VARIABLE Boo[] = NEW System.String()
END FUNCTION";

            Assert.AreEqual(expected, code);
        }
示例#20
0
        public void CSharpCodeGeneratorProperty()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("foo").WithDefaultValue(new PrimitiveExpression("Hello")),
                    new ReturnStatement(new PropertyReferenceExpression(new VariableReferenceExpression("foo"), "Length"))
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            dynamic foo = ""Hello"";
            return foo.Length;
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#21
0
        public void CSharpCodeGeneratorClassReference()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("Baz", true).WithDefaultValue(new InstantiateExpression(new ClassReferenceExpression("System", "Array"))),
                    new VariableDeclaration("Boo", true).WithDefaultValue(new InstantiateExpression(new ClassReferenceExpression("System", "String")))
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            dynamic Baz = new System.Array();
            dynamic Boo = new System.String();
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#22
0
        public void CSharpCodeGeneratorArrayIndexer()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new VariableDeclaration("Foo", true),
                    new ReturnStatement(new ArrayIndexerExpression(new VariableReferenceExpression("Foo"), new Expression[] { new PrimitiveExpression(0) }))
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            dynamic Foo = null;
            return Foo[0];
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }
示例#23
0
        /// <summary>
        /// Generates a BaZic code from a syntax tree.
        /// </summary>
        /// <param name="syntaxTree">The syntax tree that represents the algorithm</param>
        /// <returns>A BaZic code</returns>
        public string Generate(BaZicProgram syntaxTree)
        {
            if (syntaxTree is BaZicUiProgram)
            {
                return(Generate((BaZicUiProgram)syntaxTree));
            }

            _indentSpaceCount = 0;

            var globalVariables = new List <string>();

            foreach (var variable in syntaxTree.GlobalVariables)
            {
                globalVariables.Add(GenerateVariableDeclaration(variable));
            }

            var globalVariablesString = string.Join(Environment.NewLine, globalVariables);

            if (!string.IsNullOrWhiteSpace(globalVariablesString))
            {
                globalVariablesString += Environment.NewLine + Environment.NewLine;
            }

            var methods = new List <string>();

            foreach (var method in syntaxTree.Methods)
            {
                methods.Add(GenerateMethodDeclaration(method));
            }

            var methodsString = string.Join(Environment.NewLine + Environment.NewLine, methods);

            return($"# BaZic code generated automatically" + Environment.NewLine + Environment.NewLine +
                   $"{globalVariablesString}" +
                   $"{methodsString}");
        }
示例#24
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BaZicInterpreter"/> class.
 /// </summary>
 /// <param name="program">The <see cref="BaZicProgram"/> to interpret.</param>
 public BaZicInterpreter(BaZicProgram program)
     : this()
 {
     _core = _assemblySandbox.CreateInstanceMarshalByRefObject <BaZicInterpreterCore>(new BaZicInterpreterMiddleware(this), _assemblySandbox, program);
 }
示例#25
0
        /// <summary>
        /// Parse the program's root context.
        /// </summary>
        /// <param name="xamlCode">The XAML code to analyze that represents the user interface.</param>
        /// <param name="resourceFilePaths">Paths to the resources files (like PNG or JPG) required for the XAML code.</param>
        /// <returns>A <see cref="BaZicProgram"/> that represents the syntax tree that corresponds to the input code.</returns>
        private BaZicProgram ParseProgram(string xamlCode, IEnumerable <string> resourceFilePaths)
        {
            var variables        = new List <VariableDeclaration>();
            var methods          = new List <MethodDeclaration>();
            var entryPointExists = false;

            var statements = ParseStatements(true, TokenType.EndCode);

            DiscardToken(TokenType.EndCode);

            foreach (var statement in statements)
            {
                switch (statement)
                {
                case VariableDeclaration variable:
                    ValidateGlobalVariableDeclarationDefaultValue(variable.DefaultValue);
                    variables.Add(variable);
                    break;

                case EntryPointMethod entryPointMethod:
                    entryPointExists = true;
                    methods.Add(entryPointMethod);
                    break;

                case MethodDeclaration method:
                    methods.Add(method);
                    break;

                default:
                    AddIssue(new BaZicParserException(L.BaZic.Parser.ForbiddenMember));
                    break;
                }
            }

            if (!entryPointExists)
            {
                methods.Add(new EntryPointMethod());
            }

            foreach (var methodInvocation in _methodInvocations)
            {
                ValidateMethodInvocation(methodInvocation);
            }

            if (_parsedXamlRoot != null || _controlAccessors.Count > 0 || _declaredEvents.Count > 0)
            {
                ValidateResources(resourceFilePaths);

                var uiProgram = new BaZicUiProgram();
                uiProgram.Xaml = xamlCode;
                uiProgram.WithControlAccessors(_controlAccessors.ToArray());
                uiProgram.WithUiEvents(_declaredEvents.ToArray());
                uiProgram.WithVariables(variables.ToArray());
                uiProgram.WithMethods(methods.ToArray());
                if (resourceFilePaths != null)
                {
                    uiProgram.WithResourceFilePaths(resourceFilePaths.ToArray());
                }

                return(uiProgram);
            }
            else
            {
                var program = new BaZicProgram();
                program.WithVariables(variables.ToArray());
                program.WithMethods(methods.ToArray());
                return(program);
            }
        }
示例#26
0
        /// <summary>
        /// Parse a BaZic code and returns a syntax tree representation of the algorithm.
        /// </summary>
        /// <param name="tokens">The BaZic code represented by tokens to analyze.</param>
        /// <param name="xamlCode">The XAML code to analyze that represents the user interface.</param>
        /// <param name="resourceFilePaths">Paths to the resources files (like PNG or JPG) required for the XAML code.</param>
        /// <param name="optimize">(optional) Defines whether the generated syntax tree must be optimized for the interpreter or not.</param>
        /// <returns>A <see cref="BaZicProgram"/> that represents the syntax tree that corresponds to the input code.</returns>
        public ParserResult Parse(List <Token> tokens, string xamlCode, IEnumerable <string> resourceFilePaths = null, bool optimize = false)
        {
            Requires.NotNull(tokens, nameof(tokens));

            _issues.Clear();
            BaZicProgram program = null;

            if (tokens.Count == 0)
            {
                return(new ParserResult(program, new AggregateException(_issues)));
            }

            ThreadHelper.RunOnStaThread(() =>
            {
                try
                {
                    _reflectionHelper = new FastReflection();

                    // Parse BaZic user interface code (XAML).
                    _parsedXamlRoot = ParseXaml(xamlCode);

                    // Parse BaZic code.
                    _catchIndicator  = 0;
                    _doLoopIndicator = 0;
                    _tokenStack.Clear();

                    for (var i = tokens.Count - 1; i >= 0; i--)
                    {
                        _tokenStack.Push(tokens[i]);
                    }

                    if (_tokenStack.Peek().TokenType != TokenType.StartCode)
                    {
                        AddIssue(new BaZicParserException(L.BaZic.Parser.FormattedBadFirstToken(TokenType.StartCode)));
                    }

                    if (_tokenStack.Count <= 2)
                    {
                        if (_parsedXamlRoot == null)
                        {
                            program = new BaZicProgram();
                        }
                        else
                        {
                            ValidateResources(resourceFilePaths);

                            var uiProgram  = new BaZicUiProgram();
                            uiProgram.Xaml = xamlCode;
                            if (resourceFilePaths != null)
                            {
                                uiProgram.WithResourceFilePaths(resourceFilePaths.ToArray());
                            }
                            program = uiProgram;
                        }
                    }
                    else
                    {
                        PreviousToken = _tokenStack.Pop();
                        CurrentToken  = _tokenStack.Pop();
                        NextToken     = _tokenStack.Pop();

                        program = ParseProgram(xamlCode, resourceFilePaths);
                    }

                    if (optimize && _issues.OfType <BaZicParserException>().Count(issue => issue.Level == BaZicParserExceptionLevel.Error) == 0)
                    {
                        var optimizer = new BaZicOptimizer();
                        program       = optimizer.Optimize(program);
                    }

                    tokens.Clear();
                }
                catch (Exception exception)
                {
                    CoreHelper.ReportException(exception);
                    _issues.Add(exception);
                }
                finally
                {
                    _expectedExpressionGroupSeparator.Clear();
                    _declaredVariables.Clear();
                    _declaredParameterDeclaration.Clear();
                    _declaredMethods.Clear();
                    _declaredEvents.Clear();
                    _controlAccessors.Clear();
                    _methodInvocations.Clear();
                    _catchIndicator  = 0;
                    _doLoopIndicator = 0;
                    if (_parsedXamlRoot != null)
                    {
                        if (_parsedXamlRoot is Window window)
                        {
                            window.Close();
                        }
                        _parsedXamlRoot = null;
                    }
                    _reflectionHelper.Dispose();
                    _reflectionHelper = null;
                }
            }, true);

            return(new ParserResult(program, new AggregateException(_issues)));
        }
示例#27
0
        public void CSharpCodeGeneratorCondition()
        {
            var program = new BaZicProgram()
                          .WithMethods(
                new EntryPointMethod()
                .WithBody(
                    new ConditionStatement(new BinaryOperatorExpression(new BinaryOperatorExpression(new BinaryOperatorExpression(new PrimitiveExpression(1), BinaryOperatorType.LessThan, new PrimitiveExpression(2)), BinaryOperatorType.LogicalAnd, new BinaryOperatorExpression(new PrimitiveExpression(3), BinaryOperatorType.LessThan, new PrimitiveExpression(4))), BinaryOperatorType.LogicalOr, new NotOperatorExpression(new PrimitiveExpression(false))))
                    .WithThenBody(
                        new CommentStatement("If true")
                        ).WithElseBody(
                        new ConditionStatement(new BinaryOperatorExpression(new PrimitiveExpression(1), BinaryOperatorType.LessThan, new PrimitiveExpression(2)))
                        .WithThenBody(
                            new ConditionStatement(new NotOperatorExpression(new BinaryOperatorExpression(new PrimitiveExpression(1), BinaryOperatorType.LessThan, new PrimitiveExpression(2))))
                            .WithThenBody(
                                new CommentStatement("If true")
                                ).WithElseBody(
                                new CommentStatement("If not true")
                                )
                            ).WithElseBody(
                            new CommentStatement("If not true")
                            )
                        )
                    )
                );

            var code = new CSharpCodeGenerator().Generate(program);

            var expected =
                @"namespace BaZicProgramReleaseMode
{
    [System.Serializable]
    public class Program
    {
        private readonly ProgramHelper _programHelperInstance = new ProgramHelper();
        public ProgramHelper ProgramHelperInstance => _programHelperInstance;
        public dynamic Main(dynamic args)
        {
            try {
            if (((1 < 2) && (3 < 4)) || (!false))
            {
                // If true
            }
            else
            {
                if (1 < 2)
                {
                    if (!(1 < 2))
                    {
                        // If true
                    }
                    else
                    {
                        // If not true
                    }
                }
                else
                {
                    // If not true
                }
            }
            } finally {
            _programHelperInstance.WaitAllUnwaitedThreads();
            }
            return null;
        }
    }
}";

            Assert.IsTrue(code.Contains(expected));
        }