internal static LispExecutionState CreateExecutionState(LispStackFrame stackFrame, string inputName, string code, bool useTailCalls, bool allowHalting) { var reader = new StringReader(code); var executionState = new LispExecutionState(stackFrame, inputName, reader, useTailCalls, allowHalting); return(executionState); }
public static LispEvaluationState Evaluate(LispHost host, LispExecutionState executionState) { var shouldDribbleReturnValue = executionState.StackFrame.Root.DribbleStream != null; while (executionState.TryDequeueOperation(out var operation)) { if (executionState.LastResult is LispError error) { // re-queue, because we can never finish executionState.InsertOperation(operation); error.StackFrame ??= executionState.StackFrame; executionState.StackFrame.Root.OnErrorOccured(error, executionState.StackFrame); return(LispEvaluationState.FatalHalt); } // value setting can only occur when evaluating a native macro or native function; if any of the set operations wants to halt, we do that below var captureValueSetHalt = false; var haltDueToValueSet = false; var valueSet = new EventHandler <LispValueSetEventArgs>((s, e) => { if (captureValueSetHalt) { haltDueToValueSet = haltDueToValueSet || e.HaltExecution; } }); executionState.StackFrame.Root.ValueSet += valueSet; switch (operation) { case LispEvaluatorPopForTailCall tailPop: { // the shape of the operation stack at the time of a tail call should be either: // pop // tail-call-expression // function-return // or // tail-call-expression // function-return ILispEvaluatorOperation tailCallExpression = null; ILispEvaluatorOperation invocationExit = null; if ((executionState.PeekOperation() is LispEvaluatorPopArgument pop && executionState.TryDequeueOperation(out var _) && executionState.PeekOperation() is LispEvaluatorObjectExpression && executionState.TryDequeueOperation(out tailCallExpression) && executionState.PeekOperation() is LispEvaluatorFunctionExit && executionState.TryDequeueOperation(out invocationExit)) || (executionState.PeekOperation() is LispEvaluatorObjectExpression && executionState.TryDequeueOperation(out tailCallExpression) && executionState.PeekOperation() is LispEvaluatorFunctionExit && executionState.TryDequeueOperation(out invocationExit))) { var concreteInvocationExit = (LispEvaluatorFunctionExit)invocationExit; Debug.Assert(ReferenceEquals(tailPop.Function, concreteInvocationExit.Function)); // restore the tail call operation and pop the stack executionState.InsertOperation(concreteInvocationExit.WithoutFramePop()); executionState.InsertOperation(tailCallExpression); executionState.StackFrame.CopyLocalsToParentForTailCall(host.CurrentPackage, new HashSet <string>(tailPop.InvocationArgumentNames)); executionState.StackFrame = executionState.StackFrame.Parent; }
internal void Eval(LispExecutionState executionState) { Host.EvalContinue(executionState); }
public LispObject Untrace(LispHost host, LispExecutionState executionState, LispObject[] args) { var untracedList = _repl.Untrace(args); return(LispList.FromItems(LispSymbol.CreateFromString("COMMON-LISP:QUOTE"), untracedList)); }