Esempio n. 1
0
        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);
        }
Esempio n. 2
0
        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;
                    }
Esempio n. 3
0
 internal void Eval(LispExecutionState executionState)
 {
     Host.EvalContinue(executionState);
 }
Esempio n. 4
0
        public LispObject Untrace(LispHost host, LispExecutionState executionState, LispObject[] args)
        {
            var untracedList = _repl.Untrace(args);

            return(LispList.FromItems(LispSymbol.CreateFromString("COMMON-LISP:QUOTE"), untracedList));
        }