Example #1
0
        private static void CgFuncDefExp(FuncInfo fi, FuncDefExp node, int a)
        {
            var subFi = new FuncInfo(fi, node);

            fi.SubFuncs.Add(subFi);

            foreach (var param in node.ParList)
            {
                subFi.AddLocVar(param);
            }

            CgBlock(subFi, node.Block);
            subFi.ExitScope();
            subFi.EmitReturn(0, 0);
            var bx = fi.SubFuncs.Count - 1;

            fi.EmitClosure(a, bx);
        }
Example #2
0
        private static void CgRetStat(FuncInfo fi, List <Exp> exps)
        {
            var nExps = exps.Count;

            if (nExps == 0)
            {
                fi.EmitReturn(0, 0);
                return;
            }

            if (nExps == 1)
            {
                if (exps[0] is NameExp nameExp)
                {
                    var r = fi.SlotOfLocVar(nameExp.Name);
                    if (r >= 0)
                    {
                        fi.EmitReturn(r, 1);
                        return;
                    }
                }

                if (exps[0] is FuncCallExp fcExp)
                {
                    var r = fi.AllocReg();
                    CgTailCallExp(fi, fcExp, r);
                    fi.FreeReg();
                    fi.EmitReturn(r, -1);
                    return;
                }
            }

            var multRet = IsVarargOrFuncCall(exps[nExps - 1]);

            for (var i = 0; i < nExps; i++)
            {
                var exp = exps[i];
                var r   = fi.AllocReg();

                if (i == nExps - 1 && multRet)
                {
                    CgExp(fi, exp, r, -1);
                }
                else
                {
                    CgExp(fi, exp, r, 1);
                }
            }

            fi.FreeRegs(nExps);

            var a = fi.UsedRegs;

            if (multRet)
            {
                fi.EmitReturn(a, -1);
            }
            else
            {
                fi.EmitReturn(a, nExps);
            }
        }