@@ -220,6 +220,67 @@ jsp_skip_braces (token_type brace_type) /**< type of the opening brace */
220
220
current_token_must_be (closing_bracket_type);
221
221
} /* jsp_skip_braces */
222
222
223
+ /* *
224
+ * Find next token of specified type before the specified location
225
+ *
226
+ * Note:
227
+ * If skip_brace_blocks is true, every { should correspond to } brace before search end location,
228
+ * otherwise a syntax error is raised.
229
+ *
230
+ * @return true - if token was found (in the case, it is the current token,
231
+ * and lexer locus points to it),
232
+ * false - otherwise (in the case, lexer locus points to end_loc).
233
+ */
234
+ static bool
235
+ jsp_find_next_token_before_the_locus (token_type token_to_find, /* *< token to search for
236
+ * (except TOK_NEWLINE and TOK_EOF) */
237
+ locus end_loc, /* *< location to search before */
238
+ bool skip_brace_blocks) /* *< skip blocks, surrounded with { and } braces */
239
+ {
240
+ JERRY_ASSERT (token_to_find != TOK_NEWLINE
241
+ && token_to_find != TOK_EOF);
242
+
243
+ while (tok.loc < end_loc)
244
+ {
245
+ if (skip_brace_blocks)
246
+ {
247
+ if (token_is (TOK_OPEN_BRACE))
248
+ {
249
+ jsp_skip_braces (TOK_OPEN_BRACE);
250
+
251
+ JERRY_ASSERT (token_is (TOK_CLOSE_BRACE));
252
+ skip_newlines ();
253
+
254
+ if (tok.loc >= end_loc)
255
+ {
256
+ lexer_seek (end_loc);
257
+ tok = lexer_next_token ();
258
+
259
+ return false ;
260
+ }
261
+ }
262
+ else if (token_is (TOK_CLOSE_BRACE))
263
+ {
264
+ EMIT_ERROR (" Unmatched } brace" );
265
+ }
266
+ }
267
+
268
+ if (token_is (token_to_find))
269
+ {
270
+ return true ;
271
+ }
272
+ else
273
+ {
274
+ JERRY_ASSERT (!token_is (TOK_EOF));
275
+ }
276
+
277
+ skip_newlines ();
278
+ }
279
+
280
+ JERRY_ASSERT (tok.loc == end_loc);
281
+ return false ;
282
+ } /* jsp_find_next_token_before_the_locus */
283
+
223
284
/* property_name
224
285
: Identifier
225
286
| Keyword
@@ -1726,88 +1787,146 @@ parse_variable_declaration (void)
1726
1787
(LT!* ',' LT!* variable_declaration)*
1727
1788
; */
1728
1789
static void
1729
- parse_variable_declaration_list (bool *several_decls )
1790
+ parse_variable_declaration_list (void )
1730
1791
{
1792
+ JERRY_ASSERT (is_keyword (KW_VAR));
1793
+
1731
1794
while (true )
1732
1795
{
1796
+ skip_newlines ();
1797
+
1733
1798
parse_variable_declaration ();
1734
1799
1735
1800
skip_newlines ();
1736
1801
if (!token_is (TOK_COMMA))
1737
1802
{
1738
1803
lexer_save_token (tok);
1739
- return ;
1740
- }
1741
-
1742
- skip_newlines ();
1743
- if (several_decls)
1744
- {
1745
- *several_decls = true ;
1804
+ break ;
1746
1805
}
1747
1806
}
1748
1807
}
1749
1808
1809
+ /* *
1810
+ * Parse for statement
1811
+ *
1812
+ * See also:
1813
+ * ECMA-262 v5, 12.6.3
1814
+ *
1815
+ * Note:
1816
+ * Syntax:
1817
+ * Initializer Condition Increment Body LoopEnd
1818
+ * - for ([ExpressionNoIn]; [Expression]; [Expression]) Statement
1819
+ * - for (var VariableDeclarationListNoIn; [Expression]; [Expression]) Statement
1820
+ *
1821
+ * Note:
1822
+ * Layout of generated byte-code is the following:
1823
+ * Initializer ([ExpressionNoIn] / VariableDeclarationListNoIn)
1824
+ * Jump -> ConditionCheck
1825
+ * NextIteration:
1826
+ * Body (Statement)
1827
+ * ContinueTarget:
1828
+ * Increment ([Expression])
1829
+ * ConditionCheck:
1830
+ * Condition ([Expression])
1831
+ * If Condition is evaluted to true, jump -> NextIteration
1832
+ */
1750
1833
static void
1751
- parse_plain_for (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
1752
- * the statement (or NULL, if there are no named
1753
- * labels associated with the statement) */
1834
+ jsp_parse_for_statement (jsp_label_t *outermost_stmt_label_p, /* *< outermost (first) label, corresponding to
1835
+ * the statement (or NULL, if there are no named
1836
+ * labels associated with the statement) */
1837
+ locus for_body_statement_loc) /* *< locus of loop body statement */
1754
1838
{
1755
- dump_jump_to_end_for_rewrite ();
1756
-
1757
- // Skip till body
1758
- JERRY_ASSERT (token_is (TOK_SEMICOLON));
1839
+ current_token_must_be (TOK_OPEN_PAREN);
1759
1840
skip_newlines ();
1760
- const locus cond_loc = tok.loc ;
1761
- while (!token_is (TOK_SEMICOLON))
1841
+
1842
+ // Initializer
1843
+ if (is_keyword (KW_VAR))
1762
1844
{
1763
- skip_newlines ();
1845
+ parse_variable_declaration_list ();
1846
+ skip_token ();
1764
1847
}
1765
- skip_newlines ();
1766
- const locus incr_loc = tok.loc ;
1767
- while (!token_is (TOK_CLOSE_PAREN))
1848
+ else if (!token_is (TOK_SEMICOLON))
1768
1849
{
1769
- skip_newlines ();
1850
+ parse_expression (false , JSP_EVAL_RET_STORE_NOT_DUMP);
1851
+ skip_token ();
1770
1852
}
1853
+ else
1854
+ {
1855
+ // Initializer is empty
1856
+ }
1857
+
1858
+ // Jump -> ConditionCheck
1859
+ dump_jump_to_end_for_rewrite ();
1771
1860
1772
1861
dumper_set_next_interation_target ();
1773
1862
1774
- // Parse body
1863
+ current_token_must_be (TOK_SEMICOLON);
1864
+ skip_token ();
1865
+
1866
+ // Save Condition locus
1867
+ const locus condition_loc = tok.loc ;
1868
+
1869
+ if (!jsp_find_next_token_before_the_locus (TOK_SEMICOLON,
1870
+ for_body_statement_loc,
1871
+ true ))
1872
+ {
1873
+ EMIT_ERROR (" Invalid for statement" );
1874
+ }
1875
+
1876
+ current_token_must_be (TOK_SEMICOLON);
1877
+ skip_token ();
1878
+
1879
+ // Save Increment locus
1880
+ const locus increment_loc = tok.loc ;
1881
+
1882
+ // Body
1883
+ lexer_seek (for_body_statement_loc);
1775
1884
skip_newlines ();
1885
+
1776
1886
parse_statement (NULL );
1777
1887
1778
- const locus end_loc = tok.loc ;
1888
+ // Save LoopEnd locus
1889
+ const locus loop_end_loc = tok.loc ;
1779
1890
1891
+ // Setup ContinueTarget
1780
1892
jsp_label_setup_continue_target (outermost_stmt_label_p,
1781
1893
serializer_get_current_opcode_counter ());
1782
1894
1783
- lexer_seek (incr_loc);
1784
- skip_token ();
1895
+ // Increment
1896
+ lexer_seek (increment_loc);
1897
+ skip_newlines ();
1898
+
1785
1899
if (!token_is (TOK_CLOSE_PAREN))
1786
1900
{
1787
1901
parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
1788
1902
}
1789
1903
1904
+ current_token_must_be (TOK_CLOSE_PAREN);
1905
+
1906
+ // Setup ConditionCheck
1790
1907
rewrite_jump_to_end ();
1791
1908
1792
- lexer_seek (cond_loc);
1793
- skip_token ();
1909
+ // Condition
1910
+ lexer_seek (condition_loc);
1911
+ skip_newlines ();
1912
+
1794
1913
if (token_is (TOK_SEMICOLON))
1795
1914
{
1796
1915
dump_continue_iterations_check (empty_operand ());
1797
1916
}
1798
1917
else
1799
1918
{
1800
- const operand cond = parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
1919
+ operand cond = parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
1801
1920
dump_continue_iterations_check (cond);
1802
1921
}
1803
1922
1804
- lexer_seek (end_loc );
1805
- skip_token ();
1923
+ lexer_seek (loop_end_loc );
1924
+ skip_newlines ();
1806
1925
if (tok.type != TOK_CLOSE_BRACE)
1807
1926
{
1808
1927
lexer_save_token (tok);
1809
1928
}
1810
- }
1929
+ } /* jsp_parse_for_statement */
1811
1930
1812
1931
static void
1813
1932
parse_for_in (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
@@ -1819,92 +1938,48 @@ parse_for_in (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) label,
1819
1938
EMIT_SORRY (" 'for in' loops are not supported yet" );
1820
1939
}
1821
1940
1822
- /* for_statement
1823
- : 'for' LT!* '(' (LT!* for_statement_initialiser_part)? LT!* ';'
1824
- (LT!* expression)? LT!* ';' (LT!* expression)? LT!* ')' LT!* statement
1825
- ;
1826
-
1827
- for_statement_initialiser_part
1828
- : expression
1829
- | 'var' LT!* variable_declaration_list
1830
- ;
1831
-
1832
- for_in_statement
1833
- : 'for' LT!* '(' LT!* for_in_statement_initialiser_part LT!* 'in'
1834
- LT!* expression LT!* ')' LT!* statement
1835
- ;
1836
-
1837
- for_in_statement_initialiser_part
1838
- : left_hand_side_expression
1839
- | 'var' LT!* variable_declaration
1840
- ;*/
1841
-
1941
+ /* *
1942
+ * Parse for/for-in statements
1943
+ *
1944
+ * See also:
1945
+ * ECMA-262 v5, 12.6.3 and 12.6.4
1946
+ */
1842
1947
static void
1843
- parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
1844
- * the statement (or NULL, if there are no named
1845
- * labels associated with the statement) */
1948
+ jsp_parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label,
1949
+ * corresponding to the statement
1950
+ * (or NULL, if there are no name
1951
+ * labels associated with the statement) */
1846
1952
{
1847
1953
assert_keyword (KW_FOR);
1848
1954
token_after_newlines_must_be (TOK_OPEN_PAREN);
1849
1955
1850
- skip_newlines ();
1851
- if (token_is (TOK_SEMICOLON))
1852
- {
1853
- parse_plain_for (outermost_stmt_label_p);
1854
- return ;
1855
- }
1856
- /* Both for_statement_initialiser_part and for_in_statement_initialiser_part
1857
- contains 'var'. Check it first. */
1858
- if (is_keyword (KW_VAR))
1859
- {
1860
- bool several_decls = false ;
1861
- skip_newlines ();
1862
- parse_variable_declaration_list (&several_decls);
1863
- if (several_decls)
1864
- {
1865
- token_after_newlines_must_be (TOK_SEMICOLON);
1866
- parse_plain_for (outermost_stmt_label_p);
1867
- return ;
1868
- }
1869
- else
1870
- {
1871
- skip_newlines ();
1872
- if (token_is (TOK_SEMICOLON))
1873
- {
1874
- parse_plain_for (outermost_stmt_label_p);
1875
- return ;
1876
- }
1877
- else if (is_keyword (KW_IN))
1878
- {
1879
- parse_for_in (outermost_stmt_label_p);
1880
- return ;
1881
- }
1882
- else
1883
- {
1884
- EMIT_ERROR (" Expected either ';' or 'in' token" );
1885
- }
1886
- }
1887
- }
1956
+ locus for_open_paren_loc, for_body_statement_loc;
1888
1957
1889
- /* expression contains left_hand_side_expression. */
1890
- parse_expression (false , JSP_EVAL_RET_STORE_NOT_DUMP);
1958
+ for_open_paren_loc = tok.loc ;
1891
1959
1960
+ jsp_skip_braces (TOK_OPEN_PAREN);
1892
1961
skip_newlines ();
1893
- if (token_is (TOK_SEMICOLON))
1894
- {
1895
- parse_plain_for (outermost_stmt_label_p);
1896
- return ;
1897
- }
1898
- else if (is_keyword (KW_IN))
1962
+
1963
+ for_body_statement_loc = tok.loc ;
1964
+
1965
+ lexer_seek (for_open_paren_loc);
1966
+ tok = lexer_next_token ();
1967
+
1968
+ bool is_plain_for = jsp_find_next_token_before_the_locus (TOK_SEMICOLON,
1969
+ for_body_statement_loc,
1970
+ true );
1971
+ lexer_seek (for_open_paren_loc);
1972
+ tok = lexer_next_token ();
1973
+
1974
+ if (is_plain_for)
1899
1975
{
1900
- parse_for_in (outermost_stmt_label_p);
1901
- return ;
1976
+ jsp_parse_for_statement (outermost_stmt_label_p, for_body_statement_loc);
1902
1977
}
1903
1978
else
1904
1979
{
1905
- EMIT_ERROR ( " Expected either ';' or 'in' token " );
1980
+ parse_for_in (outermost_stmt_label_p );
1906
1981
}
1907
- }
1982
+ } /* jsp_parse_for_or_for_in_statement */
1908
1983
1909
1984
static operand
1910
1985
parse_expression_inside_parens (void )
@@ -2318,7 +2393,7 @@ parse_iterational_statement (jsp_label_t *outermost_named_stmt_label_p) /**< out
2318
2393
else
2319
2394
{
2320
2395
JERRY_ASSERT (is_keyword (KW_FOR));
2321
- parse_for_or_for_in_statement (outermost_stmt_label_p);
2396
+ jsp_parse_for_or_for_in_statement (outermost_stmt_label_p);
2322
2397
}
2323
2398
2324
2399
jsp_label_rewrite_jumps_and_pop (&label,
@@ -2412,8 +2487,7 @@ parse_statement (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
2412
2487
}
2413
2488
if (is_keyword (KW_VAR))
2414
2489
{
2415
- skip_newlines ();
2416
- parse_variable_declaration_list (NULL );
2490
+ parse_variable_declaration_list ();
2417
2491
return ;
2418
2492
}
2419
2493
if (is_keyword (KW_FUNCTION))
0 commit comments