Example #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="BlockchainParser" /> class.
        /// </summary>
        /// <param name="blockchainPath">
        /// The path to the folder containing the blockchain files.
        /// </param>
        /// <param name="firstBlockchainFileName">
        /// The name of the first blockchain file that should be processed from the series of blockchain files.
        /// In the list of blockchain files ordered by name, any blockchain file that appears prior
        /// to the file specified by this parameter will be ignored.
        /// If null then all file from the series of blockchain files will be processed.
        /// </param>
        /// </param name="nextNblockDataFiles">
        /// process the next N blockdata files. the default value is int.MaxValue.
        /// </param>
        /// <exception cref="InvalidBlockchainFilesException">
        /// Thrown when the list of Bitcoin blockchain files is found to be invalid.
        /// The blockchain folder must contain files named with the pattern "blkxxxxx.dat",
        //ader.BlockVersion != 0x30000007 &&
        //    //    blockHeader.BlockVersion != 0x20000004)
        //    //{
        //    //    throw new UnknownBlockVersionException(string.Format(CultureInfo.InvariantCulture, "Unknown block version: {0} ({0:X}).", blockHeader.BlockVersion));
        //    //}

        //    blockHeader.PreviousBlockHash = new ByteArray(blockMemoryStreamReader.ReadBytes(32).ReverseByteArray());
        //    blockHeader.MerkleRootHash = new ByteArray(blockMemoryStreamReader.ReadBytes(32).ReverseByteArray());

        //    blockHeader.BlockTimestampUnix = blockMemoryStreamReader.ReadUInt32();
        //    blockHeader.BlockTimestamp = new DateTime(1970, 1, 1).AddSeconds(blockHeader.BlockTimestampUnix);

        //    blockHeader.BlockTargetDifficulty = blockMemoryStreamReader.ReadUInt32();
        //    blockHeader.BlockNonce = blockMemoryStreamReader.ReadUInt32();

        //    int positionInBaseStreamAfterBlockHeaderEnd = (int)blockMemoryStreamReader.BaseStream.Position;

        //    using (SHA256Managed sha256 = new SHA256Managed())
        //    {
        //        //// We need to calculate the double SHA256 hash of this transaction.
        //        //// We need to access the buffer that contains the transaction that we jut read through.
        //        //// Here we take advantage of the fact that the entire block was loaded as an in-memory buffer.
        //        //// The base stream of blockMemoryStreamReader is that in-memory buffer.

        //        byte[] baseBuffer = blockMemoryStreamReader.GetBuffer();
        //        int blockHeaderBufferSize = positionInBaseStreamAfterBlockHeaderEnd - positionInBaseStreamAtBlockHeaderStart;

        //        if (blockHeaderBufferSize != ExpectedBlockHeaderBufferSize)
        //        {
        //            // We have a problem. The block header should be 80 bytes in size.
        //            throw new InvalidBlockchainContentException(string.Format(CultureInfo.InvariantCulture, "Block header buffer size has an invalid length: {0}. Expected: {1}.", blockHeaderBufferSize, ExpectedBlockHeaderBufferSize));
        //        }

        //        byte[] hash1 = sha256.ComputeHash(baseBuffer, positionInBaseStreamAtBlockHeaderStart, blockHeaderBufferSize);
        //        blockHeader.BlockHash = new ByteArray(sha256.ComputeHash(hash1).ReverseByteArray());
        //    }

        //    return blockHeader;
        //}

        /// <summary>
        /// Parses a Bitcoin transaction input.
        /// </summary>
        /// <param name="blockMemoryStreamReader">
        /// Provides access to a section of the Bitcoin blockchain file.
        /// </param>
        /// <returns>
        /// The Bitcoin transaction input that was parsed.
        /// </returns>
        //private static TransactionInput ParseTransactionInput(BlockMemoryStreamReader blockMemoryStreamReader)
        //{
        //    TransactionInput transactionInput = new TransactionInput();

        //    transactionInput.SourceTransactionHash = new ByteArray(blockMemoryStreamReader.ReadBytes(32).ReverseByteArray());
        //    transactionInput.SourceTransactionOutputIndex = blockMemoryStreamReader.ReadUInt32();

        //    int scriptLength = (int)blockMemoryStreamReader.ReadVariableLengthInteger();

        //    // Ignore the script portion.
        //    transactionInput.InputScript = new ByteArray(blockMemoryStreamReader.ReadBytes(scriptLength));

        //    // Ignore the sequence number.
        //    blockMemoryStreamReader.SkipBytes(4);

        //    return transactionInput;
        //}

        /// <summary>
        /// Parses a Bitcoin transaction output.
        /// </summary>
        /// <param name="blockMemoryStreamReader">
        /// Provides access to a section of the Bitcoin blockchain file.
        /// </param>
        /// <returns>
        /// The Bitcoin transaction output that was parsed.
        /// </returns>
        //private static TransactionOutput ParseTransactionOutput(BlockMemoryStreamReader blockMemoryStreamReader)
        //{
        //    TransactionOutput transactionOutput = new TransactionOutput();

        //    transactionOutput.OutputValueSatoshi = blockMemoryStreamReader.ReadUInt64();
        //    int scriptLength = (int)blockMemoryStreamReader.ReadVariableLengthInteger();
        //    transactionOutput.OutputScript = new ByteArray(blockMemoryStreamReader.ReadBytes(scriptLength));

        //    return transactionOutput;
        //}

        /// <summary>
        /// Parses a Bitcoin transaction.
        /// </summary>
        /// <param name="blockMemoryStreamReader">
        /// Provides access to a section of the Bitcoin blockchain file.
        /// </param>
        /// <returns>
        /// The Bitcoin transaction that was parsed.
        /// </returns>
        //private static Transaction ParseTransaction(BlockMemoryStreamReader blockMemoryStreamReader)
        //{
        //    Transaction transaction = new Transaction();

        //    int positionInBaseStreamAtTransactionStart = (int)blockMemoryStreamReader.BaseStream.Position;

        //    transaction.TransactionVersion = blockMemoryStreamReader.ReadUInt32();

        //    int inputsCount = (int)blockMemoryStreamReader.ReadVariableLengthInteger();

        //    for (int inputIndex = 0; inputIndex < inputsCount; inputIndex++)
        //    {
        //        TransactionInput transactionInput = BlockchainParser.ParseTransactionInput(blockMemoryStreamReader);
        //        transaction.AddInput(transactionInput);
        //    }

        //    int outputsCount = (int)blockMemoryStreamReader.ReadVariableLengthInteger();

        //    for (int outputIndex = 0; outputIndex < outputsCount; outputIndex++)
        //    {
        //        TransactionOutput transactionOutput = BlockchainParser.ParseTransactionOutput(blockMemoryStreamReader);
        //        transaction.AddOutput(transactionOutput);
        //    }

        //    // TODO: Need to find out more details about the semantic of TransactionLockTime.
        //    transaction.TransactionLockTime = blockMemoryStreamReader.ReadUInt32();

        //    int positionInBaseStreamAfterTransactionEnd = (int)blockMemoryStreamReader.BaseStream.Position;

        //    using (SHA256Managed sha256 = new SHA256Managed())
        //    {
        //        //// We need to calculate the double SHA256 hash of this transaction.
        //        //// We need to access the buffer that contains the transaction that we jut read through.
        //        //// Here we take advantage of the fact that the entire block was loaded as an in-memory buffer.
        //        //// The base stream of blockMemoryStreamReader is that in-memory buffer.

        //        byte[] baseBuffer = blockMemoryStreamReader.GetBuffer();
        //        int transactionBufferSize = positionInBaseStreamAfterTransactionEnd - positionInBaseStreamAtTransactionStart;

        //        byte[] hash1 = sha256.ComputeHash(baseBuffer, positionInBaseStreamAtTransactionStart, transactionBufferSize);
        //        transaction.TransactionHash = new ByteArray(sha256.ComputeHash(hash1).ReverseByteArray());
        //    }

        //    return transaction;
        //}

        /// <summary>
        /// Parses one Bitcoin block except for a few fields before the actual block header.
        /// </summary>
        /// <param name="blockchainFileName">
        /// The name of the blockchain file that contains the block being parsed.
        /// </param>
        /// <param name="blockMemoryStreamReader">
        /// Provides access to a section of the Bitcoin blockchain file.
        /// </param>
        private static ParserBlock InternalParseBlockchainFile(byte[] blockBuffer,
                                                               string blockchainFileName, BlockMemoryStreamReader blockMemoryStreamReader)
        {
            Block       nblk  = ParserBlock.Load(blockBuffer, NBitcoin.Network.Main);
            ParserBlock block = new ParserBlock(nblk, blockBuffer.Length, blockchainFileName);

            //BlockHeader blockHeader = BlockchainParser.ParseBlockHeader(blockMemoryStreamReader);
            //Block block = new Block(blockBuffer, blockchainFileName, blockHeader);
            //if (block.BlockHeader.BlockVersion < 0x20000002)
            //{

            //int blockTransactionCount = (int)blockMemoryStreamReader.ReadVariableLengthInteger();
            //    for (int transactionIndex = 0; transactionIndex < blockTransactionCount; transactionIndex++)
            //    {
            //        Transaction transaction = BlockchainParser.ParseTransaction(blockMemoryStreamReader);
            //        block.AddTransaction(transaction);
            //    }
            //}
            //else
            //{
            //NBitcoin.Block nblock = NBitcoin.Block.Load(blockBuffer, NBitcoin.Network.Main);
            //foreach(NBitcoin.Transaction ntx in nblock.Transactions)
            //{
            //    //block.AddTransaction()
            //}
            //}
            //NBitcoin.Block nblock = NBitcoin.Block.Load(blockBuffer, NBitcoin.Network.Main);
            return(block);
        }
 //g.获取创世区块
 public ParserBlock get_GenesisBlock(bool displayMark)
 {
     if (Directory.Exists(blockchainFilePath))
     {
         Console.WriteLine("正在获取创世区块.........");
         string blockfileName  = get_filename(0);
         string blockchainFile = Path.Combine(blockchainFilePath, blockfileName);
         if (File.Exists(blockchainFile))
         {
             IBlockchainParser  blockFileParser        = new BlockchainParser(blockchainFilePath, blockfileName, 1);
             List <ParserBlock> blocksOfFirstBlockFile = blockFileParser.ParseBlockchain().ToList();
             ParserBlock        genesisBlock           = blocksOfFirstBlockFile[0];
             if (displayMark)
             {
                 Console.WriteLine("创世区块前一个区块hash:" + genesisBlock.Header.HashPrevBlock);
                 Console.WriteLine("创世区块time:" + genesisBlock.Header.BlockTime);
                 Console.WriteLine("创世区块hash:" + genesisBlock.Header.GetHash());
                 Console.WriteLine("**********************************************************");
             }
             return(genesisBlock);
         }
         else
         {
             Console.WriteLine("区块文件:" + blockchainFile + " 不存在!!!");
             return(null);
         }
     }
     else
     {
         Console.WriteLine("区块链文件路径不存在!!!");
         return(null);
     }
 }
