• Subject: Re: Why does numeric for loop not accept an explist?
• From: Doug Rogers <rogers@...>
• Date: Mon, 31 Dec 2007 13:08:59 -0500

```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_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) {