コード例 #1
0
        private static Environment extendFunctionEnv(Function function, List <IObject> args)
        {
            var enviroment = Environment.EnclosedEnvironment(function.Enviroment);

            for (int i = 0; i < function.Parameters.Count; i++)
            {
                enviroment.Set(function.Parameters[i].StringValue, args[i]);
            }

            return(enviroment);
        }
コード例 #2
0
        private static IObject TestEval(string input)
        {
            var lexer = new Lexer(input);

            var parser = new Parser(lexer);

            var program = parser.ParseProgram();

            var enviroment = new Environment();

            return(Evaluator.Evaluate(program, enviroment));
        }
コード例 #3
0
        private static IObject EvalBlockStatement(BlockStatement block, Environment environment)
        {
            foreach (var statement in block.Statements)
            {
                var result = Evaluate(statement, environment);

                return(result != null && result.Type() == ObjectType.RETURN_VALUE_OBJ.ToString() ||
                       result?.Type() == ObjectType.ERROR_OBJ.ToString()
                    ? result
                    : result);
            }

            return(null);
        }
コード例 #4
0
        private static IObject EvalIfExpression(IfExpression expression, Environment environment)
        {
            var condition = Evaluate(expression.Condition, environment);

            if (IsError(condition))
            {
                return(condition);
            }

            if (IsTruthy(condition))
            {
                return(Evaluate(expression.Consequence, environment));
            }

            return(expression.Alternative != null?Evaluate(expression.Alternative, environment) : null);
        }
コード例 #5
0
        private static IObject EvalProgram(Program program, Environment environment)
        {
            foreach (var statement in program.Statements)
            {
                var result = Evaluate(statement, environment);

                if (result != null && result.GetType() == typeof(ReturnValue))
                {
                    return(result.ObjectValue);
                }

                if (result != null && result.GetType() == typeof(Error))
                {
                    return(result);
                }

                return(result);
            }

            return(null);
        }
コード例 #6
0
 private static IObject EvalIdentifier(INode node, Environment enviroment)
 {
     (var value, var result) = enviroment.Get(node.StringValue);
     return(!result?NewError(string.Format("Identifier not found: {0}", node.StringValue)) : value);
 }
コード例 #7
0
        private static List <IObject> evalExpressions(IEnumerable <IExpression> expressions, Environment environment)
        {
            var result = new List <IObject>();

            foreach (var expression in expressions)
            {
                var evaluated = Evaluate(expression, environment);
                if (IsError(evaluated))
                {
                    result.Add(evaluated);
                    return(result);
                }

                result.Add(evaluated);
            }

            return(result);
        }
コード例 #8
0
        public static IObject Evaluate(INode node, Environment environment)
        {
            while (true)
            {
                switch (node.GetType().ToString())
                {
                case "Aurora_Language.Program":
                    return(EvalProgram(node as Program, environment));

                case "Aurora_Language.Data.ExpressionStatement":
                    node = node.Expression;
                    continue;

                case "Aurora_Language.Data.IntegerLiteral":
                    return(new Integer(Convert.ToInt64(node.TokenLiteral())));

                case "Aurora_Language.Data.BooleanExpression":
                    return(new Boolean(Convert.ToBoolean(node.TokenLiteral())));

                case "Aurora_Language.Data.PrefixExpression":
                {
                    var right = Evaluate(node.Right, environment);
                    return(IsError(right) ? right : EvalPrefixExpression(node.Operator, right));
                }

                case "Aurora_Language.Data.InfixExpression":
                {
                    var left  = Evaluate(node.Left, environment);
                    var right = Evaluate(node.Right, environment);

                    if (IsError(left))
                    {
                        return(left);
                    }

                    return(IsError(right) ? right : EvalInfixExpression(node.Operator, left, right));
                }

                case "Aurora_Language.Data.BlockStatement":
                    return(EvalBlockStatement(node as BlockStatement, environment));

                case "Aurora_Language.Data.IfExpression":
                    return(EvalIfExpression(node as IfExpression, environment));

                case "Aurora_Language.Data.ReturnStatement":
                {
                    var value = Evaluate(node.ReturnValue, environment);
                    return(IsError(value) ? value : new ReturnValue(value));
                }

                case "Aurora_Language.Data.LetStatement":
                {
                    var value = Evaluate(node.Name, environment);
                    if (IsError(value))
                    {
                        return(value);
                    }

                    environment.Set(node.Name.StringValue, value);


                    return(new ReturnValue(value));
                }

                case "Aurora_Language.Data.Identifier":
                {
                    return(EvalIdentifier(node as Identifier, environment));
                }

                case "Aurora_Language.Data.FunctionLiteral":
                {
                    var @params = node.Parameters;
                    var body    = node.Body;
                    return(new Function(@params, body, environment));
                }

                case "Aurora_Language.Data.CallExpression":
                {
                    var function = Evaluate(node.Function, environment);
                    if (IsError(function))
                    {
                        return(function);
                    }

                    var args = evalExpressions(node.Arguments, environment);
                    if (args.Count == 1 && IsError(args.First()))
                    {
                        return(args.First());
                    }

                    return(applyFunction(function, args));
                }

                default:
                    return(null);
                }
            }
        }