コード例 #1
0
 public static Delegate CompileLambda(Node n)
 {
     var compiler = new SchemeExpressionCompiler();
     var expr = (LambdaExpression)compiler.ToExpr(n);
     if (expr == null) return null;
     return expr.Compile();
 }
コード例 #2
0
 Node ToAssignment(Node left, string op, Node right)
 {
     var assignOp = new Node("AssignOp", "=");
     var binOp = new Node("Binaryop", op);
     var binExpr = new Node("BinaryExpr", left, binOp, right);
     return new Node("AssignExpr", left, assignOp, binExpr);
 }
コード例 #3
0
 public static Delegate CompileLambda(Node n)
 {
     var compiler = new CSharpFunctionCompiler();
     var expr = compiler.ToExpr(n) as LambdaExpression;
     if (expr == null) return null;
     return expr.Compile();
 }
コード例 #4
0
ファイル: Printer.cs プロジェクト: IkeKeren/jigsaw-library
 public Printer PrintLine(Node n)
 {
     Print(n);
     sb.AppendLine();
     sb.Append(LineBeginning);
     return this;
 }
コード例 #5
0
ファイル: ILCompiler.cs プロジェクト: IkeKeren/jigsaw-library
 public dynamic GetOperand(Node n)
 {
     Debug.Assert(n.Count == 2);
     string type = n[0].Text;
     string value = n[1].Text;
     switch (type.ToLower())
     {
         case "byte":    return Byte.Parse(value);
         case "int16":   return Int16.Parse(value);
         case "int32":   return Int32.Parse(value);
         case "int64":   return Int64.Parse(value);
         case "uint16":  return UInt16.Parse(value);
         case "uint32":  return UInt32.Parse(value);
         case "uint64":  return UInt64.Parse(value);
         case "float":   return float.Parse(value);
         case "double":  return double.Parse(value);
         case "decimal": return decimal.Parse(value);
         case "string":  return value.Substring(1, value.Length - 2);
         case "char":    return char.Parse(value.Substring(1, value.Length - 2));
         case "function": return GetMethodFromNode(n[1]);
         case "type":    return GetTypeFromNode(n[1]);
         case "var":     return vars[value];
         case "label":   return GetOrCreateLabel(value);
         default: throw new Exception("Unreocognized operand type " + type);
     }
 }
コード例 #6
0
 public Expression ToExpr(Node node)
 {
     switch (node.Label)
     {
         case "Integer":
             return Expression.Constant(int.Parse(node.Text));
         case "Float":
             return Expression.Constant(double.Parse(node.Text));
         case "String":
             return Expression.Constant(node.Text.Substring(1, node.Text.Length - 2));
         case "SExpr":
             return SExprToExpr(node);
         case "Symbol":
             return Lookup(node.Text);
         case "Param":
             return Expression.Parameter(typeof(Object), node[0].Text);
         case "Term":
             return ToExpr(node[0]);
         case "Atom":
             return ToExpr(node[0]);
         case "Lambda":
             return CreateExpressionLambda(node["ParamList"].Nodes.Select(ToExpr)
                 .OfType<ParameterExpression>().ToArray(), () => ToExpr(node["Term"]));
         case "Begin":
             return Expression.Block(node.Nodes.Select(n => ToExpr(n)));
         case "Let":
             return LetToExpr(node);
         case "If":
             return node.Count == 3 
                 ? Expression.IfThenElse(ToExpr(node[0]), ToExpr(node[1]), ToExpr(node[2]))
                 : Expression.IfThen(ToExpr(node[0]), ToExpr(node[1]));
         default:
             throw new Exception("Unrecognized node type " + node.Label);
     }
 }
