Fixed handling of 'for (;;)'

This commit is contained in:
Gordon Williams (u36) 2013-11-22 17:47:08 +00:00
parent d606c2cec8
commit c2927a14c2
4 changed files with 34 additions and 11 deletions

View File

@ -12,7 +12,7 @@
Turned 'http' into a library
Added process.version and process.env (fix #131)
Changed handling of 2nd arg of << so that precedence is correct
Fixed handling of 'for (;;)'
1v42 : [ebirger] allowing 'new' with no brackets
Allow built-in functions with variable numbers of arguments (fix #83)

View File

@ -1773,7 +1773,11 @@ JsVar *jspeStatementFor() {
JSP_MATCH(LEX_R_FOR);
JSP_MATCH('(');
execInfo.execute |= EXEC_FOR_INIT;
JsVar *forStatement = jspeStatement(); // initialisation
// initialisation
JsVar *forStatement = 0;
// we could have 'for (;;)' - so don't munch up our semicolon if that's all we have
if (execInfo.lex->tk != ';')
forStatement = jspeStatement();
execInfo.execute &= (JsExecFlags)~EXEC_FOR_INIT;
if (execInfo.lex->tk == LEX_R_IN) {
// for (i in array)
@ -1864,12 +1868,14 @@ JsVar *jspeStatementFor() {
jsvUnLock(forStatement);
JSP_MATCH(';');
JslCharPos forCondStart = execInfo.lex->tokenStart;
JsVar *cond = jspeBase(); // condition
loopCond = JSP_SHOULD_EXECUTE && jsvGetBoolAndUnLock(jsvSkipName(cond));
jsvUnLock(cond);
if (execInfo.lex->tk != ';') {
JsVar *cond = jspeBase(); // condition
loopCond = JSP_SHOULD_EXECUTE && jsvGetBoolAndUnLock(jsvSkipName(cond));
jsvUnLock(cond);
}
JSP_MATCH(';');
JslCharPos forIterStart = execInfo.lex->tokenStart;
{
if (execInfo.lex->tk != ')') { // we could have 'for (;;)'
JSP_SAVE_EXECUTE();
jspSetNoExecute();
jsvUnLock(jspeBase()); // iterator
@ -1893,7 +1899,7 @@ JsVar *jspeStatementFor() {
if (!loopCond) JSP_RESTORE_EXECUTE();
if (loopCond) {
jslSeekTo(execInfo.lex, forIterStart);
jsvUnLock(jspeBase());
if (execInfo.lex->tk != ')') jsvUnLock(jspeBase());
}
while (!hasHadBreak && JSP_SHOULD_EXECUTE && loopCond
#ifdef JSPARSE_MAX_LOOP_ITERATIONS
@ -1901,9 +1907,14 @@ JsVar *jspeStatementFor() {
#endif
) {
jslSeekTo(execInfo.lex, forCondStart);
cond = jspeBase();
loopCond = jsvGetBoolAndUnLock(jsvSkipName(cond));
jsvUnLock(cond);
;
if (execInfo.lex->tk == ';') {
loopCond = true;
} else {
JsVar *cond = jspeBase();
loopCond = jsvGetBoolAndUnLock(jsvSkipName(cond));
jsvUnLock(cond);
}
if (JSP_SHOULD_EXECUTE && loopCond) {
jslSeekTo(execInfo.lex, forBodyStart);
execInfo.execute |= EXEC_IN_LOOP;
@ -1918,7 +1929,7 @@ JsVar *jspeStatementFor() {
}
if (JSP_SHOULD_EXECUTE && loopCond) {
jslSeekTo(execInfo.lex, forIterStart);
jsvUnLock(jspeBase());
if (execInfo.lex->tk != ')') jsvUnLock(jspeBase());
}
}
jslSeekTo(execInfo.lex, forBodyEnd);

6
tests/test_for_empty.js Normal file
View File

@ -0,0 +1,6 @@
a=42;
b=0;
for (;a;) { b++; a-- }
result = b==42;

6
tests/test_for_empty2.js Normal file
View File

@ -0,0 +1,6 @@
a=42;
b=0;
for (;;) { b++; a--; if (!a) break; }
result = b==42;