Ejemplo n.º 1
0
        private void CGTableConstructorExp(FuncInfo funcInfo, TableConstructorExpNode node, int a)
        {
            int nArray = 0;

            foreach (var key in node.KeyExpList)
            {
                var nilNode = key as ConstExpNode;
                if (nilNode != null && nilNode.ExpType == ConstExpNode.ConstExpType.NilExp)
                {
                    nArray++;
                }
            }
            int nExps = node.KeyExpList.Count;

            funcInfo.EmitNewTable(a, nArray, nExps - nArray);

            int i = 0;

            foreach (var key in node.KeyExpList)
            {
                var nilNode = key as ConstExpNode;
                var valNode = node.ValExpList[i];
                if (nilNode.ExpType == ConstExpNode.ConstExpType.NilExp)
                {
                }
                int b = funcInfo.AllocReg();
                CGExp(funcInfo, key, b, 1);
                int c = funcInfo.AllocReg();
                CGExp(funcInfo, valNode, c, 1);
                funcInfo.FreeRegs(2);
                funcInfo.EmitSetTable(a, b, c);
                i++;
            }
        }
Ejemplo n.º 2
0
        private void CGTableAccessExp(FuncInfo funcInfo, TableAccessExpNode node, int a)
        {
            int b = funcInfo.AllocReg();

            CGExp(funcInfo, node.PreExp, b, 1);
            int c = funcInfo.AllocReg();

            CGExp(funcInfo, node.Exp, c, 1);
            funcInfo.EmitGetTable(a, b, c);
            funcInfo.FreeRegs(2);
        }
Ejemplo n.º 3
0
        private void CGUnaryExp(FuncInfo funcInfo, UnaryExpNode node, int a)
        {
            int b = funcInfo.AllocReg();

            CGExp(funcInfo, node.Exp, b, 1);
            funcInfo.EmitUnaryOp(a, b, node.OpType);
            funcInfo.FreeReg();
        }
Ejemplo n.º 4
0
        private void CGFuncCallStat(FuncInfo funcInfo, FuncCallStatNode node)
        {
            var             r        = funcInfo.AllocReg();
            FuncCallExpNode funcCall = new FuncCallExpNode();

            funcCall.Args    = node.Args;
            funcCall.NameExp = node.NameExp;
            funcCall.PreExp  = node.PreExp;
            CGFuncCallExp(funcInfo, funcCall, r, 0);
        }
Ejemplo n.º 5
0
        private void CGBinOpExp(FuncInfo funcInfo, DoubleOperationExpNode node, int a)
        {
            switch (node.OpType)
            {
            case TokenType.And:
            case TokenType.Or:
            {
                int b = funcInfo.AllocReg();
                CGExp(funcInfo, node.Exp1, b, 1);
                funcInfo.FreeReg();
                if (node.OpType == TokenType.And)
                {
                    funcInfo.EmitTestSet(a, b, 0);
                }
                else
                {
                    funcInfo.EmitTestSet(a, b, 1);
                }
                int jmpPC = funcInfo.EmitJMP(0, 0);
                int c     = funcInfo.AllocReg();
                CGExp(funcInfo, node.Exp2, c, 1);
                funcInfo.FreeReg();
                funcInfo.EmitMove(a, c);
                funcInfo.FixSBX(jmpPC, funcInfo.PC() - jmpPC);
                break;
            }

            default:
            {
                int b = funcInfo.AllocReg();
                CGExp(funcInfo, node.Exp1, b, 1);
                int c = funcInfo.AllocReg();
                CGExp(funcInfo, node.Exp2, c, 1);
                funcInfo.EmitDoubleOperator(a, b, c, node.OpType);
                funcInfo.FreeRegs(2);
                break;
            }
            }
        }
Ejemplo n.º 6
0
        private void CGConcatExp(FuncInfo funcInfo, ConcatExpNode node, int a)
        {
            foreach (var exp in node.ExpList)
            {
                int r = funcInfo.AllocReg();
                CGExp(funcInfo, exp, r, 1);
            }
            int c = funcInfo.UsedReg - 1;
            int b = node.ExpList.Count - 1;

            funcInfo.FreeRegs(c - b + 1);
            funcInfo.EmitABC(a, b, c, OP.OP_CONCAT);
        }
Ejemplo n.º 7
0
        private void CGRepeatStat(FuncInfo funcInfo, RepeatStatNode node)
        {
            funcInfo.EnterScope(true);
            int blockPC = funcInfo.PC();

            CGBlock(funcInfo, node.Block);

            int r = funcInfo.AllocReg();

            CGExp(funcInfo, node.Exp, r, 1);
            funcInfo.FreeReg();

            funcInfo.EmitTest(r, 0);
            funcInfo.EmitJMP(0, blockPC - funcInfo.PC() - 1);
            funcInfo.ExitScope();
        }
