@@ -1768,7 +1768,7 @@ parse_expression (bool in_allowed, /**< flag indicating if 'in' is allowed insid
1768
1768
initialiser
1769
1769
: '=' LT!* assignment_expression
1770
1770
; */
1771
- static void
1771
+ static operand
1772
1772
parse_variable_declaration (void )
1773
1773
{
1774
1774
current_token_must_be (TOK_NAME);
@@ -1785,6 +1785,8 @@ parse_variable_declaration (void)
1785
1785
{
1786
1786
lexer_save_token (tok);
1787
1787
}
1788
+
1789
+ return name;
1788
1790
}
1789
1791
1790
1792
/* variable_declaration_list
@@ -1933,15 +1935,176 @@ jsp_parse_for_statement (jsp_label_t *outermost_stmt_label_p, /**< outermost (fi
1933
1935
}
1934
1936
} /* jsp_parse_for_statement */
1935
1937
1938
+ /* *
1939
+ * Parse VariableDeclarationNoIn / LeftHandSideExpression (iterator part) of for-in statement
1940
+ *
1941
+ * See also:
1942
+ * jsp_parse_for_in_statement
1943
+ *
1944
+ * @return true - if iterator consists of base and property name,
1945
+ * false - otherwise, iterator consists of an identifier name (without base).
1946
+ */
1947
+ static bool
1948
+ jsp_parse_for_in_statement_iterator (operand *base_p, /* *< out: base value of member expression, if any,
1949
+ * empty operand - otherwise */
1950
+ operand *identifier_p) /* *< out: property name (if base value is not empty),
1951
+ * identifier - otherwise */
1952
+ {
1953
+ JERRY_ASSERT (base_p != NULL );
1954
+ JERRY_ASSERT (identifier_p != NULL );
1955
+
1956
+ if (is_keyword (KW_VAR))
1957
+ {
1958
+ skip_newlines ();
1959
+
1960
+ *base_p = empty_operand ();
1961
+ *identifier_p = parse_variable_declaration ();
1962
+
1963
+ return false ;
1964
+ }
1965
+ else
1966
+ {
1967
+ operand base, identifier;
1968
+
1969
+ /*
1970
+ * FIXME:
1971
+ * Remove evaluation of last part of identifier chain
1972
+ */
1973
+ operand i = parse_left_hand_side_expression (&base, &identifier);
1974
+
1975
+ if (operand_is_empty (base))
1976
+ {
1977
+ *base_p = empty_operand ();
1978
+ *identifier_p = i;
1979
+
1980
+ return false ;
1981
+ }
1982
+ else
1983
+ {
1984
+ *base_p = base;
1985
+ *identifier_p = identifier;
1986
+
1987
+ return true ;
1988
+ }
1989
+ }
1990
+ } /* jsp_parse_for_in_statement_iterator */
1991
+
1992
+ /* *
1993
+ * Parse for-in statement
1994
+ *
1995
+ * See also:
1996
+ * ECMA-262 v5, 12.6.4
1997
+ *
1998
+ * Note:
1999
+ * Syntax:
2000
+ * Iterator Collection Body LoopEnd
2001
+ * - for ( LeftHandSideExpression in Expression) Statement
2002
+ * - for (var VariableDeclarationNoIn in Expression) Statement
2003
+ *
2004
+ * Note:
2005
+ * Layout of generate byte-code is the following:
2006
+ * tmp <- Collection (Expression)
2007
+ * for_in instruction (tmp, opcode counter of for-in end mark)
2008
+ * {
2009
+ * Assignment of OPCODE_REG_SPECIAL_FOR_IN_PROPERTY_NAME to
2010
+ * Iterator (VariableDeclarationNoIn / LeftHandSideExpression)
2011
+ * }
2012
+ * Body (Statement)
2013
+ * ContinueTarget:
2014
+ * meta (OPCODE_META_TYPE_END_FOR_IN)
2015
+ */
1936
2016
static void
1937
- parse_for_in (jsp_label_t *outermost_stmt_label_p) /* *< outermost (first) label, corresponding to
1938
- * the statement (or NULL, if there are no named
1939
- * labels associated with the statement) */
2017
+ jsp_parse_for_in_statement (jsp_label_t *outermost_stmt_label_p, /* *< outermost (first) label,
2018
+ * corresponding to the statement
2019
+ * (or NULL, if there are no name
2020
+ * labels associated with the statement) */
2021
+ locus for_body_statement_loc) /* *< locus of loop body statement */
1940
2022
{
1941
- ( void ) outermost_stmt_label_p ;
2023
+ jsp_label_raise_nested_jumpable_border () ;
1942
2024
1943
- EMIT_SORRY (" 'for in' loops are not supported yet" );
1944
- }
2025
+ current_token_must_be (TOK_OPEN_PAREN);
2026
+ skip_newlines ();
2027
+
2028
+ // Save Iterator location
2029
+ locus iterator_loc = tok.loc ;
2030
+
2031
+ while (tok.loc < for_body_statement_loc)
2032
+ {
2033
+ if (jsp_find_next_token_before_the_locus (TOK_KEYWORD,
2034
+ for_body_statement_loc,
2035
+ true ))
2036
+ {
2037
+ if (is_keyword (KW_IN))
2038
+ {
2039
+ break ;
2040
+ }
2041
+ else
2042
+ {
2043
+ skip_token ();
2044
+ }
2045
+ }
2046
+ else
2047
+ {
2048
+ EMIT_ERROR (" Invalid for statement" );
2049
+ }
2050
+ }
2051
+
2052
+ JERRY_ASSERT (is_keyword (KW_IN));
2053
+ skip_newlines ();
2054
+
2055
+ // Collection
2056
+ operand collection = parse_expression (true , JSP_EVAL_RET_STORE_NOT_DUMP);
2057
+ current_token_must_be (TOK_CLOSE_PAREN);
2058
+ skip_token ();
2059
+
2060
+ // Dump for-in instruction
2061
+ opcode_counter_t for_in_oc = dump_for_in_for_rewrite (collection);
2062
+
2063
+ // Dump assignment VariableDeclarationNoIn / LeftHandSideExpression <- OPCODE_REG_SPECIAL_FOR_IN_PROPERTY_NAME
2064
+ lexer_seek (iterator_loc);
2065
+ tok = lexer_next_token ();
2066
+
2067
+ operand iterator_base, iterator_identifier, for_in_special_reg;
2068
+ for_in_special_reg = jsp_create_operand_for_in_special_reg ();
2069
+
2070
+ if (jsp_parse_for_in_statement_iterator (&iterator_base, &iterator_identifier))
2071
+ {
2072
+ dump_prop_setter (iterator_base, iterator_identifier, for_in_special_reg);
2073
+ }
2074
+ else
2075
+ {
2076
+ JERRY_ASSERT (operand_is_empty (iterator_base));
2077
+ dump_variable_assignment (iterator_identifier, for_in_special_reg);
2078
+ }
2079
+
2080
+ // Body
2081
+ lexer_seek (for_body_statement_loc);
2082
+ tok = lexer_next_token ();
2083
+
2084
+ parse_statement (NULL );
2085
+
2086
+ // Save LoopEnd locus
2087
+ const locus loop_end_loc = tok.loc ;
2088
+
2089
+ // Setup ContinueTarget
2090
+ jsp_label_setup_continue_target (outermost_stmt_label_p,
2091
+ serializer_get_current_opcode_counter ());
2092
+
2093
+ // Write position of for-in end to for_in instruction
2094
+ rewrite_for_in (for_in_oc);
2095
+
2096
+ // Dump meta (OPCODE_META_TYPE_END_FOR_IN)
2097
+ dump_for_in_end ();
2098
+
2099
+ lexer_seek (loop_end_loc);
2100
+ tok = lexer_next_token ();
2101
+ if (tok.type != TOK_CLOSE_BRACE)
2102
+ {
2103
+ lexer_save_token (tok);
2104
+ }
2105
+
2106
+ jsp_label_remove_nested_jumpable_border ();
2107
+ } /* jsp_parse_for_in_statement */
1945
2108
1946
2109
/* *
1947
2110
* Parse for/for-in statements
@@ -1982,7 +2145,7 @@ jsp_parse_for_or_for_in_statement (jsp_label_t *outermost_stmt_label_p) /**< out
1982
2145
}
1983
2146
else
1984
2147
{
1985
- parse_for_in (outermost_stmt_label_p);
2148
+ jsp_parse_for_in_statement (outermost_stmt_label_p, for_body_statement_loc );
1986
2149
}
1987
2150
} /* jsp_parse_for_or_for_in_statement */
1988
2151
0 commit comments