static Object.Environment extendFunctionEnv(Object.Function fn, List <Object.Object> args) { Object.Environment env = Object.Environment.NewEnclosedEnvironment(fn.Env); for (int paramIdx = 0; paramIdx < args.Count; paramIdx++) { env.Set(fn.Parameters[paramIdx].Value, args[paramIdx]); } return(env); }
private static Object.Environment extendFunctionEnv(Function fn, IImmutableList <MonkeyObject> args) { var env = new Object.Environment(fn.Env); for (int i = 0; i < fn.Parameters.Count; i++) { env.Set(fn.Parameters[i].Value, args[i]); } return(env); }
private static Object.Environment ExtendFuncitonEnv(Object.Function function, IEnumerable <Object.Object> args) { var env = new Object.Environment(function.Env); var idx = 0; foreach (var arg in args) { env.Set(function.Parameters[idx].Value, arg); idx++; } return(env); }
static Object.Environment extendMacroEnv(Object.Macro macro, List <Object.Quote> args) { Object.Environment extended = Object.Environment.NewEnclosedEnvironment(macro.Env); int paramIdx = 0; foreach (ast.Identifier param in macro.Parameters) { extended.Set(param.Value, args[paramIdx++]); } return(extended); }
static void addMacro(ast.Statement stmt, Object.Environment env) { ast.LetStatement letStatement = (ast.LetStatement)stmt; ast.MacroLiteral macroLiteral = (ast.MacroLiteral)letStatement.Value; Object.Macro macro = new Object.Macro { Parameters = macroLiteral.Parameters, Env = env, Body = macroLiteral.Body }; env.Set(letStatement.Name.Value, macro); }
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); }
public static Object.Object Eval(Ast.Node node, Object.Environment env) { if (node is Ast.Program) { return(EvalProgram((Ast.Program)node, env)); } if (node is Ast.ExpressionStatement) { return(Eval(((Ast.ExpressionStatement)node).Expression, env)); } if (node is Ast.IntegerLiteral) { return(new Object.Integer { Value = ((Ast.IntegerLiteral)node).Value }); } if (node is Ast.Boolean) { return(NativeBoolToBooleanObject(((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.BlockStatement) { return(EvalBlockStatement((Ast.BlockStatement)node, env)); } if (node is Ast.IfExpression) { return(EvalIfExpression((Ast.IfExpression)node, 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); } if (node is Ast.Identifier) { return(EvalIdentifier((Ast.Identifier)node, env)); } if (node is Ast.FunctionLiteral) { Ast.FunctionLiteral func = node as Ast.FunctionLiteral; return(new Object.Function { Parameters = func.Parameters, Env = env, Body = func.Body }); } if (node is Ast.CallExpression) { Object.Object function = Eval(((Ast.CallExpression)node).Function, env); if (IsError(function)) { return(function); } var args = EvalExpressions(((Ast.CallExpression)node).Arguments, env); if (args.Count() == 1 && IsError(args.First())) { return(args.First()); } return(ApplyFunction(function, args)); } if (node is StringLiteral) { return(new Object.Strings { Value = ((StringLiteral)node).Value }); } if (node is ArrayLiteral) { var elements = EvalExpressions(((ArrayLiteral)node).Elements, env); if (elements.Count == 1 && IsError(elements[0])) { return(elements.First()); } return(new Object.Array { Elements = elements }); } if (node is IndexExpression) { Object.Object left = Eval(((IndexExpression)node).Left, env); if (IsError(left)) { return(left); } Object.Object index = Eval(((IndexExpression)node).Index, env); if (IsError(index)) { return(index); } return(EvalIndexExpression(left, index)); } if (node is HashLiteral) { return(EvalHashLiteral(node as HashLiteral, env)); } return(null); }
public static MonkeyObject Eval(AST.Node node, Object.Environment environment) { MonkeyObject left; MonkeyObject index; MonkeyObject val; switch (node) { case AST.Program p: return(evalProgram(p, environment)); case AST.BlockStatement bs: return(evalBlockStatement(bs, environment)); case AST.ExpressionStatement xs: return(Eval(xs.Expression, environment)); case AST.LetStatement ls: val = Eval(ls.Value, environment); if (val?.Type == MonkeyObjectType.ERROR) { return(val); } environment.Set(ls.Name.Value, val); break; case AST.ReturnStatement rs: val = Eval(rs.ReturnValue, environment); if (val?.Type == MonkeyObjectType.ERROR) { return(val); } return(new MonkeyReturnValue { Value = val }); case AST.HashLiteral hl: return(evalHashLiteral(hl, environment)); case AST.ArrayLiteral al: var elements = evalExpressions(al.Elements, environment); if (elements.Count == 1 && elements[0]?.Type == MonkeyObjectType.ERROR) { return(elements[0]); } return(new MonkeyArray { Elements = elements }); case AST.FunctionLiteral fl: return(new Object.Function { Parameters = fl.Parameters, Env = environment, Body = fl.Body }); case AST.IfExpression ifx: return(evalIfExpression(ifx, environment)); case AST.CallExpression cl: var function = Eval(cl.Function, environment); if (function?.Type == MonkeyObjectType.ERROR) { return(function); } var args = evalExpressions(cl.Arguments, environment); if (args.Count == 1 && args[0]?.Type == MonkeyObjectType.ERROR) { return(args[0]); } return(applyFunction(function, args)); case AST.InfixExpression ix: left = Eval(ix.Left, environment); if (left?.Type == MonkeyObjectType.ERROR) { return(left); } index = Eval(ix.Right, environment); if (index?.Type == MonkeyObjectType.ERROR) { return(index); } return(evalInfixExpression(ix.Op, left, index)); case AST.PrefixExpression px: index = Eval(px.Right, environment); if (index?.Type == MonkeyObjectType.ERROR) { return(index); } return(evalPrefixExpression(px.Op, index)); case AST.IndexExpression idx: left = Eval(idx.Left, environment); if (left?.Type == MonkeyObjectType.ERROR) { return(left); } index = Eval(idx.Index, environment); if (index?.Type == MonkeyObjectType.ERROR) { return(index); } return(evalIndexExpression(left, index)); case AST.IntegerLiteral il: return(new MonkeyInteger { Value = il.Value }); case AST.BooleanExpression b: return(nativeBoolToMonkeyBoolean(b.Value)); case AST.Identifier id: return(evalIdentifier(id, environment)); case AST.StringLiteral sl: return(new MonkeyString { Value = sl.Value }); } return(null); }