/// <summary>
        /// Determine the expression type.
        /// </summary>
        /// <param name="node">The program node.</param>
        /// <returns>The expression type.</returns>
        public ExpressionNodeType DetermineNodeType(ProgramNode node)
        {
            if (node.Name.Equals("#const"))
            {
                return ExpressionNodeType.ConstVal;
            }

            if (node.Name.Equals("#var"))
            {
                return ExpressionNodeType.Variable;
            }

            if (node.ChildNodes.Count != 2)
            {
                return ExpressionNodeType.Function;
            }

            String name = node.Name;

            if (!char.IsLetterOrDigit(name[0]))
            {
                return ExpressionNodeType.Operator;
            }

            return ExpressionNodeType.Function;
        }
        private String RenderNode(ProgramNode node)
        {
            StringBuilder result = new StringBuilder();

            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                ProgramNode childNode = node.GetChildNode(i);
                result.Append(RenderNode(childNode));
            }

            result.Append('[');
            result.Append(node.Name);
            result.Append(':');
            result.Append(node.Template.ChildNodeCount);

            for (int i = 0; i < node.Template.DataSize; i++)
            {
                result.Append(':');
                EPLValueType t = node.Data[i].ExprType;
                if (t == EPLValueType.BooleanType)
                {
                    result.Append(node.Data[i].ToBooleanValue() ? 't' : 'f');
                }
                else if (t == EPLValueType.FloatingType)
                {
                    result.Append(CSVFormat.EgFormat.Format(node.Data[i].ToFloatValue(), EncogFramework.DefaultPrecision));
                }
                else if (t == EPLValueType.IntType)
                {
                    result.Append(node.Data[i].ToIntValue());
                }
                else if (t == EPLValueType.EnumType)
                {
                    result.Append(node.Data[i].EnumType);
                    result.Append("#");
                    result.Append(node.Data[i].ToIntValue());
                }
                else if (t == EPLValueType.StringType)
                {
                    result.Append("\"");
                    result.Append(node.Data[i].ToStringValue());
                    result.Append("\"");
                }
            }
            result.Append(']');

            return result.ToString().Trim();
        }
 private String RenderFunction(ProgramNode node)
 {
     StringBuilder result = new StringBuilder();
     result.Append(node.Name);
     result.Append('(');
     for (int i = 0; i < node.ChildNodes.Count; i++)
     {
         if (i > 0)
         {
             result.Append(',');
         }
         ProgramNode childNode = node.GetChildNode(i);
         result.Append(RenderNode(childNode));
     }
     result.Append(')');
     return result.ToString();
 }
 public ExpressionNodeType DetermineNodeType(ProgramNode node)
 {
     if (node.Template == StandardExtensions.EXTENSION_CONST_SUPPORT)
     {
         return ExpressionNodeType.ConstVal;
     }
     else if (node.Template == StandardExtensions.EXTENSION_VAR_SUPPORT)
     {
         return ExpressionNodeType.Variable;
     }
     else if (node.Template.NodeType == NodeType.OperatorLeft
           || node.Template.NodeType == NodeType.OperatorRight)
     {
         return ExpressionNodeType.Operator;
     }
     else
     {
         return ExpressionNodeType.Function;
     }
 }
        private String RenderNode(ProgramNode node)
        {
            StringBuilder result = new StringBuilder();

            ExpressionNodeType t = this.DetermineNodeType(node);

            for (int i = 0; i < node.ChildNodes.Count; i++)
            {
                ProgramNode childNode = node.GetChildNode(i);
                if (result.Length > 0)
                {
                    result.Append(" ");
                }
                result.Append(RenderNode(childNode));
            }

            if (result.Length > 0)
            {
                result.Append(" ");
            }

            if (t == ExpressionNodeType.ConstVal)
            {
                result.Append(HandleConst(node));
            }
            else if (t == ExpressionNodeType.Variable)
            {
                result.Append(HandleVar(node));
            }
            else if (t == ExpressionNodeType.Function || t == ExpressionNodeType.Operator)
            {
                result.Append('[');
                result.Append(node.Name);

                result.Append(']');
            }

            return result.ToString().Trim();
        }
        public ProgramNode Parse(String expression)
        {
            this.parser = new SimpleParser(expression);
            this.unary = true;

            while (!parser.EOL())
            {
                parser.EatWhiteSpace();
                char ch = parser.Peek();
                if (ch == '.' || char.IsDigit(ch))
                {
                    HandleNumeric();
                    this.unary = false;
                }
                else if (char.IsLetter(ch))
                {
                    handleAlpha(false);
                    this.unary = false;
                }
                else if (ch == '(')
                {
                    this.parser.Advance();
                    this.functionStack.Push(LEFT_PAREN);
                    this.unary = true;
                }
                else if (ch == ')')
                {
                    handleRightParen();
                    this.unary = false;
                }
                else if ("<>^*/+-=&|".IndexOf(ch) != -1)
                {
                    handleSymbol();
                    this.unary = true;
                }
                else if (ch == '\"')
                {
                    handleString();
                    this.unary = false;
                }
                else if (ch == ',')
                {
                    HandleFunctionSeparator();
                    this.unary = true;
                }
                else
                {
                    throw new EACompileError("Unparsable character: " + ch);
                }
            }

            // pop off any functions still on the stack
            while (this.functionStack.Count > 0)
            {
                IProgramExtensionTemplate f = this.functionStack.Pop();
                OutputQueue(f);
            }

            // were there no operators?
            if (this.rootNode == null)
            {
                this.rootNode = this.outputStack.Pop();
            }

            return this.rootNode;
        }
        private void OutputQueue(IProgramExtensionTemplate opp)
        {
            if (opp == this.LEFT_PAREN)
            {
                throw new EACompileError("Unmatched parentheses");
            }

            ProgramNode[] args = new ProgramNode[opp.ChildNodeCount];

            for (int i = args.Length - 1; i >= 0; i--)
            {
                if (this.outputStack.Count == 0)
                {
                    throw new EACompileError("Not enough arguments");
                }
                args[i] = this.outputStack.Pop();
            }

            this.rootNode = this.holder.Functions.FactorProgramNode(opp,
                    this.holder, args);
            outputStack.Push(rootNode);
        }
 /// <summary>
 /// Push a leaf onto the output stack.
 /// </summary>
 /// <param name="leaf">The leaf to push onto the output stack.</param>
 private void OutputQueue(ProgramNode leaf)
 {
     outputStack.Push(leaf);
 }
 private String HandleVar(ProgramNode node)
 {
     int varIndex = (int)node.Data[0].ToIntValue();
     return this.program.Variables.GetVariableName(varIndex);
 }
 private String RenderNode(ProgramNode node)
 {
     switch (DetermineNodeType(node))
     {
         case ExpressionNodeType.ConstVal:
             return HandleConst(node);
         case ExpressionNodeType.Operator:
             return HandleOperator(node);
         case ExpressionNodeType.Variable:
             return HandleVar(node);
         case ExpressionNodeType.Function:
             return HandleFunction(node);
     }
     throw new EACompileError("Uknown node type: " + node.ToString());
 }
        /// <summary>
        ///     Clone a branch of the program from the specified node.
        /// </summary>
        /// <param name="targetProgram">The program that this branch will be "grafted" into.</param>
        /// <param name="sourceBranch">The branch to clone, from the source program.</param>
        /// <returns>The cloned branch.</returns>
        public ProgramNode CloneBranch(EncogProgram targetProgram,
                                       ProgramNode sourceBranch)
        {
            if (sourceBranch == null)
            {
                throw new EncogError("Can't clone null branch.");
            }

            String name = sourceBranch.Name;

            // create any subnodes
            var args = new ProgramNode[sourceBranch.ChildNodes.Count];
            for (int i = 0; i < args.Length; i++)
            {
                args[i] = CloneBranch(targetProgram, (ProgramNode) sourceBranch
                                                                       .ChildNodes[i]);
            }

            ProgramNode result = targetProgram.Context.Functions
                                              .FactorProgramNode(name, targetProgram, args);

            // now copy the expression data for the node
            for (int i = 0; i < sourceBranch.Data.Length; i++)
            {
                result.Data[i] = new ExpressionValue(sourceBranch.Data[i]);
            }

            // return the new node
            return result;
        }
        public ProgramNode Parse(String expression)
        {
            this.parser = new SimpleParser(expression);

            while (!this.parser.EOL())
            {
                this.parser.EatWhiteSpace();

                // read in the command
                if (this.parser.ReadChar() != '[')
                {
                    throw new EACompileError("Expected [");
                }
                this.parser.EatWhiteSpace();
                StringBuilder cmd = new StringBuilder();
                while (this.parser.Peek() != ']' && !this.parser.EOL())
                {
                    cmd.Append(this.parser.ReadChar());
                }

                if (this.parser.Peek() != ']')
                {
                    throw new EACompileError("Expected ]");
                }
                this.parser.Advance();

                // parse out the command
                string[] tok = cmd.ToString().Split(':');
                int idx = 0;
                String name = tok[idx++];
                int childCount = int.Parse(tok[idx++]);
                IProgramExtensionTemplate temp = EncogOpcodeRegistry.Instance.FindOpcode(name, childCount);
                if (temp == null)
                {
                    throw new EACompileError("Invalid instruction: " + name);
                }

                // build the arguments
                ProgramNode[] args = new ProgramNode[childCount];
                for (int i = args.Length - 1; i >= 0; i--)
                {
                    args[i] = this.nodeStack.Pop();
                }

                // factor the node
                ProgramNode node = this.holder.Functions.FactorProgramNode(name, this.holder, args);
                this.nodeStack.Push(node);

                // add any needed data to the node
                for (int i = 0; i < temp.DataSize; i++)
                {
                    String str = tok[idx++].Trim();
                    int strIdx = str.IndexOf('#');
                    if (strIdx != -1)
                    {
                        int enumType = int.Parse(str.Substring(0, strIdx));
                        int enumVal = int.Parse(str.Substring(strIdx + 1));
                        node.Data[0] = new ExpressionValue(enumType, enumVal);

                    }
                    // is it boolean?
                    else if (str.Length == 1 && "tf".IndexOf(char.ToLower(str[0])) != -1)
                    {
                        node.Data[i] = new ExpressionValue(string.Compare(str, "t", true));
                    }
                    // is it a string?
                    else if (str[0] == '\"')
                    {
                        node.Data[i] = new ExpressionValue(str.Substring(1, str.Length - 1));
                    }
                    // is it an integer
                    else if (str.IndexOf('.') == -1 && str.ToLower().IndexOf('e') == -1)
                    {
                        long l;
                        try
                        {
                            l = long.Parse(str);
                        }
                        catch (FormatException ex)
                        {
                            // sometimes C# will output a long value that is larger than can be parsed
                            // this is very likely not a useful genome and we just set it to zero so that
                            // the population load does not fail.
                            l = 0;
                        }
                        node.Data[i] = new ExpressionValue(l);
                    }
                    // At this point, must be a float
                    else
                    {
                        node.Data[i] = new ExpressionValue(CSVFormat.EgFormat.Parse(str));
                    }
                }
            }

            return this.nodeStack.Pop();
        }
 private String RenderConst(ProgramNode node)
 {
     return node.Data[0].ToStringValue();
 }
 private String RenderVar(ProgramNode node)
 {
     int varIndex = (int)node.Data[0].ToIntValue();
     return this.holder.Variables.GetVariableName(varIndex);
 }
 private String RenderOperator(ProgramNode node)
 {
     StringBuilder result = new StringBuilder();
     result.Append("(");
     result.Append(RenderNode(node.GetChildNode(0)));
     result.Append(node.Name);
     result.Append(RenderNode(node.GetChildNode(1)));
     result.Append(")");
     return result.ToString();
 }
        private String HandleFunction(ProgramNode node)
        {
            IProgramExtensionTemplate temp = node.Template;
            StringBuilder result = new StringBuilder();

            if (temp == StandardExtensions.EXTENSION_SQRT)
            {
                result.Append("\\sqrt{");
                result.Append(RenderNode(node.GetChildNode(0)));
                result.Append("}");
            }
            else
            {
                result.Append(temp.Name);
                result.Append('(');
                for (int i = 0; i < temp.ChildNodeCount; i++)
                {
                    if (i > 0)
                    {
                        result.Append(',');
                    }
                    result.Append(RenderNode(node.GetChildNode(i)));
                }
                result.Append(')');
            }
            return result.ToString();
        }
 private String HandleConst(ProgramNode node)
 {
     ExpressionValue v = node.Data[0];
     return v.ToStringValue();
 }
        private String RenderNode(ProgramNode node)
        {
            StringBuilder result = new StringBuilder();

            switch (DetermineNodeType(node))
            {
                case ExpressionNodeType.ConstVal:
                    result.Append(RenderConst(node));
                    break;
                case ExpressionNodeType.Operator:
                    result.Append(RenderOperator(node));
                    break;
                case ExpressionNodeType.Variable:
                    result.Append(RenderVar(node));
                    break;
                case ExpressionNodeType.Function:
                    result.Append(RenderFunction(node));
                    break;
            }

            return result.ToString();
        }
 private String HandleConst(ProgramNode node)
 {
     return node.Data[0].ToStringValue();
 }
 /// <summary>
 ///     Replace the specified node with another.
 /// </summary>
 /// <param name="replaceThisNode">The node to replace.</param>
 /// <param name="replaceWith">The node that is replacing that node.</param>
 public void ReplaceNode(ProgramNode replaceThisNode,
                         ProgramNode replaceWith)
 {
     if (replaceThisNode == RootNode)
     {
         RootNode = replaceWith;
     }
     else
     {
         TaskReplaceNode
             .Process(RootNode, replaceThisNode, replaceWith);
     }
 }
        private String HandleOperator(ProgramNode node)
        {
            IProgramExtensionTemplate temp = node.Template;
            StringBuilder result = new StringBuilder();

            if (temp.ChildNodeCount == 2)
            {
                String a = RenderNode(node.GetChildNode(0));
                String b = RenderNode(node.GetChildNode(1));

                if (temp == StandardExtensions.EXTENSION_DIV)
                {
                    result.Append("\\frac{");
                    result.Append(b);
                    result.Append("}{");
                    result.Append(a);
                    result.Append("}");
                }
                else if (temp == StandardExtensions.EXTENSION_MUL)
                {
                    result.Append("(");
                    result.Append(b);
                    result.Append("\\cdot ");
                    result.Append(a);
                    result.Append(")");
                }
                else
                {
                    result.Append("(");
                    result.Append(b);
                    result.Append(temp.Name);
                    result.Append(a);
                    result.Append(")");
                }

            }
            else if (temp.ChildNodeCount == 1)
            {
                String a = RenderNode(node.GetChildNode(0));
                result.Append("(");
                result.Append(temp.Name);
                result.Append(a);
                result.Append(")");
            }
            else
            {
                throw new EACompileError(
                        "An operator must have an arity of 1 or 2, probably should be made a function.");
            }

            return result.ToString();
        }