Ejemplo n.º 8
0
        private void CGWhileStat(FuncInfo funcInfo, WhileStatNode node)
        {
            int beforePc = funcInfo.PC();
            int r        = funcInfo.AllocReg();

            CGExp(funcInfo, node.Exp, r, 1);
            funcInfo.FreeReg();
            funcInfo.EmitTest(r, 0);
            int jumPC = funcInfo.EmitJMP(0, 0);

            funcInfo.EnterScope(true);
            CGBlock(funcInfo, node.DoStatNode.Block);
            funcInfo.EmitJMP(0, beforePc - funcInfo.PC());
            funcInfo.ExitScope();
            funcInfo.FixSBX(jumPC, funcInfo.PC() - jumPC);
        }
Ejemplo n.º 9
0
        private int PrepFuncCall(FuncInfo funcInfo, FuncCallExpNode node, int a)
        {
            int  nArgs = node.Args.Count;
            bool lastVarIsVarargOrFuncCall = false;

            CGExp(funcInfo, node.PreExp, a, 1);
            if (node.NameExp.ExpType != ConstExpNode.ConstExpType.NilExp)
            {
                int c = 0x100 + funcInfo.IndexOfConstVar(node.NameExp.name);
                funcInfo.EmitSelf(a, a, c);
            }
            int i = 0;

            foreach (var arg in node.Args)
            {
                int r = funcInfo.AllocReg();
                if (i == nArgs - 1 && IsVarargOrFuncCall(arg))
                {
                    lastVarIsVarargOrFuncCall = true;
                    CGExp(funcInfo, arg, r, -1);
                }
                else
                {
                    CGExp(funcInfo, arg, r, 1);
                }
                i++;
            }
            funcInfo.FreeRegs(nArgs);
            if (node.NameExp.ExpType != ConstExpNode.ConstExpType.NilExp)
            {
                nArgs++;
            }
            if (lastVarIsVarargOrFuncCall)
            {
                nArgs--;
            }
            return(nArgs);
        }
Ejemplo n.º 10
0
        private void CGReturnStat(FuncInfo funcInfo, List <ExpNode> returneExps)
        {
            if (returneExps == null)
            {
                funcInfo.EmitReturn(0, 0);
                return;
            }
            bool muleRet = IsVarargOrFuncCall(returneExps.Last());

            foreach (var exp in returneExps)
            {
                int r = funcInfo.AllocReg();
                if (r == returneExps.Count - 1 && muleRet)
                {
                    CGExp(funcInfo, exp, r, -1);
                }
                else
                {
                    CGExp(funcInfo, exp, r, 1);
                }
            }
            funcInfo.FreeRegs(returneExps.Count);
        }
Ejemplo n.º 11
0
        private void CGIfStat(FuncInfo funcInfo, IfStatNode node)
        {
            var jmpToEndsPC    = new int[node.Exp.Count];
            int jmpToNextExpPc = -1;
            int i = 0;

            foreach (var exp in node.Exp)
            {
                if (jmpToNextExpPc > 0)
                {
                    funcInfo.FixSBX(jmpToNextExpPc, funcInfo.PC() - jmpToNextExpPc);
                }
                int r = funcInfo.AllocReg();
                CGExp(funcInfo, exp, r, 1);
                funcInfo.FreeReg();
                funcInfo.EmitTest(r, 0);
                jmpToNextExpPc = funcInfo.EmitJMP(0, 0);
                funcInfo.EnterScope(false);
                CGBlock(funcInfo, node.Block);
                funcInfo.ExitScope();
                if (i < node.Exp.Count - 1)
                {
                    jmpToEndsPC[i] = funcInfo.EmitJMP(0, 0);
                }
                else
                {
                    jmpToEndsPC[i] = jmpToNextExpPc;
                }
                i++;
            }

            foreach (int j in jmpToEndsPC)
            {
                funcInfo.FixSBX(j, funcInfo.PC() - j);
            }
        }
