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; }
public Stack(MemoryStream data) { m_data = data; }
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); } }
private String readNextProgramString(MemoryStream programCode) { programCode.Position = m_eip; String ret = programCode.Reader.ReadString(); m_eip += ret.Length+1; return ret; }
private int readNextProgramInt(MemoryStream programCode) { programCode.Position = m_eip; m_eip += sizeof(int); return programCode.Reader.ReadInt32(); }
private float readNextProgramFloat(MemoryStream programCode) { programCode.Position = m_eip; m_eip += sizeof(float); return programCode.Reader.ReadSingle(); }
private OpCode readNextOpCode(MemoryStream programCode) { programCode.Position = m_eip; m_eip += sizeof(int); m_opcode = (OpCode)programCode.Reader.ReadInt32(); return m_opcode; }
/// <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); } }