コード例 #7
0
        /// <summary>
        /// Возвращает новый экземпляр <see cref="T" />, построенный по заданному AST-дереву.
        /// </summary>
        /// <param name="node">Корень AST-дерева.</param>
        /// <returns>
        /// Возвращает новый экземпляр <see cref="T" />, построенный по заданному AST-дереву.
        /// </returns>
        public ILogicalQuery Build(Diggins.Jigsaw.Node node)
        {
            Node actionList = node[ProductionActionGrammar.ProductionActionList.Name];
            List <IKnowledgeBaseAction> actions      = new List <IKnowledgeBaseAction>();
            List <ProductionFact>       queriedFacts = new List <ProductionFact>();

            foreach (var n in node.Nodes)
            {
                if (n.Label == ProductionActionGrammar.ProductionActionList.Name)
                {
                    foreach (var action in n.Nodes)
                    {
                        actions.Add(actionBuilders[action.Label].Build(action));
                    }
                }
                else if (n.Label == ProductionQueryGrammar.FactName.Name)
                {
                    queriedFacts.Add(new ProductionFact(n.Text, null));
                }
                else if (n.Label == ProductionQueryGrammar.Property.Name)
                {
                    queriedFacts[queriedFacts.Count - 1].Value = n.Text;
                }
            }
            return(new ProductionFactQuery(actions, queriedFacts));
        }
コード例 #8
0
 public void CacheResult(Rule rule, int pos, Node node)
 {
     if (!cache.ContainsKey(pos)) 
         cache.Add(pos, new Dictionary<Rule, Node>());
     var tmp = cache[pos];
     if (!tmp.ContainsKey(rule))
         tmp.Add(rule, node);
 }
コード例 #9
0
 public static Delegate CompileLambda(Node n)
 {
     n = JavaScriptTransformer.Transform(n);
     var compiler = new JavaScriptExpressionCompiler();
     var expr = (LambdaExpression)compiler.ToExpr(n);
     if (expr == null) return null;
     return expr.Compile();
 }
コード例 #10
0
        /// <summary>
        /// По заданному дереву строит <see cref="ExpertSystemShell.KnowledgeBases.ProductionModel.IKnowledgeBaseAction" />.
        /// </summary>
        /// <param name="node">Корень дерева разбора..</param>
        /// <returns>
        /// Возвращает построенный экземпляр <see cref="ExpertSystemShell.KnowledgeBases.ProductionModel.IKnowledgeBaseAction" />.
        /// </returns>
        public KnowledgeBases.IKnowledgeBaseAction Build(Diggins.Jigsaw.Node node)
        {
            Node   fact  = node[0];
            string name  = fact[ProductionFactGrammar.Property.Name].Text;
            string value = fact[ProductionFactGrammar.Value.Name].Text;

            return(new AddFactAction(new ProductionFact(name, value)));
        }
コード例 #11
0
 public Expression SExprToExpr(Node node)
 {
     var terms = node["Terms"];
     var head = terms[0];
     var mi = typeof(Primitives).GetMethod(head.Text);
     if (mi == null) throw new Exception("Could not find primitive named " + head.Text);
     var args = terms.Nodes.Skip(1).Select(n => ToExpr(n));
     return Expression.Call(mi, args);
 }
コード例 #12
0
 public bool GetCachedResult(NodeRule rule, out Node node)
 {
     node = null;
     if (!cache.ContainsKey(pos))
         return false;
     if (cache[pos].ContainsKey(rule))
     {
         node = cache[pos][rule];
         return true;
     }
     return false;
 }
コード例 #13
0
 public Expression LetToExpr(Node node)
 {
     var exprs = new List<Expression>();
     foreach (var binding in node[0].Nodes) {
         var name = binding[0].Text;
         var param = AddBinding(Expression.Parameter(typeof(Object), name));
         exprs.Add(param);
         exprs.Add(Expression.Assign(Lookup(name), ToExpr(binding[1])));
     }
     exprs.Add(ToExpr(node["Term"]));
     return Expression.Block(exprs);
 }
