示例#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
文件: Lexer.cs 项目: ztmurphy21/Klip
        public Lexer(string c)
        {
            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.Split('\n'))
            {
                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 "))
                {
                    int value = Convert.ToInt32(a.Substring(10));
                    code.Write(Opcodes.pushInt);
                    code.Write(value);
                }
                else if (a.StartsWith("pushString "))
                {
                    string temp  = a.Substring(11);
                    string value = temp.Substring(temp.IndexOf("\"") + 1, temp.LastIndexOf("\"") - 1);
                    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 == "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 { }

                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.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, 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;
                    }
                }
            }
        }