/* * Implementation of std::run-interpreter. */ internal void NativeRunInterpreter(CPU cpu) { string end = cpu.Pop().String; cpu.PushMarker(); savedBuilders.Add(CurrentBuilder); CurrentBuilder = new FunctionBuilder(); ShareAutoLocals(); InterpreterStep is1 = new InterpreterStep(this, ")"); /* * Make the CPU enter the loop for that first builder, * with a continuation to the rest of function building. */ cpu.Enter(new Opcode[] { new OpcodeSpecial(cpu2 => { FinishInterpreter(cpu2); }), new OpcodeRet() }, 0, null); cpu.Enter(new Opcode[] { new OpcodeSpecial(is1.Run), new OpcodeJumpUncond(-2) }, 0, null); }
/* * Implementation of std:::. */ internal void StartFunction(CPU cpu) { string name = ParseAndCompleteName(); bool immediate = false; bool export = false; for (;;) { string t = ParseName(); switch (t) { case "<immediate>": immediate = true; continue; case "<export>": export = true; continue; case "(": break; default: throw new Exception(string.Format("unexpected token: {0}", t)); } break; } /* * Create a new automatic builder for gathering the * parameter types. */ cpu.PushMarker(); savedBuilders.Add(CurrentBuilder); CurrentBuilder = new FunctionBuilder(); ShareAutoLocals(); InterpreterStep is1 = new InterpreterStep(this, ")"); /* * Make the CPU enter the loop for that first builder, * with a continuation to the rest of function building. */ cpu.Enter(new Opcode[] { new OpcodeSpecial(cpu2 => { ContinueFunction(cpu2, name, immediate, export); }), new OpcodeRet() }, 0, null); cpu.Enter(new Opcode[] { new OpcodeSpecial(is1.Run), new OpcodeJumpUncond(-2) }, 0, null); }
internal void Run() { CPU cpu = new CPU(this); savedBuilders.Clear(); CurrentBuilder = new FunctionBuilder(); InterpreterStep is0 = new InterpreterStep(this, null); cpu.Enter(new Opcode[] { new OpcodeSpecial(is0.Run), new OpcodeJumpUncond(-2) }, 0, null); while (!cpu.IsFinished) { Opcode op = cpu.ipBuf[cpu.ipOff++]; op.Run(cpu); } }
void ContinueFunction(CPU cpu, string name, bool immediate, bool export) { /* * Gather parameter types left by the first builder. */ XValue[] vv = cpu.PopToMarker(); XType[] pp = new XType[vv.Length]; for (int i = 0; i < vv.Length; i++) { pp[i] = vv[i].XTypeInstance; } if (immediate && pp.Length > 0) { throw new Exception(string.Format("cannot define immediate function {0} with {1} parameter(s)", name, pp.Length)); } /* * Make the second builder, for the function body. This is * a non-automatic builder; the intended function name is * used as debug name. */ savedBuilders.Add(CurrentBuilder); CurrentBuilder = new FunctionBuilder(name); InterpreterStep is2 = new InterpreterStep(this, ";"); /* * We exit the hook we had put in place to get here, then * put a new hook for function registration, and create * the builder loop. */ cpu.Exit(); cpu.Enter(new Opcode[] { new OpcodeSpecial(cpu2 => { EndFunction(cpu2, name, pp, immediate, export, is2.BuiltFunction); }), new OpcodeRet() }, 0, null); cpu.Enter(new Opcode[] { new OpcodeSpecial(is2.Run), new OpcodeJumpUncond(-2) }, 0, null); }