Example #3
0
        private void Restore(StateForCompiler state, ParserBlock block,
                             BlockLocal oldLeftHandSide,
                             BlockLocal oldPrecedenceCanEqualCurrent,
                             BlockLocal oldRecursionExclude)
        {
            block.LoadState();
            block.LoadLocal(oldRecursionExclude);
            block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));

            BlockLabel nullLabel = new BlockLabel("null");

            block.LoadLocal(oldRecursionExclude);
            block.LoadNull();
            block.BranchIfEqual(nullLabel);

            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
            block.LoadLocal(oldRecursionExclude);
            block.Call(typeof(Multiset <Pattern>).GetMethod("Add"));

            block.MarkLabel(nullLabel);

            if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
            {
                block.LoadState();
                block.LoadLocal(oldPrecedenceCanEqualCurrent);
                block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
            }
            else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
            {
                block.LoadState();
                block.LoadLocal(oldLeftHandSide);
                block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
            }
        }
        //e.从区块队列池中取出一个区块
        public ParserBlock dequeue_FromBlockQueuePooling()
        {
            ParserBlock dequeueBlock = null;

            if (blockQueuePooling.Count != 0)
            {
                dequeueBlock = blockQueuePooling.Dequeue();
                lastProcessedBlockElement = dequeueBlock;
                for (int i = 0; i < blockReadPointer; i++)
                {
                    if (blockReadBlocksFromFile[i] != null)
                    {
                        if (blockReadBlocksFromFile[i].Header.GetHash() == dequeueBlock.Header.GetHash())
                        {
                            blockReadBlocksFromFile[i] = null;
                            return(dequeueBlock);
                        }
                    }
                }
                for (int j = blockReadPointer; j < blockReadBlocksFromFile.Count; j++)
                {
                    if (blockReadBlocksFromFile[j] != null)
                    {
                        if (blockReadBlocksFromFile[j].Header.GetHash() == dequeueBlock.Header.GetHash())
                        {
                            blockReadBlocksFromFile[j] = null;
                            return(dequeueBlock);
                        }
                    }
                }
            }
            return(dequeueBlock);
        }
