Exemple #1
0
        public void AddParts(IEnumerable <CodePart> parts)
        {
            builder.AddRange(parts);
            List <Opcode> newProgram = builder.BuildProgram();

            UpdateProgram(newProgram);
        }
Exemple #2
0
Fichier : CPU.cs Projet : silky/KOS
        public void OnLoad(ConfigNode node)
        {
            try
            {
                StringBuilder scriptBuilder = new StringBuilder();

                foreach (ConfigNode contextNode in node.GetNodes("context"))
                {
                    foreach (ConfigNode varNode in contextNode.GetNodes("variables"))
                    {
                        foreach (ConfigNode.Value value in varNode.values)
                        {
                            string varValue = Persistence.ProgramFile.DecodeLine(value.value);
                            scriptBuilder.AppendLine(string.Format("set {0} to {1}.", value.name, varValue));
                        }
                    }
                }

                if (_shared.ScriptHandler != null && scriptBuilder.Length > 0)
                {
                    ProgramBuilder programBuilder = new ProgramBuilder();
                    programBuilder.AddRange(_shared.ScriptHandler.Compile(scriptBuilder.ToString()));
                    List <Opcode> program = programBuilder.BuildProgram();
                    RunProgram(program, true);
                }
            }
            catch (Exception e)
            {
                if (_shared.Logger != null)
                {
                    _shared.Logger.Log(e);
                }
            }
        }
Exemple #3
0
        public override void Execute(SharedObjects shared)
        {
            object volumeId = shared.Cpu.PopValue();
            string fileName = shared.Cpu.PopValue().ToString();

            if (shared.VolumeMgr == null)
            {
                return;
            }
            if (shared.VolumeMgr.CurrentVolume == null)
            {
                throw new Exception("Volume not found");
            }

            ProgramFile file = shared.VolumeMgr.CurrentVolume.GetByName(fileName);

            if (file == null)
            {
                throw new Exception(string.Format("File '{0}' not found", fileName));
            }
            if (shared.ScriptHandler == null)
            {
                return;
            }

            if (volumeId != null)
            {
                Volume targetVolume = shared.VolumeMgr.GetVolume(volumeId);
                if (targetVolume != null)
                {
                    if (shared.ProcessorMgr != null)
                    {
                        string          filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName);
                        List <CodePart> parts    = shared.ScriptHandler.Compile(filePath, 1, file.Content);
                        var             builder  = new ProgramBuilder();
                        builder.AddRange(parts);
                        List <Opcode> program = builder.BuildProgram();
                        shared.ProcessorMgr.RunProgramOn(program, targetVolume);
                    }
                }
                else
                {
                    throw new Exception("Volume not found");
                }
            }
            else
            {
                // clear the "program" compilation context
                shared.ScriptHandler.ClearContext("program");
                string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName;
                var    options  = new CompilerOptions {
                    LoadProgramsInSameAddressSpace = true
                };
                List <CodePart> parts          = shared.ScriptHandler.Compile(filePath, 1, file.Content, "program", options);
                var             programContext = shared.Cpu.GetProgramContext();
                programContext.AddParts(parts);
            }
        }
Exemple #4
0
        public void OnLoad(ConfigNode node)
        {
            try
            {
                var scriptBuilder = new StringBuilder();

                foreach (ConfigNode contextNode in node.GetNodes("context"))
                {
                    foreach (ConfigNode varNode in contextNode.GetNodes("variables"))
                    {
                        foreach (ConfigNode.Value value in varNode.values)
                        {
                            string varValue = PersistenceUtilities.DecodeLine(value.value);
                            scriptBuilder.AppendLine(string.Format("set {0} to {1}.", value.name, varValue));
                        }
                    }
                }

                if (shared.ScriptHandler == null || scriptBuilder.Length <= 0)
                {
                    return;
                }

                var programBuilder = new ProgramBuilder();
                // TODO: figure out how to store the filename and reload it for arg 1 below:
                // (Possibly all of OnLoad needs work because it never seemed to bring
                // back the context fully right anyway, which is why this hasn't been
                // addressed yet).
                try
                {
                    SafeHouse.Logger.Log("Parsing Context:\n\n" + scriptBuilder);
                    programBuilder.AddRange(shared.ScriptHandler.Compile("reloaded file", 1, scriptBuilder.ToString()));
                    List <Opcode> program = programBuilder.BuildProgram();
                    RunProgram(program, true);
                }
                catch (NullReferenceException ex)
                {
                    SafeHouse.Logger.Log("program builder failed on load. " + ex.Message);
                }
            }
            catch (Exception e)
            {
                if (shared.Logger != null)
                {
                    shared.Logger.Log(e);
                }
            }
        }
