lua-users home
lua-l archive

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


Doug Rogers wrote:
> Doug Rogers wrote:
> 
>> Perhaps the syntax could be:
>>   for Name `=´ explist do block end
>> Where:
>>   '(for start)' = first value of explist
>>   '(for limit)' = second value of explist, or '(for start)'
>>   '(for step)'  = third value of explist, or 1
> It's still doable, just a bit messier.

Well, attached is a patch to lparser.c that implements what you wanted.
Here's what I ran to show it:

Lua 5.1.2  Copyright (C) 1994-2007 Lua.org, PUC-Rio
> function c() return 5, 7 end
> for k=c() do print(k) end             -- [1]
5
6
7
> for k=c(), 2 do print(k) end          -- [2]
> for k=1, 6, c() do print(k) end
1
6
>

[1] is just as you would have liked it. The problem comes in line [2].
The expectation is that c() would be expanded to 5, 7 and that 2 would
be used for the step. But which would be the expected behavior to a Lua
programmer?

I think that's ultimately the rationale for requiring it. If that wasn't
the rationale, it seems like a good one!

Doug

-- 
Innovative Concepts, Inc. www.innocon.com 703-893-2007 x220
*** lua-5.1.2-orig/src/lparser.c	2007-03-23 13:06:30.000000000 -0400
--- lua-5.1.2/src/lparser.c	2007-12-31 13:01:00.000000000 -0500
***************
*** 1031,1046 ****
  }
  
  
- static int exp1 (LexState *ls) {
-   expdesc e;
-   int k;
-   expr(ls, &e);
-   k = e.k;
-   luaK_exp2nextreg(ls->fs, &e);
-   return k;
- }
- 
- 
  static void forbody (LexState *ls, int base, int line, int nvars, int isnum) {
    /* forbody -> DO block */
    BlockCnt bl;
--- 1031,1036 ----
***************
*** 1064,1069 ****
--- 1054,1061 ----
  
  static void fornum (LexState *ls, TString *varname, int line) {
    /* fornum -> NAME = exp1,exp1[,exp1] forbody */
+   expdesc v;
+   int     nexps;
    FuncState *fs = ls->fs;
    int base = fs->freereg;
    new_localvarliteral(ls, "(for index)", 0);
***************
*** 1071,1089 ****
    new_localvarliteral(ls, "(for step)", 2);
    new_localvar(ls, varname, 3);
    checknext(ls, '=');
!   exp1(ls);  /* initial value */
!   checknext(ls, ',');
!   exp1(ls);  /* limit */
!   if (testnext(ls, ','))
!     exp1(ls);  /* optional step */
!   else {  /* default step = 1 */
      luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
      luaK_reserveregs(fs, 1);
    }
    forbody(ls, base, line, 1, 1);
  }
  
- 
  static void forlist (LexState *ls, TString *indexname) {
    /* forlist -> NAME {,NAME} IN explist1 forbody */
    FuncState *fs = ls->fs;
--- 1063,1082 ----
    new_localvarliteral(ls, "(for step)", 2);
    new_localvar(ls, varname, 3);
    checknext(ls, '=');
!   nexps = explist1(ls, &v);
!   if ((nexps < 1) || (nexps > 3))
!     luaX_syntaxerror(ls, "1-3 expressions required in numeric 'for'");
!   if (nexps < 3) {
!     adjust_assign(ls, 2, nexps, &v);
      luaK_codeABx(fs, OP_LOADK, fs->freereg, luaK_numberK(fs, 1));
      luaK_reserveregs(fs, 1);
    }
+   else {
+     adjust_assign(ls, 3, nexps, &v);
+   }
    forbody(ls, base, line, 1, 1);
  }
  
  static void forlist (LexState *ls, TString *indexname) {
    /* forlist -> NAME {,NAME} IN explist1 forbody */
    FuncState *fs = ls->fs;