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++; }
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 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 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 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 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 Callable GetUdpByName(Vm vm, string udpName) { if (vm.userPrimitives == null || !vm.userPrimitives.ContainsKey (udpName)) { vm.RaiseShovelError (String.Format ( "Unknown user primitive '{0}'.", udpName) ); } return vm.userPrimitives [udpName]; }
static void ArityError(Vm vm, int expectedArity, int actualArity, bool inApply) { var message = "Function of {0} arguments called with {1} arguments."; if (inApply) { message = "The first argument of 'apply', a function of {0} arguments, was called with {1} arguments."; } vm.RaiseShovelError (String.Format ( message, expectedArity, actualArity)); }
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) { for (var i = namedBlockIndex + 1; i < vm.stack.Count; i++) { if (vm.stack.Storage [i].Kind == Value.Kinds.ReturnAddress) { vm.stack.Storage [i].ReturnAddressValue.Environment.DecreaseUsesLocally (); } } 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 ArityError(Vm vm, int expectedArity, int actualArity) { vm.RaiseShovelError (String.Format ( "Function of {0} arguments called with {1} arguments.", expectedArity, actualArity) ); }