Ejemplo n.º 1
0
        private static Object EvaluateIdentifierExpression(Expression expression, IEnvironment env)
        {
            var value      = (string)((IdentifierExpression)expression).Value;
            var identifier = env.Get(value);

            if (identifier != default(Object))
            {
                return(identifier);
            }

            var builtIn = Functions.GetByName(value);

            if (builtIn != default(Object))
            {
                return(builtIn);
            }

            return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
            {
                Code = ErrorCode.IdentifierExpressionEvaluation,
                Offenders = new List <object> {
                    value
                },
                Kind = ErrorKind.InvalidIdentifier,
                Source = ErrorSource.Evaluator
            })));
        }
Ejemplo n.º 2
0
        private static Object EvaluateHashIndexExpression(Object hash, Object key)
        {
            if (key.Kind != ObjectKind.Integer && key.Kind != ObjectKind.Boolean && key.Kind != ObjectKind.String)
            {
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.HashIndexExpressionEvaluation,
                    Offenders = new List <object> {
                        hash, key
                    },
                    Kind = ErrorKind.InvalidType,
                    Source = ErrorSource.Evaluator
                })));
            }

            var hashtable = (Dictionary <string, Object>)hash.Value;
            var keyValue  = key.Value.ToString();

            if (hashtable.Count == 0 || keyValue == String.Empty)
            {
                return(Object.Create(ObjectKind.Null, null));
            }

            var hashKey = hashtable.Keys.Where(item => item == keyValue).FirstOrDefault();

            if (hashKey == default(string))
            {
                return(Object.Create(ObjectKind.Null, null));
            }

            return(hashtable[keyValue]);
        }
Ejemplo n.º 3
0
        private void ExecuteHashOperation()
        {
            var count  = DecodeOperand(2);
            var hash   = new Dictionary <string, Object>();
            var keys   = new List <string>();
            var values = new List <Object>();

            internalState.CurrentFrame.InstructionPointer += 2;

            for (var i = 0; i < count; i++)
            {
                values.Add(internalState.Stack.Pop());
                keys.Add(internalState.Stack.Pop().Value.ToString().ToLower());
            }

            keys.Reverse();
            values.Reverse();

            for (var i = 0; i < keys.Count; i++)
            {
                hash.Add(keys[i], values[i]);
            }

            internalState.Stack.Push(Object.Create(ObjectKind.Hash, hash));
        }
Ejemplo n.º 4
0
        private static Object EvaluatePrefixExpression(Expression expression, IEnvironment env)
        {
            var prefixExpression = (PrefixExpression)expression;
            var op = ((InfixExpression)prefixExpression.Left).Operator;

            switch (op.Kind)
            {
            case SyntaxKind.Bang:
                return(EvaluateBangOperatorExpression(prefixExpression.Right, env));

            case SyntaxKind.Minus:
                return(EvaluateMinusOperatorExpression(prefixExpression.Right, env));

            default:
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.UnknownOperator,
                    Offenders = new List <object> {
                        op
                    },
                    Kind = ErrorKind.UnknownOperator,
                    Source = ErrorSource.Evaluator
                })));
            }
        }
Ejemplo n.º 5
0
        private static Object EvaluateStringInfixExpression(string left, Token op, string right)
        {
            switch (op.Kind)
            {
            case SyntaxKind.Plus:
                return(Object.Create(ObjectKind.String, string.Join(String.Empty, left, right)));

            case SyntaxKind.Equal:
                return(Object.Create(ObjectKind.Boolean, left == right));

            case SyntaxKind.NotEqual:
                return(Object.Create(ObjectKind.Boolean, left != right));

            default:
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.StringExpressionOperatorEvaluation,
                    Offenders = new List <object> {
                        left, op, right
                    },
                    Kind = ErrorKind.UnknownOperator,
                    Source = ErrorSource.Evaluator
                })));
            }
        }
