Beispiel #1
0
        private void CGForInStat(FuncInfo funcInfo, ForInStatNode node)
        {
            funcInfo.EnterScope(true);
            LocalVarDecStatNode varDecStatNode = new LocalVarDecStatNode();

            varDecStatNode.ExpList  = node.ExpList;
            varDecStatNode.NameList = new List <ConstExpNode>()
            {
                new ConstExpNode(new Token(TokenType.Identifier, "for_generator", -1)),
                new ConstExpNode(new Token(TokenType.Identifier, "for_state", -1)),
                new ConstExpNode(new Token(TokenType.Identifier, "for_control", -1))
            };

            foreach (var name in node.NameList.NameList)
            {
                funcInfo.AddLocalVar(name.name);
            }

            int jmpToTFCPC = funcInfo.EmitJMP(0, 0);

            CGBlock(funcInfo, node.DoBlock.Block);
            funcInfo.FixSBX(jmpToTFCPC, funcInfo.PC() - jmpToTFCPC);
            var geneartor = funcInfo.VarDic1["for_generator"];

            funcInfo.EmitTForCall(geneartor.RegIndex, node.NameList.NameList.Count);
            funcInfo.EmitTForLoop(geneartor.RegIndex + 2, jmpToTFCPC - funcInfo.PC() - 1);
            funcInfo.ExitScope();
        }
Beispiel #2
0
        private void CGForNumStat(FuncInfo funcInfo, ForNumStatNode node)
        {
            funcInfo.EnterScope(true);
            LocalVarDecStatNode varDecStatNode = new LocalVarDecStatNode();

            varDecStatNode.ExpList = new List <ExpNode>()
            {
                node.InitExp, node.LimitExp, node.StepExp
            };
            if (node.StepExp == null)
            {
                varDecStatNode.ExpList[2] = new ConstExpNode(new Token(TokenType.Number, "1", -1));
            }
            varDecStatNode.NameList = new List <ConstExpNode>()
            {
                new ConstExpNode(new Token(TokenType.Identifier, "for_index", -1)),
                new ConstExpNode(new Token(TokenType.Identifier, "for_limit", -1)),
                new ConstExpNode(new Token(TokenType.Identifier, "for_step", -1))
            };
            CGLocalVarDefStat(funcInfo, varDecStatNode);
            funcInfo.AddLocalVar(node.VarName.name);
            int a         = funcInfo.UsedReg - 4;
            int forPrepPC = funcInfo.EmitForPrep(a, 0);

            CGBlock(funcInfo, node.DoBlock.Block);
            int forLoopPC = funcInfo.EmitForLoop(a, 0);

            funcInfo.FixSBX(forPrepPC, forLoopPC - forPrepPC - 1);
            funcInfo.FixSBX(forLoopPC, forPrepPC - forLoopPC - 1);
            funcInfo.ExitScope();
        }
Beispiel #3
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);
            }
        }