Example #1
0
        private static bool ExtractLastIf(DoStatement stat)
        {
            // search for an if condition at the end of the loop
            Statement last = stat.GetFirst();

            while (last.type == Statement.Type_Sequence)
            {
                last = last.GetStats().GetLast();
            }
            if (last.type == Statement.Type_If)
            {
                IfStatement lastif = (IfStatement)last;
                if (lastif.iftype == IfStatement.Iftype_If && lastif.GetIfstat() != null)
                {
                    Statement ifstat   = lastif.GetIfstat();
                    StatEdge  elseedge = lastif.GetAllSuccessorEdges()[0];
                    if (elseedge.GetType() == StatEdge.Type_Continue && elseedge.closure == stat)
                    {
                        HashSet <Statement> set = stat.GetNeighboursSet(StatEdge.Type_Continue, Statement.
                                                                        Direction_Backward);
                        set.Remove(last);
                        if ((set.Count == 0))
                        {
                            // no direct continues in a do{}while loop
                            if (IsExternStatement(stat, ifstat, ifstat))
                            {
                                ExtractIfBlock(stat, lastif);
                                return(true);
                            }
                        }
                    }
                }
            }
            return(false);
        }
Example #2
0
 private static void RemoveLastEmptyStatement(DoStatement dostat, Statement stat)
 {
     if (stat == dostat.GetFirst())
     {
         BasicBlockStatement bstat = new BasicBlockStatement(new BasicBlock(DecompilerContext
                                                                            .GetCounterContainer().GetCounterAndIncrement(CounterContainer.Statement_Counter
                                                                                                                          )));
         bstat.SetExprents(new List <Exprent>());
         dostat.ReplaceStatement(stat, bstat);
     }
     else
     {
         foreach (StatEdge edge in stat.GetAllPredecessorEdges())
         {
             edge.GetSource().ChangeEdgeType(Statement.Direction_Forward, edge, StatEdge.Type_Continue
                                             );
             stat.RemovePredecessor(edge);
             edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, dostat);
             dostat.AddPredecessor(edge);
             dostat.AddLabeledEdge(edge);
         }
         // parent is a sequence statement
         stat.GetParent().GetStats().RemoveWithKey(stat.id);
     }
 }
Example #3
0
        private static bool ExtractFirstIf(DoStatement stat)
        {
            // search for an if condition at the entrance of the loop
            Statement first = stat.GetFirst();

            while (first.type == Statement.Type_Sequence)
            {
                first = first.GetFirst();
            }
            // found an if statement
            if (first.type == Statement.Type_If)
            {
                IfStatement firstif = (IfStatement)first;
                if ((firstif.GetFirst().GetExprents().Count == 0))
                {
                    if (firstif.iftype == IfStatement.Iftype_If && firstif.GetIfstat() != null)
                    {
                        Statement ifstat = firstif.GetIfstat();
                        if (IsExternStatement(stat, ifstat, ifstat))
                        {
                            ExtractIfBlock(stat, firstif);
                            return(true);
                        }
                    }
                }
            }
            return(false);
        }
Example #4
0
 public void ExecuteHandler(DoStatement handler)
 {
     for (; this.counter < repetitions; this.counter++)
     {
         handler();
     }
 }
Example #5
0
        public override Object Visit(DoStatement node, Object obj)
        {
            int indent = Convert.ToInt32(obj);

            this.printIndentation(indent);
            this.output.WriteLine("DoStatement [{0}:{1}]", node.Location.Line, node.Location.Column);
            this.printIndentation(indent + 1);
            this.output.WriteLine("Init");
            for (int i = 0; i < node.InitDo.Count; i++)
            {
                node.InitDo[i].Accept(this, indent + 2);
            }
            this.printIndentation(indent + 1);
            this.output.WriteLine("Before Body");
            for (int i = 0; i < node.BeforeBody.Count; i++)
            {
                node.BeforeBody[i].Accept(this, indent + 2);
            }
            this.printIndentation(indent + 1);
            this.output.WriteLine("Statements");
            node.Statements.Accept(this, indent + 2);
            this.printIndentation(indent + 1);
            this.output.WriteLine("Condition");
            node.Condition.Accept(this, indent + 2);
            return(null);
        }
