示例#1
0
文件: Runtime.cs 项目: blapaz/buddy
        static IfBlock GetIf(int blockNumber)
        {
            IfBlock ifblock = null;

            foreach (Block b in _blocks)
            {
                if (b is IfBlock)
                {
                    IfBlock bl = (IfBlock)b;

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

            return(ifblock);
        }
示例#2
0
文件: Runtime.cs 项目: blapaz/buddy
        public static void Run(string funcName)
        {
            Func func = GetFunc(funcName);

            if (func != null)
            {
                _isRunning   = true;
                _code.pos    = func.location;
                _currentFunc = func;

                int           opcode       = 0;
                Block         currentBlock = null;
                Stack <Block> block_stack  = new Stack <Block>();

                while (_isRunning)
                {
                    try
                    {
                        opcode = _code.ReadInt();
                    }
                    catch
                    {
                    }

                    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.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(value2 - value1);
                    }
                    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(value2, value1))
                        {
                            if (currentBlock == null)
                            {
                                currentBlock = ifblock;
                            }
                            else
                            {
                                block_stack.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(value2, value1))
                        {
                            if (currentBlock == null)
                            {
                                currentBlock = ifblock;
                            }
                            else
                            {
                                block_stack.Push(currentBlock);
                                currentBlock = ifblock;
                            }

                            IncVars();
                            _ifWorked = true;
                        }
                        else
                        {
                            _code.pos = ifblock.endBlock;
                            _ifWorked = false;
                        }
                    }
                    else if (opcode == Opcodes.ifgt)
                    {
                        int     blockNumber = _code.ReadInt();
                        IfBlock ifblock     = GetIf(blockNumber);

                        object value1 = _stack.Pop();
                        object value2 = _stack.Pop();

                        if (IfGreater(value2, value1))
                        {
                            if (currentBlock == null)
                            {
                                currentBlock = ifblock;
                            }
                            else
                            {
                                block_stack.Push(currentBlock);
                                currentBlock = ifblock;
                            }

                            IncVars();
                            _ifWorked = true;
                        }
                        else
                        {
                            _code.pos = ifblock.endBlock;
                            _ifWorked = false;
                        }
                    }
                    else if (opcode == Opcodes.ifgte)
                    {
                        int     blockNumber = _code.ReadInt();
                        IfBlock ifblock     = GetIf(blockNumber);

                        object value1 = _stack.Pop();
                        object value2 = _stack.Pop();

                        if (IfGreater(value2, value1) || IfEqual(value2, value1))
                        {
                            if (currentBlock == null)
                            {
                                currentBlock = ifblock;
                            }
                            else
                            {
                                block_stack.Push(currentBlock);
                                currentBlock = ifblock;
                            }

                            IncVars();
                            _ifWorked = true;
                        }
                        else
                        {
                            _code.pos = ifblock.endBlock;
                            _ifWorked = false;
                        }
                    }
                    else if (opcode == Opcodes.iflt)
                    {
                        int     blockNumber = _code.ReadInt();
                        IfBlock ifblock     = GetIf(blockNumber);

                        object value1 = _stack.Pop();
                        object value2 = _stack.Pop();

                        if (IfLesser(value2, value1))
                        {
                            if (currentBlock == null)
                            {
                                currentBlock = ifblock;
                            }
                            else
                            {
                                block_stack.Push(currentBlock);
                                currentBlock = ifblock;
                            }

                            IncVars();
                            _ifWorked = true;
                        }
                        else
                        {
                            _code.pos = ifblock.endBlock;
                            _ifWorked = false;
                        }
                    }
                    else if (opcode == Opcodes.iflte)
                    {
                        int     blockNumber = _code.ReadInt();
                        IfBlock ifblock     = GetIf(blockNumber);

                        object value1 = _stack.Pop();
                        object value2 = _stack.Pop();

                        if (IfLesser(value2, value1) || IfEqual(value2, value1))
                        {
                            if (currentBlock == null)
                            {
                                currentBlock = ifblock;
                            }
                            else
                            {
                                block_stack.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(value2, value1))
                            {
                                if (currentBlock == null)
                                {
                                    currentBlock = elseifblock;
                                }
                                else
                                {
                                    block_stack.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(value2, value1))
                            {
                                if (currentBlock == null)
                                {
                                    currentBlock = elseifblock;
                                }
                                else
                                {
                                    block_stack.Push(currentBlock);
                                    currentBlock = elseifblock;
                                }

                                IncVars();
                                _ifWorked = true;
                            }
                            else
                            {
                                _code.pos = elseifblock.endBlock;
                                _ifWorked = false;
                            }
                        }
                        else
                        {
                            _code.pos = elseifblock.endBlock;
                        }
                    }
                    else if (opcode == Opcodes.elseifgt)
                    {
                        int         blockNumber = _code.ReadInt();
                        ElseIfBlock elseifblock = GetElseIf(blockNumber);

                        if (!_ifWorked)
                        {
                            object value1 = _stack.Pop();
                            object value2 = _stack.Pop();

                            if (IfGreater(value2, value1))
                            {
                                if (currentBlock == null)
                                {
                                    currentBlock = elseifblock;
                                }
                                else
                                {
                                    block_stack.Push(currentBlock);
                                    currentBlock = elseifblock;
                                }

                                IncVars();
                                _ifWorked = true;
                            }
                            else
                            {
                                _code.pos = elseifblock.endBlock;
                                _ifWorked = false;
                            }
                        }
                        else
                        {
                            _code.pos = elseifblock.endBlock;
                        }
                    }
                    else if (opcode == Opcodes.elseifgte)
                    {
                        int         blockNumber = _code.ReadInt();
                        ElseIfBlock elseifblock = GetElseIf(blockNumber);

                        if (!_ifWorked)
                        {
                            object value1 = _stack.Pop();
                            object value2 = _stack.Pop();

                            if (IfGreater(value2, value1) || IfEqual(value2, value1))
                            {
                                if (currentBlock == null)
                                {
                                    currentBlock = elseifblock;
                                }
                                else
                                {
                                    block_stack.Push(currentBlock);
                                    currentBlock = elseifblock;
                                }

                                IncVars();
                                _ifWorked = true;
                            }
                            else
                            {
                                _code.pos = elseifblock.endBlock;
                                _ifWorked = false;
                            }
                        }
                        else
                        {
                            _code.pos = elseifblock.endBlock;
                        }
                    }
                    else if (opcode == Opcodes.elseiflt)
                    {
                        int         blockNumber = _code.ReadInt();
                        ElseIfBlock elseifblock = GetElseIf(blockNumber);

                        if (!_ifWorked)
                        {
                            object value1 = _stack.Pop();
                            object value2 = _stack.Pop();

                            if (IfLesser(value2, value1))
                            {
                                if (currentBlock == null)
                                {
                                    currentBlock = elseifblock;
                                }
                                else
                                {
                                    block_stack.Push(currentBlock);
                                    currentBlock = elseifblock;
                                }

                                IncVars();
                                _ifWorked = true;
                            }
                            else
                            {
                                _code.pos = elseifblock.endBlock;
                                _ifWorked = false;
                            }
                        }
                        else
                        {
                            _code.pos = elseifblock.endBlock;
                        }
                    }
                    else if (opcode == Opcodes.elseiflte)
                    {
                        int         blockNumber = _code.ReadInt();
                        ElseIfBlock elseifblock = GetElseIf(blockNumber);

                        if (!_ifWorked)
                        {
                            object value1 = _stack.Pop();
                            object value2 = _stack.Pop();

                            if (IfLesser(value2, value1) || IfEqual(value2, value1))
                            {
                                if (currentBlock == null)
                                {
                                    currentBlock = elseifblock;
                                }
                                else
                                {
                                    block_stack.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
                            {
                                block_stack.Push(currentBlock);
                                currentBlock = elseblock;
                            }

                            IncVars();
                        }
                        else
                        {
                            _code.pos = elseblock.endBlock;
                        }
                    }
                    else if (opcode == Opcodes.endif)
                    {
                        if (block_stack.Count > 0)
                        {
                            currentBlock = block_stack.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
                        {
                            _isRunning = false;
                        }
                    }
                    else if (opcode == Opcodes.print)
                    {
                        Console.WriteLine(_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.inputInt32)
                    {
                        _stack.Push(Convert.ToInt32(Console.ReadLine()));
                    }
                    else if (opcode == Opcodes.inputString)
                    {
                        _stack.Push(Console.ReadLine());
                    }
                    else if (opcode == Opcodes.delay)
                    {
                        System.Threading.Thread.Sleep(Convert.ToInt32(_stack.Pop()));
                    }
                    else if (opcode == Opcodes.captureScreen)
                    {
                        string value = _stack.Pop().ToString();

                        if (value.Equals(""))
                        {
                            value = Guid.NewGuid().ToString();
                        }

                        Screenshot.CaptureAndOpen($"{value}.jpg", ImageFormat.Jpeg);
                    }
                    else if (opcode == Opcodes.getClipboard)
                    {
                        _stack.Push(Clipboard.GetText());
                    }
                    else if (opcode == Opcodes.setClipboard)
                    {
                        Clipboard.SetText(_stack.Pop().ToString());
                    }
                    else if (opcode == Opcodes.write)
                    {
                        _inputSimulator.Keyboard.TextEntry(_stack.Pop().ToString());
                    }
                    else if (opcode == Opcodes.msg)
                    {
                        string value = _stack.Pop().ToString();

                        MessageBox.Show(value);
                    }
                    else if (opcode == Opcodes.exit)
                    {
                        Environment.Exit(0);
                        Application.Exit();
                    }
                }
            }
            else
            {
                if (!funcName.Equals("Main"))
                {
                    throw new Exception($"No function named {funcName} was found");
                }
            }
        }
示例#3
0
文件: Lexer.cs 项目: blapaz/buddy
        public Lexer(string compiledCode)
        {
            Func          currentFunc  = null;
            Block         currentBlock = null;
            int           blockNumber  = 0;
            Stack <Block> blockstack   = new Stack <Block>();

            foreach (string line in compiledCode.Replace(((char)13).ToString(), "").Split('\n'))
            {
                if (line.StartsWith(":"))
                {
                    string op = line.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 (line.StartsWith("e:"))
                {
                    string op = line.Substring(2);

                    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);
                    }

                    Events.Add(currentFunc);
                }
                else if (line.StartsWith("."))
                {
                    string name = line.Substring(1);
                    Label  l    = new Label(name, Code.buffer.Count());
                    currentFunc.labels.Add(l);
                }
                else if (line.StartsWith($"{nameof(Opcodes.pushInt)} "))
                {
                    int value = Convert.ToInt32(line.Substring(8));
                    Code.Write(Opcodes.pushInt);
                    Code.Write(value);

                    _pushVarValue = value.ToString();
                }
                else if (line.StartsWith($"{nameof(Opcodes.pushString)} "))
                {
                    string temp  = line.Substring(11);
                    string value = temp.Substring(temp.IndexOf("\"") + 1, temp.LastIndexOf("\"") - 1);
                    Code.Write(Opcodes.pushString);
                    Code.Write(value);

                    _pushVarValue = value;
                }
                else if (line.StartsWith($"{nameof(Opcodes.pushVar)} "))
                {
                    string name = line.Substring(8);
                    Code.Write(Opcodes.pushVar);
                    Code.Write(name);
                }
                else if (line.Equals(nameof(Opcodes.pop)))
                {
                    Code.Write(Opcodes.pop);
                }
                else if (line.Equals(nameof(Opcodes.popa)))
                {
                    Code.Write(Opcodes.popa);
                }
                else if (line.StartsWith($"{nameof(Opcodes.decVar)} "))
                {
                    string name = line.Substring(7);
                    Code.Write(Opcodes.decVar);
                    Code.Write(name);
                }
                else if (line.StartsWith($"{nameof(Opcodes.setGlobalVar)} "))
                {
                    string name = line.Substring(13);
                    Code.Write(Opcodes.setGlobalVar);
                    Code.Write(name);

                    if (_pushVarValue != null)
                    {
                        GlobalVars.Add(new Var(name, _pushVarValue));
                    }
                }
                else if (line.StartsWith($"{nameof(Opcodes.setVar)} "))
                {
                    string name = line.Substring(7);
                    Code.Write(Opcodes.setVar);
                    Code.Write(name);
                }
                else if (line.Equals(nameof(Opcodes.add)))
                {
                    Code.Write(Opcodes.add);
                }
                else if (line.Equals(nameof(Opcodes.sub)))
                {
                    Code.Write(Opcodes.sub);
                }
                else if (line.Equals(nameof(Opcodes.mul)))
                {
                    Code.Write(Opcodes.mul);
                }
                else if (line.Equals(nameof(Opcodes.div)))
                {
                    Code.Write(Opcodes.div);
                }
                else if (line.Equals(nameof(Opcodes.clear)))
                {
                    Code.Write(Opcodes.clear);
                }
                else if (line.StartsWith("if"))
                {
                    string op = line.Substring(2);

                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                    }

                    currentBlock = new IfBlock(blockNumber);

                    if (op.Equals("e"))
                    {
                        Code.Write(Opcodes.ife);
                    }
                    else if (op.Equals("n"))
                    {
                        Code.Write(Opcodes.ifn);
                    }
                    else if (op.Equals("gt"))
                    {
                        Code.Write(Opcodes.ifgt);
                    }
                    else if (op.Equals("gte"))
                    {
                        Code.Write(Opcodes.ifgte);
                    }
                    else if (op.Equals("lt"))
                    {
                        Code.Write(Opcodes.iflt);
                    }
                    else if (op.Equals("lte"))
                    {
                        Code.Write(Opcodes.iflte);
                    }

                    Code.Write(blockNumber);
                    blockNumber++;
                }
                else if (line.StartsWith("elseif"))
                {
                    string op = line.Substring(6);

                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                    }

                    currentBlock = new ElseIfBlock(blockNumber);

                    if (op.Equals("e"))
                    {
                        Code.Write(Opcodes.elseife);
                    }
                    else if (op.Equals("n"))
                    {
                        Code.Write(Opcodes.elseifn);
                    }
                    else if (op.Equals("gt"))
                    {
                        Code.Write(Opcodes.elseifgt);
                    }
                    else if (op.Equals("gte"))
                    {
                        Code.Write(Opcodes.elseifgte);
                    }
                    else if (op.Equals("lt"))
                    {
                        Code.Write(Opcodes.elseiflt);
                    }
                    else if (op.Equals("lte"))
                    {
                        Code.Write(Opcodes.elseiflte);
                    }

                    Code.Write(blockNumber);
                    blockNumber++;
                }
                else if (line.Equals("else"))
                {
                    if (currentBlock != null)
                    {
                        blockstack.Push(currentBlock);
                    }

                    currentBlock = new ElseBlock(blockNumber);
                    Code.Write(Opcodes.els);
                    Code.Write(blockNumber);
                    blockNumber++;
                }
                else if (line.Equals(nameof(Opcodes.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 (line.StartsWith($"{nameof(Opcodes.call)} "))
                {
                    string name = line.Substring(5);
                    Code.Write(Opcodes.call);
                    Code.Write(name);
                }
                else if (line.StartsWith("goto "))
                {
                    string name = line.Substring(6);
                    Code.Write(Opcodes.got);
                    Code.Write(name);
                }
                else if (line.Equals(nameof(Opcodes.print)))
                {
                    Code.Write(Opcodes.print);
                }
                else if (line.Equals(nameof(Opcodes.printLine)))
                {
                    Code.Write(Opcodes.printLine);
                }
                else if (line.Equals(nameof(Opcodes.read)))
                {
                    Code.Write(Opcodes.read);
                }
                else if (line.Equals(nameof(Opcodes.readLine)))
                {
                    Code.Write(Opcodes.readLine);
                }
                else if (line.Equals(nameof(Opcodes.delay)))
                {
                    Code.Write(Opcodes.delay);
                }
                else if (line.Equals(nameof(Opcodes.captureScreen)))
                {
                    Code.Write(Opcodes.captureScreen);
                }
                else if (line.Equals(nameof(Opcodes.getClipboard)))
                {
                    Code.Write(Opcodes.getClipboard);
                }
                else if (line.Equals(nameof(Opcodes.setClipboard)))
                {
                    Code.Write(Opcodes.setClipboard);
                }
                else if (line.Equals(nameof(Opcodes.write)))
                {
                    Code.Write(Opcodes.write);
                }
                else if (line.Equals(nameof(Opcodes.exit)))
                {
                    Code.Write(Opcodes.exit);
                }
                else if (line.StartsWith(nameof(Opcodes.msg)))
                {
                    Code.Write(Opcodes.msg);
                }
                else if (line.Equals(nameof(Opcodes.inputInt32)))
                {
                    Code.Write(Opcodes.inputInt32);
                }
                else if (line.Equals(nameof(Opcodes.inputString)))
                {
                    Code.Write(Opcodes.inputString);
                }
                else if (line.Equals(nameof(Opcodes.ret)))
                {
                    Code.Write(Opcodes.ret);
                }
            }

            Code.Write(Opcodes.ret);
            Funcs.Add(currentFunc);
        }