Example #5
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of token --------------------");

            // todo enter

            block.BeginScope();

            BlockLocal start = block.SavePosition();

            block.Emit(body.Compile(runtime, state));

            BlockLocal bodyTree = new BlockLocal(typeof(ParseTree));

            block.DeclareLocal(bodyTree);
            block.Dup();
            block.StoreLocal(bodyTree);

            BlockLabel yes = new BlockLabel("yes");

            block.BranchIfNotNo(yes);

            // todo no

            block.LoadNo();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Branch(returnLabel);

            block.MarkLabel(yes);

            // todo yes

            block.LoadLexer();
            block.GetProperty(typeof(Lexer).GetProperty("Text"));
            block.LoadLocal(start);
            block.LoadLexer();
            block.GetProperty(typeof(Lexer).GetProperty("Position"));
            block.LoadLocal(start);
            block.Sub();
            block.Call(typeof(string).GetMethod("Substring", new Type[] { typeof(int), typeof(int) }));
            block.New(typeof(ParseTree).GetConstructor(new Type[] { typeof(object) }));

            block.LoadLocal(bodyTree);
            block.Call(typeof(ParseTree).GetMethod("ExtendFields"));

            block.MarkLabel(returnLabel);

            block.EndScope();

            block.Comment("end of token --------------------");

            return(block);
        }
        //d.向区块队列池中补充区块
        public bool enqueue_ToBlockQueuePooling()
        {
            int invalidBlockCount = 0;
            Queue <ParserBlock> tempBlockQueuePooling = new Queue <ParserBlock>();
            ParserBlock         priorBlock            = blockQueueTailElement;
            ParserBlock         tailBlock;

            while (blockQueuePooling.Count < blockQueuePoolingSize)
            {
                if (search_NextBlock_FromBlockPooling(priorBlock, out tailBlock))
                {
                    blockQueuePooling.Enqueue(tailBlock);
                    priorBlock = tailBlock;
                }
                else
                {
                    if (missingBlockFile)
                    {
                        Console.WriteLine("区块文件全部加载,找不到下一个区块文件,将处理结束!!!");
                        return(false);
                    }
                    else
                    {
                        invalidBlockCount++;
                        tempBlockQueuePooling.Clear();
                        for (int i = 0; i < blockQueuePooling.Count - 1; i++)
                        {
                            tempBlockQueuePooling.Enqueue(blockQueuePooling.Dequeue());
                        }
                        forkedBlockList.Add(blockQueuePooling.Dequeue().Header.GetHash().ToString());//向分叉块列表中添加分叉上的块
                        Console.WriteLine("出现分叉上的块,正在收集分叉上的块!!!");
                        blockQueuePooling.Clear();
                        for (int j = 0; j < tempBlockQueuePooling.Count; j++)
                        {
                            ParserBlock dequeueBlock = tempBlockQueuePooling.Dequeue();
                            blockQueuePooling.Enqueue(dequeueBlock);
                            if (j == tempBlockQueuePooling.Count - 1)
                            {
                                priorBlock = dequeueBlock;
                            }
                        }
                    }
                }
                if (blockQueuePooling.Count == blockQueuePoolingSize)
                {
                    blockQueueTailElement = tailBlock;
                }
                if (blockQueuePooling.Count == 0)
                {
                    return(false);
                }
            }
            return(true);
        }
Example #7
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Load(this);
            block.LoadLexer();
            block.LoadState();
            block.Call(typeof(UserDefinedNode).GetMethod("Parse"));

            return(block);
        }
Example #8
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of any --------------------");

            BlockLabel returnLabel = new BlockLabel("return");

            // todo enter

            block.BeginScope();

            block.LoadLexer();
            block.Call(typeof(Lexer).GetMethod("Peek", new Type[] {}));

            BlockLabel failed = new BlockLabel("failed");

            block.BranchIfFalse(failed);

            block.LoadLexer();
            block.Call(typeof(Lexer).GetMethod("Read"));

            // todo yes

            if (state.BuildTextNodes)
            {
                block.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(char) }));
                block.New(typeof(ParseTree).GetConstructor(new Type[] { typeof(object) }));
            }
            else
            {
                block.Pop();
                block.LoadYes();
            }

            block.Branch(returnLabel);

            block.MarkLabel(failed);

            // todo no

            block.LoadNo();

            block.MarkLabel(returnLabel);

            block.EndScope();

            block.Comment("end of any --------------------");

            return(block);
        }
        //I.获取下一个区块
        public ParserBlock getNextBlock()
        {
            ParserBlock nextBlock = dequeue_FromBlockQueuePooling();

            processedBlockAmount++;
            if (!enqueue_ToBlockQueuePooling())
            {
                if (missingBlockFile)
                {
                    Console.WriteLine("本次请求区块已返回,但没有充足的区块文件补区块池。区块队列无法中添加下一个区块!!!");
                }
            }
            return(nextBlock);
        }
Example #10
0
        /// <summary>
        /// Parses one Bitcoin blockchain file.
        /// </summary>
        /// <param name="blockchainFile">
        /// Contains information about and provides access to the Bitcoin blockchain file that needs to be parsed.
        /// </param>
        /// <returns>
        /// An IEnumerable containing instances of class <see cref="Block"/> each storing data about one Bitcoin block.
        /// </returns>
        private IEnumerable <Block> ParseBlockchainFile(BlockchainFile blockchainFile)
        {
            BinaryReader binaryReader = blockchainFile.BinaryReader;

            while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length)
            {
                ParserBlock block = this.ParseBlockchainFile(blockchainFile.FileName, binaryReader);
                if (block != null)
                {
                    block.PercentageOfCurrentBlockchainFile = (int)(100 * binaryReader.BaseStream.Position / binaryReader.BaseStream.Length);
                    yield return(block);
                }
            }
        }
