Beispiel #1
0
 public override void Visit(ForNode node)
 {
     node.Counter.Visit(this);
     node.Begin.Visit(this);
     node.End.Visit(this);
     node.Stat.Visit(this);
 }
Beispiel #2
0
        /// <summary>
        /// This method type checks the ForNode node in the AST.
        /// </summary>
        /// <param name="forNode">The node to check.</param>
        /// <returns>Returns null</returns>
        public override object Visit(ForNode forNode)
        {
            CurrentScope = GlobalScope.FindChild($"LOOPF_{forNode.Line}");
            TypeContext fromType = (TypeContext)forNode.From.Accept(this);
            TypeContext toType   = (TypeContext)forNode.To.Accept(this);

            if (null == CurrentScope.FindSymbol(forNode.CountingVariable))
            {
                CurrentScope.Symbols.Add(new Symbol(forNode.CountingVariable.Id, NUMERIC, false, forNode.CountingVariable));
            }
            else
            {
                CurrentScope.UpdateTypedef(forNode.CountingVariable, new TypeContext(TokenType.NUMERIC)
                {
                    IsFloat = false
                }, CurrentScope.Name, true);
            }
            if (fromType.Type != toType.Type)
            {
                new InvalidTypeException($"Mismatch in range types at {forNode.Line}:{forNode.Offset}");
            }
            forNode.Statements.ForEach(stmnt => stmnt.Accept(this));
            CurrentScope = CurrentScope.Parent ?? GlobalScope;
            return(null);
        }
 public override void VisitForNode(ForNode c)
 {
     c.Parent = st.Peek();
     st.Push(c);
     base.VisitForNode(c);
     st.Pop();
 }
Beispiel #4
0
        public virtual ASTNode Transform(ForNode item)
        {
            var primaryBlock = item.PrimaryBlock.Transform(this) as ContainerNode;

            if (primaryBlock == default)
            {
                throw new NotImplementedException();
            }
            ContainerNode?elseBlock = null;

            if (item.ElseBlock != null)
            {
                elseBlock = item.ElseBlock.Transform(this) as ContainerNode;
                if (elseBlock == default)
                {
                    throw new NotImplementedException();
                }
            }
            if (item.Expression != null)
            {
                return(new ForNode(primaryBlock, elseBlock, item.VariableNames, item.Expression, item.Filter, item.Recursive, item.EndParsingNode, item.WhiteSpaceControl));
            }
            else
            {
                return(new ForNode(primaryBlock, elseBlock, item.VariableNames, item.AlreadyEvaluatedObject, item.Filter, item.Recursive, item.EndParsingNode, item.WhiteSpaceControl));
            }
        }
        public virtual void Visit(ForNode node)
        {
            if (node != null)
            {
                if (node.Initializer != null)
                {
                    node.Initializer.Accept(this);
                }

                if (node.Condition != null)
                {
                    node.Condition.Accept(this);
                }

                if (node.Incrementer != null)
                {
                    node.Incrementer.Accept(this);
                }

                if (node.Body != null)
                {
                    node.Body.Accept(this);
                }
            }
        }
Beispiel #6
0
        public override void VisitForNode(ForNode c)
        {
            c.Assign.Visit(this);
            c.Expr.Visit(this);
            var limit = genc.DeclareLocal(typeof(int));             // переменная цикла cycle

            genc.Emit(OpCodes.Stloc, limit);
            Label startLoop = genc.DefineLabel();
            Label endLoop   = genc.DefineLabel();

            genc.MarkLabel(startLoop);

            genc.Emit(OpCodes.Ldloc, vars[c.Assign.Id.Name]);
            genc.Emit(OpCodes.Ldloc, limit);
            genc.Emit(OpCodes.Bge, endLoop);

            c.Stat.Visit(this);

            genc.Emit(OpCodes.Ldloc, vars[c.Assign.Id.Name]);
            genc.Emit(OpCodes.Ldc_I4_1);
            genc.Emit(OpCodes.Add);
            genc.Emit(OpCodes.Stloc, vars[c.Assign.Id.Name]);

            genc.Emit(OpCodes.Br, startLoop);

            genc.MarkLabel(endLoop);
        }