Ejemplo n.º 6
0
        private void ExecuteBinaryIntegerOperation(byte op, int left, int right)
        {
            switch (op)
            {
            case 2:      // Opcode.Add
                internalState.Stack.Push(Object.Create(ObjectKind.Integer, left + right));
                break;

            case 4:      // Opcode.Subtract
                internalState.Stack.Push(Object.Create(ObjectKind.Integer, left - right));
                break;

            case 5:      // Opcode.Multiply
                internalState.Stack.Push(Object.Create(ObjectKind.Integer, left * right));
                break;

            case 6:      // Opcode.Divide
                internalState.Stack.Push(Object.Create(ObjectKind.Integer, left / right));
                break;

            case 9:      // Opcode.Equal
                internalState.Stack.Push(left == right ? Invariants[true] : Invariants[false]);
                break;

            case 10:     // Opcode.NotEqual
                internalState.Stack.Push(left != right ? Invariants[true] : Invariants[false]);
                break;

            case 11:     // Opcode.GreaterThan
                internalState.Stack.Push(left > right ? Invariants[true] : Invariants[false]);
                break;
            }
        }
Ejemplo n.º 7
0
        private static Object EvaluateCallExpression(Expression expression, IEnvironment env)
        {
            List <Object>  args           = new List <Object>();
            CallExpression callExpression = (CallExpression)expression;
            Object         obj;

            if (callExpression.Identifier != default(Token))
            {
                obj = env.Get(callExpression.Identifier.Literal);
                obj = obj == default(Object) ? Functions.GetByName(callExpression.Identifier.Literal) : obj;
            }
            else
            {
                obj = Object.Create(ObjectKind.Function, callExpression.Function);
            }

            if (callExpression.Arguments != default(List <Expression>))
            {
                args = EvaluateExpressionList(callExpression.Arguments, env);
            }

            if (obj.Kind == ObjectKind.BuiltIn)
            {
                var fn = (Func <List <Object>, Object>)obj.Value;
                return(fn(args));
            }
            else
            {
                return(ApplyFunction(obj, args));
            }
        }
Ejemplo n.º 8
0
        private static Object EvaluateFunctionExpression(Expression expression, IEnvironment env)
        {
            var obj = Object.Create(ObjectKind.Function, expression);

            obj.Environment = env;
            return(obj);
        }
Ejemplo n.º 9
0
 private void ExecuteBinaryStringOperation(byte op, string left, string right)
 {
     switch (op)
     {
     case 2:     // Opcode.Add
         internalState.Stack.Push(Object.Create(ObjectKind.String, string.Join(String.Empty, left, right)));
         break;
     }
 }
Ejemplo n.º 10
0
        private static Object EvaluateInfixExpression(Expression expression, IEnvironment env)
        {
            var infixExpression = (InfixExpression)expression;

            var left = EvaluateExpression(infixExpression.Left, env);

            if (left.Kind == ObjectKind.Error)
            {
                return(left);
            }

            var right = EvaluateExpression(infixExpression.Right, env);

            if (right.Kind == ObjectKind.Error)
            {
                return(right);
            }

            if (left.Kind != right.Kind)
            {
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.InfixExpressionEvaluation,
                    Offenders = new List <object> {
                        left, right
                    },
                    Kind = ErrorKind.InvalidType,
                    Source = ErrorSource.Evaluator
                })));
            }

            switch (left.Kind)
            {
            case ObjectKind.Integer:
                return(EvaluateIntegerInfixExpression((int)left.Value, infixExpression.Operator, (int)right.Value));

            case ObjectKind.Boolean:
                return(EvaluateBooleanInfixExpression((bool)left.Value, infixExpression.Operator, (bool)right.Value));

            case ObjectKind.String:
                return(EvaluateStringInfixExpression((string)left.Value, infixExpression.Operator, (string)right.Value));

            default:
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.InfixExpressionOperatorEvaluation,
                    Offenders = new List <object> {
                        left, infixExpression.Operator, right
                    },
                    Kind = ErrorKind.UnknownOperator,
                    Source = ErrorSource.Evaluator
                })));
            }
        }
Ejemplo n.º 11
0
        private CompilerState CompileStringExpression(Expression expression, CompilerState previousState)
        {
            var stringExpression = (StringExpression)expression;

            var index = DetermineConstantIndex(expression, previousState);

            return(Factory.CompilerState()
                   .Assign(Emit((byte)Opcode.Name.Constant, new List <int> {
                index
            }, previousState))
                   .Constant(index, Object.Create(ObjectKind.String, stringExpression.Value))
                   .Create());
        }
