@@ -171,6 +171,39 @@ is_strict_mode (void)
171
171
return scopes_tree_strict_mode (STACK_TOP (scopes));
172
172
}
173
173
174
+ /* *
175
+ * Find next token of specified type before the specified location
176
+ *
177
+ * @return true - if token was found (in the case, it is the current token,
178
+ * and lexer locus points to it),
179
+ * false - otherwise (in the case, lexer locus points to end_loc).
180
+ */
181
+ static bool
182
+ jsp_find_next_token_before_the_locus (token_type token_to_find, /* *< token to search for
183
+ * (except TOK_NEWLINE and TOK_EOF) */
184
+ locus end_loc) /* *< location to search before */
185
+ {
186
+ JERRY_ASSERT (token_to_find != TOK_NEWLINE
187
+ && token_to_find != TOK_EOF);
188
+
189
+ while (tok.loc < end_loc)
190
+ {
191
+ if (token_is (token_to_find))
192
+ {
193
+ return true ;
194
+ }
195
+ else
196
+ {
197
+ JERRY_ASSERT (!token_is (TOK_EOF));
198
+ }
199
+
200
+ skip_newlines ();
201
+ }
202
+
203
+ JERRY_ASSERT (tok.loc == end_loc);
204
+ return false ;
205
+ } /* jsp_find_next_token_before_the_locus */
206
+
174
207
/* *
175
208
* Skip block, defined with braces of specified type
176
209
*
@@ -1725,88 +1758,145 @@ parse_variable_declaration (void)
1725
1758
(LT!* ',' LT!* variable_declaration)*
1726
1759
; */
1727
1760
static void
1728
- parse_variable_declaration_list (bool *several_decls )
1761
+ parse_variable_declaration_list (void )
1729
1762
{
1763
+ JERRY_ASSERT (is_keyword (KW_VAR));
1764
+
1730
1765
while (true )
1731
1766
{
1767
+ skip_newlines ();
1768
+
1732
1769
parse_variable_declaration ();
1733
1770
1734
1771
skip_newlines ();
1735
1772
if (!token_is (TOK_COMMA))
1736
1773
{
1737
1774
lexer_save_token (tok);
1738
- return ;
1739
- }
1740
-
1741
- skip_newlines ();
1742
- if (several_decls)
1743
- {
1744
- *several_decls = true ;
1775
+ break ;
1745
1776
}
1746
1777
}
1747
1778
}
1748
1779
1780
+ /* *
1781
+ * Parse for statement
1782
+ *
1783
+ * See also:
1784
+ * ECMA-262 v5, 12.6.3
1785
+ *
1786
+ * Note:
1787
+ * Syntax:
1788
+ * Initializer Condition Increment Body LoopEnd
1789
+ * - for ([ExpressionNoIn]; [Expression]; [Expression]) Statement
1790
+ * - for (var VariableDeclarationListNoIn; [Expression]; [Expression]) Statement
1791
+ *
1792
+ * Note:
1793
+ * Layout of generated byte-code is the following:
1794
+ * Initializer ([ExpressionNoIn] / VariableDeclarationListNoIn)
1795
+ * Jump -> ConditionCheck
1796
+ * NextIteration:
1797
+ * Body (Statement)
1798
+ * ContinueTarget:
1799
+ * Increment ([Expression])
1800
+ * ConditionCheck:
1801
+ * Condition ([Expression])
1802
+ * If Condition is evaluted to true, jump -> NextIteration
1803
+ */
1749
1804
static void
1750
- parse_plain_for (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
1751
- * the statement (or NULL, if there are no named
1752
- * labels associated with the statement) */
1805
+ jsp_parse_for_statement (jsp_label_t *outermost_stmt_label_p, /* *< outermost (first) label, corresponding to
1806
+ * the statement (or NULL, if there are no named
1807
+ * labels associated with the statement) */
1808
+ locus for_body_statement_loc) /* *< locus of loop body statement */
1753
1809
{
1754
- dump_jump_to_end_for_rewrite ();
1755
-
1756
- // Skip till body
1757
- JERRY_ASSERT (token_is (TOK_SEMICOLON));
1810
+ current_token_must_be (TOK_OPEN_PAREN);
1758
1811
skip_newlines ();
1759
- const locus cond_loc = tok.loc ;
1760
- while (!token_is (TOK_SEMICOLON))
1812
+
1813
+ // Initializer
1814
+ if (is_keyword (KW_VAR))
1761
1815
{
1762
- skip_newlines ();
1816
+ parse_variable_declaration_list ();
1817
+ skip_token ();
1763
1818
}
1764
- skip_newlines ();
1765
- const locus incr_loc = tok.loc ;
1766
- while (!token_is (TOK_CLOSE_PAREN))
1819
+ else if (!token_is (TOK_SEMICOLON))
1767
1820
{
1768
- skip_newlines ();
1821
+ parse_expression (false , JSP_EVAL_RET_STORE_NOT_DUMP);
1822
+ skip_token ();
1823
+ }
1824
+ else
1825
+ {
1826
+ // Initializer is empty
1769
1827
}
1770
1828
1829
+ // Jump -> ConditionCheck
1830
+ dump_jump_to_end_for_rewrite ();
1831
+
1771
1832
dumper_set_next_interation_target ();
1772
1833
1773
- // Parse body
1774
- skip_newlines ();
1834
+ current_token_must_be (TOK_SEMICOLON);
1835
+ skip_token ();
1836
+
1837
+ // Save Condition locus
1838
+ const locus condition_loc = tok.loc ;
1839
+
1840
+ if (!jsp_find_next_token_before_the_locus (TOK_SEMICOLON,
1841
+ for_body_statement_loc))
1842
+ {
1843
+ EMIT_ERROR (" Invalid for statement" );
1844
+ }
1845
+
1846
+ current_token_must_be (TOK_SEMICOLON);
1847
+ skip_token ();
1848
+
1849
+ // Save Increment locus
1850
+ const locus increment_loc = tok.loc ;
1851
+
1852
+ // Body
1853
+ lexer_seek (for_body_statement_loc);
1854
+ tok = lexer_next_token ();
1855
+
1775
1856
parse_statement (NULL );
1776
1857
1777
- const locus end_loc = tok.loc ;
1858
+ // Save LoopEnd locus
1859
+ const locus loop_end_loc = tok.loc ;
1778
1860
1861
+ // Setup ContinueTarget
1779
1862
jsp_label_setup_continue_target (outermost_stmt_label_p,
1780
1863
serializer_get_current_opcode_counter ());
1781
1864
1782
- lexer_seek (incr_loc);
1783
- skip_token ();
1865
+ // Increment
1866
+ lexer_seek (increment_loc);
1867
+ tok = lexer_next_token ();
1868
+
1784
1869
if (!token_is (TOK_CLOSE_PAREN))
1785
1870
{
1786
1871
parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
1787
1872
}
1788
1873
1874
+ current_token_must_be (TOK_CLOSE_PAREN);
1875
+
1876
+ // Setup ConditionCheck
1789
1877
rewrite_jump_to_end ();
1790
1878
1791
- lexer_seek (cond_loc);
1792
- skip_token ();
1879
+ // Condition
1880
+ lexer_seek (condition_loc);
1881
+ tok = lexer_next_token ();
1882
+
1793
1883
if (token_is (TOK_SEMICOLON))
1794
1884
{
1795
1885
dump_continue_iterations_check (empty_operand ());
1796
1886
}
1797
1887
else
1798
1888
{
1799
- const operand cond = parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
1889
+ operand cond = parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
1800
1890
dump_continue_iterations_check (cond);
1801
1891
}
1802
1892
1803
- lexer_seek (end_loc );
1804
- skip_token ();
1893
+ lexer_seek (loop_end_loc );
1894
+ tok = lexer_next_token ();
1805
1895
if (tok.type != TOK_CLOSE_BRACE)
1806
1896
{
1807
1897
lexer_save_token (tok);
1808
1898
}
1809
- }
1899
+ } /* jsp_parse_for_statement */
1810
1900
1811
1901
static void
1812
1902
parse_for_in (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
@@ -1818,92 +1908,48 @@ parse_for_in (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) label,
1818
1908
EMIT_SORRY (" 'for in' loops are not supported yet" );
1819
1909
}
1820
1910
1821
- /* for_statement
1822
- : 'for' LT!* '(' (LT!* for_statement_initialiser_part)? LT!* ';'
1823
- (LT!* expression)? LT!* ';' (LT!* expression)? LT!* ')' LT!* statement
1824
- ;
1825
-
1826
- for_statement_initialiser_part
1827
- : expression
1828
- | 'var' LT!* variable_declaration_list
1829
- ;
1830
-
1831
- for_in_statement
1832
- : 'for' LT!* '(' LT!* for_in_statement_initialiser_part LT!* 'in'
1833
- LT!* expression LT!* ')' LT!* statement
1834
- ;
1835
-
1836
- for_in_statement_initialiser_part
1837
- : left_hand_side_expression
1838
- | 'var' LT!* variable_declaration
1839
- ;*/
1840
-
1911
+ /* *
1912
+ * Parse for/for-in statements
1913
+ *
1914
+ * See also:
1915
+ * ECMA-262 v5, 12.6.3 and 12.6.4
1916
+ */
1841
1917
static void
1842
- parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
1843
- * the statement (or NULL, if there are no named
1844
- * labels associated with the statement) */
1918
+ jsp_parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label,
1919
+ * corresponding to the statement
1920
+ * (or NULL, if there are no name
1921
+ * labels associated with the statement) */
1845
1922
{
1846
1923
assert_keyword (KW_FOR);
1847
1924
token_after_newlines_must_be (TOK_OPEN_PAREN);
1848
1925
1849
- skip_newlines ();
1850
- if (token_is (TOK_SEMICOLON))
1851
- {
1852
- parse_plain_for (outermost_stmt_label_p);
1853
- return ;
1854
- }
1855
- /* Both for_statement_initialiser_part and for_in_statement_initialiser_part
1856
- contains 'var'. Check it first. */
1857
- if (is_keyword (KW_VAR))
1858
- {
1859
- bool several_decls = false ;
1860
- skip_newlines ();
1861
- parse_variable_declaration_list (&several_decls);
1862
- if (several_decls)
1863
- {
1864
- token_after_newlines_must_be (TOK_SEMICOLON);
1865
- parse_plain_for (outermost_stmt_label_p);
1866
- return ;
1867
- }
1868
- else
1869
- {
1870
- skip_newlines ();
1871
- if (token_is (TOK_SEMICOLON))
1872
- {
1873
- parse_plain_for (outermost_stmt_label_p);
1874
- return ;
1875
- }
1876
- else if (is_keyword (KW_IN))
1877
- {
1878
- parse_for_in (outermost_stmt_label_p);
1879
- return ;
1880
- }
1881
- else
1882
- {
1883
- EMIT_ERROR (" Expected either ';' or 'in' token" );
1884
- }
1885
- }
1886
- }
1926
+ locus for_open_paren_loc, for_body_statement_loc;
1887
1927
1888
- /* expression contains left_hand_side_expression. */
1889
- parse_expression (false , JSP_EVAL_RET_STORE_NOT_DUMP);
1928
+ for_open_paren_loc = tok.loc ;
1890
1929
1930
+ jsp_skip_braces (TOK_OPEN_PAREN);
1891
1931
skip_newlines ();
1892
- if (token_is (TOK_SEMICOLON))
1893
- {
1894
- parse_plain_for (outermost_stmt_label_p);
1895
- return ;
1896
- }
1897
- else if (is_keyword (KW_IN))
1932
+
1933
+ for_body_statement_loc = tok.loc ;
1934
+
1935
+ lexer_seek (for_open_paren_loc);
1936
+ tok = lexer_next_token ();
1937
+
1938
+ bool is_plain_for = jsp_find_next_token_before_the_locus (TOK_SEMICOLON,
1939
+ for_body_statement_loc);
1940
+ lexer_seek (for_open_paren_loc);
1941
+ tok = lexer_next_token ();
1942
+
1943
+ if (is_plain_for)
1898
1944
{
1899
- parse_for_in (outermost_stmt_label_p);
1900
- return ;
1945
+ jsp_parse_for_statement (outermost_stmt_label_p, for_body_statement_loc);
1901
1946
}
1902
1947
else
1903
1948
{
1904
- EMIT_ERROR ( " Expected either ';' or 'in' token " );
1949
+ parse_for_in (outermost_stmt_label_p );
1905
1950
}
1906
- }
1951
+
1952
+ } /* jsp_parse_for_or_for_in_statement */
1907
1953
1908
1954
static operand
1909
1955
parse_expression_inside_parens (void )
@@ -2317,7 +2363,7 @@ parse_iterational_statement (jsp_label_t *outermost_named_stmt_label_p) /**< out
2317
2363
else
2318
2364
{
2319
2365
JERRY_ASSERT (is_keyword (KW_FOR));
2320
- parse_for_or_for_in_statement (outermost_stmt_label_p);
2366
+ jsp_parse_for_or_for_in_statement (outermost_stmt_label_p);
2321
2367
}
2322
2368
2323
2369
jsp_label_rewrite_jumps_and_pop (&label,
@@ -2411,8 +2457,7 @@ parse_statement (jsp_label_t *outermost_stmt_label_p) /**< outermost (first) lab
2411
2457
}
2412
2458
if (is_keyword (KW_VAR))
2413
2459
{
2414
- skip_newlines ();
2415
- parse_variable_declaration_list (NULL );
2460
+ parse_variable_declaration_list ();
2416
2461
return ;
2417
2462
}
2418
2463
if (is_keyword (KW_FUNCTION))
0 commit comments