Ejemplo n.º 1
0
 private void PrepareMainBlock()
 {
     RootBlock = new SimanticsBlock()
     {
         BlockType = SimanticsBlockType.BlockSequence,
         //IBody = Instructions.Values.ToList()
     };
 }
Ejemplo n.º 2
0
 private void ResetBlock(SimanticsBlock block)
 {
     block.VisitCount = 0;
     foreach (var sblock in block.Body)
     {
         ResetBlock(sblock);
     }
 }
Ejemplo n.º 3
0
        private void IdentifySequences()
        {
            //O(n) scan through instructions
            //keep track of a "start" instruction, initially the first instruction.
            //and build a list of instructions following it.
            //whenever the new instruction has more than one input (or yields), complete the sequence (minus new) and start a new one on this instruction
            //whenever the new instruction has more than one output, complete the sequence (including new) and start on the following
            var firstSequence = new SimanticsBlock()
            {
                BlockType             = SimanticsBlockType.InstructionSequence,
                Parent                = RootBlock,
                StartInstructionIndex = 0,
            };
            var toProcess = new Queue <Tuple <byte, SimanticsBlock> >();

            toProcess.Enqueue(new Tuple <byte, SimanticsBlock>(0, firstSequence));
            Instructions[0].VisitCount = 1;
            while (toProcess.Count > 0)
            {
                var process         = toProcess.Dequeue();
                var inst            = Instructions[process.Item1];
                var currentSequence = process.Item2;
                if (currentSequence != null && (inst.From.Count > 1 || inst.Yields))
                {
                    //something jumps back in here, likely a loop or yield.
                    if (currentSequence.IBody.Count > 0)
                    {
                        RootBlock.Body.Add(currentSequence);
                        currentSequence.LastInstructionIndex = currentSequence.IBody.Last().Index;
                        currentSequence = null;

                        /*
                         * currentSequence = new SimanticsBlock()
                         * {
                         *  BlockType = SimanticsBlockType.InstructionSequence,
                         *  Parent = RootBlock,
                         *  StartInstructionIndex = inst.Index,
                         * };
                         */
                    }
                }

                if (currentSequence == null)
                {
                    currentSequence = new SimanticsBlock()
                    {
                        BlockType             = SimanticsBlockType.InstructionSequence,
                        Parent                = RootBlock,
                        StartInstructionIndex = inst.Index,
                    };
                }
                currentSequence.IBody.Add(inst);
                var nextSequence = currentSequence;
                if (inst.To.Count > 1 || inst.ReturnType == PrimitiveReturnType.SimanticsSubroutine)
                {
                    RootBlock.Body.Add(currentSequence);
                    currentSequence.LastInstructionIndex = currentSequence.IBody.Last().Index;
                    nextSequence = null;
                }

                var hadDest = false;
                foreach (var dest in inst.To)
                {
                    if (dest != null && dest.VisitCount == 0)
                    {
                        toProcess.Enqueue(new Tuple <byte, SimanticsBlock>(dest.Index, nextSequence));
                        dest.VisitCount++;
                        hadDest = true;
                    }
                }
                if (!hadDest && nextSequence != null)
                {
                    RootBlock.Body.Add(currentSequence);
                    currentSequence.LastInstructionIndex = currentSequence.IBody.Last().Index;
                }
            }

            foreach (var sequence in RootBlock.Body)
            {
                var firstInst = sequence.IBody.First();
                var lastInst  = sequence.IBody.Last();

                sequence.FromBlocks = RootBlock.Body.Where(x => firstInst.From.Contains(x.IBody.Last())).ToList();

                sequence.NextBlocks = lastInst.To.Select(x => (x == null) ? null : RootBlock.Body.First(y => y.StartInstructionIndex == x.Index)).ToList();
            }
        }