コード例 #14
0
ファイル: List.cs プロジェクト: IkeKeren/jigsaw-library
 public static object Parse(Node node)
 {
     switch (node.Label)
     {
         case "Integer": return Int32.Parse(node.Text);
         case "String":  return node.Text;
         case "Atom":    return Parse(node[0]);
         case "Term":    return Parse(node[0]);
         case "SExpr":   return Build(node["Terms"].Nodes.Select(Parse));
         case "Symbol":  return node.Text;
         default: throw new Exception("Unrecognized node type " + node.Label);
     }
 }
コード例 #15
0
 public static dynamic Eval(Node n)
 {
     switch (n.Label)
     {
         case "Number":      return Eval(n[0]);
         case "Integer":     return Int64.Parse(n.Text);
         case "Float":       return Double.Parse(n.Text);
         case "PrefixExpr":
             switch (n[0].Text)
             {
                 case "-": return -Eval(n[1]);
                 case "!": return !Eval(n[1]);
                 case "~": return ~Eval(n[1]);
                 default: throw new Exception(n[0].Text);
             }
         case "ParanExpr":   return Eval(n[0]);
         case "Expression":
             switch (n.Count)
             {
                 case 1: 
                     return Eval(n[0]);
                 case 3: 
                     switch (n[1].Text)
                     {
                         case "+": return Eval(n[0]) + Eval(n[2]);
                         case "-": return Eval(n[0]) - Eval(n[2]);
                         case "*": return Eval(n[0]) * Eval(n[2]);
                         case "/": return Eval(n[0]) / Eval(n[2]);
                         case "%": return Eval(n[0]) % Eval(n[2]);
                         case "<<": return Eval(n[0]) << Eval(n[2]);
                         case ">>": return Eval(n[0]) >> Eval(n[2]);
                         case "==": return Eval(n[0]) == Eval(n[2]);
                         case "!=": return Eval(n[0]) != Eval(n[2]);
                         case "<=": return Eval(n[0]) <= Eval(n[2]);
                         case ">=": return Eval(n[0]) >= Eval(n[2]);
                         case "<": return Eval(n[0]) < Eval(n[2]);
                         case ">": return Eval(n[0]) > Eval(n[2]);
                         case "&&": return Eval(n[0]) && Eval(n[2]);
                         case "||": return Eval(n[0]) || Eval(n[2]);
                         case "&": return Eval(n[0]) & Eval(n[2]);
                         case "|": return Eval(n[0]) | Eval(n[2]);
                         default: throw new Exception("Unreocognized operator " + n[1].Text);
                     }
                 default: 
                     throw new Exception(String.Format("Unexpected number of nodes {0} in expression", n.Count));
             }
         default:
             throw new Exception("Unexpected type of node " + n.Label);
     }
 }
コード例 #16
0
 public void Eval(Node n) 
 {
     switch (n.Label)
     {
         case "Integer": Push(Int32.Parse(n.Text)); break;
         case "String": Push(n.Text.Substring(1, n.Text.Length - 2)); break;
         case "Quotation": Push(n); break;
         case "Terms": foreach (var t in n.Nodes) Eval(t); break;
         case "Term": Eval(n.Nodes[0]); break;
         case "Atom": Eval(n.Nodes[0]); break;
         case "Symbol": Eval(Functions[n.Text]); break;
         case "Define": Functions.Add(n.GetNode("Symbol").Text, n.GetNode("Terms")); break;
         default: throw new Exception("Can't evaluate node of type " + n.Label);
     }
 }
コード例 #17
0
 public JSFunction(VarBindings c, Node n) { 
     capture = c;  
     node = n;
     if (n.Count == 3)
     {
         name = n[0].Text;
         parms = n[1];
         body = n[2];
     }
     else
     {
         parms = n[0];
         body = n[1];
     }
 }
