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); }
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)); }
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); }
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); }
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); }
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); }
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); }
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); } } }