Beispiel #7
0
        public void Visit(ForNode forNode)
        {
            if (forNode.Initialize != null)
            {
                forNode.Initialize.Parent = forNode;
                forNode.Initialize.Accept(this);
            }

            if (forNode.Condition != null)
            {
                forNode.Condition.Parent = forNode;
                forNode.Condition.Accept(this);
            }

            forNode.Body.Parent = forNode;

            var loop = _currentLoop;

            _currentLoop = LoopType.Loop;
            forNode.Body.Accept(this);
            _currentLoop = loop;

            if (forNode.Increment != null)
            {
                forNode.Increment.Parent = forNode;
                forNode.Increment.Accept(this);
            }
        }
 /// <summary>
 /// Посещение узла с циклом for
 /// </summary>
 /// <param name="w">Узел ForNode</param>
 public virtual void VisitForNode(ForNode w)
 {
     Text += IndentStr() + "for(";
     w.Assign.Visit(this);
     Text += ",";
     w.Border.Visit(this);
     if (w.Inc != null)
     {
         Text += ",";
         w.Inc.Visit(this);
     }
     Text += ")";
     Text += Environment.NewLine;
     if (!(w.Body is BlockNode))
     {
         IndentPlus();
         w.Body.Visit(this);
         Text += ";" + Environment.NewLine;
         IndentMinus();
     }
     else
     {
         w.Body.Visit(this);
     }
 }
Beispiel #9
0
 public override void VisitForNode(ForNode f)
 {
     f.Start.Visit(this);
     f.Id.Visit(this);
     f.End.Visit(this);
     f.Stat.Visit(this);
 }
        /// <summary>
        /// This method visits a for loop node
        /// It first checks count value start is smaller then the amount of loop required and then inserts the symbols
        /// It either increments or decrements
        /// The second if statements accepts the statements in the forloop
        /// </summary>
        /// <param name="forNode">The name of the node</param>
        /// <returns>It returns the for loop</returns>
        public override object Visit(ForNode forNode)
        {
            string forLoop = "";

            if (forNode.From.IValue < forNode.To.IValue)
            {
                forLoop += "for(int " + forNode.CountingVariable.Id + "=" +
                           forNode.From.IValue + ";" + forNode.CountingVariable.Id + "<" +
                           forNode.To.IValue + ";" +
                           forNode.CountingVariable.Id + "++){";
            }
            else
            {
                forLoop += "for(int " + forNode.CountingVariable.Id + "=" +
                           forNode.From.IValue + ";" + forNode.CountingVariable.Id + "<" +
                           forNode.To.IValue + ";" +
                           forNode.CountingVariable.Id + "--){";
            }
            if (forNode.Statements.Any())
            {
                forNode.Statements.ForEach(node => node.Parent = forNode);
                forNode.Statements.ForEach(node => forLoop    += ((string)node.Accept(this)));
            }
            forLoop += "}";
            return(forLoop);
        }
        public override void VisitForNode(ForNode f)
        {
            string Id           = f.Id.Name;
            string forHeadLabel = ThreeAddressCodeTmp.GenTmpLabel();
            string forBodyLabel = ThreeAddressCodeTmp.GenTmpLabel();
            string exitLabel    = ThreeAddressCodeTmp.GenTmpLabel();

            string fromTmpName = Gen(f.From);

            GenCommand("", "assign", fromTmpName, "", Id);

            string toTmpName = Gen(f.To);
            // Делаем допущение, что for шагает на +1 до границы, не включая ее
            string condTmpName = ThreeAddressCodeTmp.GenTmpName();

            GenCommand(forHeadLabel, "LESS", Id, toTmpName, condTmpName);

            GenCommand("", "ifgoto", condTmpName, forBodyLabel, "");
            GenCommand("", "goto", exitLabel, "", "");

            var instructionIndex = Instructions.Count;

            f.Stat.Visit(this);
            Instructions[instructionIndex].Label = forBodyLabel;

            GenCommand("", "PLUS", Id, "1", Id);
            GenCommand("", "goto", forHeadLabel, "", "");
            GenCommand(exitLabel, "noop", "", "", "");
        }
 public virtual void VisitForNode(ForNode f)
 {
     f.Assign.Visit(this);
     f.Border.Visit(this);
     f.Inc.Visit(this);
     f.Body.Visit(this);
 }
