コード例 #1
0
            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();
                }
            }