Ejemplo n.º 1
0
        /// <summary>
        /// Executes the given program.
        /// </summary>
        /// <param name="program">Program to execute.</param>
        /// <returns>Returns a variable that contains the result of the program.</returns>
        public Variable Execute(CompiledProgram program)
        {
            if (program == null)
            {
                throw new ArgumentNullException(nameof(program));
            }
            if (program.IsEmpty)
            {
                throw new Exception("Cannot execute empty program");
            }

            // Populate data
            Reader        = new ByteCodeReader(program.GetByteCodes());
            Functions     = program.GetFunctions();
            Variables     = program.GetVariables();
            Literals      = program.GetLiterals();
            FunctionStack = new Stack <RuntimeFunction>();
            VarStack      = new Stack <Variable>();
            UserData      = null;

            OnBegin();

            // Initial bytecode is call to main() function
            ByteCode bytecode = Reader.GetNext();

            Debug.Assert(bytecode == ByteCode.ExecFunction);
            int mainId = Reader.GetNextValue();

            Debug.Assert(Functions[mainId] is UserFunction);
            RuntimeFunction function = new RuntimeFunction(Functions[mainId] as UserFunction);

            try
            {
                // Execute this function
                ExecuteFunction(function);
            }
            catch (Exception ex)
            {
                // Include line-number information if possible
                if (program.LineNumbers != null)
                {
                    Debug.Assert(program.LineNumbers.Length == program.ByteCodes.Length);
                    int ip = (Reader.IP - 1);
                    if (ip >= 0 && ip < program.LineNumbers.Length)
                    {
                        string s = $"\"{ex.Message}\" exception on line {program.LineNumbers[ip]}. See inner exception for details.";
                        throw new Exception(s, ex);
                    }
                }
                throw;
            }
            finally
            {
                OnEnd();
            }

            // Return result
            return(function.ReturnValue);
        }
Ejemplo n.º 2
0
 public void Reset(CompiledProgram program)
 {
     Program       = program ?? throw new ArgumentNullException(nameof(program));
     Reader        = new ByteCodeReader(Program.GetByteCodes());
     FunctionStack = new Stack <RuntimeFunction>();
     VarStack      = new Stack <Variable>();
     UserData      = null;
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Initializes a new <see cref="Runtime"/> instance and prepares to execute the
 /// given program.
 /// </summary>
 /// <param name="program">The program to prepare to execute.</param>
 public Runtime(CompiledProgram program)
 {
     Reset(program);
 }
Ejemplo n.º 4
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="source">The source code to compile.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool CompileSource(string source, out CompiledProgram program)
Ejemplo n.º 5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="source"></param>
        /// <param name="program"></param>
        /// <returns></returns>
#if NETSTANDARD2_0
        private bool InternalCompile(string source, out CompiledProgram program)
Ejemplo n.º 6
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="stream">A stream that contains the source code to compile.</param>
        /// <param name="encoding">The charcter encoding to use.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool Compile(Stream stream, Encoding encoding, out CompiledProgram program)
Ejemplo n.º 7
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="stream">A stream that contains the source code to compile.</param>
        /// <param name="encoding">The character encoding to use.</param>
        /// <param name="detectEncodingFromByteOrderMarks">Set to true to look for byte order marks at the beginning
        /// of the file.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool Compile(Stream stream, Encoding encoding, bool detectEncodingFromByteOrderMarks, out CompiledProgram program)
Ejemplo n.º 8
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="stream">A stream that contains the source code to compile.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool Compile(Stream stream, out CompiledProgram program)
Ejemplo n.º 9
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="path">Name of the file that contains the source code to compile.</param>
        /// <param name="encoding">The character encoding to use.</param>
        /// <param name="detectEncodingFromByteOrderMarks">Set to true to look for byte order marks at the beginning
        /// of the file.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool Compile(string path, Encoding encoding, bool detectEncodingFromByteOrderMarks, out CompiledProgram program)
Ejemplo n.º 10
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="path">Name of the file that contains the source code to compile.</param>
        /// <param name="encoding">The character encoding to use.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool Compile(string path, Encoding encoding, out CompiledProgram program)
Ejemplo n.º 11
0
        /// <summary>
        /// Compiles the source code in the specified file to byte codes.
        /// </summary>
        /// <param name="path">Name of the file that contains the source code to compile.</param>
        /// <param name="program">If successful, returns the compiled program.</param>
        /// <returns>True if successful, false if there were compile errors.</returns>
#if NETSTANDARD2_0
        public bool Compile(string path, out CompiledProgram program)
Ejemplo n.º 12
0
        public bool Compile(string path, out CompiledProgram program)
        {
            Functions       = new OrderedDictionary <string, Function>(StringComparer.OrdinalIgnoreCase);
            Variables       = new OrderedDictionary <string, Variable>(StringComparer.OrdinalIgnoreCase);
            Literals        = new List <Variable>();
            Lexer           = new LexicalAnalyzer(this);
            Lexer.Error    += Lexer_Error;
            Writer          = new ByteCodeWriter(Lexer);
            InHeader        = true;
            CurrentFunction = null;
            Errors          = new List <Error>();
            program         = null;

            // Add intrinsic functions to function collection
            foreach (var function in IntrinsicFunctions.Values)
            {
                Functions.Add(function.Name, function);
            }
            // Add intrinsic variables to variable collection
            foreach (var pair in IntrinsicVariables.GetKeyValuePairs())
            {
                Variables.Add(pair.Key, pair.Value);
            }
            // Add internal functions and variables
            if (EnableInternalFunctions)
            {
                InternalFunctions.AddInternalFunctionsAndVariables(Functions, Variables);
            }

            try
            {
                // Load file and initialize lexer
                Lexer.Reset(File.ReadAllText(path));
                // Write bytecodes to call function main.
                // Also causes error if main function is not defined
                Writer.Write(ByteCode.ExecFunction, GetFunctionId(Function.Main));
                // Parse statements
                while (ParseStatement())
                {
                    ;
                }
                // Verify end of file
                Token token = Lexer.GetNext();
                if (token.Type != TokenType.EndOfFile)
                {
                    Error(ErrorCode.UnexpectedToken, token);
                }
                // Check for undefined functions
                foreach (var funcInfo in Functions.GetKeyValuePairs())
                {
                    if (funcInfo.Value == null)
                    {
                        if (funcInfo.Key.Equals(Function.Main, StringComparison.CurrentCultureIgnoreCase))
                        {
                            Error(ErrorCode.MainNotDefined, Function.Main.MakeQuoted());
                        }
                        else
                        {
                            Error(ErrorCode.FunctionNotDefined, funcInfo.Key.MakeQuoted());
                        }
                    }
                }
            }
            catch (TooManyErrorsException)
            {
                // Already handled
            }
            catch (Exception ex)
            {
                Error(ErrorCode.InternalError, ex.Message, ErrorLevel.FatalError);
            }
            // Done if compile failed
            if (Errors.Count > 0)
            {
                return(false);
            }
            // Implement logging
            if (CreateLogFile)
            {
                Writer.WriteLogFile(path, Path.ChangeExtension(path, "log"));
            }
            // Return compiled data
            program = new CompiledProgram
            {
                ByteCodes = Writer.GetBytecodes(),
                Functions = Functions.Values.Select(f =>
                                                    (f is CompileTimeUserFunction userFunction) ? new UserFunction(userFunction) : f).ToArray(),
                Variables   = Variables.Values.ToArray(),
                Literals    = Literals.ToArray(),
                LineNumbers = EnableLineNumbers ? Writer.GetLineNumbers() : null,
            };
            return(true);
        }