Example #6
0
        private static Statement DetectStatement(Statement head)
        {
            Statement res;

            if ((res = DoStatement.IsHead(head)) != null)
            {
                return(res);
            }
            if ((res = SwitchStatement.IsHead(head)) != null)
            {
                return(res);
            }
            if ((res = IfStatement.IsHead(head)) != null)
            {
                return(res);
            }
            // synchronized statements will be identified later
            // right now they are recognized as catchall
            if ((res = SequenceStatement.IsHead2Block(head)) != null)
            {
                return(res);
            }
            if ((res = CatchStatement.IsHead(head)) != null)
            {
                return(res);
            }
            if ((res = CatchAllStatement.IsHead(head)) != null)
            {
                return(res);
            }
            return(null);
        }
Example #7
0
        private static bool EnhanceLoop(DoStatement stat)
        {
            int oldloop = stat.GetLooptype();

            switch (oldloop)
            {
            case DoStatement.Loop_Do:
            {
                // identify a while loop
                if (MatchWhile(stat))
                {
                    // identify a for loop - subtype of while
                    MatchFor(stat);
                }
                else
                {
                    // identify a do{}while loop
                    MatchDoWhile(stat);
                }
                break;
            }

            case DoStatement.Loop_While:
            {
                MatchFor(stat);
                break;
            }
            }
            return(stat.GetLooptype() != oldloop);
        }
        public virtual Statement visit(DoStatement doStatement)
        {
            doStatement.statement  = visitStatement(doStatement.statement);
            doStatement.expression = visitExpression(doStatement.expression);

            return(doStatement);
        }
Example #9
0
        private static void ExtractIfBlock(DoStatement loop, IfStatement ifstat)
        {
            Statement target = ifstat.GetIfstat();
            StatEdge  ifedge = ifstat.GetIfEdge();

            ifstat.SetIfstat(null);
            ifedge.GetSource().ChangeEdgeType(Statement.Direction_Forward, ifedge, StatEdge.Type_Break
                                              );
            ifedge.closure = loop;
            ifstat.GetStats().RemoveWithKey(target.id);
            loop.AddLabeledEdge(ifedge);
            SequenceStatement block = new SequenceStatement(Sharpen.Arrays.AsList(loop, target
                                                                                  ));

            loop.GetParent().ReplaceStatement(loop, block);
            block.SetAllParent();
            loop.AddSuccessor(new StatEdge(StatEdge.Type_Regular, loop, target));
            foreach (StatEdge edge in new List <StatEdge>(block.GetLabelEdges()))
            {
                if (edge.GetType() == StatEdge.Type_Continue || edge == ifedge)
                {
                    loop.AddLabeledEdge(edge);
                }
            }
            foreach (StatEdge edge in block.GetPredecessorEdges(StatEdge.Type_Continue))
            {
                if (loop.ContainsStatementStrict(edge.GetSource()))
                {
                    block.RemovePredecessor(edge);
                    edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, loop);
                    loop.AddPredecessor(edge);
                }
            }
        }
Example #10
0
        /* "Do-While" loop always enters the loop body.
         */
        public override Exit visitDo(DoStatement doStat, Environment env)
        {
            Exit bodyExit = analyzeLoopBody(doStat.body, env);

            analyzeExpr(doStat.condition, env);
            return(bodyExit);
        }
Example #11
0
 public int Visit(DoStatement statement)
 {
     _writer.WriteLine("do");
     statement.Block.Accept(this);
     _writer.Write("while (");
     statement.Condition.Accept(this);
     _writer.WriteLine(");");
     return(0);
 }
Example #12
0
        protected override void VisitDoStatement(DoStatement tree)
        {
            _TrySetResult(tree);
            if (_result != null)
            {
                return;
            }

            VisitAnySyntaxTree(tree.block);
        }
Example #13
0
        private static IEnumerable <Command> CompileDoStatement(SubroutineCompilationUnit compilationUnit,
                                                                DoStatement doStatement)
        {
            foreach (var command in CompileSubroutineCall(compilationUnit, doStatement.SubroutineCall))
            {
                yield return(command);
            }

            yield return(Commands.Pop.Temp(0));
        }
Example #14
0
 private void WriteDoStatement(DoStatement doStatement, StringBuilder programBuilder)
 {
     labelCount += 1;
     programBuilder.AppendFormat("jmp .L{0} ", labelCount);
     programBuilder.AppendLine();
     programBuilder.AppendFormat(".L{0}: ", labelCount);
     programBuilder.AppendLine();
     WriteBlock(doStatement.Statements as BlockStatement, programBuilder);
     WriteExpr(doStatement.Expressions, registerFile, programBuilder);
 }
        private static DoStatement GetDoStatement(ASTNode prev, StatementList body)
        {
            var stat = new DoStatement(prev.Parent, prev.Scope, new List <LToken> (new[]
            {
                new LToken("do", "do", "do", TokenType.Keyword, AdjustRange(prev.Range, "do")),
                new LToken("end", "end", "end", TokenType.Keyword, AdjustRange(prev.Range, "end"))
            }));

            stat.SetBody(body);
            return(stat);
        }
