/// <summary> /// (rename old-name new-name) /// </summary> public static SSObject Rename(SSExpression[] exps, SSScope scope) { string oname = exps[0].Token.Value; string nname = exps[1].Token.Value; (!oname.Equals(nname)).OrThrows("same name {0}".Fmt(oname)); try { var obj = scope.Find(oname); scope.Define(nname, obj); scope.Undefine(oname); return(nname + " " + obj.ToString()); } catch (Exception) { Func <SSExpression[], SSScope, SSObject> obj = null; if (SSScope.BuiltinFunctions.TryGetValue(oname, out obj)) { SSScope.BuiltinFunctions[nname] = obj; SSScope.BuiltinFunctions.Remove(oname); return(nname + " " + obj.ToString()); } throw new Exception("cannot find {0} in scope, and it is not a builtin".Fmt(nname)); } }
public SSObject Evaluate(SSScope scope) { var current = this; while (true) { var tok = current.Token; // current.Parent.Children.ForEach(a => Console.WriteLine(a.Token.Value)); try { switch (current.Token.Type) { case TokenType.LeftCurlyBracket: // { SSObject ret = null; foreach (var exp in current.Children) { if (exp.Token.Type == TokenType.Continue) { break; } else if (exp.Token.Type == TokenType.Break) { return(SSSignal.Break); } ret = exp.Evaluate(scope); } return(ret); case TokenType.LeftBracket: // [ return(new SSList(current.Children.Select(a => a.Evaluate(scope)))); case TokenType.Integer: return(Int64.Parse(tok.Value)); case TokenType.SciNumber: case TokenType.Float: return(double.Parse(tok.Value)); case TokenType.String: return(tok.Value); case TokenType.Char: return(new SSChar(tok.Value[0])); case TokenType.True: return(SSBool.True); case TokenType.False: return(SSBool.False); case TokenType.Slingshot: return(current.Parent.Children.Skip(1).ParseCmd(scope)); case TokenType.Identifier: return(scope.Find(tok.Value)); default: var first = current.Children[0]; tok = first.Token; Func <SSExpression[], SSScope, SSObject> func; SSScope.BuiltinFunctions.TryGetValue(tok.Value, out func); if (func != null) { var arguments = current.Children.Skip(1).ToArray(); return(func(arguments, scope)); } SSFunction function = tok.Type == TokenType.LeftParentheses ? (SSFunction)first.Evaluate(scope) : (SSFunction)scope.Find(tok.Value); var args = current.Children.Skip(1).Select(s => s.Evaluate(scope)).ToArray(); SSFunction newFunction = function.Update(args); if (newFunction.IsPartial()) { return(newFunction.Evaluate()); } current = newFunction.Body; scope = newFunction.Scope; break; } } catch (Exception e) { var c = current; var cc = ConsoleColor.Green; var console = false; if (scope.Output == Console.Out) { console = true; cc = Console.ForegroundColor; Console.ForegroundColor = ConsoleColor.Yellow; } c.Print(scope.Output); scope.Output.WriteLine(); if (console) { Console.ForegroundColor = ConsoleColor.Red; } if (console) { Console.ForegroundColor = cc; } Console.WriteLine("=====================" + current.Token.Value); throw; } } }