Example #1
0
        public IScript Compile(String scriptCode, String name)
        {
            Stack stack = new Stack();
            //System.Diagnostics.Debugger.Launch();
            XDocument script = XDocument.Parse(scriptCode.Trim());

            m_entryPoint = -1;

            m_currentProgramCode = new MemoryStream();
            m_parameterSequence = new ParameterSequence();
            XElement root = script.Element("Root");
            if (root == null)
            {
                root = script.Element("root");
                if (root == null)
                {
                    throw new Exception("Error. Script must contain a root node.");
                }
            }
            foreach (XElement node in root.Elements())
            {
                bool isMain = false;
                if (node.Name.LocalName == "Main" || node.Name.LocalName == "main")
                {
                    // scripts starts here
                    m_entryPoint = (int)m_currentProgramCode.Position;
                    // push all attributes to the parameter sequencer (so the script can run with default parameters)
                    ParameterSequenceBuilder sequenceBuilder = new ParameterSequenceBuilder();
                    sequenceBuilder.createSequence();
                    foreach (XAttribute attr in node.Attributes())
                    {
                        sequenceBuilder.addParameter(new StringParameter(attr.Name.ToString(), attr.Value));
                    }
                    m_parameterSequence = sequenceBuilder.CurrentSequence;
                    stack = new Stack(m_parameterSequence.getMemStream());
                    isMain = true;
                }
                // add node as a function
                else
                {
                    //m_dataTable.Data.Add(node.Name.LocalName, (int)m_currentProgramCode.Position);
                    m_functionTable.add(node.Name.LocalName, (int)m_currentProgramCode.Position);
                    isMain = false;
                }
                compileRoutine(node, isMain,stack);
            }

            // end of program
            m_currentProgramCode.Writer.Write((int)XmlScriptExecutor.OpCode.HALT);

            XmlScriptCompiled compiledScript = new XmlScriptCompiled(scriptCode);
            compiledScript.Name = name;
            compiledScript.ProgramCode = m_currentProgramCode;
            compiledScript.EntryPoint = m_entryPoint;
            compiledScript.ParameterSequence = m_parameterSequence;

            if (m_entryPoint == -1)
            {
                throw new Exception("Error no entrypoint for script: " + name);
            }
            return compiledScript;
        }
Example #2
0
 public Stack(MemoryStream data)
 {
     m_data = data;
 }
Example #3
0
 private void serializeData(XmlDocument doc, XmlElement data, AbstractElement element)
 {
     XnaScrapCore.Core.MemoryStream memoryStream = new XnaScrapCore.Core.MemoryStream();
     XnaScrapCore.Core.StringWriter sw = new XnaScrapCore.Core.StringWriter(memoryStream);
     element.doSerialize(sw);
     // stream is now filled with string
     long end = memoryStream.Position;
     memoryStream.Position = 0;
     while (memoryStream.Position < end)
     {
         XmlElement value = doc.CreateElement("Value");
         value.InnerXml = memoryStream.Reader.ReadString();
         data.AppendChild(value);
     }
 }
Example #4
0
 private String readNextProgramString(MemoryStream programCode)
 {
     programCode.Position = m_eip;
     String ret = programCode.Reader.ReadString();
     m_eip += ret.Length+1;
     return ret;
 }
Example #5
0
 private int readNextProgramInt(MemoryStream programCode)
 {
     programCode.Position = m_eip;
     m_eip += sizeof(int);
     return programCode.Reader.ReadInt32();
 }
Example #6
0
 private float readNextProgramFloat(MemoryStream programCode)
 {
     programCode.Position = m_eip;
     m_eip += sizeof(float);
     return programCode.Reader.ReadSingle();
 }
Example #7
0
 private OpCode readNextOpCode(MemoryStream programCode)
 {
     programCode.Position = m_eip;
     m_eip += sizeof(int);
     m_opcode = (OpCode)programCode.Reader.ReadInt32();
     return m_opcode;
 }