Example #16
0
        public void Visit(DoStatement doStatement)
        {
            var exitLabel     = new Label();
            var continueLabel = new Label();

            InnerCode.Add(IntermediateCode.Emit.Label(continueLabel));
            doStatement.Statement.Accept(this);
            doStatement.Condition.Accept(this);
            InnerCode.Add(IntermediateCode.Emit.JumpIfFalse(doStatement.Condition.Reference, exitLabel));
            InnerCode.Add(new Jump(continueLabel));
            InnerCode.Add(IntermediateCode.Emit.Label(exitLabel));
        }
Example #17
0
 public override void ConstructDoStatement(DoStatement node)
 {
     this.WriteLineIndented("do");
     this.Indent( );
     this.ConstructInternal(node.Body);
     this.Outdent( );
     this.WriteIndented("end");
     if (node.HasSemicolon)
     {
         this.Write(";");
     }
 }
        public override Object Visit(DoStatement node, Object obj)
        {
            if (node.Location == ((AstNode)obj).Location || found)
            {
                found = true;
                return(this.table);
            }

            for (int i = 0; i < node.InitDo.Count; i++)
            {
                if (found)
                {
                    return(this.table);
                }
                node.InitDo[i].Accept(this, obj);
            }
            if (found)
            {
                return(this.table);
            }
            this.table.Set();
            for (int i = 0; i < node.BeforeBody.Count; i++)
            {
                if (found)
                {
                    return(this.table);
                }
                node.BeforeBody[i].Accept(this, obj);
            }

            if (found)
            {
                return(this.table);
            }
            node.Statements.Accept(this, obj);
            if (found)
            {
                return(this.table);
            }
            this.table.Reset();

            if (found)
            {
                return(this.table);
            }
            node.Condition.Accept(this, obj);
            if (found)
            {
                return(this.table);
            }
            return(this.table);
        }
Example #19
0
        public override Type visitDo(DoStatement doStatement, Environment env)
        {
            analyze(doStatement.body, env);

            Type conditionType = analyzeExpr(doStatement.condition, env.subScope(doStatement));

            if (!isBoolean(conditionType))
            {
                log.error(doStatement.condition.Pos, messages.whileConditonType);
            }

            return(null);
        }
Example #20
0
    static void Main(string[] args)
    {
        Console.WriteLine("------------ for examples ---------------");
        ForStatement.Examples();

        Console.WriteLine("------------ foreach examples -----------");
        ForeachStatement.Examples();

        Console.WriteLine("------------ do examples ----------------");
        DoStatement.Examples();

        Console.WriteLine("------------ while examples -------------");
        WhileStatement.Examples();
    }
Example #21
0
        public override Object Visit(DoStatement node, Object obj)
        {
            DoStatement clonedDoStatement = new DoStatement((Statement)node.Statements.Accept(this, obj), (Expression)node.Condition.Accept(this, obj), node.Location);

            for (int i = 0; i < node.InitDo.Count; i++)
            {
                clonedDoStatement.InitDo.Add((MoveStatement)node.InitDo[i].Accept(this, obj));
            }
            for (int i = 0; i < node.BeforeBody.Count; i++)
            {
                clonedDoStatement.BeforeBody.Add((ThetaStatement)node.BeforeBody[i].Accept(this, obj));
            }
            return(clonedDoStatement);
        }
Example #22
0
        protected virtual ASTNode FoldDoStatement(DoStatement node, params Object[] args)
        {
            if (node.Body == null)
            {
                throw new Exception("Cannot have a DoStatement with a null body.");
            }
            node.SetBody(this.FoldStatementList(node.Body));

            if (node.Body.Statements.Count == 0)
            {
                return(null);
            }
            return(node);
        }
Example #23
0
 public void Visit(DoStatement l)
 {
     ColorCommand(l);
     if (IsClassnameKnown(l.Param))
     {
         ColorClass(l.pParam + l.Param);
     }
     else
     {
         ColorExpression(l.pParam + l.Param);
     }
     ColorError(l);
     //NextLine();
 }
