Example #1
0
        static Object.Object evalBlockStatement(ast.BlockStatement block, Object.Environment env)
        {
            Object.Object result = null;

            foreach (ast.Statement statement in block.Statements)
            {
                result = Eval(statement, env);

                if (result != null)
                {
                    string rt = result.Type();
                    if (rt == Object._ObjType.RETURN_VALUE_OBJ || rt == Object._ObjType.ERROR_OBJ)
                    {
                        return(result);
                    }
                }
            }

            return(result);
        }
Example #2
0
        static ast.BlockStatement parseBlockStatement()
        {
            ast.BlockStatement block = new ast.BlockStatement {
                Token = curToken
            };
            block.Statements = new List <ast.Statement>();

            nextToken();

            while (!curTokenIs(token.RBRACE) && !curTokenIs(token.EOF))
            {
                ast.Statement stmt = parseStatement();
                if (stmt != null)
                {
                    block.Statements.Add(stmt);
                }
                nextToken();
            }

            return(block);
        }
Example #3
0
        public static Object.Object Eval(ast.Node node, Object.Environment env)
        {
            // Statements
            if (node is ast.Program)
            {
                return(evalProgram((ast.Program)node, env));
            }

            if (node is ast.BlockStatement)
            {
                return(evalBlockStatement((ast.BlockStatement)node, env));
            }

            if (node is ast.ExpressionStatement)
            {
                return(Eval(((ast.ExpressionStatement)node).Expression, env));
            }

            if (node is ast.ReturnStatement)
            {
                Object.Object val = Eval(((ast.ReturnStatement)node).ReturnValue, env);
                if (isError(val))
                {
                    return(val);
                }
                return(new Object.ReturnValue {
                    Value = val
                });
            }

            if (node is ast.LetStatement)
            {
                Object.Object val = Eval(((ast.LetStatement)node).Value, env);
                if (isError(val))
                {
                    return(val);
                }
                env.Set(((ast.LetStatement)node).Name.Value, val);

                return(null);
            }

            // Expressions
            if (node is ast.IntegerLiteral)
            {
                return new Object.Integer {
                           Value = ((ast.IntegerLiteral)node).Value
                }
            }
            ;

            if (node is ast.StringLiteral)
            {
                return new Object.String {
                           Value = ((ast.StringLiteral)node).Value
                }
            }
            ;

            if (node is ast.Boolean)
            {
                return(nativeToBooleanObject(((ast.Boolean)node).Value));
            }

            if (node is ast.PrefixExpression)
            {
                Object.Object right = Eval(((ast.PrefixExpression)node).Right, env);
                if (isError(right))
                {
                    return(right);
                }
                return(evalPrefixExpression(((ast.PrefixExpression)node).Operator, right));
            }

            if (node is ast.InfixExpression)
            {
                Object.Object left = Eval(((ast.InfixExpression)node).Left, env);
                if (isError(left))
                {
                    return(left);
                }

                Object.Object right = Eval(((ast.InfixExpression)node).Right, env);
                if (isError(right))
                {
                    return(right);
                }

                return(evalInfixExpression(((ast.InfixExpression)node).Operator, left, right));
            }


            if (node is ast.IfExpression)
            {
                return(evalIfExpression((ast.IfExpression)node, env));
            }


            if (node is ast.Identifier)
            {
                return(evalIdentifier((ast.Identifier)node, env));
            }

            if (node is ast.FunctionLiteral)
            {
                List <ast.Identifier> params_ = ((ast.FunctionLiteral)node).Parameters;
                ast.BlockStatement    body    = ((ast.FunctionLiteral)node).Body;
                return(new Object.Function {
                    Parameters = params_, Env = env, Body = body
                });
            }

            if (node is ast.CallExpression)
            {
                Object.Object function = Eval(((ast.CallExpression)node).Function, env);
                if (isError(function))
                {
                    return(function);
                }

                List <Object.Object> args = evalExpressions(((ast.CallExpression)node).Arguments, env);
                if (args.Count == 1 && isError(args[0]))
                {
                    return(args[0]);
                }

                return(applyFunction(function, args));
            }

            if (node is ast.ArrayLiteral)
            {
                List <Object.Object> elements = evalExpressions(((ast.ArrayLiteral)node).Elements, env);
                if (elements.Count == 1 && isError(elements[0]))
                {
                    return(elements[0]);
                }
                return(new Object.Array {
                    Elements = elements
                });
            }

            if (node is ast.IndexExpression)
            {
                Object.Object left = Eval(((ast.IndexExpression)node).Left, env);
                if (isError(left))
                {
                    return(left);
                }
                Object.Object index = Eval(((ast.IndexExpression)node).Index, env);
                if (isError(index))
                {
                    return(index);
                }
                return(evalIndexExpression(left, index));
            }

            if (node is ast.HashLiteral)
            {
                return(evalHashLiteral((ast.HashLiteral)node, env));
            }

            return(null);
        }