Example #11
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of fail --------------------");

            // todo no

            block.LoadNo();

            block.Comment("end of fail --------------------");

            return(block);
        }
Example #12
0
        public PatternTrampoline(Pattern pattern, Runtime runtime,
                                 StateForCompiler state)
        {
            this.pattern = pattern;
            this.runtime = runtime;
            this.state   = state;

            callBlock = new ParserBlock();
            callBlock.Comment("start of call to " + pattern.Type.Name + " -------------");
            callBlock.Load(this);
            callBlock.GetProperty(typeof(PatternTrampoline).GetProperty("Implementation"));
            callBlock.LoadLexer();
            callBlock.LoadState();
            callBlock.Call(typeof(ParseDelegate).GetMethod("Invoke"));
            callBlock.Comment("end of call to " + pattern.Type.Name + " -------------");
        }
 //d.执行一个区块的交易
 public void execute_TransactionsOfOneBlock(ParserBlock block)
 {
     foreach (Transaction transaction in block.Transactions)
     {
         if (transaction.IsCoinBase)
         {
             execute_CoinbaseTransaction(transaction);
         }
         else
         {
             if (isValidTransaction(transaction))
             {
                 execute_RegularTransaction(transaction);
             }
         }
     }
 }
Example #14
0
        public ParseDelegate CompileImplementation(Runtime runtime,
                                                   StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Emit(CompileNew(runtime, state));
            block.Return();

            DynamicMethod implementation = new DynamicMethod(
                "parse" + type.Name,
                typeof(ParseTree),
                new Type[] { typeof(Lexer), typeof(ParserState) },
                runtime.CompilerModule.ModuleBuilder);

            block.Build(new DynamicMethodProxy(implementation));

            return((ParseDelegate)implementation.CreateDelegate(typeof(ParseDelegate)));
        }
Example #15
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of label --------------------");

            BlockLabel returnLabel = new BlockLabel("returnLabel");

            block.Emit(body.Compile(runtime, state));

            block.Dup();
            block.BranchIfNo(returnLabel);

            block.BeginScope();

            BlockLocal bodyTree = new BlockLocal(typeof(ParseTree));

            block.DeclareLocal(bodyTree);
            block.StoreLocal(bodyTree);

            block.NewParseTree();

            block.LoadLocal(bodyTree);
            block.Call(typeof(ParseTree).GetMethod("ExtendFields"));

            block.Dup();
            block.GetProperty(typeof(ParseTree).GetProperty("Fields"));

            block.Load(label);

            block.LoadLocal(bodyTree);
            block.GetProperty(typeof(ParseTree).GetProperty("Value"));

            block.SetProperty(typeof(Dictionary <string, object>).GetProperty("Item"));

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of label --------------------");

            return(block);
        }
        //主要使用
        public OrderedBitcoinBlockchainParser_Class(string blockchainFilePath, string blockProcessContextFilePath,
                                                    string blockProcessContextFileName = null, int blockQueuePoolingSize = 10)
        {
            this.blockchainFilePath          = blockchainFilePath;
            this.blockProcessContextFilePath = blockProcessContextFilePath;
            this.blockProcessContextFileName = blockProcessContextFileName;
            this.blockQueuePoolingSize       = blockQueuePoolingSize;

            if (blockProcessContextFileName == null)
            {
                ParserBlock genesisBlock = get_GenesisBlock(true);
                initialize_BlockQueuePooling(genesisBlock);
                recentlySliceDateTime = genesisBlock.Header.BlockTime.DateTime;
            }
            else
            { //从中断处恢复
                restore_BlockProcessContextForProgram();
            }
        }
Example #17
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of and --------------------");

            BlockLabel returnLabel = new BlockLabel("return");

            block.BeginScope();

            BlockLocal start = block.SavePosition();

            // todo enter

            block.Emit(body.Compile(runtime, state));

            BlockLabel yes = new BlockLabel("yes");

            block.BranchIfNotNo(yes);

            // todo no

            block.LoadNo();
            block.Branch(returnLabel);

            block.MarkLabel(yes);

            // todo yes

            block.RestorePosition(start);
            block.LoadYes();

            block.MarkLabel(returnLabel);

            block.EndScope();

            block.Comment("end of and --------------------");

            return(block);
        }
        //f.初始化区块队列池
        public void initialize_BlockQueuePooling(ParserBlock firstBlock)
        {
            ParserBlock priorBlock = firstBlock;
            ParserBlock nextBlock;

            blockQueuePooling.Enqueue(priorBlock);
            for (int i = 0; i < blockQueuePoolingSize - 1; i++)
            {
                if (search_NextBlock_FromBlockPooling(priorBlock, out nextBlock))
                {
                    blockQueuePooling.Enqueue(nextBlock);
                    if (i == blockQueuePoolingSize - 2)
                    {
                        blockQueueTailElement = nextBlock;
                    }
                    priorBlock = nextBlock;
                }
                else
                {
                    Console.WriteLine("已经找到" + i + 1 + "个区块,无法找到下一个区块");
                }
            }
        }
