Example #1
0
        private void ProcessSwitchStatement(ISwitchStatement pStatement)
        {
            //if (mCurrentBlock.Terminated) mCurrentBlock = CreateBlock(CreateLabel());

            HLLocation         locationCondition = ProcessExpression(pStatement.Expression);
            HLInstructionBlock blockParent       = mCurrentBlock;

            List <HLInstructionBlock> blocksStarts           = new List <HLInstructionBlock>();
            List <HLInstructionBlock> blocksEnds             = new List <HLInstructionBlock>();
            HLInstructionBlock        blockDefaultCase       = null;
            List <Tuple <HLLiteralLocation, HLLabel> > cases = new List <Tuple <HLLiteralLocation, HLLabel> >();

            foreach (ISwitchCase switchCase in pStatement.Cases)
            {
                HLInstructionBlock blockCase = CreateBlock(CreateLabel());
                mCurrentBlock = blockCase;
                blocksStarts.Add(blockCase);
                if (switchCase.IsDefault)
                {
                    blockDefaultCase = blockCase;
                }
                else
                {
                    HLLiteralLocation locationCase = (HLLiteralLocation)ProcessCompileTimeConstantExpression(switchCase.Expression);
                    cases.Add(new Tuple <HLLiteralLocation, HLLabel>(locationCase, blockCase.StartLabel));
                }
                foreach (IStatement statementCase in switchCase.Body)
                {
                    ProcessStatement(statementCase);
                }
                blocksEnds.Add(mCurrentBlock);
            }
            if (blockDefaultCase == null)
            {
                blockDefaultCase = CreateBlock(CreateLabel());
                mCurrentBlock    = blockDefaultCase;
                blocksStarts.Add(blockDefaultCase);
                blocksEnds.Add(blockDefaultCase);
            }

            blockParent.EmitSwitch(locationCondition, blockDefaultCase.StartLabel, cases);

            if (!blocksEnds.TrueForAll(b => b.Terminated))
            {
                mCurrentBlock = CreateBlock(CreateLabel());
                blocksEnds.ForEach(b => b.Terminate(mCurrentBlock.StartLabel));
            }
        }