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())) { continue; } Console.ForegroundColor = ConsoleColor.Green; if (code.Equals("quit", StringComparison.OrdinalIgnoreCase)) { break; } Console.WriteLine(">> " + evaluate(code.PrefixConvert(), scope)); } catch (Exception ex) { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine(">> " + ex.Message); } } }
public static SList RetrieveSList(this SExpression[] expressions, SScope scope, string operationName) { SList list = null; (expressions.Length == 1 && (list = expressions[0].Evaluate(scope) as SList) != null) .OrThrows("<" + operationName + "> 必须是一个list"); return(list); }
public SScope SpawnScopeWith(string[] names, SObject[] values) { (names.Length >= values.Length).OrThrows("参数过多"); var scope = new SScope(this); for (var i = 0; i < values.Length; i++) { scope._variableTable.Add(names[i], values[i]); } return scope; }
public static SBool ChainRelation(this SExpression[] expressions, SScope scope, Func <SNumber, SNumber, bool> relation) { (expressions.Length > 1).OrThrows("该操作要求至少有一个操作符"); var current = (SNumber)expressions[0].Evaluate(scope); foreach (var obj in expressions.Skip(1)) { var next = (SNumber)obj.Evaluate(scope); if (relation(current, next)) { current = next; } else { return(SBool.False); } } return(SBool.True); }
public SObject Evaluate(SScope scope) { var current = this; while (true) { if (current.Children.Count == 0) { long number; return(long.TryParse(current.Value, out number) ? number : scope.Find(current.Value)); } var first = current.Children[0]; switch (first.Value) { case "if": var condition = (SBool)(current.Children[1].Evaluate(scope)); current = condition ? current.Children[2] : current.Children[3]; break; case "def": return(scope.Define(current.Children[1].Value, current.Children[2].Evaluate(new SScope(scope)))); case "begin": SObject result = null; foreach (var statement in current.Children.Skip(1)) { result = statement.Evaluate(scope); } return(result); case "func": var body = current.Children[2]; var parameters = current.Children[1].Children.Select(exp => exp.Value).ToArray(); var newScope = new SScope(scope); return(new SFunction(body, parameters, newScope)); case "list": return(new SList(current.Children.Skip(1).Select(exp => exp.Evaluate(scope)))); default: if (SScope.BuiltinFunctions.ContainsKey(first.Value)) { var arguments = current.Children.Skip(1).ToArray(); return(SScope.BuiltinFunctions[first.Value](arguments, scope)); } else { var function = first.Value == "(" ? (SFunction)first.Evaluate(scope) : (SFunction)scope.Find(first.Value); var arguments = current.Children.Skip(1).Select(s => s.Evaluate(scope)).ToArray(); var newFunction = function.Update(arguments); if (newFunction.IsPartial) { return(scope.Define($"{first}{"".CustomJoin(arguments)}", newFunction.Evaluate())); } current = newFunction.Body; scope = newFunction.Scope; } break; } } }
public static IEnumerable <SObject> Evaluate(this IEnumerable <SExpression> expressions, SScope scope) { return(expressions.Select(exp => exp.Evaluate(scope))); }
public static IEnumerable <T> Evaluate <T>(this IEnumerable <SExpression> expressions, SScope scope) where T : SObject { return(expressions.Evaluate(scope).Cast <T>()); }
public SFunction(SExpression body, string[] parameters, SScope scope) { Body = body; Parameters = parameters; Scope = scope; }
public SScope(SScope parent) { Parent = parent; _variableTable = new Dictionary<string, SObject>(); }