Example #24
0
        public override void Accept(DoStatement doStmt)
        {
            IodineLabel doLabel    = methodBuilder.CreateLabel();
            IodineLabel breakLabel = methodBuilder.CreateLabel();

            breakLabels.Push(breakLabel);
            continueLabels.Push(doLabel);
            methodBuilder.MarkLabelPosition(doLabel);
            doStmt.Body.Visit(this);
            doStmt.Condition.Visit(this);
            methodBuilder.EmitInstruction(doStmt.Condition.Location, Opcode.JumpIfTrue,
                                          doLabel);
            methodBuilder.MarkLabelPosition(breakLabel);
            breakLabels.Pop();
            continueLabels.Pop();
        }
Example #25
0
 private static bool ExtractLoop(DoStatement stat)
 {
     if (stat.GetLooptype() != DoStatement.Loop_Do)
     {
         return(false);
     }
     foreach (StatEdge edge in stat.GetLabelEdges())
     {
         if (edge.GetType() != StatEdge.Type_Continue && edge.GetDestination().type != Statement
             .Type_Dummyexit)
         {
             return(false);
         }
     }
     return(ExtractLastIf(stat) || ExtractFirstIf(stat));
 }
Example #26
0
 public override Object Visit(DoStatement node, Object obj)
 {
     for (int i = 0; i < node.InitDo.Count; i++)
     {
         node.InitDo[i].Accept(this, obj);
     }
     this.table.Set();
     for (int i = 0; i < node.BeforeBody.Count; i++)
     {
         node.BeforeBody[i].Accept(this, obj);
     }
     node.Statements.Accept(this, obj);
     this.table.Reset();
     node.Condition.Accept(this, obj);
     return(null);
 }
Example #27
0
        // 5.4
        int IStatementVisitor <int> .VisitDo(DoStatement statement)
        {
            _Writer.WriteLine("do {");

            if (statement.HasStatement)
            {
                _Writer.Indent++;
                foreach (var s in statement.Statements)
                {
                    s.Accept(this);
                }
                _Writer.Indent--;
            }

            _Writer.Write("} while (");
            statement.Condition.Accept(this);
            _Writer.WriteLine(");");

            return(0);
        }
Example #28
0
 private static bool IsExternStatement(DoStatement loop, Statement block, Statement
                                       stat)
 {
     foreach (StatEdge edge in stat.GetAllSuccessorEdges())
     {
         if (loop.ContainsStatement(edge.GetDestination()) && !block.ContainsStatement(edge
                                                                                       .GetDestination()))
         {
             return(false);
         }
     }
     foreach (Statement st in stat.GetStats())
     {
         if (!IsExternStatement(loop, block, st))
         {
             return(false);
         }
     }
     return(true);
 }
Example #29
0
        public static void LowContinueLabels(Statement stat, HashSet <StatEdge> edges)
        {
            bool ok = (stat.type != Statement.Type_Do);

            if (!ok)
            {
                DoStatement dostat = (DoStatement)stat;
                ok = dostat.GetLooptype() == DoStatement.Loop_Do || dostat.GetLooptype() == DoStatement
                     .Loop_While || (dostat.GetLooptype() == DoStatement.Loop_For && dostat.GetIncExprent
                                         () == null);
            }
            if (ok)
            {
                Sharpen.Collections.AddAll(edges, stat.GetPredecessorEdges(StatEdge.Type_Continue
                                                                           ));
            }
            if (ok && stat.type == Statement.Type_Do)
            {
                foreach (StatEdge edge in edges)
                {
                    if (stat.ContainsStatementStrict(edge.GetSource()))
                    {
                        edge.GetDestination().RemovePredecessor(edge);
                        edge.GetSource().ChangeEdgeNode(Statement.Direction_Forward, edge, stat);
                        stat.AddPredecessor(edge);
                        stat.AddLabeledEdge(edge);
                    }
                }
            }
            foreach (Statement st in stat.GetStats())
            {
                if (st == stat.GetFirst())
                {
                    LowContinueLabels(st, edges);
                }
                else
                {
                    LowContinueLabels(st, new HashSet <StatEdge>());
                }
            }
        }
