示例#1
0
 private static void anchor_token(LexState ls)
 {
     if (ls.t.token == (int)RESERVED.TK_NAME || ls.t.token == (int)RESERVED.TK_STRING)
     {
         TString ts = ls.t.seminfo.ts;
         Lua.luaX_newstring(ls, Lua.getstr(ts), ts.tsv.len);
     }
 }
示例#2
0
 private static int testnext(LexState ls, int c)
 {
     if (ls.t.token == c)
     {
         Lua.luaX_next(ls);
         return 1;
     }
     else return 0;
 }
示例#3
0
 private static void adjust_assign(LexState ls, int nvars, int nexps, expdesc e)
 {
     FuncState fs = ls.fs;
     int extra = nvars - nexps;
     if (hasmultret(e.k) != 0)
     {
         extra++;  /* includes call itself */
         if (extra < 0) extra = 0;
         Lua.luaK_setreturns(fs, e, extra);  /* last exp. provides the difference */
         if (extra > 1) Lua.luaK_reserveregs(fs, extra - 1);
     }
     else
     {
         if (e.k != expkind.VVOID) Lua.luaK_exp2nextreg(fs, e);  /* close last expression */
         if (extra > 0)
         {
             int reg = fs.freereg;
             Lua.luaK_reserveregs(fs, extra);
             Lua.luaK_nil(fs, reg, extra);
         }
     }
 }
示例#4
0
 private static void expr(LexState ls, expdesc v)
 {
     subexpr(ls, v, 0);
 }
示例#5
0
 private static void check_match(LexState ls, int what, int who, int where)
 {
     if (testnext(ls, what) == 0)
     {
         if (where == ls.linenumber)
             error_expected(ls, what);
         else
         {
             Lua.luaX_syntaxerror(ls, Lua.luaO_pushfstring(ls.L,
                                                   Lua.LUA_QS + " expected (to close " + Lua.LUA_QS + " at line %d)",
                                                   Lua.luaX_token2str(ls, what), Lua.luaX_token2str(ls, who), where));
         }
     }
 }
示例#6
0
 private static void simpleexp(LexState ls, expdesc v)
 {
     /* simpleexp . NUMBER | STRING | NIL | true | false | ... |
                   constructor | FUNCTION body | primaryexp */
     switch (ls.t.token)
     {
         case (int)RESERVED.TK_NUMBER:
             {
                 init_exp(v, expkind.VKNUM, 0);
                 v.u.nval = ls.t.seminfo.r;
                 break;
             }
         case (int)RESERVED.TK_STRING:
             {
                 codestring(ls, v, ls.t.seminfo.ts);
                 break;
             }
         case (int)RESERVED.TK_NIL:
             {
                 init_exp(v, expkind.VNIL, 0);
                 break;
             }
         case (int)RESERVED.TK_TRUE:
             {
                 init_exp(v, expkind.VTRUE, 0);
                 break;
             }
         case (int)RESERVED.TK_FALSE:
             {
                 init_exp(v, expkind.VFALSE, 0);
                 break;
             }
         case (int)RESERVED.TK_DOTS:
             {  /* vararg */
                 FuncState fs = ls.fs;
                 check_condition(ls, fs.f.is_vararg != 0,
                                 "cannot use " + Lua.LUA_QL("...") + " outside a vararg function");
                 fs.f.is_vararg &= unchecked((lu_byte)(~Lua.VARARG_NEEDSARG));  /* don't need 'arg' */
                 init_exp(v, expkind.VVARARG, Lua.luaK_codeABC(fs, OpCode.OP_VARARG, 0, 1, 0));
                 break;
             }
         case '{':
             {  /* constructor */
                 constructor(ls, v);
                 return;
             }
         case (int)RESERVED.TK_FUNCTION:
             {
                 Lua.luaX_next(ls);
                 body(ls, v, 0, ls.linenumber);
                 return;
             }
         default:
             {
                 primaryexp(ls, v);
                 return;
             }
     }
     Lua.luaX_next(ls);
 }