コード例 #18
0
ファイル: ILCompiler.cs プロジェクト: IkeKeren/jigsaw-library
 public void EmitTerm(Node n)
 {
     switch (n.Label)
     {
         case "Label":
             {
                 var name = n["Name"].Text;                        
                 g.MarkLabel(GetOrCreateLabel(name));
             }
             break;
         case "Statement":
             {
                 EmitTerm(n[0]);
             }
             break;
         case "Block":
             {
                 foreach (var n2 in n.Nodes)
                     EmitTerm(n2);
             }
             break;
         case "VarDecl":
             {
                 var name = n["Name"].Text;
                 var type = GetTypeFromNode(n["DotName"]);
                 var decl = g.DeclareLocal(type);
                 vars.Add(name, decl);
             }
             break;
         case "OpStatement":
             {
                 var opcode = GetOpCode(n[0].Text);
                 if (n.Count > 1)
                 {
                     dynamic d = GetOperand(n[1]);                                                       
                     g.Emit(opcode, d);
                 }
                 else
                 {
                     g.Emit(opcode);
                 }
             }
             break;
         default:
             throw new Exception("Unrecognized node type " + n.Label);
     }
 }
コード例 #19
0
        /// <summary>
        /// По заданному дереву строит экземпляр <see cref="ExpertSystemShell.KnowledgeBases.ILogicalStatement" />.
        /// </summary>
        /// <param name="node">Корень дерева разбора.</param>
        /// <returns>
        /// Возвращает построенный экземпляр <see cref="ExpertSystemShell.KnowledgeBases.ILogicalStatement" />.
        /// </returns>
        public KnowledgeBases.ILogicalStatement Build(Diggins.Jigsaw.Node node)
        {
            Node condition = node[ProductionExprGrammar.Expression.Name];
            Node name      = node.Nodes.FirstOrDefault((a) =>
                                                       { return(a.Label == ProductionRuleGrammar.Name.Name); });
            Node actionList = node.Nodes.FirstOrDefault((a) =>
                                                        { return(a.Label == ProductionActionGrammar.ProductionActionList.Name); });
            Expression expression = eh.CreateExpression(condition);
            string     ruleName   = name == null ? null : name.Text;
            List <IKnowledgeBaseAction> actions = new List <IKnowledgeBaseAction>();

            foreach (var n in actionList.Nodes)
            {
                actions.Add(builders[n.Label].Build(n));
            }
            return(new ProductionRule(ruleName, expression, actions));
        }
コード例 #20
0
ファイル: Printer.cs プロジェクト: IkeKeren/jigsaw-library
 public abstract Printer Print(Node n);