Ejemplo n.º 12
0
        private void ExecuteMinusOperation()
        {
            Object operand = internalState.Stack.Pop();

            if (operand.Kind != ObjectKind.Integer)
            {
                return;
            }

            int value = (int)operand.Value;

            internalState.Stack.Push(Object.Create(ObjectKind.Integer, -value));
        }
Ejemplo n.º 13
0
        private static Object EvaluateStatements(List <Statement> statements, IEnvironment env)
        {
            var obj = Object.Create(ObjectKind.Null, null);

            foreach (var statement in statements)
            {
                obj = EvaluateNode(statement, env);

                if (obj.Kind == ObjectKind.Error || obj.Kind == ObjectKind.Return)
                {
                    return(obj);
                }
            }

            return(obj);
        }
Ejemplo n.º 14
0
        private void ExecuteArrayOperation()
        {
            var count    = DecodeOperand(2);
            var elements = new List <Object>();

            internalState.CurrentFrame.InstructionPointer += 2;

            for (var i = 0; i < count; i++)
            {
                elements.Add(internalState.Stack.Pop());
            }

            elements.Reverse();

            internalState.Stack.Push(Object.Create(ObjectKind.Array, elements));
        }
Ejemplo n.º 15
0
        private static Object ApplyFunction(Object obj, List <Object> args)
        {
            var          functionExpression = (FunctionExpression)obj.Value;
            IEnvironment env = obj.Environment;

            if (functionExpression.Parameters != default(List <Token>) && args != default(List <Object>))
            {
                env = EncloseEnvironment(functionExpression.Parameters, args, env);
            }

            if (functionExpression.Body != default(BlockStatement))
            {
                return(EvaluateStatements(functionExpression.Body.Statements, env));
            }

            return(Object.Create(ObjectKind.Null, null));
        }
Ejemplo n.º 16
0
        private static Object EvaluateExpression(Expression expression, IEnvironment env)
        {
            switch (expression.Kind)
            {
            case ExpressionKind.Integer:
                return(EvaluateIntegerExpression(expression));

            case ExpressionKind.Boolean:
                return(EvaluateBooleanExpression(expression));

            case ExpressionKind.String:
                return(EvaluateStringExpression(expression));

            case ExpressionKind.Identifier:
                return(EvaluateIdentifierExpression(expression, env));

            case ExpressionKind.Prefix:
                return(EvaluatePrefixExpression(expression, env));

            case ExpressionKind.Infix:
                return(EvaluateInfixExpression(expression, env));

            case ExpressionKind.IfElse:
                return(EvaluateIfElseExpression(expression, env));

            case ExpressionKind.Function:
                return(EvaluateFunctionExpression(expression, env));

            case ExpressionKind.Call:
                return(EvaluateCallExpression(expression, env));

            case ExpressionKind.Array:
                return(EvaluateArrayExpression(expression, env));

            case ExpressionKind.Hash:
                return(EvaluateHashExpression(expression, env));

            case ExpressionKind.Index:
                return(EvaluateIndexExpression(expression, env));

            default:
                return(Object.Create(ObjectKind.Null, null));
            }
        }
Ejemplo n.º 17
0
        private static Object EvaluateNode(Node node, IEnvironment env)
        {
            switch (node.Kind)
            {
            case NodeKind.Program:
                return(EvaluateStatements(((Program)node).Statements, env));

            case NodeKind.Let:
                return(EvaluateLetStatement((Statement)node, env));

            case NodeKind.Return:
                return(EvaluateReturnStatement((Statement)node, env));

            case NodeKind.Expression:
                return(EvaluateExpression(((Statement)node).Expression, env));

            default:
                return(Object.Create(ObjectKind.Null, null));
            }
        }
Ejemplo n.º 18
0
        private static Object EvaluateLetStatement(Statement statement, IEnvironment env)
        {
            var obj = Object.Create(ObjectKind.Null, null);

            if (statement.Identifier == default(Token) || statement.Expression == default(Expression))
            {
                return(obj);
            }

            var value = EvaluateExpression(statement.Expression, env);

            if (value.Kind == ObjectKind.Error)
            {
                return(value);
            }

            env.Set(statement.Identifier.Literal, value);

            return(obj);
        }
