/* ** Constant capture */ static int lp_constcapture (lua_State *L) { int i; int n = lua_gettop(L); /* number of values */ if (n == 0) /* no values? */ newleaf(L, TTrue); /* no capture */ else if (n == 1) newemptycapkey(L, Cconst, 1); /* single constant capture */ else { /* create a group capture with all values */ TTree *tree = newtree(L, 1 + 3 * (n - 1) + 2); newktable(L, n); /* create a 'ktable' for new tree */ tree->tag = TCapture; tree->cap = Cgroup; tree->key = 0; tree = sib1(tree); for (i = 1; i <= n - 1; i++) { tree->tag = TSeq; tree->u.ps = 3; /* skip TCapture and its sibling */ auxemptycap(sib1(tree), Cconst); sib1(tree)->key = addtoktable(L, i); tree = sib2(tree); } auxemptycap(tree, Cconst); tree->key = addtoktable(L, i); } return 1; }
static int lp_matchtime (lua_State *L) { TTree *tree; luaL_checktype(L, 2, LUA_TFUNCTION); tree = newroot1sib(L, TRunTime); tree->key = addtoktable(L, 2); return 1; }
/* ** Fill a tree with an empty capture, using an empty (TTrue) sibling. */ static TTree *auxemptycap (lua_State *L, TTree *tree, int cap, int idx) { tree->tag = TCapture; tree->cap = cap; tree->key = addtoktable(L, idx); sib1(tree)->tag = TTrue; return tree; }
/* ** Convert value at index 'idx' to a pattern */ static TTree *getpatt (lua_State *L, int idx, int *len) { TTree *tree; switch (lua_type(L, idx)) { case LUA_TSTRING: { size_t slen; const char *s = lua_tolstring(L, idx, &slen); /* get string */ if (slen == 0) /* empty? */ tree = newleaf(L, TTrue); /* always match */ else { tree = newtree(L, 2 * (slen - 1) + 1); fillseq(tree, TChar, slen, s); /* sequence of 'slen' chars */ } break; } case LUA_TNUMBER: { int n = lua_tointeger(L, idx); tree = numtree(L, n); break; } case LUA_TBOOLEAN: { tree = (lua_toboolean(L, idx) ? newleaf(L, TTrue) : newleaf(L, TFalse)); break; } case LUA_TTABLE: { tree = newgrammar(L, idx); break; } case LUA_TFUNCTION: { tree = newtree(L, 2); tree->tag = TRunTime; tree->key = addtoktable(L, idx); sib1(tree)->tag = TTrue; break; } default: { return gettree(L, idx, len); } } lua_replace(L, idx); /* put new tree into 'idx' slot */ if (len) *len = getsize(L, idx); return tree; }
/* ** Create a new 'ktable' to the pattern at the top of the stack, adding ** all elements from pattern 'p' (if not 0) plus element 'idx' to it. ** Return index of new element. */ static int addtonewktable (lua_State *L, int p, int idx) { newktable(L, 1); if (p) mergektable(L, p, NULL); return addtoktable(L, idx); }
/* ** Create a tree for a non-empty capture, with a body and ** optionally with an associated Lua value (at index 'labelidx' in the ** stack) */ static int capture_aux (lua_State *L, int cap, int labelidx) { TTree *tree = newroot1sib(L, TCapture); tree->cap = cap; tree->key = addtoktable(L, labelidx); return 1; }
/* ** Create a non-terminal */ static int lp_V (lua_State *L) { TTree *tree = newleaf(L, TOpenCall); luaL_argcheck(L, !lua_isnoneornil(L, 1), 1, "non-nil value expected"); tree->key = addtoktable(L, 1); return 1; }