コード例 #21
0
 public override Printer Print(Node n)
 {
     switch (n.Label)
     {
         case "Script":
             return Print(n.Nodes);
         case "Statement":
             return Print(n[0]);
         case "Empty":
             return Print(";");
         case "Return":
             return (n.Count > 0) 
                 ? Print("return ").Print(n[0]).Print(";")
                 : Print("return;");
         case "ExprStatement":
             return Print(n[0]).Print(";");
         case "If":
             Print("if (").Print(n[0]).Print(")").Indent().Print(n[1]).Unindent();
             return n.Count > 2 
                 ? Print(n[2]) 
                 : this;
         case "Else":
             return Print("else").Indent().Print(n[0]).Unindent();
         case "For":
             return Print("for (").Print(n[0]).Print(";").Print(n[1]).Print(";").Print(n[2]).Print(") ").Indent().Print(n[3]).Unindent();
         case "While":
             return Print("while (").Print(n[0]).Print(") ") .Indent().Print(n[1]).Unindent();
         case "VarDecl":
             return (n.Count > 1)
                 ? Print("var ").Print(n[0]).Print(" = ").Print(n[1]).Print(";")
                 : Print("var ").Print(n[0]).Print(";");
         case "Block":
             if (n.Count > 0)
             {
                 Print("{").Indent();
                 foreach (var n2 in n.Nodes.Take(n.Count - 1))
                     PrintLine(n2);
                 return Print(n[n.Count - 1]).Unindent().Print("}");
             }
             else
             {
                 return Print("{}");
             }
         case "Expr":
             return Print(n[0]);
         case "TertiaryExpr":
             return (n.Count == 3)
                 ? Print(n[0]).Print(" ? ").Print(n[1]).Print(" : ").Print(n[2])
                 : Print(n[0]);
         case "AssignOp":
         case "BinaryOp":
             return Print(" ").Print(n.Text).Print(" ");
         case "PostfixOp":
         case "PrefixOp":
             return Print(n.Text);
         case "BinaryExpr":
         case "AssignExpr":
         case "PostfixExpr":
             return Print(n.Nodes);
         case "NewExpr":
             return Print("new ").Print(n.Nodes);
         case "ParenExpr":
             return Print("(").Print(n[0]).Print(")");
         case "Field":
             return Print(".").Print(n.Nodes);
         case "Index":
             return Print("[").Print(n.Nodes).Print("]");
         case "ArgList":
             return Print("(").Print(n.Nodes, ", ").Print(")");
         case "NamedFunc":
             return Print("function ").Print(n[0]).Print(n[1]).Print(" ").Indent().Print(n[2]).Unindent();
         case "AnonFunc":
             return Print("function ").Print(n[0]).Print(" ").Indent().Print(n[1]).Unindent();
         case "ParamList":
             return Print("(").Print(n.Nodes, ", ").Print(")");
         case "Object":
             return Print("{").Indent().Print(n.Nodes, ", ").Unindent().Print("}");
         case "Array":
             return Print("[").Indent().Print(n.Nodes, ", ").Unindent().Print("]");
         case "Pair":
             return Print(n[0]).Print(" : ").Print(n[1]);
         case "PairName":
             return Print(n[0]);
         case "Literal":
             return Print(n[0]);
         case "Identifier":
         case "String":
         case "Integer":
         case "Float":
         case "True":
         case "False":
         case "Null":
             return Print(n.Text);
         default:
             throw new Exception("Unrecognized node type " + n.Label);
     }
 }
コード例 #22
0
 protected virtual Node InternalTransform(Node n) { return n; }
コード例 #23
0
 protected static bool HasChild(Node n, string label)
 {
     return n.Nodes.Any(x => x.Label == label);
 }
コード例 #24
0
 protected static bool IsFirstChild(Node n, string label)
 {
     return IsNthChild(n, 0, label);
 }
コード例 #25
0
 protected static bool IsLastChild(Node n, string label)
 {
     if (n.Count == 0) return false;
     return IsNthChild(n, n.Count - 1, label);
 }
コード例 #26
0
 public static Stack<dynamic> Eval(Node node)
 {
     var cat = new CatEvaluator();
     cat.Eval(node);
     return cat.Values;
 }
コード例 #27
0
 protected Node TransformAlNodes(Node n)
 {
     n.Nodes = n.Nodes.Select(TransformAlNodes).ToList();
     return InternalTransform(n);
 }
コード例 #28
0
 public static string ToString(Node n)
 {
     return new JavaScriptSourcePrinter().Print(n).GetStringBuilder().ToString();
 }