Ejemplo n.º 19
0
 static Functions()
 {
     List = new List <BuiltIn>
     {
         new BuiltIn {
             Name = "len", Function = Object.Create(ObjectKind.BuiltIn, Len)
         },
         new BuiltIn {
             Name = "first", Function = Object.Create(ObjectKind.BuiltIn, First)
         },
         new BuiltIn {
             Name = "last", Function = Object.Create(ObjectKind.BuiltIn, Last)
         },
         new BuiltIn {
             Name = "rest", Function = Object.Create(ObjectKind.BuiltIn, Rest)
         },
         new BuiltIn {
             Name = "push", Function = Object.Create(ObjectKind.BuiltIn, Push)
         }
     };
 }
Ejemplo n.º 20
0
        private static Object EvaluateIntegerInfixExpression(int left, Token op, int right)
        {
            switch (op.Kind)
            {
            case SyntaxKind.Plus:
                return(Object.Create(ObjectKind.Integer, left + right));

            case SyntaxKind.Minus:
                return(Object.Create(ObjectKind.Integer, left - right));

            case SyntaxKind.Asterisk:
                return(Object.Create(ObjectKind.Integer, left * right));

            case SyntaxKind.Slash:
                return(Object.Create(ObjectKind.Integer, left / right));

            case SyntaxKind.GreaterThan:
                return(Object.Create(ObjectKind.Boolean, left > right));

            case SyntaxKind.LessThan:
                return(Object.Create(ObjectKind.Boolean, left < right));

            case SyntaxKind.Equal:
                return(Object.Create(ObjectKind.Boolean, left == right));

            case SyntaxKind.NotEqual:
                return(Object.Create(ObjectKind.Boolean, left != right));

            default:
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.InfixExpressionOperatorEvaluation,
                    Offenders = new List <object> {
                        left, op, right
                    },
                    Kind = ErrorKind.UnknownOperator,
                    Source = ErrorSource.Evaluator
                })));
            }
        }
Ejemplo n.º 21
0
        private void ExecuteClosureOperation()
        {
            var index = DecodeOperand(2);

            internalState.CurrentFrame.InstructionPointer += 2;

            var freeCount = DecodeOperand(1);

            internalState.CurrentFrame.InstructionPointer += 1;

            var frees = new List <Object>();

            for (var i = 0; i < freeCount; i++)
            {
                frees.Add(internalState.Stack[internalState.Stack.Count - freeCount + i]);
            }

            var fn      = internalState.Constants[index];
            var closure = Object.Create(ObjectKind.Closure, new Closure((List <byte>)fn.Value, frees));

            internalState.Stack.Push(closure);
        }
Ejemplo n.º 22
0
        private static Object EvaluateBooleanInfixExpression(bool left, Token op, bool right)
        {
            switch (op.Kind)
            {
            case SyntaxKind.Equal:
                return(Object.Create(ObjectKind.Boolean, left == right));

            case SyntaxKind.NotEqual:
                return(Object.Create(ObjectKind.Boolean, left != right));

            default:
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.BooleanInfixExpressionEvaluation,
                    Offenders = new List <object> {
                        left, op, right
                    },
                    Kind = ErrorKind.UnknownOperator,
                    Source = ErrorSource.Evaluator
                })));
            }
        }
Ejemplo n.º 23
0
        private static Object EvaluateArrayIndexExpression(Object array, Object index)
        {
            if (array.Kind != ObjectKind.Array)
            {
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.ArrayExpressionEvaluation,
                    Offenders = new List <object> {
                        array, index
                    },
                    Kind = ErrorKind.InvalidType,
                    Source = ErrorSource.Evaluator
                })));
            }

            if (index.Kind != ObjectKind.Integer)
            {
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.ArrayIndexExpressionEvaluation,
                    Offenders = new List <object> {
                        array, index
                    },
                    Kind = ErrorKind.InvalidType,
                    Source = ErrorSource.Evaluator
                })));
            }

            var elements   = (List <Object>)array.Value;
            var indexValue = (int)index.Value;

            if (elements.Count == 0 || indexValue < 0 || indexValue > elements.Count - 1)
            {
                return(Object.Create(ObjectKind.Null, null));
            }

            return(elements[indexValue]);
        }
