/// <summary> /// Update block information /// </summary> /// <param name="block">Block</param> /// <param name="previousBlock">Previous block</param> public static void UpdateBlockInfo(this BlockStat block, Block currentBlock, BlockStat previousBlock) { bool firstTime = block.Size == 0; var time = unixEpoch.AddMilliseconds(currentBlock.Timestamp); if (!firstTime) { if (block.Hash.ToString() != currentBlock.Hash.ToString() || block.Size != currentBlock.Size || block.Timestamp != time) { throw new ArgumentException($"Fork on {block.Index}"); } } block.Size = currentBlock.Size; block.Hash = currentBlock.Hash.ToString(); block.Timestamp = time; block.Transactions.Update(currentBlock.Transactions); block.ElapsedTime = (previousBlock == null ? TimeSpan.Zero : time - previousBlock.Timestamp); if (block.Index != 0 && !firstTime) { // We can't access to Blockchain on GenesisBlock block.MemPool.UpdateMemPool(); } }
/// <summary> /// Get block /// </summary> /// <param name="index">Index</param> /// <returns>Get block</returns> public BlockStat GetBlock(uint index) { if (!_blocks.Blocks.TryGetValue(index, out var ret)) { ret = new BlockStat(index); _blocks.Blocks[index] = ret; return(ret); } return(ret); }
/// <summary> /// Log /// </summary> /// <param name="block">Block</param> public void Log(BlockStat block) { if (_blocks.Blocks.TryRemove(block.Index - 5, out var remove)) { // Save 5 blocks } using (var stream = IO.File.OpenWrite(Settings.Default.Path)) { stream.Seek(Math.Max(0, stream.Length - 2), IO.SeekOrigin.Begin); var str = block.ToJson() + "\n]"; if (stream.Position > 2) { str = ",\n" + str; } var data = Encoding.ASCII.GetBytes(str); stream.Write(data, 0, data.Length); } }
/// <summary> /// Get block /// </summary> /// <param name="block">Block</param> /// <returns>Get block</returns> public BlockStat GetBlock(Block block) { // Find if (!_blocks.Blocks.TryGetValue(block.Index, out var ret)) { ret = new BlockStat(block.Index); _blocks.Blocks[block.Index] = ret; } // Update block info if (_blocks.Blocks.TryGetValue(block.Index - 1, out var prev)) { ret.UpdateBlockInfo(block, prev); } else { ret.UpdateBlockInfo(block, null); } return(ret); }
} // NT_Block private static void NT_Stat(out Stat s) { Symbol locSymbols = null; Stat statList = null; SrcPos sp = null; s = null; for (;;) { switch (Syn.Interpret()) { case 0: return; case 1: NT_IncDecAssignOrCallStat(out s); break; case 2: NT_IfStat(out s); break; case 3: NT_WhileStat(out s); break; case 4: NT_BreakStat(out s); break; case 5: NT_InputStat(out s); break; case 6: NT_OutputStat(out s); break; case 7: NT_DeleteStat(out s); break; case 8: NT_ReturnStat(out s); break; case 9: // SEM sp = new SrcPos(); break; case 10: NT_Block(out locSymbols, out statList); break; case 11: // SEM s = new BlockStat(sp, statList); break; case 12: // SEM s = new EmptyStat(null); break; } // switch } // for } // NT_Stat
} // DumpSymTab // === generate source text from symbol table and AST === public static void WriteStat(Stat stat) { switch (stat.kind) { case Stat.Kind.emptyStatKind: genMcpp.WriteLine(Indent() + ";"); break; case Stat.Kind.blockStatKind: BlockStat b_s = (BlockStat)stat; genMcpp.WriteLine(Indent() + "{"); IncIndent(); WriteStatList(b_s.statList); DecIndent(); genMcpp.WriteLine(Indent() + "}"); break; case Stat.Kind.incStatKind: IncStat i_s = (IncStat)stat; genMcpp.WriteLine(Indent() + i_s.vo.sy + "++;"); break; case Stat.Kind.decStatKind: DecStat d_s = (DecStat)stat; genMcpp.WriteLine(Indent() + d_s.vo.sy + "--;"); break; case Stat.Kind.assignStatKind: AssignStat a_s = (AssignStat)stat; genMcpp.WriteLine(Indent() + a_s.lhs + " = " + a_s.rhs + ";"); break; case Stat.Kind.callStatKind: CallStat c_s = (CallStat)stat; genMcpp.WriteLine(Indent() + c_s.func + "(" + c_s.apl + ");"); break; case Stat.Kind.ifStatKind: IfStat if_s = (IfStat)stat; genMcpp.WriteLine(Indent() + "if (" + if_s.cond + ")"); IncIndent(); WriteStatList(if_s.thenStat); DecIndent(); if (if_s.elseStat != null) { genMcpp.WriteLine(Indent() + "else "); IncIndent(); WriteStatList(if_s.elseStat); DecIndent(); } // if break; case Stat.Kind.whileStatKind: WhileStat w_s = (WhileStat)stat; genMcpp.WriteLine(Indent() + "while (" + w_s.cond + ")"); IncIndent(); WriteStatList(w_s.body); DecIndent(); break; case Stat.Kind.breakStatKind: genMcpp.WriteLine(Indent() + "break;"); break; case Stat.Kind.inputStatKind: InputStat in_s = (InputStat)stat; genMcpp.WriteLine(Indent() + "cin >> " + in_s.vo.sy + ";"); break; case Stat.Kind.outputStatKind: OutputStat out_s = (OutputStat)stat; genMcpp.Write(Indent() + "cout"); foreach (Object o in out_s.values) { genMcpp.Write(" << "); if (o is Expr) { genMcpp.Write(o); } else if (o is String) { String s = o as String; if (s == "\n") { genMcpp.Write("endl"); } else { genMcpp.Write('"' + s + '"'); } } else { throw new Exception("invalid value"); } } // foreach genMcpp.WriteLine(";"); break; case Stat.Kind.deleteStatKind: DeleteStat del_s = (DeleteStat)stat; genMcpp.WriteLine(Indent() + "delete[] " + NameList.NameOf(del_s.vo.sy.spix) + ";"); break; case Stat.Kind.returnStatKind: ReturnStat r_s = (ReturnStat)stat; genMcpp.Write(Indent() + "return"); if (r_s.e != null) { genMcpp.Write(" " + r_s.e); } genMcpp.WriteLine(";"); break; default: throw new Exception("invalid statement kind"); } // switch } // WriteStatList