public void Execute(OpCode ins) { if (DebugMode) { string o = typeof(OpCode).GetEnumName(ins); if (ins.HasArgument()) { o += " " + Code[PC].ToString(); } Console.Write("!ins {0,-12}", o); Console.Write("state: "); } Steps++; switch (ins) { case OpCode.NOP: break; case OpCode.LEA: A = Stack[BP + Code[PC++]]; break; case OpCode.SEA: Stack[BP + Code[PC++]] = A; break; case OpCode.ENTER: Stack[--SP] = new Cell(BP); BP = SP; SP -= Code[PC++]; break; case OpCode.ADJ: SP += Code[PC++]; break; case OpCode.LEAVE: SP = BP; BP = (int)Stack[SP++]; PC = (int)Stack[SP++]; break; case OpCode.PUSH: Stack[--SP] = A; break; case OpCode.POP: A = Stack[SP++]; break; case OpCode.PEEK: A = Stack[SP]; break; case OpCode.DUP: Stack[SP - 1] = Stack[SP]; --SP; break; case OpCode.SWITCH: Cell tmp = Stack[SP + 1]; Stack[SP + 1] = Stack[SP]; Stack[SP] = tmp; break; case OpCode.DATA: A = Data[Code[PC++]]; break; /*case OpCode.PROCEX: * Cell args = Stack[SP]; * A = A.ProcValue(args.ListValue.ToArray()); * break;*/ case OpCode.LE: A = new Cell(((int)Stack[SP++] <= (int)A) ? 1 : 0); break; case OpCode.GT: A = new Cell(((int)Stack[SP++] > (int)A) ? 1 : 0); break; case OpCode.EQ: A = new Cell((Stack[SP++] == A) ? 1 : 0); break; case OpCode.EQK: A = new Cell((Stack[SP] == A) ? 1 : 0); break; case OpCode.NEQ: A = new Cell((Stack[SP++] != A) ? 1 : 0); break; case OpCode.NEQK: A = new Cell((Stack[SP] != A) ? 1 : 0); break; case OpCode.JSR: Stack[--SP] = new Cell(PC + 1); PC = Code[PC]; break; case OpCode.BZ: PC = (int)A == 0 ? Code[PC] : PC + 1; break; case OpCode.BNZ: PC = (int)A != 0 ? Code[PC] : PC + 1; break; case OpCode.JMP: PC = Code[PC]; break; case OpCode.SUB: A = Stack[SP++] - A; break; case OpCode.MUL: A = Stack[SP++] * A; break; case OpCode.CELLNEW: A = new Cell((CellType)(int)A); break; case OpCode.CELLTYPE: A = new Cell((int)A.Type); break; case OpCode.CELLCOUNT: A = new Cell(A.ListValue.Count); break; case OpCode.CELLINDEX: A = Stack[SP].ListValue[(int)A]; break; case OpCode.CELLINVOKE: A = A.ProcValue(Stack[SP++].ListValue.ToArray()); break; case OpCode.CELLINVENV: A = A.ProcEnvValue(Stack[SP + 1].ListValue.ToArray(), Stack[SP].Environment); break; case OpCode.CELLHEAD: A = Stack[SP].Head(); break; case OpCode.CELLTAIL: A = Stack[SP].Tail(); break; case OpCode.CELLPUSH: Stack[SP].ListValue.Add(A); break; case OpCode.CELLSETTYPE: Stack[SP].Type = (CellType)(int)A; break; case OpCode.CELLSETENV: Stack[SP].Environment = A.Environment; break; case OpCode.CELLGETENV: A = new Cell(A.Environment); break; case OpCode.ENVNEW: A = new Cell(new SchemeEnvironment(Stack[SP + 1].ListValue, Stack[SP].ListValue, A.Environment)); ++SP; break; case OpCode.ENVLOOKUP: A = A.Environment.Lookup(Stack[SP++]); break; case OpCode.ENVSET: // *Stack++.Environment[*Stack++] = A Stack[SP + 1].Environment.Set(Stack[SP], A); SP--; // remove key from stack break; case OpCode.ENVDEFINE: Stack[SP + 1].Environment.Define(Stack[SP], A); SP--; // remove key from stack break; case OpCode.PRINT: Console.Write("{0}", A); break; case OpCode.HALTMSG: Console.Write((string)Data[Code[PC++]] + Environment.NewLine); finished = true; break; case OpCode.STATE: PrintState(); break; case OpCode.EXIT: finished = true; if (DebugMode) { Console.WriteLine("!Exit with code {0}", A); } break; case OpCode.BREAK: System.Diagnostics.Debugger.Break(); break; default: throw new MissingOpCodeException(ins); } if (DebugMode) { PrintStateLine(); } }