You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

223 lines
3.3 KiB

/*
* Automatic semicolon insertion (E5 Section 7.9).
*
* Note: depending on implementation a few tests will cover behavior,
* or insertion must be tested in all possible syntactic constructs.
*/
/*FIXME*/
/*===
10
14
===*/
function f_basic1() {
var x
// parsed as "x = 1 + 2 + 3 + 4;"
x = 1 + 2 +
3 + 4
print(x)
// parsed as "x = 2 + 3 + 4 + 5;", because must parse longest
// possible valid expression
x = 2 + 3
+ 4 + 5
print(x)
}
f_basic1();
/*===
123
===*/
// semicolon inserted at end of block, offending token is '}'
// rule 1 of E5 Section 7.9.1
function f_basic2() { return 123 }
print(f_basic2());
/*===
234
===*/
// semicolon inserted at end of input
// rule 2 of E5 Section 7.9.1
function f_basic3() { return eval("234"); }
print(f_basic3());
/*===
10 20
-> 10 21
-> 11 21
10 20
-> 10 19
-> 9 19
return from inner
return from inner
undefined
SyntaxError
===*/
// semicolon inserted in the middle of a restricted
// production (even if continuing was possible syntactically)
// rule 3 of E5 Section 7.9.1
var x = 10;
var y = 20;
function f_postinc() {
print(x, y);
// interpreted as "x; ++y;"
x
++y
print('->', x, y);
// interpreted as "x++; y;"
x++
y
print('->', x, y);
}
function f_postdec() {
print(x, y);
// interpreted as "x; --y;"
x
--y
print('->', x, y);
// interpreted as "x--; y;"
x--
y
print('->', x, y);
}
function f_continue() {
var done = false;
outer:
for (;;) {
if (done) {
print('return from outer');
return;
}
for (;;) {
if (done) {
print('return from inner');
return;
}
done = true;
// interpreted as 'continue; outer;'
// continues inner loop -> exits from inner
// ('continue outer' would exit from outer)
continue
outer
}
}
}
function f_break() {
outer:
for (;;) {
for (;;) {
// interpreted as 'break: outer'
break
outer
}
print('return from inner');
return;
}
print('return from outer');
}
function f_return() {
/* interpreted as "return; 123;" */
return
123;
}
/* Note: there is no empty variant for 'throw' (unlike for return, break,
* and continue), so a line break between throw and its value is a
* SyntaxError.
*/
var src_throw = "function() {\n" +
" try {\n" +
" // interpreted as 'throw; 123' instead of 'throw 123'\n" +
" throw\n" +
" 123\n" +
" } catch(e) {\n" +
" print(e);\n" +
" }\n" +
"}";
try {
x = 10; y = 20; f_postinc();
} catch (e) {
print(e.name);
}
try {
x = 10; y = 20; f_postdec();
} catch (e) {
print(e.name);
}
try {
f_continue();
} catch (e) {
print(e.name);
}
try {
f_break();
} catch (e) {
print(e.name);
}
try {
print(f_return());
} catch (e) {
print(e.name);
}
try {
var f_throw = eval(src_throw);
f_throw();
} catch (e) {
print(e.name);
}
/*===
SyntaxError
SyntaxError
===*/
/* A specific post-increment/decrement case; e.g. "a+b\n++" must be
* interpreted as "a+b;++;" which is a SyntaxError.
*/
try {
eval("a+b\n++");
} catch (e) {
print(e.name);
}
try {
eval("a+b\n--");
} catch (e) {
print(e.name);
}