Example #1
0
 /// <summary>
 /// Evaluates the given expression.
 /// </summary>
 /// <param name="expr"></param>
 /// <returns></returns>
 public Value Evaluate(Expression expr)
 {
     return FScheme.EvaluateInEnvironment
         .Invoke(this.env.CompilationEnvironment)
         .Invoke(this.env.RuntimeEnvironment)
         .Invoke(expr);
 }
Example #2
0
        protected override Expression compileBody(
            Dictionary <INode, string> symbols,
            Dictionary <INode, List <INode> > letEntries,
            HashSet <string> initializedIds,
            HashSet <string> conditionalIds)
        {
            var testBranch = arguments[_test].compile(symbols, letEntries, initializedIds, conditionalIds);

            var trueSet  = new HashSet <string>(initializedIds);
            var falseSet = new HashSet <string>(initializedIds);

            var trueCond  = new HashSet <string>(conditionalIds);
            var falseCond = new HashSet <string>(conditionalIds);

            var trueBranch  = arguments[_true].compile(symbols, letEntries, trueSet, trueCond);
            var falseBranch = arguments[_false].compile(symbols, letEntries, falseSet, falseCond);

            var alwaysInitialized = trueSet.Intersect(falseSet).ToList();

            conditionalIds.UnionWith(trueCond.Union(falseCond));
            conditionalIds.UnionWith(trueSet.Union(falseSet).Except(alwaysInitialized));

            initializedIds.UnionWith(alwaysInitialized);

            return(Expression.NewIf(testBranch, trueBranch, falseBranch));
        }
Example #3
0
        protected override Expression GetBody(
            Dictionary <INode, string> symbols,
            Dictionary <INode, List <INode> > letEntries,
            HashSet <string> initializedIds,
            HashSet <string> conditionalIds)
        {
            var uninitialized = new HashSet <INode>();

            NodeUtils.GatherUninitializedIds(EntryPoint, symbols, letEntries, initializedIds, uninitialized);

            var initialized = new List <Expression>();

            foreach (var node in uninitialized)
            {
                var symbol = symbols[node];

                if (!initializedIds.Contains(symbol))
                {
                    symbols.Remove(node);
                    var binding = node.compile(symbols, letEntries, initializedIds, conditionalIds);
                    symbols[node] = symbol;
                    initialized.Add(Expression.NewSetId(symbol, binding));
                    initializedIds.Add(symbol);
                }
            }

            initialized.Add(Utils.MakeAnon(
                                Inputs,
                                EntryPoint.compile(symbols, letEntries, initializedIds, conditionalIds)));

            return(Expression.NewBegin(Utils.SequenceToFSharpList(initialized)));
        }
Example #4
0
 //Binds symbols of the given string to the given body.
 public void DefineSymbol(string name, Expression body)
 {
     FScheme.Define(
     IDENT, env.Env, Utils.mkList(Expression.NewSymbol(name), body)
      );
      //this.env.Add(name, body);
 }
Example #5
0
 /// <summary>
 /// Evaluates the given expression.
 /// </summary>
 /// <param name="expr"></param>
 /// <returns></returns>
 public Value Evaluate(Expression expr)
 {
     return(FScheme.EvaluateInEnvironment
            .Invoke(this.env.CompilationEnvironment)
            .Invoke(this.env.RuntimeEnvironment)
            .Invoke(expr));
 }
Example #6
0
 protected override Expression compileBody(
     Dictionary <INode, string> symbols,
     Dictionary <INode, List <INode> > letEntries,
     HashSet <string> initializedIds,
     HashSet <string> conditionalIds)
 {
     return(Expression.NewContainer_E(_obj));
 }
Example #7
0
 //Symbol referenced by this function.
 protected override Expression GetBody(
     Dictionary <INode, string> symbols,
     Dictionary <INode, List <INode> > letEntries,
     HashSet <string> initializedIds,
     HashSet <string> conditionalIds)
 {
     return(Expression.NewId(Symbol));
 }
Example #8
0
 protected override Expression GetBody(
     Dictionary <INode, string> symbols,
     Dictionary <INode, List <INode> > letEntries,
     HashSet <string> initializedIds,
     HashSet <string> conditionalIds)
 {
     return(Expression.NewFunction_E(
                Utils.ConvertToFSchemeFunc(EntryPoint)));
 }