Example #8
0
        /// <summary>
        /// Executes a subroutine. All parameters must be written to the heap before execution.
        /// Afterwards the addresses of the parameters have to be stored in the stack (realtive to stackpointer).
        /// Mind this if you want to execute a script with external parameters.
        /// </summary>
        /// <param name="programCode">The script's code.</param>
        /// <param name="data">The data stack of the current script execution.</param>
        public void executeSub(MemoryStream programCode, int entryPoint, Stack data, Heap heap)
        {
            m_eip = entryPoint;
            m_ebp = (int)data.Position; // base pointer
            readNextOpCode(programCode);
            while (m_opcode != OpCode.HALT)
            {
                //eip = (int)programCode.Position;
                switch (m_opcode)
                {
                    case OpCode.POP_INT:
                        {
                            break;
                        }
                    case OpCode.POP_FLOAT:
                        {
                            break;
                        }
                    case OpCode.POP_STRING:
                        {
                            break;
                        }
                    case OpCode.PUSH_INT:
                        {
                            data.push(readNextProgramInt(programCode));
                            break;
                        }
                    case OpCode.PUSH_FLOAT:
                        {
                            data.push(readNextProgramFloat(programCode));
                            break;
                        }
                    case OpCode.PUSH_STRING:
                        {
                            data.push(readNextProgramString(programCode));
                            break;
                        }
                    case OpCode.PUSH_ADDR:
                        {
                            int addr = readNextProgramInt(programCode); // address relative to ebp
                            // read heap address from stack
                            int heapAddr = data.readInt(m_ebp + addr);
                            data.push(heapAddr);
                            break;
                        }
                    case OpCode.PUSH_EBP:
                        {
                            data.push(m_ebp);
                            break;
                        }
                    case OpCode.ADD_INT:
                        {
                            int val1 = data.popInt();
                            int val2 = data.popInt();
                            data.push(val1 + val2);
                            break;
                        }
                    case OpCode.SUB_INT:
                        {
                            int val1 = data.popInt();
                            int val2 = data.popInt();
                            data.push(val1 - val2);
                            break;
                        }
                    case OpCode.READ_INT:
                        {
                            int addr = data.popInt();
                            data.push(data.readInt(addr));
                            break;
                        }
                    case OpCode.WRITE_INT:
                        {
                            // read address
                            int addr = data.popInt();
                            // read value
                            int value = data.popInt();
                            // write
                            data.writeInt(addr,value);
                            break;
                        }
                    case OpCode.READ_FLOAT:
                        {
                            int addr = data.popInt();
                            data.push(data.readFlt(addr));
                            break;
                        }
                    case OpCode.WRITE_FLOAT:
                        {
                            // read address
                            int addr = data.popInt();
                            // read value
                            float value = data.popInt();
                            // write
                            data.writeFlt(addr, value);
                            break;
                        }
                    case OpCode.ALLOC_STRING_ON_HEAP:
                        {
                            String s = data.popString();
                            int address = heap.allocString(s);
                            data.push(address);
                            break;
                        }
                    case OpCode.READ_STRING_FROM_HEAP:
                        {
                            //int ptr = data.readInt((int)data.Position + addr * sizeof(int));
                            int ptr = data.popInt();
                            String s = heap.readString(ptr);
                            data.push(s);
                            break;
                        }
                    case OpCode.BEGIN_BLOCK:
                        {
                            // save base pointer
                            m_ebp = (int)data.Position;
                            data.push(m_ebp);
                            break;
                        }
                    case OpCode.CALL_FUNCTION:
                        {
                            // get function address
                            int func_addr = data.popInt();
                            // save instruction pointer
                            data.push(m_eip);

                            m_eip = func_addr;
                            programCode.Position = m_eip;
                            break;
                        }

                    case OpCode.RETURN:
                        {
                            m_eip = data.popInt(); // restore eip
                            programCode.Position = m_eip;
                            break;
                        }
                    case OpCode.END_BLOCK:
                        {
                            m_ebp = data.popInt(); // restore ebp
                            data.set(m_ebp);
                            break;
                        }
                        // Built in function
                    case OpCode.NATIVE_CALL:
                        {
                            int f = readNextProgramInt(programCode);
                            if (f > 0)
                            {
                                m_registeredFunctions.RegisteredFunctionAddresses[f].execute(data,heap);
                            }
                            else if (f < 0)
                            {
                                m_registeredFunctions.RegisteredFunctionAddresses[-1*f].end(data,heap);
                            }
                            break;
                        }
                }
                readNextOpCode(programCode);
            }
        }