示例#1
0
        static ElseBlock GetElse(int blockNumber)
        {
            ElseBlock elseblock = null;

            foreach (Block b in blocks)
            {
                if (b is ElseBlock)
                {
                    ElseBlock bl = (ElseBlock)b;

                    if (bl.blockNumber == blockNumber)
                    {
                        elseblock = bl;
                    }
                }
            }

            return(elseblock);
        }
示例#2
0
        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);
        }
示例#3
0
        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;
                    }
                }
            }
        }