コード例 #29
0
 public Expression ToExpr(Node n)
 {
     switch (n.Label)
     {
         case "Expr":
             return ToExpr(n[0]);
         case "TertiaryExpr":
             if (n.Count > 1)
                 return Expression.Condition(ToExpr(n[0]), ToExpr(n[1]), ToExpr(n[2]));
             else
                 return ToExpr(n[0]);    
         case "AssignExpr":
             throw new NotImplementedException();
         case "BinaryExpr":
             if (n.Count > 1)
                 return CreateBinaryExpression(n[1].Text, ToExpr(n[0]), ToExpr(n[2]));
             else
                 return ToExpr(n[0]);
         case "UnaryExpr":
             {
                 var x = ToExpr(n[0]);
                 for (int i = 1; i < n.Count; ++i)
                 {
                     switch (n[i].Label)
                     {
                         case "Inc":         
                             x = Expression.Increment(x); 
                             break;
                         case "Dec":         
                             x = Expression.Decrement(x); 
                             break;
                         case "Indexer":     
                             x = Expression.ArrayIndex(x, ToExpr(n[i][0])); 
                             break;
                         case "ArgList":
                             x = Expression.Invoke(x, n[1].Nodes.Select(ToExpr)); 
                             break;
                         case "Selector":    
                             x = Expression.Field(x, n[i][0].Text); 
                             break;
                         default: 
                             throw new Exception("Unrecognized postfix operator " + n[i].Label);
                     }
                 }
                 return x;
             }
         case "PrefixExpr":
             if (n[0].Label == "LeafExpr") 
                 return ToExpr(n[0]);
             switch (n[0].Text)
             {
                 case "++":  
                     return Expression.PreIncrementAssign(ToExpr(n[1]));                                
                 case "--":  
                     return Expression.PreDecrementAssign(ToExpr(n[1]));
                 case "!":   
                     return Expression.Not(ToExpr(n[1]));
                 case "-":   
                     return Expression.Negate(ToExpr(n[1]));
                 case "~":   
                     return Expression.OnesComplement(ToExpr(n[1]));
                 default:    
                     throw new Exception("Unrecognized prefix operator " + n[0].Text);
             }
         case "LeafExpr":
             return ToExpr(n[0]);
         case "ParenthesizedExpr":
             return ToExpr(n[0]);
         case "NewExpr":
             throw new NotImplementedException();
         case "Identifier":
             return Lookup(n.Text);
         case "Integer":
             return Expression.Constant(Int32.Parse(n.Text));
         case "Float":
             return Expression.Constant(Double.Parse(n.Text));
         case "String":
             return Expression.Constant(n.Text.StripQuotes());
         case "UntypedLambdaParam":
             return Expression.Parameter(typeof(Object), n[0].Text);
         case "TypedLambdaParam":
             return Expression.Parameter(Utilities.GetType(n[0].Text), n[1].Text);
         case "LambdaExpr":
             var ps = n[0].Nodes.Select(ToExpr).OfType<ParameterExpression>();
             if (n[1].Label == "Block")
                 return CreateStatementLambda(ps, () => ToExpr(n[1]));
             else
                 return CreateExpressionLambda(ps, () => ToExpr(n[1]));
         case "Block":
             return ScopedExpr(() => Expression.Block(n.Nodes.Select(ToExpr)));
         case "ExprStatement":
             return Expression.Block(ToExpr(n[0]));
         case "ReturnStatement":
             if (n.Count > 0)
                 return Expression.Return(GetReturnTarget(), Expression.Constant(null)); else
                 return Expression.Return(GetReturnTarget(), ToExpr(n[0]));
         case "Statement":
             return ToExpr(n[0]);
         default:
             throw new Exception("Node type not handled " + n.Label);
     }
 }
コード例 #30
0
 public Type ToType(Node node)
 {
     return Utilities.GetType(node.Text.Trim());
 }
コード例 #31
0
 protected static bool IsNthChild(Node node, int n, string label)
 {
     if (node.Count <= n) return false;
     return node[n].Label == label;
 }
コード例 #32
0
 protected Node LeftGroup(Node n, string leftLabel)
 {
     var leftChild = InternalTransform(new Node(n.Label, n.Nodes.Take(n.Count - 1)));
     return new Node(leftLabel, leftChild, n.Nodes.Last());
 }
