예제 #1
0
        public LuaFile Compile(Ast.Chunk c, string name)
        {
            file = new LuaFile();
            block = new Block();
            block.Chunk.Name = name;
            block.Chunk.ArgumentCount = 0;
            block.Chunk.Vararg = 2;

            DoChunk(c);

            file.Main = block.Chunk;
            file.Main.ArgumentCount = 0;
            file.Main.Vararg = 2;
            file.Main.UpvalueCount = file.Main.Upvalues.Count;
            bool addRet = file.Main.Instructions.Count == 0;
            if (addRet == false)
                addRet = file.Main.Instructions[file.Main.Instructions.Count - 1].Opcode != Instruction.LuaOpcode.RETURN;
            if (addRet)
            {
                Instruction ret = new Instruction("RETURN");
                ret.A = 0;
                ret.B = 1;
                ret.C = 0;
                file.Main.Instructions.Add(ret);
            }
            return file;
        }
예제 #2
0
파일: Block.cs 프로젝트: chenzuo/SharpLua
 public Block(Block parent)
 {
     K = new K2Reg(this);
     //parent.PreviousBlock = this;
     this.PreviousBlock = parent;
     V = new Var2Reg(parent.V);
     Chunk = parent.Chunk;
 }
예제 #3
0
        void DoStatement(Statement s)
        {
            line = s.LineNumber;
            if (s is AssignmentStatement && !(s is AugmentedAssignmentStatement))
            {
                AssignmentStatement a = s as AssignmentStatement;
                if (a.IsLocal == false)
                {

                    for (int i = a.Rhs.Count; i > 0; i--)
                        DoExpr(a.Rhs[i - 1], false, a.Lhs.Count);

                    for (int i = a.Lhs.Count; i > 0; i--)
                        DoExpr(a.Lhs[i - 1], true);

                    return;
                }
                else
                {
                    for (int i = a.Rhs.Count; i > 0; i--)
                        DoExpr(a.Rhs[i - 1], false, a.Lhs.Count);

                    for (int i = a.Lhs.Count; i > 0; i--)
                        DoExpr(a.Lhs[i - 1], true);

                    return;
                }
            }
            else if (s is AugmentedAssignmentStatement)
            {
                AugmentedAssignmentStatement aas = s as AugmentedAssignmentStatement;
                StringBuilder sb = new StringBuilder();
                //sb.Append(DoExpr(a.Lhs[0]));
                if (aas.IsLocal)
                    throw new LuaSourceException(s.LineNumber, 0, "Local assignment cannot have augmented operators");

                DoExpr(aas.Rhs[0], true, 1);
                DoExpr(aas.Lhs[0], true, 1);
                return;
            }
            else if (s is BreakStatement)
            {
                bool hadLoop = false;
                while (block != null)
                {
                    if (block.IsLoop)
                    {
                        hadLoop = true;
                        break;
                    }
                    block = block.PreviousBlock;
                }
                if (!hadLoop)
                    throw new LuaSourceException(s.LineNumber, 0, "No loop to break");

                Instruction i = new Instruction("JMP");
                i.A = 0;
                i.sBx = -1; // Infinite loop ;)
                emit(i);
                patchSbx.Push(i);
                return;
            }
            else if (s is ContinueStatement)
            {
            }
            else if (s is CallStatement)
            {
                CallStatement cs = s as CallStatement;
                DoExpr(cs.Expression);
                return;
            }
            else if (s is DoStatement)
            {
            }
            else if (s is GenericForStatement)
            {
            }
            else if (s is NumericForStatement)
            {
            }
            else if (s is FunctionStatement)
            {

            }
            else if (s is GotoStatement)
                ;
            else if (s is IfStmt)
            {
            }
            else if (s is LabelStatement)
                ;
            else if (s is RepeatStatement)
            {
            }
            else if (s is ReturnStatement)
            {
            }
            else if (s is UsingStatement)
            {
            }
            else if (s is WhileStatement)
            {
                WhileStatement ws = s as WhileStatement;

                int start = block.Chunk.Instructions.Count;

                DoExpr(ws.Condition);

                Instruction t = new Instruction("TEST");
                t.A = block.regnum;
                t.C = 0;
                emit(t);

                DoChunk(ws.Body, true);

                Instruction i = new Instruction("JMP");
                i.A = 0;
                i.sBx = -(block.Chunk.Instructions.Count - start) - 1;
                emit(i);

                while (patchSbx.Count > 0)
                    patchSbx.Pop().sBx = Math.Abs(block.Chunk.Instructions.Count + i.sBx - 1);

                //return;
            }

            throw new NotImplementedException(s.GetType().Name + " is not implemented");
        }
예제 #4
0
 void DoChunk(List<Statement> ss, bool isLoop = false)
 {
     block = new Block(block) { IsLoop = isLoop };
     foreach (Statement s in ss)
     {
         DoStatement(s);
         block.regnum = 0;
     }
     block = block.PreviousBlock;
 }
예제 #5
0
파일: K2Reg.cs 프로젝트: chenzuo/SharpLua
 public K2Reg(Block b)
 {
     this.b = b;
 }