Beispiel #13
0
        private void Parsing(ForNode node, StringBuilder sb, ref int lineNum)
        {
            Parsing(node.GetChild(0) as dynamic, sb, ref lineNum); // инициализация
            int logicLine = lineNum;

            Parsing(node.GetChild(1) as dynamic, sb, ref lineNum); // условие
            PrintCommand(sb, "clt", ref lineNum);                  // проверка условия

            // цикл
            int lineBlock = lineNum + 1;

            StringBuilder sb2 = new StringBuilder();

            Parsing(node.Block, sb2, ref lineBlock); // блок кода



            Parsing(node.GetChild(2) as dynamic, sb2, ref lineBlock); //инкремент

            PrintCommand(sb2, String.Format("br L_{0:D6}", logicLine), ref lineBlock);
            // цикл

            PrintCommand(sb, String.Format("brfalse L_{0:D6}", lineBlock), ref lineNum); // выход из цикла

            sb.Append(sb2);

            lineNum = lineBlock;
        }
 public override void VisitForNode(ForNode c)
 {
     c.Begin.Visit(this);
     c.End.Visit(this);
     c.Counter.Visit(this);
     c.Stat.Visit(this);
 }
 public void VisitFor(ForNode node)
 {
     node.Declaration = _processor.ProcessReplacement(node.Declaration);
     node.Condition   = _processor.ProcessReplacement(node.Condition);
     node.Update      = _processor.ProcessReplacement(node.Update);
     node.Body        = _processor.ProcessReplacement(node.Body);
 }
Beispiel #16
0
        public void Accept(ForNode node)
        {
            var bodyLabel   = nextLabel();
            var repeatLabel = nextLabel();
            var endLabel    = nextLabel();

            int breakLabelCount    = methodStack.Peek().BreakLabels.Count;
            int continueLabelCount = methodStack.Peek().ContinueLabels.Count;

            methodStack.Peek().BreakLabels.Push(endLabel);
            methodStack.Peek().ContinueLabels.Push(repeatLabel);

            table.EnterScope();
            node.InitialStatement.Visit(this);
            emitLabel(node.Condition.SourceLocation, bodyLabel);
            node.Condition.Visit(this);
            emit(node.Condition.SourceLocation, InstructionType.JumpIfFalse, endLabel);
            if (node.Body is CodeBlockNode)
            {
                node.Body.VisitChildren(this);
            }
            else
            {
                node.Body.Visit(this);
            }
            emitLabel(node.RepeatStatement.SourceLocation, repeatLabel);
            node.RepeatStatement.Visit(this);
            emit(node.RepeatStatement.SourceLocation, InstructionType.Jump, bodyLabel);
            emitLabel(node.RepeatStatement.SourceLocation, endLabel);
            table.LeaveScope();

            restoreLabels(breakLabelCount, continueLabelCount);
        }
 public void Transform(ForNode item, bool inner = false)
 {
     SetTrim(item.WhiteSpaceControl.Start);
     item.PrimaryBlock.Transform(this, inner: true);
     item.ElseBlock?.Transform(this, inner: true);
     _WhiteSpaceMode = item.WhiteSpaceControl.End;
 }