Example #9
0
        //Function used to construct our expression. This is used to properly create a curried function call, which will be
        //able to support partial function application.
        protected Expression ToExpression(
            Expression function,
            IEnumerable <string> parameters,
            int expectedArgs,
            Dictionary <INode, string> symbols,
            Dictionary <INode, List <INode> > letEntries,
            HashSet <string> initializedIds,
            HashSet <string> conditionalIds)
        {
            //If no arguments have been supplied and if we are expecting arguments, simply return the function.
            if (arguments.Keys.Count == 0 && expectedArgs > 0)
            {
                return(function);
            }

            //If the number of expected arguments is greater than how many arguments have been supplied, we perform a partial
            //application, returning a function which takes the remaining arguments.
            if (arguments.Keys.Count < expectedArgs)
            {
                //Get all of the missing arguments.
                IEnumerable <string> missingArgs = parameters.Where(
                    input => !arguments.ContainsKey(input)
                    );
                //Return a function that...
                return(Utils.MakeAnon(
                           //...takes all of the missing arguments...
                           missingArgs.ToList(),
                           Expression.NewList_E(
                               FSharpList <Expression> .Cons(
                                   //...and calls this function...
                                   function,
                                   Utils.SequenceToFSharpList(
                                       //...with the arguments which were supplied.
                                       parameters.Select(
                                           input =>
                                           missingArgs.Contains(input)
                                    ? Expression.NewId(input)
                                    : arguments[input].compile(
                                               symbols, letEntries, initializedIds, conditionalIds)))))));
            }

            //If all the arguments were supplied, just return a standard function call expression.
            else
            {
                return(Expression.NewList_E(
                           FSharpList <Expression> .Cons(
                               function,
                               Utils.SequenceToFSharpList(
                                   parameters.Select(
                                       input => arguments[input].compile(
                                           symbols, letEntries, initializedIds, conditionalIds))
                                   )
                               )
                           ));
            }
        }
Example #10
0
 protected override Expression compileBody(
     Dictionary <INode, string> symbols,
     Dictionary <INode, List <INode> > letEntries,
     HashSet <string> initializedIds,
     HashSet <string> conditionalIds)
 {
     return(Expression.NewBegin(
                Utils.SequenceToFSharpList(
                    Inputs.Select(
                        x => arguments[x].compile(symbols, letEntries, initializedIds, conditionalIds)))));
 }
Example #11
0
        /// <summary>
        /// Makes an FScheme Expression representing an anonymous function, where all extra
        /// arguments are packed into the last parameter.
        /// </summary>
        /// <param name="inputSyms">List of parameters</param>
        /// <param name="body">Body of the function</param>
        /// <returns></returns>
        public static Expression MakeVarArgAnon(IEnumerable <string> inputSyms, Expression body)
        {
            var cnt = inputSyms.Count();

            return(Expression.NewFun(
                       SequenceToFSharpList(inputSyms.Select(
                                                (x, i) =>
                                                i == cnt
                        ? FScheme.Parameter.NewTail(x)
                        : FScheme.Parameter.NewNormal(x))),
                       body));
        }
Example #12
0
 /// <summary>
 /// Looks up the value associated with the given symbol in this environment.
 /// </summary>
 /// <param name="p"></param>
 /// <returns></returns>
 public Value LookupSymbol(string p)
 {
     //try
     //{
     //    return this.frozenEnv.Value[p];
     //}
     //catch (Exception)
     //{
     //    throw new Exception("Could not find key " + p + " in environment");
     //}
     //return env.Lookup(p);
     return(Evaluate(Expression.NewId(p)));
 }
Example #13
0
 private static Expression WrapLets(
     Expression body,
     Dictionary <INode, string> symbols,
     List <INode> bindings)
 {
     return(Expression.NewLet(
                Utils.SequenceToFSharpList(
                    bindings.Select(x => symbols[x])
                    .Concat(bindings.Select(x => symbols[x] + "-init"))),
                Utils.SequenceToFSharpList(
                    Enumerable.Repeat(
                        Expression.NewBegin(FSharpList <Expression> .Empty),
                        bindings.Count)
                    .Concat(Enumerable.Repeat(Expression.NewNumber_E(0), bindings.Count))),
                body));
 }