Example #4
0
        public static ast.Node Modify(ast.Node node, MofifierFunc modifier)
        {
            if (node is ast.Program)
            {
                ast.Program _node = (ast.Program)node;
                for (int i = 0; i < _node.Statements.Count; i++)
                {
                    _node.Statements[i] = (ast.Statement)Modify(_node.Statements[i], modifier);
                }
                node = _node;
            }

            if (node is ast.ExpressionStatement)
            {
                ast.ExpressionStatement _node = (ast.ExpressionStatement)node;
                _node.Expression = (ast.Expression)Modify(_node.Expression, modifier);
                node             = _node;
            }

            if (node is ast.InfixExpression)
            {
                ast.InfixExpression _node = (ast.InfixExpression)node;
                _node.Left  = (ast.Expression)Modify(_node.Left, modifier);
                _node.Right = (ast.Expression)Modify(_node.Right, modifier);
                node        = _node;
            }

            if (node is ast.PrefixExpression)
            {
                ast.PrefixExpression _node = (ast.PrefixExpression)node;
                _node.Right = (ast.Expression)Modify(_node.Right, modifier);
                node        = _node;
            }

            if (node is ast.IndexExpression)
            {
                ast.IndexExpression _node = (ast.IndexExpression)node;
                _node.Left  = (ast.Expression)Modify(_node.Left, modifier);
                _node.Index = (ast.Expression)Modify(_node.Index, modifier);
                node        = _node;
            }

            if (node is ast.IfExpression)
            {
                ast.IfExpression _node = (ast.IfExpression)node;
                _node.Condition   = (ast.Expression)Modify(_node.Condition, modifier);
                _node.Consequence = (ast.BlockStatement)Modify(_node.Consequence, modifier);
                node = _node;
                if (_node.Alternative != null)
                {
                    _node.Alternative = (ast.BlockStatement)Modify(_node.Alternative, modifier);
                }
            }

            if (node is ast.BlockStatement)
            {
                ast.BlockStatement _node = (ast.BlockStatement)node;
                for (int i = 0; i < _node.Statements.Count; i++)
                {
                    _node.Statements[i] = (ast.Statement)Modify(_node.Statements[i], modifier);
                }
                node = _node;
            }


            if (node is ast.ReturnStatement)
            {
                ast.ReturnStatement _node = (ast.ReturnStatement)node;
                _node.ReturnValue = (ast.Expression)Modify(_node.ReturnValue, modifier);
                node = _node;
            }

            if (node is ast.LetStatement)
            {
                ast.LetStatement _node = (ast.LetStatement)node;
                _node.Value = (ast.Expression)Modify(_node.Value, modifier);
                node        = _node;
            }

            if (node is ast.FunctionLiteral)
            {
                ast.FunctionLiteral _node = (ast.FunctionLiteral)node;
                for (int i = 0; i < _node.Parameters.Count; i++)
                {
                    _node.Parameters[i] = (ast.Identifier)Modify(_node.Parameters[i], modifier);
                }
                _node.Body = (ast.BlockStatement)Modify(_node.Body, modifier);
                node       = _node;
            }

            if (node is ast.ArrayLiteral)
            {
                ast.ArrayLiteral _node = (ast.ArrayLiteral)node;
                for (int i = 0; i < _node.Elements.Count; i++)
                {
                    _node.Elements[i] = (ast.Expression)Modify(_node.Elements[i], modifier);
                }
                node = _node;
            }

            if (node is ast.HashLiteral)
            {
                ast.HashLiteral _node = (ast.HashLiteral)node;
                Dictionary <ast.Expression, ast.Expression> newPairs = new Dictionary <ast.Expression, ast.Expression>();
                foreach (KeyValuePair <ast.Expression, ast.Expression> kv in _node.Pairs)
                {
                    ast.Expression newKey = (ast.Expression)Modify(kv.Key, modifier);
                    ast.Expression newVal = (ast.Expression)Modify(kv.Value, modifier);
                    newPairs.Add(newKey, newVal);
                }
                _node.Pairs = newPairs;
                node        = _node;
            }

            return(modifier(node));
        }