Beispiel #18
0
        private Statement ProcessForStatement(ForNode node)
        {
            ForStatement statement = new ForStatement();

            symbolTable.PushScope();

            if (node.Initializer != null)
            {
                if (node.Initializer is VariableDeclarationNode)
                {
                    VariableDeclarationStatement initializer =
                        (VariableDeclarationStatement)BuildStatement((StatementNode)node.Initializer);
                    statement.AddInitializer(initializer);
                }
                else
                {
                    Debug.Assert(node.Initializer is ExpressionListNode);

                    ICollection <Expression> initializers =
                        expressionBuilder.BuildExpressionList((ExpressionListNode)node.Initializer);
                    foreach (Expression initializer in initializers)
                    {
                        statement.AddInitializer(initializer);
                    }
                }
            }

            if (node.Condition != null)
            {
                Expression condition = expressionBuilder.BuildExpression(node.Condition);

                if (condition is MemberExpression)
                {
                    condition = expressionBuilder.TransformMemberExpression((MemberExpression)condition);
                }

                statement.AddCondition(condition);
            }

            if (node.Increment != null)
            {
                Debug.Assert(node.Increment is ExpressionListNode);

                ICollection <Expression> increments =
                    expressionBuilder.BuildExpressionList((ExpressionListNode)node.Increment);
                foreach (Expression increment in increments)
                {
                    statement.AddIncrement(increment);
                }
            }

            Statement body = BuildStatement((StatementNode)node.Body);

            statement.AddBody(body);

            symbolTable.PopScope();

            return(statement);
        }
Beispiel #19
0
 private void Parsing(ForNode node, string methodName)
 {
     Parsing(node.GetChild(0) as dynamic, methodName);
     dynamic temp = node.GetChild(1); // Logic operation
     Parsing(temp, methodName);
     Parsing(node.VarInitValue, methodName);
     Parsing(node.Block, methodName);
 }
 public void VisitFor(ForNode node)
 {
     _visitor.VisitStatement(node);
     VisitDeclaration(node.Declaration);
     node.Condition.AcceptSyntaxTreeVisitor(_childrenVisitor);
     node.Update.AcceptSyntaxTreeVisitor(_childrenVisitor);
     VisitBody(node.Body);
 }
Beispiel #21
0
 public void VisitFor(ForNode node)
 {
     Print("For");
     VisitSubnode(node.Declaration);
     VisitSubnode(node.Condition);
     VisitSubnode(node.Update);
     VisitBody(node.Body);
 }
Beispiel #22
0
 public override void VisitForNode(ForNode f)
 {
     if (WithinIf)
     {
         HasCycleNestedToIf = true;
     }
     base.VisitForNode(f);
 }
Beispiel #23
0
        public void VisitFor(ForNode node)
        {
            // Don't insert unreachable code
            if (!_builder.InsertBlock.IsValid)
            {
                return;
            }

            Metadata oldLexicalScope = _lexicalScope;

            if (_genContext.DebugInfo)
            {
                _genContext.TryGetNodeSymbol(node.Declaration, out Symbol declRange);
                _lexicalScope = _genContext.DiBuilder.CreateLexicalBlock(_lexicalScope, _genContext.DiFile,
                                                                         declRange.LLVMLine, _genContext.ColumnInfo ? declRange.LLVMColumn : 0);
            }

            node.Declaration.AcceptStatementVisitor(this);

            BasicBlock condBasicBlock = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.cond");
            BasicBlock bodyBasicBlock = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.body");
            BasicBlock incBasicBlock  = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.inc");
            BasicBlock endBasicBlock  = _genContext.Context.AppendBasicBlock(_function.FunctionValue, "for.end");

            SetCurrentDebugLocation(node);
            BuildBrIfNecessary(condBasicBlock);

            _builder.PositionAtEnd(condBasicBlock);
            node.Condition.AcceptExpressionVisitor(this);
            Value condVal = _visitedValue;

            if (!condVal.IsValid)
            {
                throw new InvalidOperationException("condition did not produce a usable rvalue");
            }

            SetCurrentDebugLocation(node);
            condVal = ConvertToBool(condVal);

            _builder.BuildCondBr(condVal, bodyBasicBlock, endBasicBlock);

            _builder.PositionAtEnd(bodyBasicBlock);
            BreakContinue oldBreakContinueTop = _breakContinueTop;

            _breakContinueTop = new BreakContinue(endBasicBlock, incBasicBlock);
            VisitBody(node.Body);
            _breakContinueTop = oldBreakContinueTop;
            BuildBrIfNecessary(incBasicBlock);

            _builder.PositionAtEnd(incBasicBlock);
            node.Update.AcceptExpressionVisitor(this);
            BuildBrIfNecessary(condBasicBlock);

            _builder.PositionAtEnd(endBasicBlock);

            _lexicalScope = oldLexicalScope;
        }
