Example #1
0
 public RuntimeFunction(UserFunction function)
 {
     if (function == null)
     {
         throw new ArgumentNullException(nameof(function));
     }
     IP         = function.IP;
     Parameters = new Variable[function.NumParameters];
     for (int i = 0; i < function.NumParameters; i++)
     {
         Parameters[i] = new Variable();
     }
     Variables = new Variable[function.NumVariables];
     for (int i = 0; i < function.NumVariables; i++)
     {
         Variables[i] = new Variable();
     }
     ReturnValue = new Variable();
 }
Example #2
0
        /// <summary>
        /// Loads a precompiled program from disk.
        /// </summary>
        /// <remarks>
        /// NOTE: We should employ some sort of checksum to verify bytecode integrity.
        /// </remarks>
        /// <param name="path"></param>
        public void Load(string path)
        {
            int i, count;

            Reset();

            try
            {
                using BinaryReader reader = new(File.Open(path, FileMode.Open));

                // Check signature
                i = reader.ReadInt32();
                if (i != FileSignature)
                {
                    throw new Exception(InvalidFileFormat);
                }
                // Read reserved int
                i = reader.ReadInt32();
                if (i != 0)
                {
                    throw new Exception(InvalidFileFormat);
                }
                // Read flags
                FileFlag flags = (FileFlag)reader.ReadInt32();
                // Read bytecodes
                count     = reader.ReadInt32();
                ByteCodes = new int[count];
                for (i = 0; i < count; i++)
                {
                    ByteCodes[i] = reader.ReadInt32();
                }
                // Read functions
                count = reader.ReadInt32();
                List <Function> functions = new(count);
                for (i = 0; i < count; i++)
                {
                    string       name = reader.ReadString();
                    FunctionType type = (FunctionType)reader.ReadInt32();
                    if (type == FunctionType.Internal)
                    {
                        // Temporarily set non-nullable action to null
                        // We will correct further down
                        var function = new InternalFunction(name, null !);
                        functions.Add(function);
                    }
                    else if (type == FunctionType.Intrinsic)
                    {
                        var function = new IntrinsicFunction(name);
                        functions.Add(function);
                    }
                    else // FunctionType.User
                    {
                        var function = new UserFunction(name, 0)
                        {
                            IP            = reader.ReadInt32(),
                            NumVariables  = reader.ReadInt32(),
                            NumParameters = reader.ReadInt32(),
                        };
                        functions.Add(function);
                    }
                }
                // Read global variables
                count     = reader.ReadInt32();
                Variables = new Variable[count];
                for (i = 0; i < count; i++)
                {
                    Variables[i] = ReadVariable(reader);
                }
                // Read literals
                count    = reader.ReadInt32();
                Literals = new Variable[count];
                for (i = 0; i < count; i++)
                {
                    Literals[i] = ReadVariable(reader);
                }
                // Read line numbers
                if (flags.HasFlag(FileFlag.HasLineNumbers))
                {
                    count       = reader.ReadInt32();
                    LineNumbers = new int[count];
                    for (i = 0; i < count; i++)
                    {
                        LineNumbers[i] = reader.ReadInt32();
                    }
                    Debug.Assert(LineNumbers.Length == ByteCodes.Length);
                }
                // Fixup internal functions
                foreach (var function in functions.OfType <InternalFunction>())
                {
                    if (InternalFunctions.InternalFunctionLookup.TryGetValue(function.Name, out InternalFunctionInfo? info))
                    {
                        function.Action        = info.Action;
                        function.MinParameters = info.MinParameters;
                        function.MaxParameters = info.MaxParameters;
                    }
                    else
                    {
                        throw new Exception($"Internal intrinsic function \"{function.Name}\" not found");
                    }
                }
                Functions = functions.ToArray();
            }
            catch (Exception)
            {
                // Clear to known state if error
                Reset();
                throw;
            }
        }