static void HandlePrim(Vm vm) { var instruction = vm.CurrentInstruction (); if (vm.GetCurrentCache () == null) { var udpName = (string)instruction.Arguments; vm.SetCurrentCache (Value.Make (GetUdpByName (vm, udpName))); } vm.stack.Push ((Value)vm.GetCurrentCache ()); vm.IncrementTicks (1); vm.programCounter++; }
static void HandleNot(Vm vm) { Prim0.LogicalNot (vm.api, ref vm.stack.Storage [vm.stack.Count - 1]); vm.programCounter++; }
static void HandlePopBlock(Vm vm) { var returnValue = vm.stack.PopTop (); var namedBlock = vm.stack.PopTop (); if (namedBlock.Kind != Value.Kinds.NamedBlock) { vm.RaiseShovelError ("Invalid context for POP_BLOCK."); } vm.stack.Push (returnValue); vm.programCounter++; }
static void HandleLte(Vm vm) { var start = vm.stack.Count - 2; Prim0.LessThanOrEqual (vm.api, ref vm.stack.Storage [start], ref vm.stack.Storage [start + 1]); vm.stack.Pop (); 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 HandleKeys(Vm vm) { Prim0.Keys (vm.api, ref vm.stack.Storage [vm.stack.Count - 1]); vm.programCounter++; }
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 HandleCallj(Vm vm) { var instruction = vm.CurrentInstruction (); var numArgs = (int)instruction.Arguments; Vm.HandleCallImpl (vm, numArgs, false); }
static void HandleConst(Vm vm) { vm.stack.Push ((Value)vm.CurrentInstruction ().Arguments); vm.programCounter++; vm.IncrementCells (1); }
static void HandleBlockReturn(Vm vm) { var returnValue = vm.stack.PopTop (); var name = vm.stack.PopTop (); if (name.Kind != Value.Kinds.String) { vm.RaiseShovelError ("The name of a block must be a string."); } var namedBlockIndex = vm.FindNamedBlock (name.stringValue); if (vm.stack.Count > namedBlockIndex + 1) { vm.stack.RemoveRange (namedBlockIndex + 1, vm.stack.Count - namedBlockIndex - 1); } var namedBlock = vm.stack.Top ().NamedBlockValue; vm.stack.Push (returnValue); vm.programCounter = namedBlock.BlockEnd; vm.currentEnvironment = namedBlock.Environment; }
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 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 HandleArgs3(Vm vm) { if (vm.stack.TopIsReturnAddress ()) { vm.currentEnvironment.Frame.Values [0] = vm.stack.UnderTop (3); vm.currentEnvironment.Frame.Values [1] = vm.stack.UnderTop (2); vm.currentEnvironment.Frame.Values [2] = vm.stack.UnderTop (1); vm.stack.UnderPopAndCopyTop (3); } else { vm.currentEnvironment.Frame.Values [2] = vm.stack.PopTop (); vm.currentEnvironment.Frame.Values [1] = vm.stack.PopTop (); vm.currentEnvironment.Frame.Values [0] = vm.stack.PopTop (); } vm.programCounter++; }
static void HandleArgs(Vm vm) { var instruction = vm.CurrentInstruction (); var argCount = (int)instruction.Arguments; if (argCount > 0) { Value? returnAddress = null; if (vm.stack.Top ().Kind == Value.Kinds.ReturnAddress) { returnAddress = vm.stack.PopTop (); } var values = vm.currentEnvironment.Frame.Values; Array.Copy ( vm.stack.Storage, vm.stack.Count - argCount, values, 0, argCount); vm.stack.PopMany (argCount); if (returnAddress.HasValue) { vm.stack.Push (returnAddress.Value); } } vm.programCounter++; }
public static Exception VmUserDefinedPrimitiveError(Shovel.Vm.Vm vm) { return(vm.UserDefinedPrimitiveError); }
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 HandleJump(Vm vm) { vm.programCounter = (int)vm.CurrentInstruction ().Arguments; }
static void HandleDelete(Vm vm) { var start = vm.stack.Count - 2; Prim0.DeleteDictionary (vm.api, ref vm.stack.Storage [start], ref vm.stack.Storage [start + 1]); vm.stack.Pop (); vm.programCounter++; }
static void HandleLen(Vm vm) { Prim0.GetLength (vm.api, ref vm.stack.Storage [vm.stack.Count - 1]); vm.programCounter++; }
static void HandleDropFrame(Vm vm) { vm.currentEnvironment = vm.currentEnvironment.Next; vm.programCounter++; }
static void HandleLset(Vm vm) { var instruction = vm.CurrentInstruction (); var args = (int[])instruction.Arguments; SetInEnvironment (vm.currentEnvironment, args [0], args [1], vm.stack.Top ()); vm.programCounter++; }
static void HandleFjump(Vm vm) { var args = (int)vm.CurrentInstruction ().Arguments; // vm.CheckBool (); if (!vm.stack.PopTop ().boolValue) { vm.programCounter = args; } else { vm.programCounter ++; } }
static void HandleNeg(Vm vm) { Prim0.UnaryMinus (vm.api, ref vm.stack.Storage [vm.stack.Count - 1]); vm.programCounter++; }
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 HandleNop(Vm vm) { vm.programCounter++; }
static void HandleGrefDot(Vm vm) { var start = vm.stack.Count - 2; var callGetter = !Prim0.HashOrStructGetDot (vm, vm.api, ref vm.stack.Storage [start], ref vm.stack.Storage [start + 1]); if (callGetter) { var obj = vm.stack.Storage[start]; if (obj.Kind == Value.Kinds.Hash) { vm.stack.Push(obj.hashValue.IndirectGet); HandleCallImpl(vm, 2, true); } } else { vm.stack.Pop (); vm.programCounter++; } }
static void HandlePop(Vm vm) { vm.stack.Pop (); vm.programCounter++; }
static void HandleIsStruct(Vm vm) { Prim0.IsStruct (vm.api, ref vm.stack.Storage [vm.stack.Count - 1]); vm.programCounter++; }
static void HandlePow(Vm vm) { var start = vm.stack.Count - 2; Prim0.Pow (vm.api, ref vm.stack.Storage [start], ref vm.stack.Storage [start + 1]); vm.stack.Pop (); vm.programCounter++; }
static void HandleIsStructInstance(Vm vm) { var start = vm.stack.Count - 2; Prim0.IsStructInstance (vm.api, ref vm.stack.Storage [start], ref vm.stack.Storage [start + 1]); vm.stack.Pop (); vm.programCounter++; }
static void HandlePrim0(Vm vm) { var instruction = vm.CurrentInstruction (); if (vm.GetCurrentCache () == null) { var primName = (string)instruction.Arguments; if (!Vm.Prim0Hash.ContainsKey (primName)) { vm.RaiseShovelError (String.Format ( "Cannot take address of primitive '{0}' (implemented as instruction).", primName) ); } vm.SetCurrentCache (Value.Make (Vm.Prim0Hash [primName])); } vm.stack.Push ((Value)vm.GetCurrentCache ()); vm.IncrementTicks (1); vm.programCounter++; }
public static ShovelException VmProgrammingError(Shovel.Vm.Vm vm) { return(vm.ProgrammingError); }