Beispiel #24
0
        public void TestForNodeLackInKeyword()
        {
            string        t  = "#{for i array[1, 2, 3]}";
            LexicalParser lp = new LexicalParser();

            lp.SetParseContent(t);
            var     tokens = lp.Parse();
            ForNode f      = new ForNode(tokens[0]);
        }
Beispiel #25
0
        public void TestForNodeInvalidVarName()
        {
            string        t  = "#{for $ in array[1, 2, 3]}";
            LexicalParser lp = new LexicalParser();

            lp.SetParseContent(t);
            var     tokens = lp.Parse();
            ForNode f      = new ForNode(tokens[0]);
        }
        public IEnumerable <ASTNode> Transform(ForNode item)
        {
            yield return(item);

            foreach (var child in TransformAll(new ASTNode?[] { item.PrimaryBlock, item.ElseBlock, item.Expression, item.Filter }))
            {
                yield return(child);
            }
        }
Beispiel #27
0
        public void TestForNodeWithColon()
        {
            string        t  = "#{:for i in array[1 : 10]:}";
            LexicalParser lp = new LexicalParser();

            lp.SetParseContent(t);
            var     tokens = lp.Parse();
            ForNode f      = new ForNode(tokens[0]);
        }
Beispiel #28
0
 public override void VisitForNode(ForNode c)
 {
     Text += IndentStr() + "for ";
     c.Assign.Visit(this);
     Text += IndentStr() + " to ";
     c.Expr.Visit(this);
     Text += Environment.NewLine;
     c.Stat.Visit(this);
 }
 public override void VisitForNode(ForNode f)
 {
     PreVisit(f);
     f.Id.Visit(this);
     f.From.Visit(this);
     f.To.Visit(this);
     f.Stat.Visit(this);
     PostVisit(f);
 }
Beispiel #30
0
        public object VisitForNode(ForNode node, Context parameter)
        {
            foreach (var child in node.Children)
            {
                child.Accept(this, parameter);
            }

            return(null);
        }
Beispiel #31
0
 public virtual void Visit(ForNode node)
 {
     if (node != null)
     {
          AcceptChildren(node);
     }
 }
