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