Example #14
0
        private Expression __compileBody(
            Dictionary <INode, string> symbols,
            Dictionary <INode, List <INode> > letEntries,
            HashSet <string> initializedIds,
            HashSet <string> conditionalIds)
        {
            string symbol;

            if (symbols.TryGetValue(this, out symbol))
            {
                var body = Expression.NewId(symbol);
                if (conditionalIds.Contains(symbol))
                {
                    symbols.Remove(this);
                    var binding = compile(symbols, letEntries, initializedIds, conditionalIds);
                    symbols[this] = symbol;

                    body = Expression.NewIf(
                        Expression.NewId(symbol + "-init"),
                        body,
                        Expression.NewBegin(
                            Utils.MakeFSharpList(
                                Expression.NewSetId(symbol, binding),
                                Expression.NewSetId(symbol + "-init", Expression.NewNumber_E(1)),
                                body)));
                }
                else if (!initializedIds.Contains(symbol))
                {
                    symbols.Remove(this);
                    var binding = compile(symbols, letEntries, initializedIds, conditionalIds);
                    symbols[this] = symbol;

                    body = Expression.NewBegin(
                        Utils.MakeFSharpList(
                            Expression.NewSetId(symbol, binding),
                            Expression.NewSetId(symbol + "-init", Expression.NewNumber_E(1)),
                            body));

                    initializedIds.Add(symbol);
                }
                return(body);
            }
            else
            {
                return(compileBody(symbols, letEntries, initializedIds, conditionalIds));
            }
        }
Example #15
0
        public Expression compile(
            Dictionary <INode, string> symbols,
            Dictionary <INode, List <INode> > letEntries,
            HashSet <string> initializedIds,
            HashSet <string> conditionalIds)
        {
            Expression body = __compileBody(symbols, letEntries, initializedIds, conditionalIds);

            List <INode> bindings;

            if (letEntries.TryGetValue(this, out bindings) && bindings.Any())
            {
                body = WrapLets(body, symbols, bindings);
            }

            return(body);
        }
Example #16
0
        public override Expression Evaluate(FSharpList<Expression> args)
        {
            if (PickedSunAndShadowSettings.Id.IntegerValue == sunAndShadowSettingsID.IntegerValue) // sanity check
               {

               XYZ sunVector = GetSunDirection(PickedSunAndShadowSettings);
               this.data = Expression.NewContainer(sunVector);
               return data;
               }
               else
               throw new Exception("SANITY CHECK FAILED");
        }
Example #17
0
        void registerButt_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            //data = Expression.NewList(FSharpList<Expression>.Empty);

               View activeView = this.UIDocument.ActiveView;
               PickedSunAndShadowSettings = activeView.SunAndShadowSettings;

               if (PickedSunAndShadowSettings != null)
               {
               sunAndShadowSettingsID = activeView.SunAndShadowSettings.Id;
               this.RegisterEvalOnModified(sunAndShadowSettingsID); // register with the DMU, TODO - watch out for view changes, as sun is view specific
               XYZ sunVector = GetSunDirection(PickedSunAndShadowSettings);

               this.data = Expression.NewContainer(sunVector);

               this.tb.Text = PickedSunAndShadowSettings.Name;
               }
               else
               {
               //sunPathButt.Content = "Select Instance";
               this.tb.Text = "Nothing Selected";
               }
        }
Example #18
0
        private Expression evalIfDirty(FSharpList<Expression> args, ExecutionEnvironment environment)
        {
            //If this node requires a re-calc or if we haven't calc'd yet...
            if (this.IsDirty || this.oldValue == null)
            {
                //Store the environment
                this.macroEnvironment = environment;

                //Evaluate arguments, then evaluate this.
                this.oldValue = this.eval(
                   Utils.convertSequence(
                      args.Select(
                         input => environment.Evaluate(input)
                      )
                   )
                );
            }
            else //Otherwise, just increment the run counter.
                this.runCount++;

            //We're done here
            return this.oldValue;
        }
Example #19
0
 private static Expression _setParam(FamilyInstance ft, Parameter p, Expression valueExpr)
 {
     if (p.StorageType == StorageType.Double)
     {
         p.Set(((Expression.Number)valueExpr).Item);
     }
     else if (p.StorageType == StorageType.Integer)
     {
         p.Set((int)((Expression.Number)valueExpr).Item);
     }
     else if (p.StorageType == StorageType.String)
     {
         p.Set(((Expression.String)valueExpr).Item);
     }
     else if (valueExpr.IsNumber)
     {
         p.Set(new ElementId((int)(valueExpr as Expression.Number).Item));
     }
     else
     {
         p.Set((ElementId)((Expression.Container)valueExpr).Item);
     }
     return Expression.NewContainer(ft);
 }