Example #19
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);

            block.Comment("start of pattern --------------------");

            if (simple)
            {
                block.Emit(pattern.CompileCall(runtime, state));
            }
            else
            {
                BlockLabel returnLabel = new BlockLabel("return");

                block.BeginScope();

                BlockLocal patternLocal = new BlockLocal(typeof(Pattern));
                block.DeclareLocal(patternLocal);
                block.Load(pattern);
                block.StoreLocal(patternLocal);

                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide"));

                BlockLabel parseNew = new BlockLabel("parseNew");
                block.BranchIfNull(parseNew);

                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                block.GetProperty(typeof(ParseTree).GetProperty("Value"));
                block.Call(typeof(object).GetMethod("GetType"));
                BlockLocal leftType = new BlockLocal(typeof(Type));
                block.DeclareLocal(leftType);
                block.Dup();
                block.StoreLocal(leftType);

                block.LoadLocal(patternLocal);
                block.GetProperty(typeof(Pattern).GetProperty("Type"));
                BlockLocal patternType = new BlockLocal(typeof(Type));
                block.DeclareLocal(patternType);
                block.Dup();
                block.StoreLocal(patternType);

                BlockLabel recurse = new BlockLabel("recurse");
                block.BranchIfEqual(recurse);

                block.LoadLocal(leftType);
                block.LoadLocal(patternType);
                block.Call(typeof(Type).GetMethod("IsSubclassOf"));

                block.BranchIfTrue(recurse);

                block.Branch(parseNew);

                block.MarkLabel(recurse);

                block.Single("left hand side from recursion");

                block.LoadLexer();
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSideEndPos"));
                block.SetProperty(typeof(Lexer).GetProperty("Position"));

                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide"));

                block.Branch(returnLabel);

                block.MarkLabel(parseNew);

                block.Emit(pattern.CompileCall(runtime, state));

                block.MarkLabel(returnLabel);

                block.EndScope();
            }

            block.Comment("end of pattern ---------------------");

            return(block);
        }
 //c.从区块池中查找下一个区块
 public bool search_NextBlock_FromBlockPooling(ParserBlock priorBlock, out ParserBlock nextBlock)
 {
     if (priorBlock != null)
     {
         for (int i = blockReadPointer; i < blockReadBlocksFromFile.Count; i++)
         {
             if (blockReadBlocksFromFile[i] != null)
             {
                 if (priorBlock.Header.GetHash() == blockReadBlocksFromFile[i].Header.HashPrevBlock)
                 {
                     if (!forkedBlockList.Contains(blockReadBlocksFromFile[i].Header.GetHash().ToString()))     //排除分叉块
                     {
                         if (!orphanBlockList.Contains(blockReadBlocksFromFile[i].Header.GetHash().ToString())) //排除孤块
                         {
                             nextBlock        = blockReadBlocksFromFile[i];
                             blockReadPointer = i;
                             return(true);
                         }
                     }
                 }
             }
         }
         if (blockReadPointer != 0)
         {
             for (int j = blockReadPointer - 1; j > 0; j--)
             {
                 if (blockReadBlocksFromFile[j] != null)
                 {
                     if (priorBlock.Header.GetHash() == blockReadBlocksFromFile[j].Header.HashPrevBlock)
                     {
                         if (!forkedBlockList.Contains(blockReadBlocksFromFile[j].Header.GetHash().ToString()))
                         {
                             if (!orphanBlockList.Contains(blockReadBlocksFromFile[j].Header.GetHash().ToString()))
                             {
                                 nextBlock        = blockReadBlocksFromFile[j];
                                 blockReadPointer = j;
                                 return(true);
                             }
                         }
                     }
                 }
             }
         }
         int oldBlockReadPointer = blockReadPointer;
         for (int m = 0; m < newlyLoadFileAmountCeiling; m++)
         {
             blockReadPointer = blockReadBlocksFromFile.Count;
             int oldAmount = blockReadBlocksFromFile.Count;
             load_NextFile_ToBlockPooling();
             if (blockReadBlocksFromFile.Count > oldAmount)
             {
                 for (int k = blockReadPointer; k < blockReadBlocksFromFile.Count; k++)
                 {
                     if (blockReadBlocksFromFile[k] != null)
                     {
                         if (priorBlock.Header.GetHash() == blockReadBlocksFromFile[k].Header.HashPrevBlock)
                         {
                             if (!forkedBlockList.Contains(blockReadBlocksFromFile[k].Header.GetHash().ToString()))
                             {
                                 if (!orphanBlockList.Contains(blockReadBlocksFromFile[k].Header.GetHash().ToString()))
                                 {
                                     nextBlock        = blockReadBlocksFromFile[k];
                                     blockReadPointer = k;
                                     return(true);
                                 }
                             }
                         }
                     }
                 }
             }
         }
         blockReadPointer = oldBlockReadPointer;
         nextBlock        = null;
         return(false);
     }
     else
     {
         Console.WriteLine("查找下一个区块时,前一个区块不能为空!!!");
         nextBlock = null;
         return(false);
     }
 }
Example #21
0
        public override Block CompileNew(Runtime runtime, StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);

            block.Comment("start of abstract pattern -------------");

            BlockLabel returnLabel = new BlockLabel("return");

            block.Enter(this, Type.Name);

            block.BeginScope();

            BlockLocal start = block.SavePosition();

            BlockLabel notExcluded = new BlockLabel("notExcluded");

            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
            block.Load(this);
            block.Call(typeof(Multiset <Pattern>).GetMethod("Contains"));
            block.BranchIfFalse(notExcluded);

            block.No(this);

            block.LoadNo();
            block.Branch(returnLabel);

            block.MarkLabel(notExcluded);

            BlockLocal oldCurrentPrecedence = new BlockLocal(typeof(Precedence));

            block.DeclareLocal(oldCurrentPrecedence);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
            block.StoreLocal(oldCurrentPrecedence);

            BlockLabel doesntOverwrite = new BlockLabel("doesntOverwrite");

            block.Load(Precedence);
            block.LoadLocal(oldCurrentPrecedence);
            block.Call(typeof(Precedence).GetMethod("Overwrites"));
            block.BranchIfFalse(doesntOverwrite);

            block.LoadState();
            block.Load(Precedence);
            block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));

            block.MarkLabel(doesntOverwrite);

            block.Emit(ParseGraph.Compile(runtime, state));

            block.LoadState();
            block.LoadLocal(oldCurrentPrecedence);
            block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));

            block.Dup();

            BlockLabel yes = new BlockLabel("yes");

            block.BranchIfNotNo(yes);

            block.No(this, start);

            block.Branch(returnLabel);

            block.MarkLabel(yes);

            block.Yes(this, start);

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of abstract pattern -------------");

            return(block);
        }