Ejemplo n.º 24
0
        private void ExecuteBinaryOperation(byte op)
        {
            Object right = internalState.Stack.Pop();
            Object left  = internalState.Stack.Pop();

            if (left.Kind != right.Kind)
            {
                var info = new ErrorInfo
                {
                    Code      = ErrorCode.BinaryOperationInvalidOperand,
                    Kind      = ErrorKind.InvalidType,
                    Offenders = new List <object> {
                        left, op, right
                    },
                    Position = 2, // Consider right side as the offender
                    Source   = ErrorSource.VM
                };

                internalState.Stack.Push(Object.Create(ObjectKind.Error, Error.Create(info)));
                return;
            }

            switch (left.Kind)
            {
            case ObjectKind.Boolean:
                ExecuteBinaryBooleanOperation(op, (bool)left.Value, (bool)right.Value);
                break;

            case ObjectKind.String:
                ExecuteBinaryStringOperation(op, left.Value.ToString(), right.Value.ToString());
                break;

            default:
                ExecuteBinaryIntegerOperation(op, (int)left.Value, (int)right.Value);
                break;
            }
        }
Ejemplo n.º 25
0
        private static Object EvaluateMinusOperatorExpression(Expression expression, IEnvironment env)
        {
            var value = EvaluateExpression(expression, env);

            if (value.Kind == ObjectKind.Error)
            {
                return(value);
            }

            if (value.Kind != ObjectKind.Integer)
            {
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.MinusOperatorExpressionEvaluation,
                    Offenders = new List <object> {
                        value
                    },
                    Kind = ErrorKind.InvalidType,
                    Source = ErrorSource.Evaluator
                })));
            }

            return(Object.Create(ObjectKind.Integer, -(int)value.Value));
        }
Ejemplo n.º 26
0
        private static Object EvaluateIfElseExpression(Expression expression, IEnvironment env)
        {
            var ifElseExpression = (IfElseExpression)expression;

            var condition = EvaluateExpression(ifElseExpression.Condition, env);

            if (condition.Kind == ObjectKind.Error)
            {
                return(condition);
            }

            if (IsTruthy(condition))
            {
                return(EvaluateStatements(ifElseExpression.Consequence.Statements, env));
            }
            else if (ifElseExpression.Alternative != default(BlockStatement))
            {
                return(EvaluateStatements(ifElseExpression.Alternative.Statements, env));
            }
            else
            {
                return(Object.Create(ObjectKind.Null, null));
            }
        }
Ejemplo n.º 27
0
        private static Object EvaluateBangOperatorExpression(Expression expression, IEnvironment env)
        {
            var obj = EvaluateExpression(expression, env);

            switch (obj.Kind)
            {
            case ObjectKind.Integer:
                return(Object.Create(ObjectKind.Boolean, !((int)obj.Value != 0)));

            case ObjectKind.Boolean:
                return(Object.Create(ObjectKind.Boolean, !(bool)obj.Value));

            default:
                return(Object.Create(ObjectKind.Error, Error.Create(new ErrorInfo
                {
                    Code = ErrorCode.BangOperatorExpressionEvaluation,
                    Offenders = new List <object> {
                        obj
                    },
                    Kind = ErrorKind.InvalidType,
                    Source = ErrorSource.Evaluator
                })));
            }
        }
Ejemplo n.º 28
0
        private static Object EvaluateHashExpression(Expression expression, IEnvironment env)
        {
            var hashExpression = (HashExpression)expression;

            var hash = new Dictionary <string, Object>();

            for (var i = 0; i < hashExpression.Keys.Count; i++)
            {
                var key   = EvaluateExpression(hashExpression.Keys[i], env);
                var value = EvaluateExpression(hashExpression.Values[i], env);

                var previousKey = hash.Keys.Where(item => item == key.Value.ToString()).FirstOrDefault();
                if (previousKey != default(string))
                {
                    hash[previousKey] = Object.Create(value.Kind, value.Value);
                }
                else
                {
                    hash.Add(key.Value.ToString(), Object.Create(value.Kind, value.Value));
                }
            }

            return(Object.Create(ObjectKind.Hash, hash));
        }
Ejemplo n.º 29
0
        private static Object EvaluateArrayExpression(Expression expression, IEnvironment env)
        {
            var arrayExpression = (ArrayExpression)expression;

            return(Object.Create(ObjectKind.Array, EvaluateExpressionList(arrayExpression.Elements, env)));
        }
Ejemplo n.º 30
0
 private static Object EvaluateStringExpression(Expression expression)
 {
     return(Object.Create(ObjectKind.String, ((StringExpression)expression).Value));
 }