lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> Table = {}&3  -- Or some other equally ugly character.
> -- preferable, I'd like:
> Table = &3{}  -- Because then the size is at the TOP of the 
> table definition instead of the bottom.
> 
> The above table definition makes a NEWTABLE 0 3 instruction 
> (instead of a NEWTABLE 0 0).  At the cost of making the table 
> definition look uglier, memory fragmentation completely 
> disappears (no reallocated hashes), the table construction is 
> run at full speed, and table writes are run much faster, 
> since there is no need to resize the hash.
> 
> I have not figured out how to do this in the parser yet.  I 
> thought I'd throw it out for general consumption, and see if 
> my logic is flawed.  If anybody knows how to easily add this 
> to the parser, I'd be grateful.

This was easier than I thought.  Note that this hasn't been tested in a
full app yet, but it generate the write VM opcode and seems to maintain
the rest of the table construction syntax.

The new syntax is:

Table = { &3 }  -- Regular table stuff can still be in there, as if the
&3 didn't exist.
Table.Index1 = 5
Table.Index2 = 10
Table.Index3 = 15

lparser.c's constructor() function was reworked to look like:

static void constructor (LexState *ls, expdesc *t) {
  /* constructor -> `{' constructor_part [`;' constructor_part] `}' */
  FuncState *fs = ls->fs;
  int line = ls->linenumber;
  int n;
  int force_size = 0;  /* NEW CODE */
  int pc;
  Constdesc cd;
  pc = luaK_codeABc(fs, OP_NEWTABLE, 0, 0);
  init_exp(t, VRELOCABLE, pc);
  luaK_exp2nextreg(ls->fs, t);  /* fix it at stack top (for gc) */
  check(ls, l_c('{'));
  /* NEW CODE BEGIN */
  if (optional(ls, l_c('&'))) {
    if (ls->t.token != TK_NUMBER)
      luaK_error(ls, l_s("size expected following &"));
    force_size = (int)ls->t.seminfo.r;
	next(ls);
  }
  /* NEW CODE END */
  constructor_part(ls, t, &cd);
  n = cd.n;
  if (optional(ls, l_c(';'))) {
    Constdesc other_cd;
    constructor_part(ls, t, &other_cd);
    check_condition(ls, (cd.k != other_cd.k), l_s("invalid constructor
syntax"));
    n += other_cd.n;
  }
  n = (n > force_size) ? n : force_size;  /* NEW CODE */
  check_match(ls, l_c('}'), l_c('{'), line);
  luaX_checklimit(ls, n, MAXARG_Bc, l_s("elements in a table
constructor"));
  SETARG_Bc(fs->f->code[pc], n);  /* set initial table size */
}

Voila!

Thanks!
Josh