18e3e3a7aSWarner Losh /* 20495ed39SKyle Evans ** $Id: lparser.h $ 38e3e3a7aSWarner Losh ** Lua Parser 48e3e3a7aSWarner Losh ** See Copyright Notice in lua.h 58e3e3a7aSWarner Losh */ 68e3e3a7aSWarner Losh 78e3e3a7aSWarner Losh #ifndef lparser_h 88e3e3a7aSWarner Losh #define lparser_h 98e3e3a7aSWarner Losh 108e3e3a7aSWarner Losh #include "llimits.h" 118e3e3a7aSWarner Losh #include "lobject.h" 128e3e3a7aSWarner Losh #include "lzio.h" 138e3e3a7aSWarner Losh 148e3e3a7aSWarner Losh 158e3e3a7aSWarner Losh /* 168e3e3a7aSWarner Losh ** Expression and variable descriptor. 178e3e3a7aSWarner Losh ** Code generation for variables and expressions can be delayed to allow 188e3e3a7aSWarner Losh ** optimizations; An 'expdesc' structure describes a potentially-delayed 198e3e3a7aSWarner Losh ** variable/expression. It has a description of its "main" value plus a 208e3e3a7aSWarner Losh ** list of conditional jumps that can also produce its value (generated 218e3e3a7aSWarner Losh ** by short-circuit operators 'and'/'or'). 228e3e3a7aSWarner Losh */ 238e3e3a7aSWarner Losh 248e3e3a7aSWarner Losh /* kinds of variables/expressions */ 258e3e3a7aSWarner Losh typedef enum { 260495ed39SKyle Evans VVOID, /* when 'expdesc' describes the last expression of a list, 278e3e3a7aSWarner Losh this kind means an empty list (so, no expression) */ 288e3e3a7aSWarner Losh VNIL, /* constant nil */ 298e3e3a7aSWarner Losh VTRUE, /* constant true */ 308e3e3a7aSWarner Losh VFALSE, /* constant false */ 318e3e3a7aSWarner Losh VK, /* constant in 'k'; info = index of constant in 'k' */ 328e3e3a7aSWarner Losh VKFLT, /* floating constant; nval = numerical float value */ 330495ed39SKyle Evans VKINT, /* integer constant; ival = numerical integer value */ 340495ed39SKyle Evans VKSTR, /* string constant; strval = TString address; 350495ed39SKyle Evans (string is fixed by the lexer) */ 368e3e3a7aSWarner Losh VNONRELOC, /* expression has its value in a fixed register; 378e3e3a7aSWarner Losh info = result register */ 38*8c784bb8SWarner Losh VLOCAL, /* local variable; var.ridx = register index; 390495ed39SKyle Evans var.vidx = relative index in 'actvar.arr' */ 408e3e3a7aSWarner Losh VUPVAL, /* upvalue variable; info = index of upvalue in 'upvalues' */ 410495ed39SKyle Evans VCONST, /* compile-time <const> variable; 420495ed39SKyle Evans info = absolute index in 'actvar.arr' */ 438e3e3a7aSWarner Losh VINDEXED, /* indexed variable; 440495ed39SKyle Evans ind.t = table register; 450495ed39SKyle Evans ind.idx = key's R index */ 460495ed39SKyle Evans VINDEXUP, /* indexed upvalue; 470495ed39SKyle Evans ind.t = table upvalue; 480495ed39SKyle Evans ind.idx = key's K index */ 490495ed39SKyle Evans VINDEXI, /* indexed variable with constant integer; 500495ed39SKyle Evans ind.t = table register; 510495ed39SKyle Evans ind.idx = key's value */ 520495ed39SKyle Evans VINDEXSTR, /* indexed variable with literal string; 530495ed39SKyle Evans ind.t = table register; 540495ed39SKyle Evans ind.idx = key's K index */ 558e3e3a7aSWarner Losh VJMP, /* expression is a test/comparison; 568e3e3a7aSWarner Losh info = pc of corresponding jump instruction */ 570495ed39SKyle Evans VRELOC, /* expression can put result in any register; 588e3e3a7aSWarner Losh info = instruction pc */ 598e3e3a7aSWarner Losh VCALL, /* expression is a function call; info = instruction pc */ 608e3e3a7aSWarner Losh VVARARG /* vararg expression; info = instruction pc */ 618e3e3a7aSWarner Losh } expkind; 628e3e3a7aSWarner Losh 638e3e3a7aSWarner Losh 640495ed39SKyle Evans #define vkisvar(k) (VLOCAL <= (k) && (k) <= VINDEXSTR) 650495ed39SKyle Evans #define vkisindexed(k) (VINDEXED <= (k) && (k) <= VINDEXSTR) 660495ed39SKyle Evans 678e3e3a7aSWarner Losh 688e3e3a7aSWarner Losh typedef struct expdesc { 698e3e3a7aSWarner Losh expkind k; 708e3e3a7aSWarner Losh union { 718e3e3a7aSWarner Losh lua_Integer ival; /* for VKINT */ 728e3e3a7aSWarner Losh lua_Number nval; /* for VKFLT */ 730495ed39SKyle Evans TString *strval; /* for VKSTR */ 748e3e3a7aSWarner Losh int info; /* for generic use */ 750495ed39SKyle Evans struct { /* for indexed variables */ 760495ed39SKyle Evans short idx; /* index (R or "long" K) */ 778e3e3a7aSWarner Losh lu_byte t; /* table (register or upvalue) */ 788e3e3a7aSWarner Losh } ind; 790495ed39SKyle Evans struct { /* for local variables */ 80*8c784bb8SWarner Losh lu_byte ridx; /* register holding the variable */ 810495ed39SKyle Evans unsigned short vidx; /* compiler index (in 'actvar.arr') */ 820495ed39SKyle Evans } var; 838e3e3a7aSWarner Losh } u; 848e3e3a7aSWarner Losh int t; /* patch list of 'exit when true' */ 858e3e3a7aSWarner Losh int f; /* patch list of 'exit when false' */ 868e3e3a7aSWarner Losh } expdesc; 878e3e3a7aSWarner Losh 888e3e3a7aSWarner Losh 890495ed39SKyle Evans /* kinds of variables */ 900495ed39SKyle Evans #define VDKREG 0 /* regular */ 910495ed39SKyle Evans #define RDKCONST 1 /* constant */ 920495ed39SKyle Evans #define RDKTOCLOSE 2 /* to-be-closed */ 930495ed39SKyle Evans #define RDKCTC 3 /* compile-time constant */ 940495ed39SKyle Evans 950495ed39SKyle Evans /* description of an active local variable */ 960495ed39SKyle Evans typedef union Vardesc { 970495ed39SKyle Evans struct { 980495ed39SKyle Evans TValuefields; /* constant value (if it is a compile-time constant) */ 990495ed39SKyle Evans lu_byte kind; 100*8c784bb8SWarner Losh lu_byte ridx; /* register holding the variable */ 1010495ed39SKyle Evans short pidx; /* index of the variable in the Proto's 'locvars' array */ 1020495ed39SKyle Evans TString *name; /* variable name */ 1030495ed39SKyle Evans } vd; 1040495ed39SKyle Evans TValue k; /* constant value (if any) */ 1058e3e3a7aSWarner Losh } Vardesc; 1068e3e3a7aSWarner Losh 1078e3e3a7aSWarner Losh 1080495ed39SKyle Evans 1098e3e3a7aSWarner Losh /* description of pending goto statements and label statements */ 1108e3e3a7aSWarner Losh typedef struct Labeldesc { 1118e3e3a7aSWarner Losh TString *name; /* label identifier */ 1128e3e3a7aSWarner Losh int pc; /* position in code */ 1138e3e3a7aSWarner Losh int line; /* line where it appeared */ 1140495ed39SKyle Evans lu_byte nactvar; /* number of active variables in that position */ 1150495ed39SKyle Evans lu_byte close; /* goto that escapes upvalues */ 1168e3e3a7aSWarner Losh } Labeldesc; 1178e3e3a7aSWarner Losh 1188e3e3a7aSWarner Losh 1198e3e3a7aSWarner Losh /* list of labels or gotos */ 1208e3e3a7aSWarner Losh typedef struct Labellist { 1218e3e3a7aSWarner Losh Labeldesc *arr; /* array */ 1228e3e3a7aSWarner Losh int n; /* number of entries in use */ 1238e3e3a7aSWarner Losh int size; /* array size */ 1248e3e3a7aSWarner Losh } Labellist; 1258e3e3a7aSWarner Losh 1268e3e3a7aSWarner Losh 1278e3e3a7aSWarner Losh /* dynamic structures used by the parser */ 1288e3e3a7aSWarner Losh typedef struct Dyndata { 1290495ed39SKyle Evans struct { /* list of all active local variables */ 1308e3e3a7aSWarner Losh Vardesc *arr; 1318e3e3a7aSWarner Losh int n; 1328e3e3a7aSWarner Losh int size; 1338e3e3a7aSWarner Losh } actvar; 1348e3e3a7aSWarner Losh Labellist gt; /* list of pending gotos */ 1358e3e3a7aSWarner Losh Labellist label; /* list of active labels */ 1368e3e3a7aSWarner Losh } Dyndata; 1378e3e3a7aSWarner Losh 1388e3e3a7aSWarner Losh 1398e3e3a7aSWarner Losh /* control of blocks */ 1408e3e3a7aSWarner Losh struct BlockCnt; /* defined in lparser.c */ 1418e3e3a7aSWarner Losh 1428e3e3a7aSWarner Losh 1438e3e3a7aSWarner Losh /* state needed to generate code for a given function */ 1448e3e3a7aSWarner Losh typedef struct FuncState { 1458e3e3a7aSWarner Losh Proto *f; /* current function header */ 1468e3e3a7aSWarner Losh struct FuncState *prev; /* enclosing function */ 1478e3e3a7aSWarner Losh struct LexState *ls; /* lexical state */ 1488e3e3a7aSWarner Losh struct BlockCnt *bl; /* chain of current blocks */ 1498e3e3a7aSWarner Losh int pc; /* next position to code (equivalent to 'ncode') */ 1508e3e3a7aSWarner Losh int lasttarget; /* 'label' of last 'jump label' */ 1510495ed39SKyle Evans int previousline; /* last line that was saved in 'lineinfo' */ 1528e3e3a7aSWarner Losh int nk; /* number of elements in 'k' */ 1538e3e3a7aSWarner Losh int np; /* number of elements in 'p' */ 1540495ed39SKyle Evans int nabslineinfo; /* number of elements in 'abslineinfo' */ 1558e3e3a7aSWarner Losh int firstlocal; /* index of first local var (in Dyndata array) */ 1560495ed39SKyle Evans int firstlabel; /* index of first label (in 'dyd->label->arr') */ 1570495ed39SKyle Evans short ndebugvars; /* number of elements in 'f->locvars' */ 1588e3e3a7aSWarner Losh lu_byte nactvar; /* number of active local variables */ 1598e3e3a7aSWarner Losh lu_byte nups; /* number of upvalues */ 1608e3e3a7aSWarner Losh lu_byte freereg; /* first free register */ 1610495ed39SKyle Evans lu_byte iwthabs; /* instructions issued since last absolute line info */ 1620495ed39SKyle Evans lu_byte needclose; /* function needs to close upvalues when returning */ 1638e3e3a7aSWarner Losh } FuncState; 1648e3e3a7aSWarner Losh 1658e3e3a7aSWarner Losh 1660495ed39SKyle Evans LUAI_FUNC int luaY_nvarstack (FuncState *fs); 1678e3e3a7aSWarner Losh LUAI_FUNC LClosure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, 1688e3e3a7aSWarner Losh Dyndata *dyd, const char *name, int firstchar); 1698e3e3a7aSWarner Losh 1708e3e3a7aSWarner Losh 1718e3e3a7aSWarner Losh #endif 172