Example #20
0
 //Binds symbols of the given string to the given External Function.
 public void DefineExternal(string name, FSharpFunc <FSharpList <Value>, Value> func)
 {
     //add(name, Value.NewFunction(func));
     Evaluate(Expression.NewDefine(name, Expression.NewFunction_E(func)));
 }
Example #21
0
 private static Expression setParam(FamilyInstance fi, Definition paramDef, Expression valueExpr)
 {
     var p = fi.get_Parameter(paramDef);
     if (p != null)
     {
         return _setParam(fi, p, valueExpr);
     }
     throw new Exception("Parameter \"" + paramDef.Name + "\" was not found!");
 }
Example #22
0
        //Binds symbols of the given string to the given body.
        public void DefineSymbol(string name, Expression body)
        {
            Evaluate(Expression.NewDefine(name, body));

            //frozenEnv.Value = frozenEnv.Value.Add(name, env.Lookup(name));
        }
Example #23
0
        protected internal virtual void Run(IEnumerable<dynNode> topElements, Expression runningExpression)
        {
            //Print some stuff if we're in debug mode
            if (_debug)
            {
                //string exp = FScheme.print(runningExpression);
                Bench.Dispatcher.Invoke(new Action(
                   delegate
                   {
                       foreach (var node in topElements)
                       {
                           string exp = node.PrintExpression();
                           Bench.Log("> " + exp);
                       }
                   }
                ));
            }

            try
            {
                //Evaluate the expression
                var expr = FSchemeEnvironment.Evaluate(runningExpression);

                //Print some more stuff if we're in debug mode
                if (_debug && expr != null)
                {
                    Bench.Dispatcher.Invoke(new Action(
                       () => Bench.Log(FScheme.print(expr))
                    ));
                }
            }
            catch (CancelEvaluationException ex)
            {
                /* Evaluation was cancelled */

                OnRunCancelled(false);
                //this.RunCancelled = false;
                if (ex.Force)
                    this.runAgain = false;
            }
            catch (Exception ex)
            {
                /* Evaluation failed due to error */

                //Print unhandled exception
                if (ex.Message.Length > 0)
                {
                    Bench.Dispatcher.Invoke(new Action(
                       delegate
                       {
                           Bench.Log(ex);
                       }
                    ));
                }
                OnRunCancelled(true);
                this.RunCancelled = true;
                this.runAgain = false;
            }

            OnEvaluationCompleted();
        }
Example #24
0
 /// <summary>
 /// Makes an FScheme Expression representing an anonymous function.
 /// </summary>
 public static Expression MakeAnon(IEnumerable <string> inputSyms, Expression body)
 {
     return(Expression.NewFun(
                SequenceToFSharpList(inputSyms.Select(FScheme.Parameter.NewNormal)),
                body));
 }
Example #25
0
 //Evaluates the given expression.
 public Expression Evaluate(Expression expr)
 {
     return FScheme.eval(IDENT, env.Env, expr);
 }
Example #26
0
 internal static dynamic convertFromExpression(Expression exp)
 {
     if (exp.IsList)
         return ((Expression.List)exp).Item.Select(x => convertFromExpression(x)).ToList();
     else if (exp.IsNumber)
         return ((Expression.Number)exp).Item;
     else if (exp.IsString)
         return ((Expression.String)exp).Item;
     else if (exp.IsContainer)
         return ((Expression.Container)exp).Item;
     //else if (exp.IsFunction)
     //{
     //   return new Func<IList<dynamic>, dynamic>(
     //      args =>
     //         ((Expression.Function)exp).Item
     //            .Invoke(ExecutionEnvironment.IDENT)
     //            .Invoke(Utils.convertSequence(args.Select(
     //               x => (Expression)Converters.convertToExpression(x)
     //            )))
     //   );
     //}
     //else if (exp.IsSpecial)
     //{
     //   return new Func<IList<dynamic>, dynamic>(
     //      args =>
     //         ((Expression.Special)exp).Item
     //            .Invoke(ExecutionEnvironment.IDENT)
     //            .Invoke(
     //}
     //else if (exp.IsCurrent)
     //{
     //   return new Func<dynamic, dynamic>(
     //      ex =>
     //         Converters.convertFromExpression(
     //            ((Expression.Current)exp).Item.Invoke(Converters.convertToExpression(ex))
     //         )
     //   );
     //}
     else
         throw new Exception("Not allowed to pass Functions into a Python Script.");
 }