示例#7
0
 private static void primaryexp(LexState ls, expdesc v)
 {
     /* primaryexp .
         prefixexp { `.' NAME | `[' exp `]' | `:' NAME funcargs | funcargs } */
     FuncState fs = ls.fs;
     prefixexp(ls, v);
     for (; ; )
     {
         switch (ls.t.token)
         {
             case '.':
                 {  /* field */
                     field(ls, v);
                     break;
                 }
             case '[':
                 {  /* `[' exp1 `]' */
                     expdesc key = new expdesc();
                     Lua.luaK_exp2anyreg(fs, v);
                     yindex(ls, key);
                     Lua.luaK_indexed(fs, v, key);
                     break;
                 }
             case ':':
                 {  /* `:' NAME funcargs */
                     expdesc key = new expdesc();
                     Lua.luaX_next(ls);
                     checkname(ls, key);
                     Lua.luaK_self(fs, v, key);
                     funcargs(ls, v);
                     break;
                 }
             case '(':
             case (int)RESERVED.TK_STRING:
             case '{':
                 {  /* funcargs */
                     Lua.luaK_exp2nextreg(fs, v);
                     funcargs(ls, v);
                     break;
                 }
             default: return;
         }
     }
 }
示例#8
0
 private static void check(LexState ls, int c)
 {
     if (ls.t.token != c)
         error_expected(ls, c);
 }
示例#9
0
 private static int explist1(LexState ls, expdesc v)
 {
     /* explist1 . expr { `,' expr } */
     int n = 1;  /* at least one expression */
     expr(ls, v);
     while (testnext(ls, ',') != 0)
     {
         Lua.luaK_exp2nextreg(ls.fs, v);
         expr(ls, v);
         n++;
     }
     return n;
 }
示例#10
0
 public static Proto luaY_parser(LuaState L, ZIO z, Mbuffer buff, CharPtr name)
 {
     LexState lexstate = new LexState();
     FuncState funcstate = new FuncState();
     lexstate.buff = buff;
     Lua.luaX_setinput(L, lexstate, z, Lua.luaS_new(L, name));
     open_func(lexstate, funcstate);
     funcstate.f.is_vararg = Lua.VARARG_ISVARARG;  /* main func. is always vararg */
     Lua.luaX_next(lexstate);  /* read first token */
     System.Threading.Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
     chunk(lexstate);
     check(lexstate, (int)RESERVED.TK_EOS);
     close_func(lexstate);
     Lua.lua_assert(funcstate.prev == null);
     Lua.lua_assert(funcstate.f.nups == 0);
     Lua.lua_assert(lexstate.fs == null);
     return funcstate.f;
 }
示例#11
0
 private static void close_func(LexState ls)
 {
     LuaState L = ls.L;
     FuncState fs = ls.fs;
     Proto f = fs.f;
     removevars(ls, 0);
     Lua.luaK_ret(fs, 0, 0);  /* final return */
     Lua.luaM_reallocvector(L, ref f.code, f.sizecode, fs.pc/*, typeof(Instruction)*/);
     f.sizecode = fs.pc;
     Lua.luaM_reallocvector(L, ref f.lineinfo, f.sizelineinfo, fs.pc/*, typeof(int)*/);
     f.sizelineinfo = fs.pc;
     Lua.luaM_reallocvector(L, ref f.k, f.sizek, fs.nk/*, TValue*/);
     f.sizek = fs.nk;
     Lua.luaM_reallocvector(L, ref f.p, f.sizep, fs.np/*, Proto*/);
     f.sizep = fs.np;
     for (int i = 0; i < f.p.Length; i++)
     {
         f.p[i].protos = f.p;
         f.p[i].index = i;
     }
     Lua.luaM_reallocvector(L, ref f.locvars, f.sizelocvars, fs.nlocvars/*, LocVar*/);
     f.sizelocvars = fs.nlocvars;
     Lua.luaM_reallocvector(L, ref f.upvalues, f.sizeupvalues, f.nups/*, TString*/);
     f.sizeupvalues = f.nups;
     Lua.lua_assert(Lua.luaG_checkcode(f));
     Lua.lua_assert(fs.bl == null);
     ls.fs = fs.prev;
     /* last token read was anchored in defunct function; must reanchor it */
     if (fs != null) anchor_token(ls);
     L.top -= 2;  /* remove table and prototype from the stack */
 }
