lua-users home
lua-l archive

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


Yep, I know there is a patch for this.  In fact, over a year ago, I
applied it to a personal distribution to test it out, understanding the
potential problems that could arise.  I meant to remove it, but I
forgot.  Finally, a year later, I discovered I had left the patch in and
removed it.  The results were very bad.  Every one of hundreds of Lua
data files (files containing table information, not code) had at least
one comma missing.  Most of them had no commas.  A discussion ensued,
and it was decided that, despite the potential ambiguity, the commas
would remain optional.

Especially when having non-programmers create or modify these data
files, not requiring commas is a boon.  The most common mistake is to
simply forget to put the commas in, and then the scripts have errors.
Some missing commas are incredibly hard to track down, depending on
circumstances.

There's also the matter of "prettiness."  When dealing with thousands of
lines of data, I find it easier to look at something like:

MyInfo =
{
	Value1 = 5
	PrettyValues =
	{
		--	Num1	Num2	String	Num3
		{	5.5	10	"A string"	20	}
		{	10	15	"Hello"	25	}
	}
}

Than the required commas version:

MyInfo =
{
	Value1 = 5,
	PrettyValues =
	{
		--	Num1	Num2	String	Num3
		{	5.5,	10,	"A string",	20,	},
		{	10,	15,	"Hello",	25,	},
	},
}

Certainly there is an ambiguity when dealing with bracketed [key] values
preceded by an identifier.  For the stuff we use Lua's data description
facilities for, this is a rarity (actually, it hasn't happened yet).

Anyway, it was simple enough to add to Lua 5.0 Beta.  In lparser.c, the
constructor function is changed to as below.

This is just a suggestion for making Lua's non-programmer (and
programmer) usage even more intuitive.

Josh

---------------------------------

//  do {
  for (;;) {
    lua_assert(cc.v.k == VVOID || cc.tostore > 0);
    testnext(ls, ';');  /* compatibility only */
    if (ls->t.token == '}') break;
    closelistfield(fs, &cc);
    switch(ls->t.token) {
      case TK_NAME: {  /* may be listfields or recfields */
        lookahead(ls);
        if (ls->lookahead.token != '=')  /* expression? */
          listfield(ls, &cc);
        else
          recfield(ls, &cc);
        break;
      }
      case '[': {  /* constructor_item -> recfield */
        recfield(ls, &cc);
        break;
      }
      default: {  /* constructor_part -> listfield */
        listfield(ls, &cc);
        break;
      }
    }
    if (ls->t.token == ',' || ls->t.token == ';')
      next(ls);
    else if (ls->t.token == '}')
      break;
  }
//  } while (testnext(ls, ',') || testnext(ls, ';'));
  check_match(ls, '}', '{', line);