Example #27
0
 private static Expression setParam(FamilySymbol fi, string paramName, Expression valueExpr)
 {
     var p = fi.get_Parameter(paramName);
     if (p != null)
     {
         return _setParam(fi, p, valueExpr);
     }
     throw new Exception("Parameter \"" + paramName + "\" was not found!");
 }
Example #28
0
        public override FScheme.Expression Evaluate(FSharpList <FScheme.Expression> args)
        {
            Element e = (Element)((Expression.Container)args[0]).Item;

            return(Expression.NewNumber(e.Id.IntegerValue));
        }
Example #29
0
        public override Expression Evaluate(FSharpList<Expression> args)
        {
            var result = new List<List<FamilyInstance>>();

            //"Get an interface to the divided surfaces on this element."
            //TODO: do we want to select a face instead and try to get
            //the divided surface that way?
            DividedSurfaceData dsd = this.SelectedElement.GetDividedSurfaceData();

            if (dsd != null)
            {
                foreach (Reference r in dsd.GetReferencesWithDividedSurfaces())
                {
                    DividedSurface ds = dsd.GetDividedSurfaceForReference(r);

                    GridNode gn = new GridNode();

                    int u = 0;
                    while (u < ds.NumberOfUGridlines)
                    {

                        var lst = new List<FamilyInstance>();

                        gn.UIndex = u;

                        int v = 0;
                        while (v < ds.NumberOfVGridlines)
                        {
                            gn.VIndex = v;

                            //"Reports whether a grid node is a "seed node," a node that is associated with one or more tiles."
                            if (ds.IsSeedNode(gn))
                            {
                                FamilyInstance fi
                                  = ds.GetTileFamilyInstance(gn, 0);

                                //put the family instance into the tree
                                lst.Add(fi);
                            }
                            v = v + 1;
                        }

                        //don't add list if it's empty
                        if(lst.Count() > 0)
                            result.Add(lst);

                        u = u + 1;
                    }
                }

                this.data = Expression.NewList(
                   Utils.convertSequence(
                      result.Select(
                         row => Expression.NewList(
                            Utils.convertSequence(
                               row.Select(Expression.NewContainer)
                            )
                         )
                      )
                   )
                );
            }

            return data;
        }
Example #30
0
            protected override Expression compileBody(
                Dictionary <INode, string> symbols,
                Dictionary <INode, List <INode> > letEntries,
                HashSet <string> initializedIds,
                HashSet <string> conditionalIds)
            {
                var arg = arguments.First().Value.compile(
                    symbols, letEntries, initializedIds, conditionalIds);

                //idle :: (() -> A) -> A
                //Evaluates the given function in the Revit Idle thread.
                var idle = Expression.NewFunction_E(
                    FSharpFunc <FSharpList <Value>, Value> .FromConverter(
                        args =>
                {
                    var f = (args[0] as Value.Function).Item;

                    if (dynSettings.Controller.DynamoViewModel.RunInDebug)
                    {
                        return(f.Invoke(FSharpList <Value> .Empty));
                    }

                    return(IdlePromise <Value> .ExecuteOnIdle(
                               () => f.Invoke(FSharpList <Value> .Empty)));
                }));

                //startTransaction :: () -> ()
                //Starts a Dynamo Transaction.
                var startTransaction = Expression.NewFunction_E(
                    FSharpFunc <FSharpList <Value>, Value> .FromConverter(
                        _ =>
                {
                    if (_node.Controller.RunCancelled)
                    {
                        throw new CancelEvaluationException(false);
                    }

                    if (!dynSettings.Controller.DynamoViewModel.RunInDebug)
                    {
                        dynRevitSettings.Controller.InIdleThread = true;
                        dynRevitSettings.Controller.InitTransaction();
                    }

                    return(Value.NewDummy("started transaction"));
                }));

                //endTransaction :: () -> ()
                //Ends a Dynamo Transaction.
                var endTransaction = Expression.NewFunction_E(
                    FSharpFunc <FSharpList <Value>, Value> .FromConverter(
                        _ =>
                {
                    if (!dynRevitSettings.Controller.DynamoViewModel.RunInDebug)
                    {
                        dynRevitSettings.Controller.EndTransaction();
                        dynRevitSettings.Controller.InIdleThread = false;

                        dynSettings.Controller.DynamoViewModel.OnRequestLayoutUpdate(this, EventArgs.Empty);

                        _node.ValidateConnections();
                    }
                    else
                    {
                        _node.setDirty(false);
                    }

                    return(Value.NewDummy("ended transaction"));
                }));

                /*  (define (idleArg)
                 *    (startTransaction)
                 *    (let ((a <arg>))
                 *      (endTransaction)
                 *      a))
                 */
                var idleArg = Expression.NewFun(
                    FSharpList <FScheme.Parameter> .Empty,
                    Expression.NewBegin(
                        Utils.SequenceToFSharpList(new List <Expression>
                {
                    Expression.NewList_E(
                        Utils.SequenceToFSharpList(
                            new List <Expression> {
                        startTransaction
                    })),
                    Expression.NewLet(
                        Utils.SequenceToFSharpList(
                            new List <string> {
                        "__result"
                    }),
                        Utils.SequenceToFSharpList(
                            new List <Expression> {
                        arg
                    }),
                        Expression.NewBegin(
                            Utils.SequenceToFSharpList(
                                new List <Expression>
                    {
                        Expression.NewList_E(
                            Utils.SequenceToFSharpList(
                                new List <Expression> {
                            endTransaction
                        })),
                        Expression.NewId("__result")
                    })))
                })));

                // (idle idleArg)
                return(Expression.NewList_E(
                           Utils.SequenceToFSharpList(new List <Expression>
                {
                    idle,
                    idleArg
                })));
            }
