コード例 #1
0
ファイル: Repl.cs プロジェクト: i-e-b/CompiledScript
        // ReSharper disable once UnusedMember.Global
        /// <summary>
        /// Start with source code, and run program to termination
        /// </summary>
        /// <param name="languageInput">Source code</param>
        /// <param name="input">User typing input (for readline / readkey etc)</param>
        /// <param name="output">Print output from the program</param>
        /// <param name="trace">Flag. If true, write the entire interpreter flow to output</param>
        /// <param name="printIL">Flag. If true, write a view of the bytecode IL to output</param>
        /// <param name="traceMemory">Flag. If true, write memory and GC state</param>
        /// <returns>Run time, excluding compile time</returns>
        public static TimeSpan BuildAndRun(string languageInput, TextReader input, TextWriter output,
                                           bool trace, bool printIL, bool traceMemory)
        {
            // Compile
            var sourceCodeReader = new SourceCodeTokeniser();

            var program = sourceCodeReader.Read(languageInput, false);

            if (!program.IsValid)
            {
                output.WriteLine("Program is not well formed"); // TODO: be more helpful
                return(TimeSpan.Zero);
            }

            ToNanCodeCompiler.BaseDirectory = baseDirectory;
            var compiledOutput = ToNanCodeCompiler.CompileRoot(program, debug: false);

            // Load
            var stream = new MemoryStream();

            compiledOutput.WriteToStream(stream);
            stream.Seek(0, SeekOrigin.Begin);
            var memoryModel = new RuntimeMemoryModel(stream);

            if (printIL)
            {
                output.WriteLine("======= BYTE CODE SUMMARY ==========");
                compiledOutput.AddSymbols(ByteCodeInterpreter.DebugSymbolsForBuiltIns());
                output.WriteLine(memoryModel.ToString(compiledOutput.GetSymbols()));
                output.WriteLine("====================================");
            }

            // Execute
            var sw          = new Stopwatch();
            var interpreter = new ByteCodeInterpreter();

            try
            {
                // Init the interpreter.
                interpreter.Init(memoryModel, input, output, debugSymbols: compiledOutput.GetSymbols());

                sw.Start();
                interpreter.Execute(false, trace, false);
                sw.Stop();

                if (traceMemory)
                {
                    output.WriteLine("======== GARBAGE SUMMARY ===========");
                    foreach (var token in memoryModel.Variables.PotentialGarbage)
                    {
                        output.WriteLine(NanTags.Describe(token));
                    }
                    output.WriteLine("====================================");
                }

                return(sw.Elapsed);
            }
            catch (Exception e)
            {
                output.WriteLine("Interpreter stopped at " + interpreter.LastPosition());
                output.WriteLine("Exception : " + e.Message);
                output.WriteLine("\r\n\r\n" + e.StackTrace);
                sw.Stop();
                return(sw.Elapsed);
            }
        }