private void CGNameExp(FuncInfo funcInfo, ConstExpNode node, int a)
        {
            LocalVarInfo varInfo = null;
            int          r       = 0;

            if (funcInfo.VarDic1.TryGetValue(node.name, out varInfo))
            {
                funcInfo.EmitMove(a, varInfo.RegIndex);
            }
            else if (funcInfo.UpValOfIndex(node.name) != -1)
            {
                r = funcInfo.UpValOfIndex(node.name);
                funcInfo.EmitGetUpval(a, r);
            }
            //else if (funcInfo.ConstDic.TryGetValue(node.name, out r))
            //   {
            //       funcInfo.EmitLoadK(a, node.name);
            //   }
            else
            {
                var exp = new TableAccessExpNode();
                exp.PreExp = new ConstExpNode(new Token(TokenType.Identifier, "_ENV", -1));
                exp.Exp    = new ConstExpNode(new Token(TokenType.String, node.name, -1));
                CGTableAccessExp(funcInfo, exp, a);
            }
        }
 private void CGVarargExp(FuncInfo funcInfo, ConstExpNode node, int a, int n)
 {
     if (!funcInfo.IsVararg)
     {
         throw new Exception("this function is not use ... beacuse it is not vararg function");
     }
     else
     {
         funcInfo.EmitVararg(a, n);
     }
 }
        private bool IsVarargOrFuncCall(ExpNode node)
        {
            switch (node.Type)
            {
            case GrammarNodeType.FuncCallExp:
                return(true);
            }
            ConstExpNode cNode = null;

            if (node is ConstExpNode)
            {
                cNode = node as ConstExpNode;
                if (cNode.ExpType == ConstExpNode.ConstExpType.VarargExp)
                {
                    return(true);
                }
            }
            return(false);
        }
        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;
        }