示例#12
0
 private static void open_func(LexState ls, FuncState fs)
 {
     LuaState L = ls.L;
     Proto f = Lua.luaF_newproto(L);
     fs.f = f;
     fs.prev = ls.fs;  /* linked list of funcstates */
     fs.ls = ls;
     fs.L = L;
     ls.fs = fs;
     fs.pc = 0;
     fs.lasttarget = -1;
     fs.jpc = Lua.NO_JUMP;
     fs.freereg = 0;
     fs.nk = 0;
     fs.np = 0;
     fs.nlocvars = 0;
     fs.nactvar = 0;
     fs.bl = null;
     f.source = ls.source;
     f.maxstacksize = 2;  /* registers 0/1 are always valid */
     fs.h = Lua.luaH_new(L, 0, 0);
     /* anchor table of constants and prototype (to avoid being collected) */
     Lua.sethvalue2s(L, L.top, fs.h);
     Lua.incr_top(L);
     Lua.setptvalue2s(L, L.top, f);
     Lua.incr_top(L);
 }
示例#13
0
 private static void pushclosure(LexState ls, FuncState func, expdesc v)
 {
     FuncState fs = ls.fs;
     Proto f = fs.f;
     int oldsize = f.sizep;
     int i;
     Lua.luaM_growvector(ls.L, ref f.p, fs.np, ref f.sizep,
                     Lua.MAXARG_Bx, "constant table overflow");
     while (oldsize < f.sizep) f.p[oldsize++] = null;
     f.p[fs.np++] = func.f;
     Lua.luaC_objbarrier(ls.L, f, func.f);
     init_exp(v, expkind.VRELOCABLE, Lua.luaK_codeABx(fs, OpCode.OP_CLOSURE, 0, fs.np - 1));
     for (i = 0; i < func.f.nups; i++)
     {
         OpCode o = ((int)func.upvalues[i].k == (int)expkind.VLOCAL) ? OpCode.OP_MOVE : OpCode.OP_GETUPVAL;
         Lua.luaK_codeABC(fs, o, 0, func.upvalues[i].info, 0);
     }
 }
示例#14
0
 private static void leavelevel(LexState ls)
 {
     ls.L.nCcalls--;
 }
示例#15
0
 private static void enterlevel(LexState ls)
 {
     if (++ls.L.nCcalls > Lua.LUAI_MAXCCALLS)
         Lua.luaX_lexerror(ls, "chunk has too many syntax levels", 0);
 }
示例#16
0
        /*============================================================*/
        /* GRAMMAR RULES */
        /*============================================================*/

        private static void field(LexState ls, expdesc v)
        {
            /* field . ['.' | ':'] NAME */
            FuncState fs = ls.fs;
            expdesc key = new expdesc();
            Lua.luaK_exp2anyreg(fs, v);
            Lua.luaX_next(ls);  /* skip the dot or colon */
            checkname(ls, key);
            Lua.luaK_indexed(fs, v, key);
        }
示例#17
0
 private static void body(LexState ls, expdesc e, int needself, int line)
 {
     /* body .  `(' parlist `)' chunk END */
     FuncState new_fs = new FuncState();
     open_func(ls, new_fs);
     new_fs.f.linedefined = line;
     checknext(ls, '(');
     if (needself != 0)
     {
         new_localvarliteral(ls, "self", 0);
         adjustlocalvars(ls, 1);
     }
     parlist(ls);
     checknext(ls, ')');
     chunk(ls);
     new_fs.f.lastlinedefined = ls.linenumber;
     check_match(ls, (int)RESERVED.TK_END, (int)RESERVED.TK_FUNCTION, line);
     close_func(ls);
     pushclosure(ls, new_fs, e);
 }
