Exemplo n.º 1
0
/*
** Join the ktables from p1 and p2 the ktable for the new pattern at the
** top of the stack, reusing them when possible.
*/
static void joinktables (lua_State *L, int p1, TTree *t2, int p2) {
  int n1, n2;
  lua_getfenv(L, p1);  /* get ktables */
  lua_getfenv(L, p2);
  n1 = ktablelen(L, -2);
  n2 = ktablelen(L, -1);
  if (n1 == 0 && n2 == 0)  /* are both tables empty? */
    lua_pop(L, 2);  /* nothing to be done; pop tables */
  else if (n2 == 0 || lua_equal(L, -2, -1)) {  /* 2nd table empty or equal? */
    lua_pop(L, 1);  /* pop 2nd table */
    lua_setfenv(L, -2);  /* set 1st ktable into new pattern */
  }
  else if (n1 == 0) {  /* first table is empty? */
    lua_setfenv(L, -3);  /* set 2nd table into new pattern */
    lua_pop(L, 1);  /* pop 1st table */
  }
  else {
    lua_createtable(L, n1 + n2, 0);  /* create ktable for new pattern */
    /* stack: new p; ktable p1; ktable p2; new ktable */
    concattable(L, -3, -1);  /* from p1 into new ktable */
    concattable(L, -2, -1);  /* from p2 into new ktable */
    lua_setfenv(L, -4);  /* new ktable becomes 'p' environment */
    lua_pop(L, 2);  /* pop other ktables */
    correctkeys(t2, n1);  /* correction for indices from p2 */
  }
}
Exemplo n.º 2
0
/*
** When joining 'ktables', constants from one of the subpatterns must
** be renumbered; 'correctkeys' corrects their indices (adding 'n'
** to each of them)
*/
static void correctkeys (TTree *tree, int n) {
  if (n == 0) return;  /* no correction? */
 tailcall:
  switch (tree->tag) {
    case TOpenCall: case TCall: case TRunTime: case TRule: {
      if (tree->key > 0)
        tree->key += n;
      break;
    }
    case TCapture: {
      if (tree->key > 0 && tree->cap != Carg && tree->cap != Cnum)
        tree->key += n;
      break;
    }
    default: break;
  }
  switch (numsiblings[tree->tag]) {
    case 1:  /* correctkeys(sib1(tree), n); */
      tree = sib1(tree); goto tailcall;
    case 2:
      correctkeys(sib1(tree), n);
      tree = sib2(tree); goto tailcall;  /* correctkeys(sib2(tree), n); */
    default: assert(numsiblings[tree->tag] == 0); break;
  }
}
Exemplo n.º 3
0
/*
** merge 'ktable' from 'stree' at stack index 'idx' into 'ktable'
** from tree at the top of the stack, and correct corresponding
** tree.
*/
static void mergektable (lua_State *L, int idx, TTree *stree) {
  int n;
  lua_getfenv(L, -1);  /* get ktables */
  lua_getfenv(L, idx);
  n = concattable(L, -1, -2);
  lua_pop(L, 2);  /* remove both ktables */
  correctkeys(stree, n);
}
Exemplo n.º 4
0
/*
** create a new tree, whith a new root and 2 siblings.
** Siblings must be on the Lua stack, first one at index 1.
*/
static TTree *newroot2sib (lua_State *L, int tag) {
  int s1, s2;
  TTree *tree1 = getpatt(L, 1, &s1);
  TTree *tree2 = getpatt(L, 2, &s2);
  TTree *tree = newtree(L, 1 + s1 + s2);  /* create new tree */
  tree->tag = tag;
  tree->u.ps =  1 + s1;
  memcpy(sib1(tree), tree1, s1 * sizeof(TTree));
  memcpy(sib2(tree), tree2, s2 * sizeof(TTree));
  correctkeys(sib2(tree), joinktables(L, 1, 2));
  return tree;
}
Exemplo n.º 5
0
/*
** [t1 - t2] == Seq (Not t2) t1
** If t1 and t2 are charsets, make their difference.
*/
static int lp_sub (lua_State *L) {
  Charset st1, st2;
  int s1, s2;
  TTree *t1 = getpatt(L, 1, &s1);
  TTree *t2 = getpatt(L, 2, &s2);
  if (tocharset(t1, &st1) && tocharset(t2, &st2)) {
    TTree *t = newcharset(L);
    loopset(i, treebuffer(t)[i] = st1.cs[i] & ~st2.cs[i]);
  }
  else {
    TTree *tree = newtree(L, 2 + s1 + s2);
    tree->tag = TSeq;  /* sequence of... */
    tree->u.ps =  2 + s2;
    sib1(tree)->tag = TNot;  /* ...not... */
    memcpy(sib1(sib1(tree)), t2, s2 * sizeof(TTree));  /* ...t2 */
    memcpy(sib2(tree), t1, s1 * sizeof(TTree));  /* ... and t1 */
    correctkeys(sib1(tree), joinktables(L, 1, 2));
  }
  return 1;
}