Example #22
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);

            block.Comment("start of text --------------------");

            block.Enter(this, TextEscape.Quote(text));

            block.BeginScope();

            block.Whitespace(runtime, state);
            BlockLocal start = block.SavePosition();

            BlockLocal n = new BlockLocal(typeof(int));

            block.DeclareLocal(n);

            BlockLabel reitterate = new BlockLabel("reitterate");

            block.MarkLabel(reitterate);

            block.Comment("itteration");

            BlockLocal character = new BlockLocal(typeof(char));

            block.DeclareLocal(character);

            block.LoadLexer();
            block.LoadLocal(n);
            block.Call(typeof(Lexer).GetMethod("Peek",
                                               new Type[] { typeof(int) }));

            block.Dup();
            block.StoreLocal(character);

            block.Load(text);
            block.LoadLocal(n);
            block.GetProperty(typeof(string).GetProperty("Chars"));

            BlockLabel matched = new BlockLabel("matched");

            block.BranchIfEqual(matched);

            block.Comment("handle the failure");

            // todo error string

            // todo specifics
            block.No(this, start);

            block.LoadNo();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Branch(returnLabel);

            block.MarkLabel(matched);

            block.Comment("increment and check the loop variable");

            block.LoadLocal(n);
            block.Increment();
            block.Dup();

            block.StoreLocal(n);

            block.Load(text.Length);
            block.BranchIfLess(reitterate);

            block.Comment("skip over the text");

            block.LoadLexer();
            block.Load(text.Length);
            block.Call(typeof(Lexer).GetMethod("Skip"));

            // todo specifics
            block.Yes(this, start);

            block.Comment("create the parse tree");

            if (state.BuildTextNodes)
            {
                block.Load(text);
                block.New(typeof(ParseTree).GetConstructor(
                              new Type[] { typeof(object) }));
            }
            else
            {
                block.LoadYes();
            }

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of text --------------------");

            return(block);
        }
Example #23
0
 /// <summary>
 /// Initializes a new instance of the <see cref="BlockProcessedEventArgs" /> class.
 /// </summary>
 /// <param name="block">
 /// Contains data describing the block that was processed.
 /// </param>
 public BlockProcessedEventArgs(ParserBlock block)
 {
     this.Block = block;
 }
Example #24
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of options --------------------");

            // todo enter

            block.BeginScope();

            block.Comment("save");

            // todo can remove this when no longer mixing jit and aot
            BlockLocal oldBuildTextNodes = null;

            BlockLocal oldWhitespace                = null;
            BlockLocal excludeLocal                 = null;
            BlockLocal oldCurrentPrecedence         = null;
            BlockLocal oldPrecedenceCanEqualCurrent = null;

            if (buildTextNodes.HasValue)
            {
                oldBuildTextNodes = new BlockLocal(typeof(bool));
                block.DeclareLocal(oldBuildTextNodes);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("BuildTextNodes"));
                block.StoreLocal(oldBuildTextNodes);

                block.LoadState();
                block.Load(buildTextNodes.Value);
                block.SetProperty(typeof(ParserState).GetProperty("BuildTextNodes"));
            }

            if (whitespace.HasValue)
            {
                block.Whitespace(runtime, state);

                oldWhitespace = new BlockLocal(typeof(Pattern));
                block.DeclareLocal(oldWhitespace);

                block.LoadLexer();
                block.GetProperty(typeof(Lexer).GetProperty("WhitespacePattern"));
                block.StoreLocal(oldWhitespace);

                block.LoadLexer();
                block.Load(whitespace.Value);
                block.SetProperty(typeof(Lexer).GetProperty("WhitespacePattern"));
            }

            if (exclude.HasValue)
            {
                if (exclude.Value == null)
                {
                    throw new Exception();
                }

                excludeLocal = new BlockLocal(typeof(Pattern));
                block.DeclareLocal(excludeLocal);
                block.Load(exclude.Value);
                block.StoreLocal(excludeLocal);

                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                block.LoadLocal(excludeLocal);
                block.Call(typeof(Multiset <Pattern>).GetMethod("Add"));
            }

            if (dropPrecedence.HasValue && dropPrecedence.Value)
            {
                oldCurrentPrecedence = new BlockLocal(typeof(Precedence));
                block.DeclareLocal(oldCurrentPrecedence);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
                block.StoreLocal(oldCurrentPrecedence);

                block.LoadState();
                block.LoadNull();
                block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));

                oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool));
                block.DeclareLocal(oldPrecedenceCanEqualCurrent);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                block.StoreLocal(oldPrecedenceCanEqualCurrent);

                block.LoadState();
                block.Load(false);
                block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
            }

            bool    oldBuildTextNodesState = state.BuildTextNodes;
            Pattern oldWhitespaceState     = state.Whitespace;

            if (buildTextNodes.HasValue)
            {
                state.BuildTextNodes = buildTextNodes.Value;
            }

            if (whitespace.HasValue)
            {
                state.Whitespace = whitespace.Value;
            }

            block.Emit(body.Compile(runtime, state));

            state.BuildTextNodes = oldBuildTextNodesState;
            state.Whitespace     = oldWhitespaceState;

            block.Comment("restore");

            if (buildTextNodes.HasValue)
            {
                block.LoadState();
                block.LoadLocal(oldBuildTextNodes);
                block.SetProperty(typeof(ParserState).GetProperty("BuildTextNodes"));
            }

            if (whitespace.HasValue)
            {
                block.LoadLexer();
                block.LoadLocal(oldWhitespace);
                block.SetProperty(typeof(Lexer).GetProperty("WhitespacePattern"));
            }

            if (exclude.HasValue)
            {
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                block.LoadLocal(excludeLocal);
                block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) }));
            }

            if (dropPrecedence.HasValue && dropPrecedence.Value)
            {
                block.LoadState();
                block.LoadLocal(oldCurrentPrecedence);
                block.SetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));

                block.LoadState();
                block.LoadLocal(oldPrecedenceCanEqualCurrent);
                block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
            }

            // todo yes or no

            block.Comment("end of options --------------------");

            block.EndScope();

            return(block);
        }
Example #25
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("start of rep " + reps.Name + " --------------------");

            // todo enter

            block.BeginScope();

            BlockLabel returnLabel = new BlockLabel("return");

            BlockLocal start = block.SavePosition();

            block.NewParseTree();

            BlockLabel reiterate = null;
            BlockLocal matched   = null;

            if (!reps.MaximumOfOne)
            {
                reiterate = new BlockLabel("reiterate");
                block.MarkLabel(reiterate);

                matched = new BlockLocal(typeof(bool));
                block.DeclareLocal(matched);
            }

            BlockLabel breakLabel = new BlockLabel("break");

            block.Emit(body.Compile(runtime, state));

            BlockLabel yes = new BlockLabel("yes");

            block.Dup();
            block.BranchIfNotNo(yes);

            block.Pop();

            block.Branch(breakLabel);

            block.MarkLabel(yes);

            block.Call(typeof(ParseTree).GetMethod("Extend"));

            if (!reps.MaximumOfOne)
            {
                block.Load(true);
                block.StoreLocal(matched);

                block.Branch(reiterate);
            }

            block.MarkLabel(breakLabel);

            if (reps.Minimum > 0)
            {
                BlockLabel enough = new BlockLabel("enough");
                block.LoadLocal(matched);
                block.BranchIfTrue(enough);

                // todo no

                block.RestorePosition(start);

                block.Pop();
                block.LoadNo();

                block.Branch(returnLabel);

                block.MarkLabel(enough);
            }

            // todo yes

            block.MarkLabel(returnLabel);

            block.EndScope();

            block.Comment("end of rep --------------------");

            return(block);
        }