示例#18
0
        private static void yindex(LexState ls, expdesc v)
        {
            /* index . '[' expr ']' */

            //luaX_next(ls);  /* skip the '[' */
            //expr(ls, v);
            //luaK_exp2val(ls.fs, v);
            //checknext(ls, ']');

            Lua.luaX_next(ls); /* skip the '[' */
            do
            {
                expr(ls, v);
                Lua.luaK_exp2val(ls.fs, v);

                //yindex(ls, key);
                //luaK_indexed(ls.fs, v, key);
            } while (testnext(ls, ',') == 1);
            checknext(ls, ']');
        }
示例#19
0
        private static void funcargs(LexState ls, expdesc f)
        {
            FuncState fs = ls.fs;
            expdesc args = new expdesc();
            int base_, nparams;
            int line = ls.linenumber;
            switch (ls.t.token)
            {
                case '(':
                    {  /* funcargs . `(' [ explist1 ] `)' */
                        if (line != ls.lastline)
                            Lua.luaX_syntaxerror(ls, "ambiguous syntax (function call x new statement)");
                        Lua.luaX_next(ls);
                        if (ls.t.token == ')')  /* arg list is empty? */
                            args.k = expkind.VVOID;
                        else
                        {
                            explist1(ls, args);
                            Lua.luaK_setmultret(fs, args);
                        }
                        check_match(ls, ')', '(', line);
                        break;
                    }
                case '{':
                    {  /* funcargs . constructor */
                        constructor(ls, args);
                        break;
                    }
                case (int)RESERVED.TK_STRING:
                    {  /* funcargs . STRING */
                        codestring(ls, args, ls.t.seminfo.ts);
                        Lua.luaX_next(ls);  /* must use `seminfo' before `next' */
                        break;
                    }
                default:
                    {
                        Lua.luaX_syntaxerror(ls, "function arguments expected");
                        return;
                    }
            }
            Lua.lua_assert(f.k == expkind.VNONRELOC);
            base_ = f.u.s.info;  /* base_ register for call */
            if (hasmultret(args.k) != 0)
                nparams = Lua.LUA_MULTRET;  /* open call */
            else
            {
                if (args.k != expkind.VVOID)
                    Lua.luaK_exp2nextreg(fs, args);  /* close last argument */
                nparams = fs.freereg - (base_ + 1);
            }
            init_exp(f, expkind.VCALL, Lua.luaK_codeABC(fs, OpCode.OP_CALL, base_, nparams + 1, 2));
            Lua.luaK_fixline(fs, line);
            fs.freereg = base_ + 1;  /* call remove function and arguments and leaves
									(unless changed) one result */
        }
示例#20
0
 private static void error_expected(LexState ls, int token)
 {
     Lua.luaX_syntaxerror(ls,
                      Lua.luaO_pushfstring(ls.L, Lua.LUA_QS + " expected", Lua.luaX_token2str(ls, token)));
 }
示例#21
0
        /*
         ** {======================================================================
         ** Expression parsing
         ** =======================================================================
         */

        private static void prefixexp(LexState ls, expdesc v)
        {
            /* prefixexp . NAME | '(' expr ')' */
            switch (ls.t.token)
            {
                case '(':
                    {
                        int line = ls.linenumber;
                        Lua.luaX_next(ls);
                        expr(ls, v);
                        check_match(ls, ')', '(', line);
                        Lua.luaK_dischargevars(ls.fs, v);
                        return;
                    }
                case (int)RESERVED.TK_NAME:
                    {
                        singlevar(ls, v);
                        return;
                    }
                default:
                    {
                        Lua.luaX_syntaxerror(ls, "unexpected symbol");
                        return;
                    }
            }
        }