コード例 #33
0
 /// <summary>
 /// The node has to be transformed before being passed
 /// </summary>
 /// <param name="n"></param>
 /// <returns></returns>
 public Expression ToExpr(Node n)
 {
     switch (n.Label)
     {
         case "Empty":
             return Noop;
         case "Return":
             return (n.Count > 0)
                 ? Expression.Return(GetReturnTarget(), ToExpr(n[0]), typeof(Object))
                 : Expression.Return(GetReturnTarget(), Expression.Constant(typeof(Object), null));
         case "If":
             return n.Count > 2
                 ? Expression.IfThenElse(Expression.Convert(ToExpr(n[0]), typeof(Boolean)), ToExpr(n[1]), ToExpr(n[2]))
                 : Expression.IfThen(Expression.Convert(ToExpr(n[0]), typeof(Boolean)), ToExpr(n[1]));
         case "Else":
             return ToExpr(n[0]);
         case "For":                    
             return CompileForLoop(ToExpr(n[0]), ToExpr(n[1]), ToExpr(n[2]), ToExpr(n[3]));
         case "VarDecl":
             {
                 var r = AddBinding(Expression.Variable(typeof(object), n[0].Text));
                 if (n.Count > 1)
                     r = Expression.Assign(r, ToExpr(n[1]));
                 return r;
             }
         case "Block":
             return ScopedExpr(() => Expression.Block(n.Nodes.Select(ToExpr)));
         case "TertiaryExpr":
             return Expression.Condition(ToExpr(n[0]), ToExpr(n[1]), ToExpr(n[2]));
         case "BinaryExpr":
             return Expression.Call(null, Primitives.GetMethodFromBinaryOperator(n[1].Text), ToExpr(n[0]), ToExpr(n[2]));
         case "AssignExpr":
             return Expression.Assign(ToExpr(n[0]), ToExpr(n[2]));
         case "FieldExpr":
             return Expression.Field(ToExpr(n[0]), n[1].Text);
         case "IndexExpr":
             return CompileIndexExpr(ToExpr(n[0]), ToExpr(n[2]));
         case "CallExpr":
             return CompileCallExpr(ToExpr(n[0]), n[1].Nodes.Select(ToExpr));
         case "MethodCallExpr":
             {
                 var self = ToExpr(n[0]);
                 var func = Expression.Field(self, n[1].Text);
                 var args = new List<Expression>() { self };
                 args.AddRange(n[2].Nodes.Select(ToExpr));
                 return CompileCallExpr(func, args);
             }
         case "PrefixExpr":
             switch (n[0].Text)
             {
                 case "!": return Expression.Not(ToExpr(n[1]));
                 case "~": return Expression.OnesComplement(ToExpr(n[1]));
                 case "-": return Expression.Negate(ToExpr(n[1]));
                 default: throw new Exception("Unrecognized prefix operator " + n[0].Text);
             }
         case "NewExpr":
             return ScopedExpr(() => 
                 {
                     AddBinding("this", Expression.Constant(new JsonObject()));
                     return ToExpr(n[0]);
                 });                    
         case "ParenExpr":
             return ToExpr(n[0]);
         case "AnonFunc":
             {
                 var ps = n[0].Nodes.Select(x => Expression.Parameter(typeof(Object), x.Text));
                 return CreateStatementLambda(ps, () => ToExpr(n[1]));
             };
         case "Object":
             throw new NotImplementedException();
         case "Array":
             return Expression.NewArrayInit(typeof(object), n.Nodes.Select(ToExpr));
         case "Identifier":
             return Lookup(n.Text);
         case "String":
             return Expression.Constant(Utilities.Unquote(n.Text));
         case "Integer":
             return Expression.Convert(Expression.Constant(int.Parse(n.Text)), typeof(Object));
         case "Float":
             return Expression.Convert(Expression.Constant(float.Parse(n.Text)), typeof(Object));
         case "True":
             return Expression.Convert(Expression.Constant(true), typeof(Object));
         case "False":
             return Expression.Convert(Expression.Constant(false), typeof(Object));
         case "Null":
             return Expression.Constant(null);
         default:
             throw new Exception("Unrecognized node type " + n.Label);
     }
 }