static ElseIfBlock GetElseIf(int blockNumber) { ElseIfBlock elseifblock = null; foreach (Block b in blocks) { if (b is ElseIfBlock) { ElseIfBlock bl = (ElseIfBlock)b; if (bl.blockNumber == blockNumber) { elseifblock = bl; } } } return(elseifblock); }
public Lexer(string c) { Log.Here().Information("Starting Lexer."); c = c.Replace(((char)13).ToString(), ""); Func currentFunc = null; Block currentBlock = null; int blockNumber = 0; Stack <Block> blockstack = new Stack <Block>(); foreach (string a in c.Replace("\r\n", "\n").Split('\n').Select(b => b.Trim())) { Log.Here().Verbose($"Current row: '{a}'"); if (a.StartsWith(":")) { string op = a.Substring(1); if (currentFunc == null) { currentFunc = new Func(op, code.buffer.Count); } else { code.Write(Opcodes.ret); funcs.Add(currentFunc); currentFunc = new Func(op, code.buffer.Count); } } else if (a.StartsWith(".")) { string name = a.Substring(1); Label l = new Label(name, code.buffer.Count()); currentFunc.labels.Add(l); } else if (a.StartsWith("pushInt ")) { // Enable if runtime takes responsibility for converting int literals //string intLiteral = ITokens.IPartial.INT_LITERAL.BinaryString; //string temp = a.Substring(10); //temp = temp.Substring( // temp.IndexOf(intLiteral) + intLiteral.Length, temp.LastIndexOf(intLiteral) - intLiteral.Length // ); //int value = Convert.ToInt32(new Binary(binaryString: temp.Trim()).ToString()); int value = Convert.ToInt32(a.Substring(8)); code.Write(Opcodes.pushInt); code.Write(value); } else if (a.StartsWith("pushString ")) { string quoteStr = ITokens.IPartial.STRING_LITERAL.BinaryString; string temp = a.Substring(11); string value = temp.Substring(temp.IndexOf(quoteStr) + quoteStr.Length, temp.LastIndexOf(quoteStr) - quoteStr.Length); value = new Binary(binaryString: value.Trim()).ToString(); code.Write(Opcodes.pushString); code.Write(value); } else if (a.StartsWith("pushVar ")) { string name = a.Substring(8); code.Write(Opcodes.pushVar); code.Write(name); } else if (a == "print") { code.Write(Opcodes.print); } else if (a == "printLine") { code.Write(Opcodes.printLine); } else if (a == "read") { code.Write(Opcodes.read); } else if (a == "readLine") { code.Write(Opcodes.readLine); } else if (a == "halt") { code.Write(Opcodes.halt); } else if (a == "inputInt32") { code.Write(Opcodes.inputInt32); } else if (a == "inputString") { code.Write(Opcodes.inputString); } else if (a == "mine") { code.Write(Opcodes.bc_mine); } else if (a == "createBlockchain") { code.Write(Opcodes.bc_createBlockchain); } else if (a == "createTransaction") { code.Write(Opcodes.bc_createTransaction); } else if (a == "randomNumberGenerator") { code.Write(Opcodes.qc_randomNumberGenerator); } else if (a == "entanglement") { code.Write(Opcodes.qc_entanglement); } else if (a == "randomBitGenerator") { code.Write(Opcodes.qc_randomBitGenerator); } else if (a == "pop") { code.Write(Opcodes.pop); } else if (a == "popa") { code.Write(Opcodes.popa); } else if (a.StartsWith("decVar ")) { string name = a.Substring(7); code.Write(Opcodes.decVar); code.Write(name); } else if (a.StartsWith("setVar ")) { string name = a.Substring(7); code.Write(Opcodes.setVar); code.Write(name); } else if (a == "add") { code.Write(Opcodes.add); } else if (a == "sub") { code.Write(Opcodes.sub); } else if (a == "mul") { code.Write(Opcodes.mul); } else if (a == "div") { code.Write(Opcodes.div); } else if (a == "clear") { code.Write(Opcodes.clear); } else if (a == "ife") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new IfBlock(blockNumber); code.Write(Opcodes.ife); code.Write(blockNumber); blockNumber++; } else if (a == "ifn") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new IfBlock(blockNumber); code.Write(Opcodes.ifn); code.Write(blockNumber); blockNumber++; } else if (a == "elseife") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new ElseIfBlock(blockNumber); code.Write(Opcodes.elseife); code.Write(blockNumber); blockNumber++; } else if (a == "elseifn") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new ElseIfBlock(blockNumber); code.Write(Opcodes.elseifn); code.Write(blockNumber); blockNumber++; } else if (a == "else") { if (currentBlock != null) { blockstack.Push(currentBlock); } currentBlock = new ElseBlock(blockNumber); code.Write(Opcodes.els); code.Write(blockNumber); blockNumber++; } else if (a == "endif") { code.Write(Opcodes.endif); currentBlock.endBlock = code.buffer.Count(); blocks.Add(currentBlock); if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); } else { currentBlock = null; } } else if (a.StartsWith("call ")) { string name = a.Substring(5); code.Write(Opcodes.call); code.Write(name); } else if (a.StartsWith("goto ")) { string name = a.Substring(5); code.Write(Opcodes.got); code.Write(name); } else if (a == "ret") { code.Write(Opcodes.ret); } } code.Write(Opcodes.ret); funcs.Add(currentFunc); }
static void Run(Func func) { int opcode = 0; code.pos = func.location; currentFunc = func; Block currentBlock = null; Stack <Block> blockstack = new Stack <Block>(); while (running) { try { opcode = code.ReadInt(); } catch (Exception ex) { Log.Here().Warning(ex, "Insignificant exception during buffer-read."); } Log.Here().Verbose($"Current opcode: {opcode}"); if (opcode == Opcodes.pushInt) { stack.Push(code.ReadInt()); } else if (opcode == Opcodes.pushString) { stack.Push(code.ReadString()); } else if (opcode == Opcodes.pushVar) { stack.Push(GetVarValue(code.ReadString())); } else if (opcode == Opcodes.print) { Console.Write(stack.Pop()); } else if (opcode == Opcodes.printLine) { Console.WriteLine(stack.Pop()); } else if (opcode == Opcodes.read) { Console.Read(); } else if (opcode == Opcodes.readLine) { Console.ReadLine(); } else if (opcode == Opcodes.qc_randomBitGenerator) { using var qsim = new QuantumSimulator(); Console.WriteLine($"Random bit: {RandomBitGenerator.Run(qsim).Result}"); } else if (opcode == Opcodes.qc_randomNumberGenerator) { using var sim = new QuantumSimulator(); // First we initialize all the variables: var bitString = "0"; // To save the bit string int max = (int)(stack.Pop() ?? throw new NullReferenceException("What's the maximum of the random number you want to generate?")); // The maximum of the range int size = Convert.ToInt32(Math.Floor(Math.Log(max, 2.0) + 1)); // To calculate the amount of needed bits int output = max + 1; // Int to store the output while (output > max) // Loop to generate the number { bitString = "0"; // Restart the bit string if fails bitString = String.Join("", Enumerable.Range(0, size).Select(idx => RandomBitGenerator.Run(sim).Result == Result.One ? "1" : "0" ) ); // Generate and concatenate the bits using using the Q# operation output = Convert.ToInt32(bitString, 2); // Convert the bit string to an integer } // Print the result Console.WriteLine($"Random number: {output}"); } else if (opcode == Opcodes.qc_entanglement) { using var qsim = new QuantumSimulator(); Result[] initials = new Result[] { Result.Zero, Result.One }; foreach (Result initial in initials) { (long, long, long)res = Entanglement.Run(qsim, 1000, initial).Result; (long numZeros, long numOnes, long agree) = res; Console.WriteLine($"Init:{initial,-4} 0s={numZeros,-4} 1s={numOnes,-4} agree={agree,-4}"); } } else if (opcode == Opcodes.bc_createBlockchain) { Console.WriteLine(vars); stack.Push(new Blockchain()); Log.Here().Information("Initialized new blockchain."); } else if (opcode == Opcodes.bc_createTransaction) { Blockchain blockchain = stack.Pop() as Blockchain ?? throw new NullReferenceException("Create a blockchain before trying to create a transaction!"); //Blockchain blockchain = GetVarValue(code.ReadString()) as Blockchain // ?? throw new NullReferenceException("Create a blockchain before trying to create a transaction!"); string fromAddress = stack.Pop() as string ?? throw new NullReferenceException("Who is receiving abinCoins?"); string toAddress = (stack.Pop() as string) ?? throw new NullReferenceException("Who is transacting abinCoins?"); int amount = (int)(stack.Pop() ?? throw new NullReferenceException("How much coins do you want to transact?")); blockchain.CreateTransaction(new Transaction(fromAddress, toAddress, amount)); Log.Here().Information($"New transaction over '{amount}' abinCoins on Blockchain from '{fromAddress}' to '{toAddress}'."); } else if (opcode == Opcodes.bc_mine) { Blockchain blockchain = stack.Pop() as Blockchain ?? throw new NullReferenceException("Create a blockchain before trying to mine abinCoins!"); string miningAddress = stack.Pop() as string ?? throw new NullReferenceException("Who is mining abinCoins?"); blockchain.ProcessPendingTransactions(miningAddress); Log.Here().Information($"'{miningAddress}' is mining abin coins."); } else if (opcode == Opcodes.bc_isValid) { Blockchain blockchain = stack.Pop() as Blockchain ?? throw new NullReferenceException("Create a blockchain before trying to verify it's validation-state!"); if (blockchain.IsValid()) { Log.Here().Information("Blockchain is valid."); } else { Log.Here().Warning("Blockchain is NOT valid. Data corrupted."); } } else if (opcode == Opcodes.halt) { while (true) { } } else if (opcode == Opcodes.inputInt32) { stack.Push(Convert.ToInt32(Console.ReadLine())); } else if (opcode == Opcodes.inputString) { stack.Push(Console.ReadLine()); } else if (opcode == Opcodes.pop) { stack.Pop(); } else if (opcode == Opcodes.popa) { stack.Clear(); } else if (opcode == Opcodes.decVar) { vars.Add(new Var(code.ReadString())); } else if (opcode == Opcodes.setVar) { SetVarValue(code.ReadString(), stack.Pop()); } else if (opcode == Opcodes.add) { object value1 = stack.Pop(); object value2 = stack.Pop(); if (value1 is string && value2 is string) { string value = ((string)value2) + ((string)value1); stack.Push(value); } else if (value1 is int && value2 is int) { int value = ((int)value1) + ((int)value2); stack.Push(value); } } else if (opcode == Opcodes.sub) { int value1 = (int)stack.Pop(); int value2 = (int)stack.Pop(); stack.Push(value1 - value2); } else if (opcode == Opcodes.mul) { int value1 = (int)stack.Pop(); int value2 = (int)stack.Pop(); stack.Push(value1 * value2); } else if (opcode == Opcodes.div) { int value1 = (int)stack.Pop(); int value2 = (int)stack.Pop(); stack.Push(value1 / value2); } else if (opcode == Opcodes.clear) { Console.Clear(); } else if (opcode == Opcodes.ife) { int blockNumber = code.ReadInt(); IfBlock ifblock = GetIf(blockNumber); object value1 = stack.Pop(); object value2 = stack.Pop(); if (IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = ifblock; } else { blockstack.Push(currentBlock); currentBlock = ifblock; } IncVars(); ifWorked = true; } else { code.pos = ifblock.endBlock; ifWorked = false; } } else if (opcode == Opcodes.ifn) { int blockNumber = code.ReadInt(); IfBlock ifblock = GetIf(blockNumber); object value1 = stack.Pop(); object value2 = stack.Pop(); if (!IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = ifblock; } else { blockstack.Push(currentBlock); currentBlock = ifblock; } IncVars(); ifWorked = true; } else { code.pos = ifblock.endBlock; ifWorked = false; } } else if (opcode == Opcodes.elseife) { int blockNumber = code.ReadInt(); ElseIfBlock elseifblock = GetElseIf(blockNumber); if (!ifWorked) { object value1 = stack.Pop(); object value2 = stack.Pop(); if (IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = elseifblock; } else { blockstack.Push(currentBlock); currentBlock = elseifblock; } IncVars(); ifWorked = true; } else { code.pos = elseifblock.endBlock; ifWorked = false; } } else { code.pos = elseifblock.endBlock; } } else if (opcode == Opcodes.elseifn) { int blockNumber = code.ReadInt(); ElseIfBlock elseifblock = GetElseIf(blockNumber); if (!ifWorked) { object value1 = stack.Pop(); object value2 = stack.Pop(); if (!IfEqual(value1, value2)) { if (currentBlock == null) { currentBlock = elseifblock; } else { blockstack.Push(currentBlock); currentBlock = elseifblock; } IncVars(); ifWorked = true; } else { code.pos = elseifblock.endBlock; ifWorked = false; } } else { code.pos = elseifblock.endBlock; } } else if (opcode == Opcodes.els) { int blockNumber = code.ReadInt(); ElseBlock elseblock = GetElse(blockNumber); if (!ifWorked) { if (currentBlock == null) { currentBlock = elseblock; } else { blockstack.Push(currentBlock); currentBlock = elseblock; } IncVars(); } else { code.pos = elseblock.endBlock; } } else if (opcode == Opcodes.endif) { if (blockstack.Count > 0) { currentBlock = blockstack.Pop(); } else { currentBlock = null; } DecVars(); } else if (opcode == Opcodes.call) { string name = code.ReadString(); Func f = GetFunc(name); Call c = new Call(currentFunc, code.pos, new List <Var>(vars)); callstack.Push(c); currentFunc = f; code.pos = f.location; vars.Clear(); } else if (opcode == Opcodes.got) { string name = code.ReadString(); int location = GetLabel(name); code.pos = location; } else if (opcode == Opcodes.ret) { if (callstack.Count > 0) { Call c = callstack.Pop(); currentFunc = c.func; code.pos = c.ret; vars = c.vars; } else { running = false; } } } }