public SmallBasicEngine(SmallBasicCompilation compilation, IEngineLibraries libraries)
        {
            Debug.Assert(!compilation.Diagnostics.Any(), "Cannot execute a compilation with errors.");

            this.compilation    = compilation;
            this.eventCallbacks = new Dictionary <string, string>(StringComparer.CurrentCultureIgnoreCase);

            this.CurrentSourceLine = 0;

            this.Mode            = ExecutionMode.RunToEnd;
            this.State           = ExecutionState.Running;
            this.ExecutionStack  = new LinkedList <Frame>();
            this.EvaluationStack = new Stack <BaseValue>();
            this.Memory          = new Dictionary <string, BaseValue>();
            this.Modules         = new Dictionary <string, RuntimeModule>();
            this.Libraries       = libraries;

            this.Libraries.SetEventCallbacks(this);

            RuntimeModule mainModule = this.EmitAndSaveModule("Program", compilation.MainModule);

            foreach (BoundSubModule subModule in compilation.SubModules.Values)
            {
                this.EmitAndSaveModule(subModule.Name, subModule.Body);
            }

            this.ExecutionStack.AddLast(new Frame(mainModule));
        }
        public static void SetEventCallbacks(this IEngineLibraries libraries, SmallBasicEngine engine)
        {
            libraries.Controls.ButtonClicked += () => engine.RaiseEvent("Controls", "ButtonClicked");
            libraries.Controls.TextTyped     += () => engine.RaiseEvent("Controls", "TextTyped");

            libraries.GraphicsWindow.KeyDown   += () => engine.RaiseEvent("GraphicsWindow", "KeyDown");
            libraries.GraphicsWindow.KeyUp     += () => engine.RaiseEvent("GraphicsWindow", "KeyUp");
            libraries.GraphicsWindow.MouseDown += () => engine.RaiseEvent("GraphicsWindow", "MouseDown");
            libraries.GraphicsWindow.MouseMove += () => engine.RaiseEvent("GraphicsWindow", "MouseMove");
            libraries.GraphicsWindow.MouseUp   += () => engine.RaiseEvent("GraphicsWindow", "MouseUp");
            libraries.GraphicsWindow.TextInput += () => engine.RaiseEvent("GraphicsWindow", "TextInput");

            libraries.Timer.Tick += () => engine.RaiseEvent("Timer", "Tick");
        }
Beispiel #3
0
        private static async Task <SmallBasicEngine> VerifyRuntimeAux(this SmallBasicCompilation compilation, IEngineLibraries libraries, string memoryContents)
        {
            compilation.VerifyDiagnostics();

            SmallBasicEngine engine = new SmallBasicEngine(compilation, libraries);

            while (engine.State != ExecutionState.Terminated)
            {
                engine.State.Should().Be(ExecutionState.Running, "loggers cannot move to another state");
                await engine.Execute().ConfigureAwait(false);
            }

            DebuggerSnapshot snapshot = engine.GetSnapshot();

            snapshot.ExecutionStack.Should().BeEmpty();

            if (!memoryContents.IsDefault())
            {
                string values = Environment.NewLine
                                + snapshot.Memory.Select(pair => $"{pair.Key} = {pair.Value.ToDisplayString()}").Join(Environment.NewLine);

                values.Should().Be(memoryContents);
            }

            return(engine);
        }