Exemple #5
0
        public override void Execute(SharedObjects shared)
        {
            // run() is strange.  It needs two levels of args - the args to itself, and the args it is meant to
            // pass on to the program it's invoking.  First, these are the args to run itself:
            object volumeId = PopValueAssert(shared, true);
            string fileName = PopValueAssert(shared, true).ToString();

            AssertArgBottomAndConsume(shared);

            // Now the args it is going to be passing on to the program:
            var progArgs = new List <object>();
            int argc     = CountRemainingArgs(shared);

            for (int i = 0; i < argc; ++i)
            {
                progArgs.Add(PopValueAssert(shared, true));
            }
            AssertArgBottomAndConsume(shared);

            if (shared.VolumeMgr == null)
            {
                return;
            }
            if (shared.VolumeMgr.CurrentVolume == null)
            {
                throw new Exception("Volume not found");
            }

            VolumeFile file = shared.VolumeMgr.CurrentVolume.Open(fileName, true);

            if (file == null)
            {
                throw new Exception(string.Format("File '{0}' not found", fileName));
            }
            if (shared.ScriptHandler == null)
            {
                return;
            }

            if (volumeId != null)
            {
                Volume targetVolume = shared.VolumeMgr.GetVolume(volumeId);
                if (targetVolume != null)
                {
                    if (shared.ProcessorMgr != null)
                    {
                        string filePath = string.Format("{0}/{1}", shared.VolumeMgr.GetVolumeRawIdentifier(targetVolume), fileName);
                        var    options  = new CompilerOptions {
                            LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager
                        };
                        List <CodePart> parts   = shared.ScriptHandler.Compile(filePath, 1, file.ReadAll().String, "program", options);
                        var             builder = new ProgramBuilder();
                        builder.AddRange(parts);
                        List <Opcode> program = builder.BuildProgram();
                        shared.ProcessorMgr.RunProgramOn(program, targetVolume);
                    }
                }
                else
                {
                    throw new KOSFileException("Volume not found");
                }
            }
            else
            {
                // clear the "program" compilation context
                shared.Cpu.StartCompileStopwatch();
                shared.ScriptHandler.ClearContext("program");
                string filePath = shared.VolumeMgr.GetVolumeRawIdentifier(shared.VolumeMgr.CurrentVolume) + "/" + fileName;
                var    options  = new CompilerOptions {
                    LoadProgramsInSameAddressSpace = true, FuncManager = shared.FunctionManager
                };
                var programContext = ((CPU)shared.Cpu).SwitchToProgramContext();

                List <CodePart> codeParts;
                FileContent     content = file.ReadAll();
                if (content.Category == FileCategory.KSM)
                {
                    string prefix = programContext.Program.Count.ToString();
                    codeParts = content.AsParts(fileName, prefix);
                }
                else
                {
                    try
                    {
                        codeParts = shared.ScriptHandler.Compile(filePath, 1, content.String, "program", options);
                    }
                    catch (Exception)
                    {
                        // If it died due to a compile error, then we won't really be able to switch to program context
                        // as was implied by calling Cpu.SwitchToProgramContext() up above.  The CPU needs to be
                        // told that it's still in interpreter context, or else it fails to advance the interpreter's
                        // instruction pointer and it will just try the "call run()" instruction again:
                        shared.Cpu.BreakExecution(false);
                        throw;
                    }
                }
                programContext.AddParts(codeParts);
                shared.Cpu.StopCompileStopwatch();
            }

            // Because run() returns FIRST, and THEN the CPU jumps to the new program's first instruction that it set up,
            // it needs to put the return stack in a weird order.  Its return value needs to be buried UNDER the args to the
            // program it's calling:
            UsesAutoReturn = false;

            shared.Cpu.PushStack(0); // dummy return that all functions have.

            // Put the args for the program being called back on in the same order they were in before (so read the list backward):
            shared.Cpu.PushStack(new KOSArgMarkerType());
            for (int i = argc - 1; i >= 0; --i)
            {
                shared.Cpu.PushStack(progArgs[i]);
            }
        }