示例#22
0
 private static void recfield(LexState ls, ConsControl cc)
 {
     /* recfield . (NAME | `['exp1`]') = exp1 */
     /* recfield -> FUNCTION funcname body */
     FuncState fs = ls.fs;
     int reg = ls.fs.freereg;
     expdesc key = new expdesc(), val = new expdesc();
     int rkkey;
     if (ls.t.token == (int)RESERVED.TK_NAME)
     {
         luaY_checklimit(fs, cc.nh, Lua.MAX_INT, "items in a constructor");
         checkname(ls, key);
     }
     else  /* ls.t.token == '[' */
         yindex(ls, key);
     cc.nh++;
     checknext(ls, '=');
     rkkey = Lua.luaK_exp2RK(fs, key);
     expr(ls, val);
     Lua.luaK_codeABC(fs, OpCode.OP_SETTABLE, cc.t.u.s.info, rkkey, Lua.luaK_exp2RK(fs, val));
     fs.freereg = reg;  /* free registers */
 }
示例#23
0
 private static void checknext(LexState ls, int c)
 {
     check(ls, c);
     Lua.luaX_next(ls);
 }
示例#24
0
 private static void listfield(LexState ls, ConsControl cc)
 {
     expr(ls, cc.v);
     luaY_checklimit(ls.fs, cc.na, Lua.MAX_INT, "items in a constructor");
     cc.na++;
     cc.tostore++;
 }
示例#25
0
 public static void check_condition(LexState ls, bool c, CharPtr msg)
 {
     if (!(c))
         Lua.luaX_syntaxerror(ls, msg);
 }
示例#26
0
 private static void constructor(LexState ls, expdesc t)
 {
     /* constructor . ?? */
     FuncState fs = ls.fs;
     int line = ls.linenumber;
     int pc = Lua.luaK_codeABC(fs, OpCode.OP_NEWTABLE, 0, 0, 0);
     ConsControl cc = new ConsControl();
     cc.na = cc.nh = cc.tostore = 0;
     cc.t = t;
     init_exp(t, expkind.VRELOCABLE, pc);
     init_exp(cc.v, expkind.VVOID, 0);  /* no value (yet) */
     Lua.luaK_exp2nextreg(ls.fs, t);  /* fix it at stack top (for gc) */
     checknext(ls, '{');
     do
     {
         Lua.lua_assert(cc.v.k == expkind.VVOID || cc.tostore > 0);
         if (ls.t.token == '}') break;
         closelistfield(fs, cc);
         switch (ls.t.token)
         {
             case (int)RESERVED.TK_NAME:
                 {  /* may be listfields or recfields */
                     Lua.luaX_lookahead(ls);
                     if (ls.lookahead.token != '=')  /* expression? */
                         listfield(ls, cc);
                     else
                         recfield(ls, cc);
                     break;
                 }
             case '[':
                 {  /* constructor_item . recfield */
                     recfield(ls, cc);
                     break;
                 }
             default:
                 {  /* constructor_part . listfield */
                     listfield(ls, cc);
                     break;
                 }
         }
     } while ((testnext(ls, ',') != 0) || (testnext(ls, ';') != 0));
     check_match(ls, '}', '{', line);
     lastlistfield(fs, cc);
     Lua.SETARG_B(new InstructionPtr(fs.f.code, pc), Lua.luaO_int2fb((uint)cc.na)); /* set initial array size */
     Lua.SETARG_C(new InstructionPtr(fs.f.code, pc), Lua.luaO_int2fb((uint)cc.nh));  /* set initial table size */
 }
