コード例 #1
0
ファイル: Continuation.cs プロジェクト: nguerrera/scheme
 internal ArgumentsContinuation(Procedure procedure, ReadOnlyCollection<Expression> arguments, SchemeEnvironment environment)
     : base(environment, ContinuationKind.Arguments)
 {
     this.Procedure = procedure;
     this.Arguments = arguments;
     this.EvaluatedArguments = new SchemeObject[arguments.Count];
 }
コード例 #2
0
ファイル: SchemeEnvironment.cs プロジェクト: nguerrera/scheme
 private static SchemeEnvironment InitializeDefaultEnvironment()
 {
     SchemeEnvironment env = new SchemeEnvironment(null);
     env.Add(Symbol.For("+"), new Primitive(Primitives.Add));
     env.Add(Symbol.For("-"), new Primitive(Primitives.Subtract));
     env.Add(Symbol.For("/"), new Primitive(Primitives.Divide));
     env.Add(Symbol.For("*"), new Primitive(Primitives.Multiply));
     env.Add(Symbol.For("="), new Primitive(Primitives.NumericEqual));
     env.Add(Symbol.For("cons"), new Primitive(Primitives.Cons));
     env.Add(Symbol.For("car"), new Primitive(Primitives.Car));
     env.Add(Symbol.For("cdr"), new Primitive(Primitives.Cdr));
     env.Add(Symbol.For("display"), new Primitive(Primitives.Display));
     env.Add(Symbol.For("exit"), new Primitive(Primitives.Exit));
     return env;
 }
コード例 #3
0
ファイル: Interpreter.cs プロジェクト: nguerrera/scheme
        private static SchemeEnvironment BuildCallEnvironment(SchemeObject[] arguments, Closure closure)
        {
            ReadOnlyCollection<Variable> parameters = closure.Parameters;
            Variable restParameter = closure.RestParameter;

            if (arguments.Length != parameters.Count && restParameter == null)
                throw InvalidSyntaxException.Format(Strings.IncorrectArgumentCount, parameters.Count, arguments.Length);

            if (arguments.Length < parameters.Count)
                throw InvalidSyntaxException.Format(Strings.TooFewArguments, parameters.Count, arguments.Length);

            SchemeEnvironment result = new SchemeEnvironment(closure.Environment);
            int index = 0;
            for (; index < parameters.Count; index++)
                result.Add(parameters[index], arguments[index]);

            if (restParameter != null)
            {
                Datum restArgument = BuildRestArgument(arguments, index);
                result.Add(closure.RestParameter, restArgument);
            }

            return result;
        }
コード例 #4
0
ファイル: Interpreter.cs プロジェクト: nguerrera/scheme
        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();
                    }
            }
            
        }
コード例 #5
0
ファイル: SchemeEnvironment.cs プロジェクト: nguerrera/scheme
 public SchemeEnvironment(SchemeEnvironment parent)
 {
     this.parent = parent;
     this.dictionary = new Dictionary<Symbol, SchemeObject>();
 }
コード例 #6
0
ファイル: Closure.cs プロジェクト: nguerrera/scheme
 internal Closure(SchemeEnvironment environment, Lambda expression)
 {
     this.environment = environment;
     this.lambda = expression;
 }
コード例 #7
0
ファイル: Continuation.cs プロジェクト: nguerrera/scheme
 internal SequenceContinuation(Sequence sequence, SchemeEnvironment environment)
     : base(environment, ContinuationKind.Sequence)
 {
     this.Sequence = sequence;
 }
コード例 #8
0
ファイル: Continuation.cs プロジェクト: nguerrera/scheme
 internal ProcedureContinuation(ReadOnlyCollection<Expression> arguments, SchemeEnvironment environment)
     : base(environment, ContinuationKind.Procedure)
 {
     this.Arguments = arguments;
 }
コード例 #9
0
ファイル: Continuation.cs プロジェクト: nguerrera/scheme
 internal AssignmentContinuation(Symbol destination, bool isDefinition, SchemeEnvironment environment)
     : base(environment, ContinuationKind.Assignment)
 {
     this.Destination = destination;
     this.IsDefinition = isDefinition;
 }
コード例 #10
0
ファイル: Continuation.cs プロジェクト: nguerrera/scheme
 internal ConditionalContinuation(Expression consequent, Expression alternate, SchemeEnvironment environment)
     : base(environment, ContinuationKind.Conditional)
 {
     this.Consequent = consequent;
     this.Alternate = alternate;
 }
コード例 #11
0
ファイル: Continuation.cs プロジェクト: nguerrera/scheme
 protected ContinuationFrame(SchemeEnvironment environment, ContinuationKind kind)
 {
     this.Environment = environment;
     this.Kind = kind;
 }