public void Execute(string function) { // get the current function Function?currentFunction = null; foreach (Function f in _functions) { if (f.Name == function) { currentFunction = f; break; } } if (currentFunction.HasValue == false) { throw new ArgumentException("Function not found: " + function); } int instructionPtr = 0; byte[] code = currentFunction.Value.Code; uint codeOffset = currentFunction.Value.CodeOffset; while (instructionPtr < code.Length) { byte op = code[instructionPtr++]; int param; Parameter[] functionParams; switch (op) { case 0x00: // SitnSpin // do nothing break; case 0x02: // CallSysFunctionV param = getIntFromBytes(code, ref instructionPtr); functionParams = buildParameterArray(); SheepMachine.CallVoidSystemFunction(Imports[param].Name, functionParams); _state.PushStack(0); break; case 0x03: // CallSysFunctionI param = getIntFromBytes(code, ref instructionPtr); functionParams = buildParameterArray(); _state.PushStack(SheepMachine.CallIntSystemFunction(Imports[param].Name, functionParams)); break; case 0x05: // CallSysFunctionS param = getIntFromBytes(code, ref instructionPtr); functionParams = buildParameterArray(); SheepMachine.CallStringSystemFunction(Imports[param].Name, functionParams); _state.PushString(0); break; case 0x06: // Branch param = getIntFromBytes(code, ref instructionPtr); instructionPtr = param - (int)codeOffset; break; case 0x08: // BranchIfZero param = getIntFromBytes(code, ref instructionPtr); if (_state.PeekStack().Type != ParameterType.Integer) { throw new InvalidOperationException("stack is bad"); } if (_state.PopStack().Integer == 0) { instructionPtr = param - (int)codeOffset; } break; case 0x09: // BeginWait // do nothing break; case 0x0A: // EndWait // do nothing break; case 0x0B: // ReturnV return; case 0x13: // PushI param = getIntFromBytes(code, ref instructionPtr); _state.PushStack(param); break; case 0x15: // PushS param = getIntFromBytes(code, ref instructionPtr); _state.PushString(param); break; case 0x16: // Pop _state.PopStack(); break; case 0x21: // IsEqualI if (_state.PeekStack().Type != ParameterType.Integer || _state.PeekStack().Type != ParameterType.Integer) { throw new InvalidOperationException("IsLessI found two non-integers on the stack"); } if (_state.PopStack().Integer == _state.PopStack().Integer) { _state.PushStack(1); } else { _state.PushStack(0); } break; case 0x27: // IsLessI if (_state.PeekStack().Type != ParameterType.Integer || _state.PeekStack().Type != ParameterType.Integer) { throw new InvalidOperationException("IsLessI found two non-integers on the stack"); } if (_state.PopStack().Integer >= _state.PopStack().Integer) { _state.PushStack(1); } else { _state.PushStack(0); } break; case 0x2D: param = getIntFromBytes(code, ref instructionPtr); _state.PushStack((float)param); break; case 0x30: // do nothing break; case 0x31: // do nothing break; case 0x33: // GetString { if (_state.PeekStack().Type != ParameterType.String) { throw new InvalidOperationException("GetString failed because value on stack isn't a string"); } param = _state.PopStack().Integer; Parameter p = new Parameter(); p.Type = ParameterType.String; p.Integer = param; p.String = Constants[_constantOffsetIndexMap[param]]; _state.PushStack(p); } break; default: throw new NotImplementedException("Instruction " + op.ToString("X") + " not implemented"); } } return; }