public Routine(string name, Instruction[] instructions) { // todo1[ak] check args this.Name = name; this.Instructions = instructions; }
public void Exec() { // todo1[ak] check args bool cont = true; while (cont) { if (_currentProcess.IsEnd()) { break; } _currentInstruction = _currentProcess.GetCurrentInstruction(); switch (_currentInstruction.Name) { case "EVAL": LispObject evForm = this.GetRegisterValue(RegisterName.EvForm); if (evForm is Atom) { this.SetRegisterValue(RegisterName.EvRes, evForm); if (_gotos == 0) { cont = false; } else { _currentProcess.Advance(); } } else { // cons Cons cons = (Cons)evForm; LispObject car = cons.Car.Value; LispObject cdr = cons.Cdr.Value; if (!(car is Symbol)) { throw new ApplicationException(); // todo2[ak] } if (!(cdr is Cons)) { throw new ApplicationException(); // todo2[ak] } string name = ((Symbol)car).Name; Routine callee = this.Env.GetRoutine(name); //this.Advance(); _currentProcess.Advance(); this.SetRegisterValue(RegisterName.Args, cdr); this.GoToRoutine(callee); } break; case "CHECK-ARGS-COUNT": this.DoCheckArgsCount(); _currentProcess.Advance(); break; case "PUSH": this.DoPush(); _currentProcess.Advance(); break; case "POP": this.DoPop(); _currentProcess.Advance(); break; case "CAR": this.DoCar(); _currentProcess.Advance(); break; case "MOV": this.DoMov(); _currentProcess.Advance(); break; case "TEST": this.DoTest(); _currentProcess.Advance(); break; case "JN": this.DoJn(); // no call to Advance()! "DoJn" calls Advance(). break; case "JT": this.DoJt(); // no call to Advance()! "DoJn" calls Advance(). break; case "NTH": this.DoNth(); _currentProcess.Advance(); break; case "RET": this.DoRet(); break; default: throw new NotImplementedException(); } } }