Example #30
0
        public override Object Visit(DoStatement node, Object obj)
        {
            Object aux  = null;
            SSAMap map1 = this.map.Clone();

            this.map.SetScope();
            node.Statements.Accept(this, obj);
            this.addLocalVariable(this.map.ResetScope(), node.Statements);
            SSAMap map2 = this.map.Clone();

            if ((aux = node.Condition.Accept(this, false)) is SingleIdentifierExpression)
            {
                node.Condition = (SingleIdentifierExpression)aux;
            }
            // map3 = this.map

            List <MoveStatement> mvSt = map1.GetMoveStatements(this.map, node.Location.FileName, node.Location.Line);

            if (mvSt.Count != 0)
            {
                node.InitDo = mvSt;
            }

            List <ThetaStatement> thSt = map1.GetThetaStatements(ref this.map, node.Location.FileName, node.Statements.Location.Line);

            if (thSt.Count != 0)
            {
                node.BeforeBody = thSt;
            }

            SSAInfo info = new SSAInfo(this.map, null, map1, this.map);

            node.Statements.Accept(new VisitorSSA2(), info);

            info = new SSAInfo(this.map, null, map1, this.map);
            node.Condition.Accept(new VisitorSSA2(), info);

            return(null);
        }
 protected internal virtual void PostWalk(DoStatement node) { }
 // DoStatement
 protected internal virtual bool Walk(DoStatement node) { return true; }
        private void Process_Do_Statement(StringBuilder sb, DoStatement statement)
        {
            sb.Append("do");
            sb.Append(ProcessStatement(statement.Statement));

            sb.Append(Indent).Append("while(").Append(FormatExpression(statement.Expression)).Append(");");
        }
