static void HandleLget(Vm vm) { var instruction = vm.CurrentInstruction (); var args = (int[])instruction.Arguments; vm.stack.Push (FindFrame (vm.currentEnvironment, args [0]).Values [args [1]]); vm.IncrementCells (1); vm.programCounter++; }
static void HandleNewFrame(Vm vm) { var instruction = vm.CurrentInstruction (); var args = (string[])instruction.Arguments; var frame = new VmEnvFrame () { VarNames = args, Values = new Value[args.Length], IntroducedAtProgramCounter = vm.programCounter }; var newEnv = new VmEnvironment () { Frame = frame, Next = vm.currentEnvironment }; vm.currentEnvironment = newEnv; vm.IncrementCells (args.Length * 3 + 5); vm.programCounter++; }
static void HandleContext(Vm vm) { var stackTraceSb = new StringBuilder (); vm.WriteStackTrace (stackTraceSb); var stackTrace = stackTraceSb.ToString (); var currentEnvironmentSb = new StringBuilder (); vm.WriteCurrentEnvironment (currentEnvironmentSb); var currentEnvironment = currentEnvironmentSb.ToString (); var result = new HashInstance (); result.Add (Value.Make ("stack"), Value.Make (stackTrace)); result.Add (Value.Make ("environment"), Value.Make (currentEnvironment)); vm.IncrementCells (6 + stackTrace.Length + currentEnvironment.Length); vm.stack.Push (Value.Make (result)); vm.programCounter ++; return; }
static void HandleFn(Vm vm) { var instruction = vm.CurrentInstruction (); var args = (int[])instruction.Arguments; var arity = args[1]; var hasCollectParameters = arity >= Callable.CollectParamsArityModifier; if (hasCollectParameters) { arity -= Callable.CollectParamsArityModifier; } var callable = new Callable () { ProgramCounter = args[0], Arity = arity, HasCollectParams = hasCollectParameters, Environment = vm.currentEnvironment }; vm.stack.Push (Value.Make (callable)); vm.IncrementCells (5); vm.programCounter++; }
static void HandleCallImpl(Vm vm, int numArgs, bool saveReturnAddress, bool inApply = false) { var maybeCallable = vm.stack.Top (); if (maybeCallable.Kind != Value.Kinds.Callable) { vm.RaiseShovelError (String.Format ( "Object [{0}] is not callable.", Prim0.ShovelStringRepresentation (vm.api, maybeCallable)) ); } var callable = maybeCallable.CallableValue; if (callable.ProgramCounter.HasValue) { vm.stack.Pop (); CallFunction (callable, vm, numArgs, saveReturnAddress, inApply); if (saveReturnAddress) { vm.IncrementCells (1); } } else { CallPrimitive (callable, vm, numArgs, saveReturnAddress, inApply); } }
static void HandleConst(Vm vm) { vm.stack.Push ((Value)vm.CurrentInstruction ().Arguments); vm.programCounter++; vm.IncrementCells (1); }
static void HandleBlock(Vm vm) { var instruction = vm.CurrentInstruction (); var blockEnd = (int)instruction.Arguments; var name = vm.stack.PopTop (); if (name.Kind != Value.Kinds.String) { vm.RaiseShovelError ("The name of a block must be a string."); } vm.stack.Push (Value.Make (new NamedBlock () { Name = name.stringValue, BlockEnd = blockEnd, Environment = vm.currentEnvironment } ) ); vm.IncrementCells (3); vm.programCounter++; }
static void HandleApply(Vm vm) { var maybeArray = vm.stack.PopTop(); var maybeCallable = vm.stack.PopTop(); if (maybeArray.Kind != Value.Kinds.Array) { vm.RaiseShovelError(String.Format( "Object [{0}] is not an array.", Prim0.ShovelStringRepresentation(vm.api, maybeArray)) ); } var numArgs = maybeArray.arrayValue.Count; foreach (var value in maybeArray.arrayValue) { vm.stack.Push((Value)value); vm.IncrementCells(1); } vm.stack.Push(maybeCallable); Vm.HandleCallImpl(vm, numArgs, true, true); }
static void FinishPrimitiveCall( Vm vm, int numArgs, bool saveReturnAddress, Value result) { vm.stack.PopMany (numArgs); if (saveReturnAddress) { vm.programCounter ++; } else { var maybeRa = vm.stack.PopTop (); if (maybeRa.Kind == Value.Kinds.ReturnAddress) { vm.ApplyReturnAddress (maybeRa.ReturnAddressValue); } else { Utils.Panic (); } } vm.stack.Push (result); vm.IncrementCells (1); }
static void HandleFn(Vm vm) { var instruction = vm.CurrentInstruction (); var args = (int[])instruction.Arguments; var callable = new Callable () { ProgramCounter = args[0], Arity = args[1], Environment = vm.currentEnvironment }; if (vm.currentEnvironment != null) { vm.currentEnvironment.IncreaseUses (); } vm.stack.Push (Value.Make (callable)); vm.IncrementCells (5); vm.programCounter++; }
static VmEnvironment FreshFrame(Vm vm, Instruction instruction) { var args = (string[])instruction.Arguments; var frame = new VmEnvFrame () { VarNames = args, Values = new Value[args.Length], IntroducedAtProgramCounter = vm.programCounter }; var result = new VmEnvironment () { Frame = frame, }; vm.IncrementCells (args.Length * 3 + 5); instruction.Cache = result; return result; }