Example #26
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);

            block.Comment("start of char --------------------");

            block.BeginScope();

            block.Whitespace(runtime, state);

            BlockLocal start = block.SavePosition();

            block.Enter(this, range.ToString());

            block.LoadLexer();
            block.Call(typeof(Lexer).GetMethod("Peek", new Type[] {}));

            BlockLabel failed = new BlockLabel("failed");

            BlockLocal character = null;

            if (range.Min == range.Max)
            {
                if (runtime.TraceParser)
                {
                    block.Dup();

                    character = new BlockLocal(typeof(char));
                    block.DeclareLocal(character);
                    block.StoreLocal(character);
                }

                block.Load(range.Min);
                block.BranchIfNotEqual(failed);
            }
            else
            {
                character = new BlockLocal(typeof(char));
                block.DeclareLocal(character);
                block.StoreLocal(character);

                block.LoadLocal(character);
                block.Load(range.Min);
                block.BranchIfLess(failed);

                block.LoadLocal(character);
                block.Load(range.Max);
                block.BranchIfGreater(failed);
            }

            block.LoadLexer();
            block.Call(typeof(Lexer).GetMethod("Read"));

            if (runtime.TraceParser)
            {
                block.LoadParseTrace();
                block.Load(this);
                block.LoadLexer();
                block.LoadLocal(start);
                block.Call(typeof(Lexer).GetMethod("SourceFrom"));
                block.LoadLocal(character);
                block.Call(typeof(TextEscape).GetMethod("Quote", new Type[] { typeof(char) }));
                block.Call(typeof(ParseTrace).GetMethod("Yes", new Type[] { typeof(object), typeof(Source), typeof(string) }));
            }

            if (state.BuildTextNodes)
            {
                if (range.Min == range.Max)
                {
                    block.Pop();
                    block.Load(Convert.ToString(range.Min));
                }
                else
                {
                    block.Call(typeof(Convert).GetMethod("ToString", new Type[] { typeof(char) }));
                }

                block.New(typeof(ParseTree).GetConstructor(new Type[] { typeof(object) }));
            }
            else
            {
                block.Pop();
                block.LoadYes();
            }

            BlockLabel returnLabel = new BlockLabel("return");

            block.Branch(returnLabel);

            block.MarkLabel(failed);

            if (runtime.TraceParser)
            {
                block.LoadParseTrace();
                block.Load(this);
                block.LoadLexer();
                block.LoadLocal(start);
                block.Call(typeof(Lexer).GetMethod("SourceFrom"));
                block.LoadLocal(character);
                block.Call(typeof(TextEscape).GetMethod("Quote", new Type[] { typeof(char) }));
                block.Call(typeof(ParseTrace).GetMethod("No", new Type[] { typeof(object), typeof(Source), typeof(string) }));
            }

            // todo error string

            block.LoadNo();

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of char --------------------");

            return(block);
        }
Example #27
0
        public override Block CompileNewState(Runtime runtime, StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            block.Comment("begin precedence alt -----------");

            // todo enter

            block.BeginScope();

            BlockLabel returnLabel = new BlockLabel("return");

            BlockLocal oldLeftRecursiveAlts = new BlockLocal(typeof(IParseable));

            block.DeclareLocal(oldLeftRecursiveAlts);
            block.LoadState();
            block.GetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts"));
            block.StoreLocal(oldLeftRecursiveAlts);

            ParseGraphNode oldLeftRecursiveAltsForCompiler = state.LeftRecursiveAlts;

            foreach (PrecedenceAltGroup group in groups)
            {
                block.BeginScope();

                BlockLocal groupLocal = new BlockLocal(typeof(PrecedenceAltGroup));
                block.DeclareLocal(groupLocal);
                block.Load(group);
                block.StoreLocal(groupLocal);

                BlockLabel apply         = new BlockLabel("apply");
                BlockLabel continueLabel = new BlockLabel("continue");

                BlockLocal currentPrecedence = new BlockLocal(typeof(Precedence));
                block.DeclareLocal(currentPrecedence);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("CurrentPrecedence"));
                block.Dup();
                block.StoreLocal(currentPrecedence);
                block.BranchIfNull(apply);

                BlockLocal groupPrecedence = new BlockLocal(typeof(Precedence));
                block.DeclareLocal(groupPrecedence);
                block.LoadLocal(groupLocal);
                block.GetProperty(groupLocal.Type.GetProperty("Precedence"));
                block.Dup();
                block.StoreLocal(groupPrecedence);
                block.BranchIfNull(apply);

                block.LoadLocal(currentPrecedence);
                block.GetProperty(currentPrecedence.Type.GetProperty("Group"));
                block.LoadLocal(groupPrecedence);
                block.GetProperty(groupPrecedence.Type.GetProperty("Group"));
                block.BranchIfNotEqual(apply);

                block.LoadLocal(groupPrecedence);
                block.LoadLocal(currentPrecedence);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                block.LogicalNot();
                block.Call(groupPrecedence.Type.GetMethod("IsLowerThan"));
                block.BranchIfTrue(continueLabel);

                block.MarkLabel(apply);

                block.LoadState();
                block.LoadLocal(groupLocal);
                block.GetProperty(groupLocal.Type.GetProperty("LeftRecursiveParseGraph"));
                block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts"));

                state.LeftRecursiveAlts = group.LeftRecursiveParseGraph;

                block.Emit(group.ParseGraph.Compile(runtime, state));

                block.Dup();

                BlockLabel no = new BlockLabel("no");
                block.BranchIfNo(no);

                block.LoadState();
                block.LoadLocal(oldLeftRecursiveAlts);
                block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts"));

                // todo yes

                block.Branch(returnLabel);

                block.MarkLabel(no);

                block.Pop();

                block.MarkLabel(continueLabel);

                block.EndScope();
            }

            block.LoadState();
            block.LoadLocal(oldLeftRecursiveAlts);
            block.SetProperty(typeof(ParserState).GetProperty("LeftRecursiveAlts"));

            state.LeftRecursiveAlts = oldLeftRecursiveAltsForCompiler;

            block.EndScope();

            // todo no

            block.LoadNo();

            block.MarkLabel(returnLabel);

            block.Comment("end precedence alt -----------");

            return(block);
        }
        //全部使用默认值,并且不从中断处恢复
        public OrderedBitcoinBlockchainParser_Class()
        {
            ParserBlock genesisBlock = get_GenesisBlock(true);

            initialize_BlockQueuePooling(genesisBlock);
        }