Example #34
0
    // Do the real work
    protected void ParseStatementOrLocal_Helper(out Statement s, out LocalVarDecl v)
    {   
        s = null;
        v = null;
        
        // For each statement, we know which type based off the first token.
        // Expect for an identifier, in which case it could be a few things.
        Token t = m_lexer.PeekNextToken();
        
        #if false
        // Skip past any ';' (as empty statements)
        while(t.TokenType == Token.Type.cSemi)
        {
            ConsumeNextToken();
            t = m_lexer.PeekNextToken();            
        }
        #endif
                       
        if (IsStartOfExp(t))
        {
            FileRange f = BeginRange();
            
            // This could be either an expression or a type
            Exp e = ParseExp();
            t = m_lexer.PeekNextToken();

            
            // Case 1 - Var declaration:
            // If an identifier follows, then we just read a type and this is
            // a var declaration:
            // Type id ';'
            // Type id '=' exp ';'
            if (t.TokenType == Token.Type.cId)
            {
                TypeSig tSig  = this.ConvertExpToType(e);

                Identifier id = ReadExpectedIdentifier();
                
                v = new LocalVarDecl(id, tSig);
                                
                // Check for optional assignment (if there's an '=' after the name)
                Token t3 = m_lexer.PeekNextToken();
                if (t3.TokenType == Token.Type.cAssign)
                {
                    ConsumeNextToken();                     // '='
                    Exp eRHS = ParseExp();                  // exp                
                    ReadExpectedToken(Token.Type.cSemi);    // ';'
                    
                    SimpleObjExp oleft = new SimpleObjExp(id);
                    StatementExp se = new AssignStmtExp(oleft, eRHS);
                    s = new ExpStatement(se);
                    
                    se.SetLocation(EndRange(f));
                } else {                
                    ReadExpectedToken(Token.Type.cSemi);    // ';'
                }


                
                return;
            } // end decl case

            // Case 2 - label declaration
            else if (t.TokenType == Token.Type.cColon)
            {                
                SimpleObjExp o2 = e as SimpleObjExp;
                if (o2 != null)
                {
                    ConsumeNextToken(); // ':'
                    s = new LabelStatement(o2.Name);
                    return; // skip reading a ';'
                } 
                
                ThrowError(new ParserErrorException(Code.cBadLabelDef, t.Location, 
                    "Bad label definition (labels must be a single identifier)"));                                
            } // end case for label decls
                        
            // Expect a StatementExp
            else if (t.TokenType == Token.Type.cSemi) {
                ReadExpectedToken(Token.Type.cSemi);
                
                // Else we must be a StatementExp
                StatementExp se = e as StatementExp;
                if (se == null)
                    //this.ThrowError_ExpectedStatementExp(e.Location);
                    ThrowError(E_ExpectedStatementExp(e.Location));
                
                se.SetLocation(EndRange(f));
                s = new ExpStatement(se);            
                return;
            }
    
            ThrowError(E_UnexpectedToken(t));
        } // end start of expressions
        
        switch(t.TokenType)
        {
        // Empty statement
        case Token.Type.cSemi:
            ConsumeNextToken();
            s = new EmptyStatement();
            break;

        // Return -> 'return' ';'
        //         | 'return' exp ';'
        case Token.Type.cReturn:
            {
                ConsumeNextToken();
                
                t = m_lexer.PeekNextToken();
                Exp e = null;
                if (t.TokenType != Token.Type.cSemi) 
                {
                    e = ParseExp();                    
                }
                ReadExpectedToken(Token.Type.cSemi);
        
                s = new ReturnStatement(e);                
            }        
            break;
            
        // Note that the semi colons are included inthe stmt            
        // IfSmt -> 'if' '(' exp ')' stmt:then 
        // IfSmt -> 'if' '(' exp ')' stmt:then 'else' stmt:else
        case Token.Type.cIf:
        {
            ConsumeNextToken(); // 'if'
            ReadExpectedToken(Token.Type.cLParen);
            Exp exp = ParseExp();            
            ReadExpectedToken(Token.Type.cRParen);
            
            Statement sThen = ParseStatement();
            Statement sElse = null;
            
            Token t2 = m_lexer.PeekNextToken();
            if (t2.TokenType == Token.Type.cElse) 
            {
                ConsumeNextToken(); // 'else'
                sElse = ParseStatement();                
            }
            
            s = new IfStatement(exp, sThen, sElse);        
        }
            break;
            
        case Token.Type.cSwitch:
            s = ParseSwitchStatement();
            break;            
        
        // Throw an expression
        // ThrowStmt -> 'throw' objexp    
        case Token.Type.cThrow:
        {
            ConsumeNextToken(); // 'throw'
            Exp oe = null;
            if (m_lexer.PeekNextToken().TokenType != Token.Type.cSemi)
            {
                oe = ParseExp();            
            }
            ReadExpectedToken(Token.Type.cSemi);
            
            s = new ThrowStatement(oe);
        }
            break;
        
        // try-catch-finally
        case Token.Type.cTry:
            s = ParseTryCatchFinallyStatement();
            break;
        
        // while loop
        // 'while' '(' exp ')' stmt            
        case Token.Type.cWhile:
        {
            ConsumeNextToken(); // 'while'
            ReadExpectedToken(Token.Type.cLParen);

            Exp e = ParseExp();

            ReadExpectedToken(Token.Type.cRParen);

            Statement body = ParseStatement();

            s = new WhileStatement(e, body);


        }
            break;

        // do loop
        // 'do' stmt 'while' '(' exp ')' ';'
        case Token.Type.cDo:
        {
            ConsumeNextToken(); // 'do'
            Statement body = ParseStatement();
            ReadExpectedToken(Token.Type.cWhile);

            ReadExpectedToken(Token.Type.cLParen);
            Exp e = ParseExp();
            ReadExpectedToken(Token.Type.cRParen);

            ReadExpectedToken(Token.Type.cSemi);

            s = new DoStatement(e, body);

        }
            break;

        // goto
        // 'goto' id:label ';'
        case Token.Type.cGoto:
        {
            ConsumeNextToken();                             // 'goto'
            Identifier id = ReadExpectedIdentifier();       // id:label
            ReadExpectedToken(Token.Type.cSemi);            // ';'

            s = new GotoStatement(id);
        }
            break;

        // break
        // 'break' ';'
        case Token.Type.cBreak:
            ConsumeNextToken();
            ReadExpectedToken(Token.Type.cSemi);
            s = new BreakStatement();
            break;

        // Continue
        // 'continue' ';'
        case Token.Type.cContinue:
            ConsumeNextToken();
            ReadExpectedToken(Token.Type.cSemi);
            s = new ContinueStatement();
            break;
            
        // For-loop            
        case Token.Type.cFor:
            s = ParseForStatement();
            break;

        // For-each
        // -> 'foreach' '(' Type id 'in' exp:collection ')' stmt
        case Token.Type.cForEach:
            s = ParseForeachStatement();
            break;
            
        // BlockStatement - can be nested inside each other
        // start with a  '{', no terminating semicolon
        case Token.Type.cLCurly:
            {
                s = ParseStatementBlock();                
            }
            break;
            
        default:
            ThrowError(E_UnexpectedToken(t)); // unrecognized statement
            break;
        
        } // end switch
        
        // Must have come up with something
        Debug.Assert(s != null || v != null);    
    }