lua-users home
lua-l archive

Re: Why does numeric for loop not accept an explist?

[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;

AltStyle によって変換されたページ (->オリジナル) /