[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- 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_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;