Beispiel #32
0
        public static ClassNode Parse(string sScript)
        {
            ArrayList aAllLines = new ArrayList();
            string[] aKeywords = new string[]{"for", "else if", "if", "else", "while", "goto", "gosub", "return"};
            //TODO: I don't handle keyword and a statement on the same line right now-
            //e.g. "if (true) blabla();" or "for (;;) put(1);"

            BaseNode rootNode = new BaseNode();
            ClassNode classNode = new ClassNode();
            rootNode.AppendChild("Class_01", classNode);
            BaseNode currentNode = classNode;

            //easier parsing if \r\n is replaced by \n
            sScript = sScript.Replace("\r\n", "\n");
            //also a little easier if script always ends with a \n
            if (!sScript.EndsWith("\n"))
                sScript+="\n";

            //structure will be [ScriptName:[MethodName:[LabelName:[clause:[clause]]]]]
            //Labels must be on top level in a method (e.g. not inside an if(){} clause)
            while (sScript.Length > 0)
            {

                //first divide into "lines" - EndOfLine represented by: return ; { or }
                string sLine = "";
                string sDividerChar = "";
                MatchCollection matches = Regex.Matches(sScript, "[^{};\\n]*[{};\\n]");
                foreach (Match m in matches)
                {
                    sLine = sScript.Substring(0, m.Index+m.Length);
                    sDividerChar = m.Value.Substring(m.Value.Length-1,1);
                    if (sDividerChar == ";")
                    {
                        //must check if the ";" is inside parenthesis - if so, it doesn't count (e.g. "for(;;)")
                        //only when the number of "(" is the same as the number of ")", the ";" is outside
                        string sCheck = sLine.Replace("(", "");
                        int nNumRight = sLine.Length-sCheck.Length;
                        sCheck = sLine.Replace(")", "");
                        int nNumLeft = sLine.Length-sCheck.Length;
                        if (nNumRight != nNumLeft)
                            continue;
                    }
                    sScript = sScript.Remove(0, sLine.Length);
                    sLine = sLine.Remove(sLine.Length-1,1);
                    break;
                }

                sLine = sLine.Trim();

                //handle if the line only consists of a { or }
                if (sLine.Length == 0)
                {
                    if (HandleNodeBorderChars(sDividerChar, ref currentNode))
                        continue;
                }

                //empty and remmed lines are ignored:
                if (sLine.Length == 0 || sLine.IndexOf("//") == 0)
                {
                    continue;
                }

                if (currentNode.GetType() == typeof(ClassNode)) //.Depth == 1) //class level, i.e. where methods are defined
                {
                    //search for "on method([args])"
                    Match m = Regex.Match(sLine, "on\\s*\\w*\\s*[(][^()]*[)]");
                    if (m.Success)
                    {
                        string sMethod = m.Value.Replace("on ", "").Trim();
                        string sArgs = sMethod.Remove(0,sMethod.IndexOf("("));
                        sMethod = sMethod.Substring(0,sMethod.IndexOf("("));

                        MethodNode methodNode = new MethodNode();
                        methodNode.DefineArguments(sArgs.Substring(1,sArgs.Length-2));
                        currentNode.AppendChild(sMethod, methodNode);
                        currentNode = methodNode;
                        continue;
                    }
                }
                //separate code flow keywords/tokens from expressions
                if (sLine.IndexOf(":") == sLine.Length-1)
                {
                    //it's a label. Labels can currently only occur on Method level
                    if (currentNode.GetType() != typeof(MethodNode))
                        throw new Exception("Labels must be defined in Method scope!");
                    //TODO: Labels can't be nodes - they're not defined with {}'s... More like an HTML anchor
                    //sLine.Substring(0,sLine.Length-2)
                }

                #region Check for keywords

                foreach (string sKeyword in aKeywords)
                {
                    //[^\\w]+*[( ]*
                    Match m = Regex.Match(sLine+" ", sKeyword+"[^\\w]+[( ]*"); //"\\s*[(]*");
                    if (m.Success)
                    {
                        ChunkNode newNode = null;

                        string sArgs = GetStringWithinParenthesis(sLine);

                        switch (sKeyword)
                        {
                            case "for":
                                ForNode forNode = new ForNode();
                                forNode.SetConditions(sArgs);
                                newNode = forNode;
                                //With the current line seek method, the ";" in for(;;) forces us to look ahead in script
                                //TODO: lookahead for(;;)
                                break;
                            case "if":
                                if (sArgs == null)
                                    throw new Exception("If statement incomplete");
                                IfNode ifNode = new IfNode();
                                ifNode.SetIfStatement(sArgs);
                                newNode = ifNode;
                                break;
                            case "else if":
                            case "else":
                                //is the current node an IfNode?
                                if (currentNode.GetType() != typeof(IfNode))
                                    throw new Exception("\""+sKeyword+"\" must come after an \"if\" statement");
                                IfNode elseifNode = new IfNode();
                                if (sKeyword == "else if")
                                {
                                    //TODO: don't understand C# scopes... Why can't I define sArgs here too? Can't see any risk for confusion or mistakes!?
                                    //And sometimes it's too slack:
                                    //a member variable can have the same name as a variable in a method with no complaits,
                                    //although that is clearly a mistake in most cases?
                                    if (sArgs == null)
                                        throw new Exception("Else if statement incomplete");
                                    elseifNode.SetIfStatement(sArgs);
                                }
                                IfNode oldIfNode = (IfNode)currentNode;
                                oldIfNode.SetNextIfNode(elseifNode);
                                newNode = elseifNode;
                                break;
                        }
                        if (newNode!=null)
                        {
                            newNode.CloseNodeAfterNextLine = true;
                            currentNode.AppendChild(sKeyword, newNode);
                            currentNode = newNode;
                        }
                        break;
                    }
                }
                #endregion

                if (HandleNodeBorderChars(sDividerChar, ref currentNode))
                    continue;

                string sStatement = sLine;
                ExpressionNode expNode = new ExpressionNode();
                expNode.SetExpression(sStatement);
                currentNode.AppendChild(sStatement, expNode);

                //TODO: how to check nicely if ChunkNode is one of the base classes of currentNode?? This is ugly (?):
                try
                {
                    ChunkNode chunkNode = (ChunkNode)currentNode;
                    if (chunkNode.CloseNodeAfterNextLine)
                        currentNode = (BaseNode)currentNode.ParentNode;
                }
                catch
                {}
            }

            //			System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            //			rootNode.AddToXml(doc);
            //			doc.Save("Testing.xml");

            return classNode;
        }