Example #29
0
        public override Block CompileNewState(Runtime runtime, StateForCompiler state)
        {
            ParserBlock block = new ParserBlock(runtime);

            block.Comment("begin longest alt -----------");

            block.Enter(this, "longest alt");

            block.BeginScope();

            BlockLocal start = block.SavePosition();

            BlockLocal longestTree = new BlockLocal(typeof(ParseTree));

            block.DeclareLocal(longestTree);
            block.LoadNull();
            block.StoreLocal(longestTree);

            BlockLocal longestTreeEnd = new BlockLocal(typeof(int));

            block.DeclareLocal(longestTreeEnd);
            block.Load(-1);
            block.StoreLocal(longestTreeEnd);

            foreach (IParseable alt in alts)
            {
                block.Emit(alt.Compile(runtime, state));

                BlockLabel no = new BlockLabel("no");
                block.Dup();
                block.BranchIfNo(no);

                block.LoadLexer();
                block.GetProperty(typeof(Lexer).GetProperty("Position"));
                block.LoadLocal(longestTreeEnd);

                block.BranchIfLessOrEqual(no);

                block.StoreLocal(longestTree);

                block.LoadLexer();
                block.GetProperty(typeof(Lexer).GetProperty("Position"));
                block.StoreLocal(longestTreeEnd);

                BlockLabel continueLabel = new BlockLabel("continue");
                block.Branch(continueLabel);

                block.MarkLabel(no);
                block.Pop();

                block.MarkLabel(continueLabel);

                block.RestorePosition(start);
            }

            BlockLabel yes = new BlockLabel("null");

            block.LoadLocal(longestTree);
            block.BranchIfNotNull(yes);

            block.Comment("no");

            block.No(this, start, "No alts matched");

            block.LoadNo();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Branch(returnLabel);

            block.Comment("yes");

            block.MarkLabel(yes);

            block.Yes(this, start);

            block.RestorePosition(longestTreeEnd);

            block.LoadLocal(longestTree);

            block.MarkLabel(returnLabel);

            block.Comment("end longest alt -----------");

            return(block);
        }
Example #30
0
        public override Block CompileNewState(Runtime runtime,
                                              StateForCompiler state)
        {
            ParserBlock block = new ParserBlock();

            BlockLabel returnLabel = new BlockLabel("return");

            block.Comment("start of seq --------------------");

            block.BeginScope();

            // Save

            BlockLocal start = block.SavePosition();

            BlockLocal oldLeftHandSide = new BlockLocal(typeof(RuntimeObject));
            BlockLocal oldPrecedenceCanEqualCurrent = new BlockLocal(typeof(bool));
            BlockLocal oldRecursionExclude          = new BlockLocal(typeof(Pattern));

            block.DeclareLocal(oldRecursionExclude);

            if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
            {
                block.DeclareLocal(oldPrecedenceCanEqualCurrent);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                block.StoreLocal(oldPrecedenceCanEqualCurrent);
            }

            if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
            {
                block.DeclareLocal(oldLeftHandSide);
                block.LoadState();
                block.GetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                block.StoreLocal(oldLeftHandSide);
            }

            block.LoadYes();

            for (int n = 0; n < nodes.Count; n++)
            {
                ParseGraphNode node = nodes[n];

                // Parse the node

                block.Emit(node.Compile(runtime, state));

                // If no

                BlockLabel yes = new BlockLabel("yes");
                block.Dup();    // dup the body tree
                block.BranchIfNotNo(yes);

                block.Pop();    // pop body tree
                block.Pop();    // pop new tree

                Restore(state, block, oldLeftHandSide,
                        oldPrecedenceCanEqualCurrent, oldRecursionExclude);

                block.RestorePosition(start);

                block.LoadNo();
                block.Branch(returnLabel);

                block.MarkLabel(yes);

                // Extend

                block.Call(typeof(ParseTree).GetMethod("Extend"));

                if (n == 0)
                {
                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.LoadNull();

                    BlockLabel recursionExcludeNull = new BlockLabel("recursionExcludeNull");
                    block.BranchIfEqual(recursionExcludeNull);

                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.StoreLocal(oldRecursionExclude);

                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("Excluded"));
                    block.LoadState();
                    block.GetProperty(typeof(ParserState).GetProperty("RecursionExclude"));
                    block.Call(typeof(Multiset <Pattern>).GetMethod("Remove", new Type[] { typeof(Pattern) }));

                    block.LoadState();
                    block.LoadNull();
                    block.SetProperty(typeof(ParserState).GetProperty("RecursionExclude"));

                    block.MarkLabel(recursionExcludeNull);

                    if (state.RecursionBehaviour == RecursionBehaviour.RightRecursive)
                    {
                        block.Comment("right recursion");

                        block.LoadState();
                        block.Load(1);
                        block.SetProperty(typeof(ParserState).GetProperty("PrecedenceCanEqualCurrent"));
                    }
                    else if (state.RecursionBehaviour == RecursionBehaviour.LeftRecursive)
                    {
                        block.Comment("left recursion");

                        block.LoadState();
                        block.LoadNull();
                        block.SetProperty(typeof(ParserState).GetProperty("LeftHandSide"));
                    }
                }
            }

            Restore(state, block, oldLeftHandSide,
                    oldPrecedenceCanEqualCurrent, oldRecursionExclude);

            block.EndScope();

            block.MarkLabel(returnLabel);

            block.Comment("end of seq --------------------");

            return(block);
        }