public SScope SpawnScopeWith(string[] names, SObject[] values) { if (names.Length < values.Length) { throw new Exception("too many arguments"); } var scope = new SScope(this); for (int i = 0; i < names.Length; ++i) { scope._symbolTable.Add(names[i], values[i]); } return(scope); }
public static void KeepInterpretingInConsole(this SScope scope, Func <string, SScope, SObject> evaluate) { while (true) { //try { Console.ForegroundColor = ConsoleColor.Gray; Console.Write(">> "); String code; if (!String.IsNullOrWhiteSpace(code = Console.ReadLine())) { Console.ForegroundColor = ConsoleColor.Green; Console.WriteLine(">> " + evaluate(code, scope)); } } //catch (Exception ex) //{ // Console.ForegroundColor = ConsoleColor.Red; // Console.WriteLine(">> " + ex.Message); //} } }
public static SBool ChainRelation(this SExpression[] expressions, SScope scope, Func <SNumber, SNumber, Boolean> relation) { if (expressions.Length <= 1) { throw new Exception("too few arguments."); } var current = expressions[0].Evaluate(scope) as SNumber; foreach (var obj in expressions.Skip(1)) { var next = obj.Evaluate(scope) as SNumber; if (relation(current, next)) { current = next; } else { return(SBool.False); } } return(SBool.True); }
public SFunction(SExpression body, string[] parameters, SScope scope) { Body = body; Parameters = parameters; Scope = scope; }
public SObject Evaluate(SScope scope) { if (Children.Count == 0) { Int64 number; if (Int64.TryParse(Value, out number)) { return(number); } else { return(scope.Find(Value)); } } else { var first = Children[0].Value; if (first == "list") { return(new SList(this.Children.Skip(1).Select(exp => exp.Evaluate(scope)))); } else if (first == "if") { var condition = Children[1].Evaluate(scope) as SBool; return(condition ? Children[2].Evaluate(new SScope(scope)) :Children[3].Evaluate(new SScope(scope))); } else if (first == "define") { var child = Children[1]; if (child.Value == "(") { var funcName = child.Children[0].Value; var body = Children[2]; var parameters = child.Children.Skip(1).Select(exp => exp.Value).ToArray(); var newScope = new SScope(scope); var func = new SFunction(body, parameters, newScope); return(scope.Define(funcName, func)); } return(scope.Define(Children[1].Value, Children[2].Evaluate(scope))); } else if (first == "set!") { var variableName = Children[1].Value; var newValue = Children[2]; if (scope.Find(variableName) != null) { return(scope.Reset(variableName, newValue.Evaluate(scope))); } } else if (first == "begin") { SObject result = null; foreach (var statement in Children.Skip(1)) { result = statement.Evaluate(scope); } return(result); } else if (SScope.BuiltinFunctions.ContainsKey(first)) { var arguments = Children.Skip(1).ToArray(); return(SScope.BuiltinFunctions[first](arguments, scope)); } else { var func = first == "(" ? /*High-order function*/ Children[0].Evaluate(scope) as SFunction : scope.Find(first) as SFunction; var arguments = Children.Skip(1).Select(s => s.Evaluate(scope)).ToArray(); return(func.Update(arguments).Evaluate()); } } throw new Exception("Sorry!"); }
public SScope(SScope parent) { Parent = parent; _symbolTable = new Dictionary <string, SObject>(); }
public static IEnumerable <T> Evaluate <T>(this IEnumerable <SExpression> expressions, SScope scope) where T : SObject { return(expressions.Evaluate(scope).Cast <T>()); }
public static IEnumerable <SObject> Evaluate(this IEnumerable <SExpression> expressions, SScope scope) { return(expressions.Select(exp => exp.Evaluate(scope))); }