示例#27
0
        public const int UNARY_PRIORITY = 8;  /* priority for unary operators */

        /*
         ** subexpr . (simpleexp | unop subexpr) { binop subexpr }
         ** where `binop' is any binary operator with a priority higher than `limit'
         */

        private static BinOpr subexpr(LexState ls, expdesc v, uint limit)
        {
            BinOpr op = new BinOpr();
            UnOpr uop = new UnOpr();
            enterlevel(ls);
            uop = getunopr(ls.t.token);
            if (uop != UnOpr.OPR_NOUNOPR)
            {
                Lua.luaX_next(ls);
                subexpr(ls, v, UNARY_PRIORITY);
                Lua.luaK_prefix(ls.fs, uop, v);
            }
            else
                simpleexp(ls, v);
            /* expand while operators have priorities higher than `limit' */
            op = getbinopr(ls.t.token);
            while (op != BinOpr.OPR_NOBINOPR && priority[(int)op].left > limit)
            {
                expdesc v2 = new expdesc();
                BinOpr nextop;
                Lua.luaX_next(ls);
                Lua.luaK_infix(ls.fs, op, v);
                /* read sub-expression with higher priority */
                nextop = subexpr(ls, v2, priority[(int)op].right);
                Lua.luaK_posfix(ls.fs, op, v, v2);
                op = nextop;
            }
            leavelevel(ls);
            return op;  /* return first untreated operator */
        }
示例#28
0
        /* }====================================================================== */

        private static void parlist(LexState ls)
        {
            /* parlist . [ param { `,' param } ] */
            FuncState fs = ls.fs;
            Proto f = fs.f;
            int nparams = 0;
            f.is_vararg = 0;
#if IMPLICIT_VARARG
            bool wasvararg = false; // if the parlist contains a '...'
#endif
            if (ls.t.token != ')')
            {  /* is `parlist' not empty? */
                do
                {
                    switch (ls.t.token)
                    {
                        case (int)RESERVED.TK_NAME:
                            {  /* param . NAME */
                                new_localvar(ls, str_checkname(ls), nparams++);
                                break;
                            }
                        case (int)RESERVED.TK_DOTS:
                            {  /* param . `...' */
#if IMPLICIT_VARARG
                                wasvararg = true;
#endif
                                Lua.luaX_next(ls);
#if LUA_COMPAT_VARARG
                                /* use `arg' as default name */
                                new_localvarliteral(ls, "arg", nparams++);
                                f.is_vararg = Lua.VARARG_HASARG | Lua.VARARG_NEEDSARG;
#endif
                                f.is_vararg |= Lua.VARARG_ISVARARG;
                                break;
                            }
                        default: Lua.luaX_syntaxerror(ls, "<name> or " + Lua.LUA_QL("...") + " expected"); break;
                    }
                } while ((f.is_vararg == 0) && (testnext(ls, ',') != 0));
            }
#if IMPLICIT_VARARG
            if (wasvararg == false)
            {
#if LUA_COMPAT_VARARG
                /* use `arg' as default name */
                new_localvarliteral(ls, "arg", nparams++);
                f.is_vararg = Lua.VARARG_HASARG | Lua.VARARG_NEEDSARG;
#else
                f.is_vararg = 0;
#endif

                f.is_vararg |= Lua.VARARG_ISVARARG;
            }
#endif
            adjustlocalvars(ls, nparams);
            f.numparams = Lua.cast_byte(fs.nactvar - (f.is_vararg & Lua.VARARG_HASARG));
            Lua.luaK_reserveregs(fs, fs.nactvar);  /* reserve register for parameters */
        }
示例#29
0
 private static void block(LexState ls)
 {
     /* block . chunk */
     FuncState fs = ls.fs;
     BlockCnt bl = new BlockCnt();
     enterblock(fs, bl, 0);
     chunk(ls);
     Lua.lua_assert(bl.breaklist == Lua.NO_JUMP);
     leaveblock(fs);
 }
示例#30
0
 private static void singlevar(LexState ls, expdesc var)
 {
     TString varname = str_checkname(ls);
     FuncState fs = ls.fs;
     if (singlevaraux(fs, varname, var, 1) == expkind.VGLOBAL)
         var.u.s.info = Lua.luaK_stringK(fs, varname);  /* info points to global name */
 }