Exemple #1
0
        public static SchemeObject Evaluate(Expression expression, SchemeEnvironment environment)
        {
            Stack<ContinuationFrame> stack = new Stack<ContinuationFrame>();
            SchemeObject value = null;

        evaluate:
            switch (expression.NodeType)
            {
                case NodeType.Assignment:
                    {
                        Assignment assignment = (Assignment)expression;
                        stack.Push(new AssignmentContinuation(assignment.Destination.Symbol, assignment.IsDefinition, environment));
                        expression = assignment.Source;
                        goto evaluate;
                    }

                case NodeType.Conditional:
                    {
                        Conditional conditional = (Conditional)expression;
                        stack.Push(new ConditionalContinuation(conditional.Consequent, conditional.Alternate, environment));
                        expression = conditional.Test;
                        goto evaluate;
                    }

                case NodeType.LambdaExpression:
                    {
                        value = new Closure(environment, (Lambda)expression);
                        goto apply;
                    }

                case NodeType.Literal:
                    {
                        value = ((Literal)expression).Value;
                        goto apply;
                    }

                case NodeType.ProcedureCall:
                    {
                        ProcedureCall procedureCall = (ProcedureCall)expression;
                        stack.Push(new ProcedureContinuation(procedureCall.Arguments, environment));
                        expression = procedureCall.Procedure;
                        goto evaluate;
                    }

                case NodeType.Sequence:
                    {
                        Sequence sequence = (Sequence)expression;
                        stack.Push(new SequenceContinuation(sequence, environment));
                        goto apply;
                    }

                case NodeType.Variable:
                    {
                        Variable variable = (Variable)expression;
                        value = environment.GetValue(variable.Symbol);
                        goto apply;
                    }

                default:
                    {
                        System.Diagnostics.Debug.Assert(false);
                        throw new InvalidOperationException();
                    }
            }

        apply:
            if (stack.Count == 0)
                return value;

            ContinuationFrame frame = stack.Pop();
            environment = frame.Environment;
            switch (frame.Kind)
            {
                case ContinuationKind.Assignment:
                    {
                        AssignmentContinuation assignmentFrame = (AssignmentContinuation)frame;
                        environment.SetValue(assignmentFrame.Destination, value, assignmentFrame.IsDefinition);
                        value = SchemeVoid.Instance;
                        goto apply;
                    }

                case ContinuationKind.Procedure:
                    {
                        ProcedureContinuation procedureFrame = (ProcedureContinuation)frame;
                        ReadOnlyCollection<Expression> arguments = procedureFrame.Arguments;

                        Procedure procedure = value as Procedure;
                        if (procedure == null)
                            throw InvalidSyntaxException.Format("Error: {0} is not a procedure", value.PrettyPrint());

                        stack.Push(new ArgumentsContinuation(procedure, arguments, environment));
                        if (arguments.Count == 0)
                            goto apply;

                        expression = arguments[0];
                        goto evaluate;
                    }

                case ContinuationKind.Sequence:
                    {
                        SequenceContinuation sequenceFrame = (SequenceContinuation)frame;
                        Sequence sequence = sequenceFrame.Sequence;

                        int index = sequenceFrame.Index++;
                        if (index < sequence.Expressions.Count - 1)
                            stack.Push(sequenceFrame);

                        expression = sequence.Expressions[index];
                        goto evaluate;
                    }

                case ContinuationKind.Conditional:
                    {
                        ConditionalContinuation testFrame = (ConditionalContinuation)frame;
                        if (value != SchemeBoolean.False)
                        {
                            expression = testFrame.Consequent;
                            goto evaluate;
                        }

                        if (testFrame.Alternate != null)
                        {
                            expression = testFrame.Alternate;
                            goto evaluate;
                        }

                        value = SchemeVoid.Instance;
                        goto apply;
                    }

                case ContinuationKind.Arguments:
                    {
                        ArgumentsContinuation argumentsFrame = (ArgumentsContinuation)frame;

                        int index = argumentsFrame.Index++;
                        if (index < argumentsFrame.Arguments.Count)
                        {
                            argumentsFrame.EvaluatedArguments[index] = value;
                        }

                        if (argumentsFrame.Index < argumentsFrame.Arguments.Count)
                        {
                            stack.Push(argumentsFrame);
                            expression = argumentsFrame.Arguments[argumentsFrame.Index];
                            goto evaluate;
                        }

                        Primitive primitive = argumentsFrame.Procedure as Primitive;
                        if (primitive != null)
                        {
                            value = primitive.Callback(argumentsFrame.EvaluatedArguments);
                            goto apply;
                        }

                        Closure closure = (Closure)argumentsFrame.Procedure;
                        expression = closure.Body;
                        environment = BuildCallEnvironment(argumentsFrame.EvaluatedArguments, closure);
                        goto evaluate;
                    }

                default:
                    {
                        Debug.Assert(false);
                        throw new InvalidOperationException();
                    }
            }
            
        }
Exemple #2
0
 internal ConditionalContinuation(Expression consequent, Expression alternate, SchemeEnvironment environment)
     : base(environment, ContinuationKind.Conditional)
 {
     this.Consequent = consequent;
     this.Alternate = alternate;
 }
Exemple #3
0
 internal ProcedureCall(Expression procedure, IList<Expression> arguments)
 {
     this.procedure = procedure;
     this.arguments = new ReadOnlyCollection<Expression>(arguments);
 }
Exemple #4
0
 public Assignment(Variable destination, Expression source, bool isDefinition)
 {
     this.destination = destination;
     this.source = source;
     this.isDefinition = isDefinition;
 }
Exemple #5
0
 public Conditional(Expression test, Expression consequent, Expression alternate)
 {
     this.test = test;
     this.consequent = consequent;
     this.alternate = alternate;
 }
Exemple #6
0
 public Lambda(Formals formals, Expression body)
 {
     this.formals = formals;
     this.body = body;
 }