1*8e3e3a7aSWarner Losh /* 2*8e3e3a7aSWarner Losh ** $Id: lparser.h,v 1.76 2015/12/30 18:16:13 roberto Exp $ 3*8e3e3a7aSWarner Losh ** Lua Parser 4*8e3e3a7aSWarner Losh ** See Copyright Notice in lua.h 5*8e3e3a7aSWarner Losh */ 6*8e3e3a7aSWarner Losh 7*8e3e3a7aSWarner Losh #ifndef lparser_h 8*8e3e3a7aSWarner Losh #define lparser_h 9*8e3e3a7aSWarner Losh 10*8e3e3a7aSWarner Losh #include "llimits.h" 11*8e3e3a7aSWarner Losh #include "lobject.h" 12*8e3e3a7aSWarner Losh #include "lzio.h" 13*8e3e3a7aSWarner Losh 14*8e3e3a7aSWarner Losh 15*8e3e3a7aSWarner Losh /* 16*8e3e3a7aSWarner Losh ** Expression and variable descriptor. 17*8e3e3a7aSWarner Losh ** Code generation for variables and expressions can be delayed to allow 18*8e3e3a7aSWarner Losh ** optimizations; An 'expdesc' structure describes a potentially-delayed 19*8e3e3a7aSWarner Losh ** variable/expression. It has a description of its "main" value plus a 20*8e3e3a7aSWarner Losh ** list of conditional jumps that can also produce its value (generated 21*8e3e3a7aSWarner Losh ** by short-circuit operators 'and'/'or'). 22*8e3e3a7aSWarner Losh */ 23*8e3e3a7aSWarner Losh 24*8e3e3a7aSWarner Losh /* kinds of variables/expressions */ 25*8e3e3a7aSWarner Losh typedef enum { 26*8e3e3a7aSWarner Losh VVOID, /* when 'expdesc' describes the last expression a list, 27*8e3e3a7aSWarner Losh this kind means an empty list (so, no expression) */ 28*8e3e3a7aSWarner Losh VNIL, /* constant nil */ 29*8e3e3a7aSWarner Losh VTRUE, /* constant true */ 30*8e3e3a7aSWarner Losh VFALSE, /* constant false */ 31*8e3e3a7aSWarner Losh VK, /* constant in 'k'; info = index of constant in 'k' */ 32*8e3e3a7aSWarner Losh VKFLT, /* floating constant; nval = numerical float value */ 33*8e3e3a7aSWarner Losh VKINT, /* integer constant; nval = numerical integer value */ 34*8e3e3a7aSWarner Losh VNONRELOC, /* expression has its value in a fixed register; 35*8e3e3a7aSWarner Losh info = result register */ 36*8e3e3a7aSWarner Losh VLOCAL, /* local variable; info = local register */ 37*8e3e3a7aSWarner Losh VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 38*8e3e3a7aSWarner Losh VINDEXED, /* indexed variable; 39*8e3e3a7aSWarner Losh ind.vt = whether 't' is register or upvalue; 40*8e3e3a7aSWarner Losh ind.t = table register or upvalue; 41*8e3e3a7aSWarner Losh ind.idx = key's R/K index */ 42*8e3e3a7aSWarner Losh VJMP, /* expression is a test/comparison; 43*8e3e3a7aSWarner Losh info = pc of corresponding jump instruction */ 44*8e3e3a7aSWarner Losh VRELOCABLE, /* expression can put result in any register; 45*8e3e3a7aSWarner Losh info = instruction pc */ 46*8e3e3a7aSWarner Losh VCALL, /* expression is a function call; info = instruction pc */ 47*8e3e3a7aSWarner Losh VVARARG /* vararg expression; info = instruction pc */ 48*8e3e3a7aSWarner Losh } expkind; 49*8e3e3a7aSWarner Losh 50*8e3e3a7aSWarner Losh 51*8e3e3a7aSWarner Losh #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXED) 52*8e3e3a7aSWarner Losh #define vkisinreg(k) ((k) == VNONRELOC || (k) == VLOCAL) 53*8e3e3a7aSWarner Losh 54*8e3e3a7aSWarner Losh typedef struct expdesc { 55*8e3e3a7aSWarner Losh expkind k; 56*8e3e3a7aSWarner Losh union { 57*8e3e3a7aSWarner Losh lua_Integer ival; /* for VKINT */ 58*8e3e3a7aSWarner Losh lua_Number nval; /* for VKFLT */ 59*8e3e3a7aSWarner Losh int info; /* for generic use */ 60*8e3e3a7aSWarner Losh struct { /* for indexed variables (VINDEXED) */ 61*8e3e3a7aSWarner Losh short idx; /* index (R/K) */ 62*8e3e3a7aSWarner Losh lu_byte t; /* table (register or upvalue) */ 63*8e3e3a7aSWarner Losh lu_byte vt; /* whether 't' is register (VLOCAL) or upvalue (VUPVAL) */ 64*8e3e3a7aSWarner Losh } ind; 65*8e3e3a7aSWarner Losh } u; 66*8e3e3a7aSWarner Losh int t; /* patch list of 'exit when true' */ 67*8e3e3a7aSWarner Losh int f; /* patch list of 'exit when false' */ 68*8e3e3a7aSWarner Losh } expdesc; 69*8e3e3a7aSWarner Losh 70*8e3e3a7aSWarner Losh 71*8e3e3a7aSWarner Losh /* description of active local variable */ 72*8e3e3a7aSWarner Losh typedef struct Vardesc { 73*8e3e3a7aSWarner Losh short idx; /* variable index in stack */ 74*8e3e3a7aSWarner Losh } Vardesc; 75*8e3e3a7aSWarner Losh 76*8e3e3a7aSWarner Losh 77*8e3e3a7aSWarner Losh /* description of pending goto statements and label statements */ 78*8e3e3a7aSWarner Losh typedef struct Labeldesc { 79*8e3e3a7aSWarner Losh TString *name; /* label identifier */ 80*8e3e3a7aSWarner Losh int pc; /* position in code */ 81*8e3e3a7aSWarner Losh int line; /* line where it appeared */ 82*8e3e3a7aSWarner Losh lu_byte nactvar; /* local level where it appears in current block */ 83*8e3e3a7aSWarner Losh } Labeldesc; 84*8e3e3a7aSWarner Losh 85*8e3e3a7aSWarner Losh 86*8e3e3a7aSWarner Losh /* list of labels or gotos */ 87*8e3e3a7aSWarner Losh typedef struct Labellist { 88*8e3e3a7aSWarner Losh Labeldesc *arr; /* array */ 89*8e3e3a7aSWarner Losh int n; /* number of entries in use */ 90*8e3e3a7aSWarner Losh int size; /* array size */ 91*8e3e3a7aSWarner Losh } Labellist; 92*8e3e3a7aSWarner Losh 93*8e3e3a7aSWarner Losh 94*8e3e3a7aSWarner Losh /* dynamic structures used by the parser */ 95*8e3e3a7aSWarner Losh typedef struct Dyndata { 96*8e3e3a7aSWarner Losh struct { /* list of active local variables */ 97*8e3e3a7aSWarner Losh Vardesc *arr; 98*8e3e3a7aSWarner Losh int n; 99*8e3e3a7aSWarner Losh int size; 100*8e3e3a7aSWarner Losh } actvar; 101*8e3e3a7aSWarner Losh Labellist gt; /* list of pending gotos */ 102*8e3e3a7aSWarner Losh Labellist label; /* list of active labels */ 103*8e3e3a7aSWarner Losh } Dyndata; 104*8e3e3a7aSWarner Losh 105*8e3e3a7aSWarner Losh 106*8e3e3a7aSWarner Losh /* control of blocks */ 107*8e3e3a7aSWarner Losh struct BlockCnt; /* defined in lparser.c */ 108*8e3e3a7aSWarner Losh 109*8e3e3a7aSWarner Losh 110*8e3e3a7aSWarner Losh /* state needed to generate code for a given function */ 111*8e3e3a7aSWarner Losh typedef struct FuncState { 112*8e3e3a7aSWarner Losh Proto *f; /* current function header */ 113*8e3e3a7aSWarner Losh struct FuncState *prev; /* enclosing function */ 114*8e3e3a7aSWarner Losh struct LexState *ls; /* lexical state */ 115*8e3e3a7aSWarner Losh struct BlockCnt *bl; /* chain of current blocks */ 116*8e3e3a7aSWarner Losh int pc; /* next position to code (equivalent to 'ncode') */ 117*8e3e3a7aSWarner Losh int lasttarget; /* 'label' of last 'jump label' */ 118*8e3e3a7aSWarner Losh int jpc; /* list of pending jumps to 'pc' */ 119*8e3e3a7aSWarner Losh int nk; /* number of elements in 'k' */ 120*8e3e3a7aSWarner Losh int np; /* number of elements in 'p' */ 121*8e3e3a7aSWarner Losh int firstlocal; /* index of first local var (in Dyndata array) */ 122*8e3e3a7aSWarner Losh short nlocvars; /* number of elements in 'f->locvars' */ 123*8e3e3a7aSWarner Losh lu_byte nactvar; /* number of active local variables */ 124*8e3e3a7aSWarner Losh lu_byte nups; /* number of upvalues */ 125*8e3e3a7aSWarner Losh lu_byte freereg; /* first free register */ 126*8e3e3a7aSWarner Losh } FuncState; 127*8e3e3a7aSWarner Losh 128*8e3e3a7aSWarner Losh 129*8e3e3a7aSWarner Losh LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 130*8e3e3a7aSWarner Losh Dyndata *dyd, const char *name, int firstchar); 131*8e3e3a7aSWarner Losh 132*8e3e3a7aSWarner Losh 133*8e3e3a7aSWarner Losh #endif 134