Ejemplo n.º 12
0
        private void CGAssignStat(FuncInfo funcInfo, AssignStatNode node)
        {
            int nExps   = node.ExpList.Count;
            int nVars   = node.VarList.Count;
            int oldRegs = funcInfo.UsedReg;
            var tRegs   = new int[nVars];
            var kRegs   = new int[nVars];
            var vRegs   = new int[nVars];

            int i = 0;

            foreach (var exp in node.VarList)
            {
                TableAccessExpNode taExp    = null;
                ConstExpNode       constExp = null;
                if ((taExp = exp as TableAccessExpNode) != null)
                {
                    tRegs[i] = funcInfo.AllocReg();
                    CGExp(funcInfo, taExp.PreExp, tRegs[i], 1);

                    kRegs[i] = funcInfo.AllocReg();
                    CGExp(funcInfo, taExp.Exp, kRegs[i], 1);
                }
                i++;
            }
            for (int j = 0; j < nVars; j++)
            {
                vRegs[j] = funcInfo.UsedReg + j;
            }
            if (nExps >= nVars)
            {
                i = 0;
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    if (i > nVars && i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        CGExp(funcInfo, exp, a, 0);
                    }
                    else
                    {
                        CGExp(funcInfo, exp, a, 1);
                    }
                    i++;
                }
            }
            else
            {
                bool multRet = false;
                i = 0;
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    if (i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        multRet = true;
                        int n = nVars - nExps + 1;
                        CGExp(funcInfo, exp, a, n);
                        funcInfo.AllocRegs(n - 1);
                    }
                    else
                    {
                        CGExp(funcInfo, exp, a, 1);
                    }
                    i++;
                }
                if (!multRet)
                {
                    int n = nVars - nExps;
                    int a = funcInfo.AllocRegs(n);
                    funcInfo.EmitLoadNil(a, n);
                }
            }

            i = 0;
            foreach (var exp in node.VarList)
            {
                ConstExpNode varNode = null;
                int          r       = 0;
                if ((varNode = exp as ConstExpNode) != null)
                {
                    var          name = varNode.name;
                    LocalVarInfo info = null;
                    if (funcInfo.VarDic1.TryGetValue(name, out info))
                    {
                        funcInfo.EmitMove(info.RegIndex, vRegs[i]);
                    }
                    else if (funcInfo.UpValOfIndex(name) >= 0)
                    {
                        int b = funcInfo.UpValOfIndex(name);
                        funcInfo.EmitSetUpval(vRegs[i], b);
                    }
                    else if (funcInfo.ConstDic.TryGetValue(varNode.name, out r))
                    {
                        funcInfo.EmitLoadK(vRegs[i], varNode.name);
                    }
                    else //全局变量
                    {
                        int a = funcInfo.UpValOfIndex("_ENV");
                        if (kRegs[i] <= 0)
                        {
                            int b = 0x100 + funcInfo.IndexOfConstVar(name);
                            funcInfo.EmitSetTabUp(a, b, vRegs[i]);
                        }
                        else
                        {
                            funcInfo.EmitSetTabUp(a, kRegs[i], vRegs[i]);
                        }
                    }
                }
                else
                {
                    funcInfo.EmitSetTable(tRegs[i], kRegs[i], vRegs[i]);
                }
                i++;
            }
            funcInfo.UsedReg = oldRegs;
        }
Ejemplo n.º 13
0
        private void CGLocalVarDefStat(FuncInfo funcInfo, LocalVarDecStatNode node)
        {
            int nExps  = node.ExpList.Count;
            int nNames = node.NameList.Count;
            int oldReg = funcInfo.UsedReg;

            if (nExps == nNames)
            {
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    CGExp(funcInfo, exp, a, 1);
                }
            }
            else if (nExps > nNames)
            {
                int i = 0;
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    if (i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        CGExp(funcInfo, exp, a, 0);
                    }
                    else
                    {
                        CGExp(funcInfo, exp, a, 1);
                    }
                    i++;
                }
            }
            else
            {
                bool multRet = false;
                int  i       = 0;
                foreach (var exp in node.ExpList)
                {
                    int a = funcInfo.AllocReg();
                    if (i == nExps - 1 && IsVarargOrFuncCall(exp))
                    {
                        multRet = true;
                        int n = nNames - nExps - 1;
                        CGExp(funcInfo, exp, a, n);
                        funcInfo.AllocRegs(n - 1);
                    }
                    else
                    {
                        CGExp(funcInfo, exp, a, 1);
                    }
                    i++;
                }
                if (!multRet)
                {
                    int n = nNames - nExps;
                    int a = funcInfo.AllocRegs(n);
                    funcInfo.EmitLoadNil(a, n);
                }
            }

            funcInfo.UsedReg = oldReg;
            foreach (var nameNode in node.NameList)
            {
                funcInfo.AddLocalVar(nameNode.name);
            }
        }