Beispiel #33
0
 public virtual bool Walk(ForNode node) { return true; }
Beispiel #34
0
 public virtual void PostWalk(ForNode node) { }
Beispiel #35
0
        private static void GenerateFor(ForNode node, DataContext data)
        {
            StartLine(data, "for (");

            data.CodeBlock.DisableNewLines = true;

            if (node.InitializeSyntax is VariableDeclarationNode)
            {
                GenerateStatement((VariableDeclarationNode)node.InitializeSyntax, data);
            }
            else if (node.InitializeSyntax is ExpressionNode)
            {
                GenerateExpression((ExpressionNode)node.InitializeSyntax, data);
            }
            else
            {
                ThrowUnableToGenerateException("For initializer", node.InitializeSyntax);
            }

            Append(data, " ");

            GenerateExpression(node.EvaluateExpression, data);
            Append(data, "; ");

            GenerateExpression(node.IncrementExpression, data);

            data.CodeBlock.DisableNewLines = false;

            EndLine(data, ") {{");

            data.CodeBlock.Padding++;
            GenerateStatementBlock(node.BodyStatementBlock, data);

            data.CodeBlock.Padding--;
            WriteLine(data, "}}");
        }
        public virtual void Visit(ForNode node)
        {
            if (node != null)
            {
                if (node.Initializer != null)
                {
                    node.Initializer.Accept(this);
                }

                if (node.Condition != null)
                {
                    node.Condition.Accept(this);
                }

                if (node.Incrementer != null)
                {
                    node.Incrementer.Accept(this);
                }

                if (node.Body != null)
                {
                    node.Body.Accept(this);
                }
            }
        }
        public ITreeNode Program()
        {
            ITreeNode programNode = new ErrorNode();

            switch (curTokenType)
            {
                case TokenType.BEGINBL:
                    Match(ref matchToken, TokenType.BEGINBL);
                    ITreeNode someStatement = Program();
                    BlockNode block = new BlockNode();
                    block.addStatement(someStatement);
                    while (curTokenType != TokenType.ENDBL)
                    {
                        someStatement = Program();
                        block.addStatement(someStatement);
                    }
                    Match(ref matchToken, TokenType.ENDBL);
                    programNode = block;
                    break;
                case TokenType.LABEL:
                    Match(ref matchToken, TokenType.LABEL);
                    LabelNode labeledBlock = new LabelNode(matchToken.getValue());
                    ITreeNode labeledStatement;
                    do
                    {
                        labeledStatement = Program();
                        labeledBlock.addStatement(labeledStatement);
                    }
                    while (curTokenType != TokenType.EOF);
                    programNode = labeledBlock;
                    break;
                case TokenType.INTDEC:
                    Match(ref matchToken, TokenType.INTDEC);
                    Match(ref matchToken, TokenType.ID);
                    programNode = new IdentifierDeclarationNode(IdentifierType.INT, matchToken.getValue());
                    Match(ref matchToken, TokenType.EOS);
                    break;
                case TokenType.BOOLDEC:
                    Match(ref matchToken, TokenType.BOOLDEC);
                    Match(ref matchToken, TokenType.ID);
                    programNode = new IdentifierDeclarationNode(IdentifierType.BOOL, matchToken.getValue());
                    Match(ref matchToken, TokenType.EOS);
                    break;
                case TokenType.FOR:
                    Match(ref matchToken, TokenType.FOR);
                    Match(ref matchToken, TokenType.LPAREN);
                    AssignmentNode init = (AssignmentNode)Program();
                    AssignmentNode step = (AssignmentNode)Program();
                    BooleanExpressionNode condition = (BooleanExpressionNode)BooleanExpression();
                    Match(ref matchToken, TokenType.RPAREN);
                    BlockNode forBody = (BlockNode)Program();
                    programNode = new ForNode(init, step, condition, forBody);
                    break;
                /*case TokenType.FUN:
                    Match(ref matchToken, TokenType.FUN);
                    IdentifierNode id = (IdentifierNode)Factor();
                    programNode = new FunctionNode(id);
                    Match(ref matchToken, TokenType.EOS);
                    break;*/
                case TokenType.GOTO:
                    Match(ref matchToken, TokenType.GOTO);
                    Match(ref matchToken, TokenType.ID);
                    IdentifierNode gotoLabel = new IdentifierNode(matchToken.getValue(), IdentifierType.LABEL);
                    programNode = new GotoNode(gotoLabel);
                    Match(ref matchToken, TokenType.EOS);
                    break;
                case TokenType.ID:
                    Match(ref matchToken, TokenType.ID);
                    IdentifierNode assignId = new IdentifierNode(matchToken.getValue(), IdentifierType.UNKNOWN);
                    Match(ref matchToken, TokenType.ASSIGN);
                    BooleanExpressionNode assignValue = (BooleanExpressionNode)BooleanExpression();
                    programNode = new AssignmentNode(assignId, assignValue);
                    Match(ref matchToken, TokenType.EOS);
                    break;
                case TokenType.IF:
                    Match(ref matchToken, TokenType.IF);
                    ITreeNode thenBranch;
                    ITreeNode elseBranch;

                    Match(ref matchToken, TokenType.LPAREN);
                    BooleanExpressionNode ifCondition = (BooleanExpressionNode)BooleanExpression();
                    Match(ref matchToken, TokenType.RPAREN);
                    Match(ref matchToken, TokenType.THEN);
                    thenBranch = (BlockNode)Program();
                    if (curTokenType == TokenType.ELSE)
                    {
                        Match(ref matchToken, TokenType.ELSE);
                        elseBranch = (BlockNode)Program();
                    }
                    else
                    {
                        elseBranch = new BlankNode();
                    }
                    programNode = new IfNode(ifCondition, thenBranch, elseBranch);
                    break;
                /*case TokenType.LET:
                    Match(ref matchToken, TokenType.LET);
                    IdentifierNode shortId = (IdentifierNode)Factor();
                    Match(ref matchToken, TokenType.ASSIGN);
                    BooleanExpressionNode subst = (BooleanExpressionNode)BooleanExpression();
                    Match(ref matchToken, TokenType.IN);
                    BooleanExpressionNode target = (BooleanExpressionNode)BooleanExpression();
                    programNode = new LetNode(shortId, subst, target);
                    Match(ref matchToken, TokenType.EOS);
                    break;*/
                case TokenType.PRINT:
                    Match(ref matchToken, TokenType.PRINT);
                    Match(ref matchToken, TokenType.LPAREN);
                    BooleanExpressionNode printArgument = (BooleanExpressionNode)BooleanExpression();
                    Match(ref matchToken, TokenType.RPAREN);
                    programNode = new PrintNode(printArgument);
                    Match(ref matchToken, TokenType.EOS);
                    break;
                case TokenType.WHILE:
                    Match(ref matchToken, TokenType.WHILE);
                    Match(ref matchToken, TokenType.LPAREN);
                    BooleanExpressionNode whileCondition = (BooleanExpressionNode)BooleanExpression();
                    Match(ref matchToken, TokenType.RPAREN);
                    BlockNode whileBody = (BlockNode)Program();
                    programNode = new WhileNode(whileCondition, whileBody);
                    break;
                case TokenType.EOF:
                    programNode = new BlankNode();
                    break;
                default:
                    Expect(TokenType.UNKNOWN, lookAheadToken);
                    break;
            }
            return programNode;
        }