Example #31
0
 //Adds a symbol to this environment.
 public void Add(string symbol, Expression expr)
 {
     this.env.Value = MapModule.Add(symbol, new FSharpRef<Expression>(expr), this.env.contents);
 }
Example #32
0
        //Binds symbols of the given string to the given body.
        public void DefineSymbol(string name, Expression body)
        {
            Evaluate(Expression.NewDefine(name, body));

            //frozenEnv.Value = frozenEnv.Value.Add(name, env.Lookup(name));
        }
Example #33
0
        WatchNode Process(Expression eIn, ref string content, string prefix, int count)
        {
            content += prefix + string.Format("[{0}]:", count.ToString());

            WatchNode node = null;

            if (eIn.IsContainer)
            {
                if ((eIn as Expression.Container).Item != null)
                {
                    //TODO: make clickable hyperlinks to show the element in Revit
                    //http://stackoverflow.com/questions/7890159/programmatically-make-textblock-with-hyperlink-in-between-text

                    string id = "";
                    Element revitEl = (eIn as Expression.Container).Item as Autodesk.Revit.DB.Element;
                    if (revitEl != null)
                    {
                        id = revitEl.Id.ToString();
                    }

                    content += (eIn as Expression.Container).Item.ToString() + ":" + id + "\n";

                    node = new WatchNode((eIn as Expression.Container).Item.ToString());
                    node.Link = id;
                }
            }
            else if (eIn.IsFunction || eIn.IsSpecial)
            {
                content += eIn.ToString() + "\n";
                node = new WatchNode(eIn.ToString());
            }
            else if (eIn.IsList)
            {
                content += eIn.GetType().ToString() + "\n";

                string newPrefix = prefix + "\t";
                int innerCount = 0;

                node = new WatchNode(eIn.GetType().ToString());

                foreach(Expression eIn2 in (eIn as Expression.List).Item)
                {
                    node.Children.Add(Process(eIn2, ref content, newPrefix, innerCount));
                    innerCount++;
                }
            }
            else if (eIn.IsNumber)
            {
                content += (eIn as Expression.Number).Item.ToString() + "\n";
                node = new WatchNode((eIn as Expression.Number).Item.ToString());
            }
            else if (eIn.IsString)
            {
                content += (eIn as Expression.String).Item.ToString() + "\n";
                node = new WatchNode((eIn as Expression.String).Item.ToString());
            }
            else if (eIn.IsSymbol)
            {
                content += (eIn as Expression.Symbol).Item.ToString() + "\n";
                node = new WatchNode((eIn as Expression.Symbol).Item.ToString());
            }

            return node;
        }