Fix && and || parsing

This commit is contained in:
Ilmir Usmanov 2014-10-05 21:39:15 +04:00
parent 17ee2eca50
commit 62cc3cc604
3 changed files with 121 additions and 3 deletions

View File

@ -245,7 +245,7 @@ do { \
#define STACK_DROP(NAME, I) \
do { \
JERRY_ASSERT ((I) >= 0); \
for (size_t i = 0; i < (size_t) (I); i++) { \
for (size_t i = 0, till = (size_t) (I); i < till; i++) { \
decrease_##NAME##_stack_size (); } } while (0)
#define STACK_CLEAN(NAME) \

View File

@ -1828,12 +1828,94 @@ PARSE_OF (bitwise_or_expression, bitwise_xor_expression, OR, b_or)
/* logical_and_expression
: bitwise_or_expression (LT!* '&&' LT!* bitwise_or_expression)*
; */
PARSE_OF (logical_and_expression, bitwise_or_expression, DOUBLE_AND, logical_and)
static void
parse_logical_and_expression (void)
{
STACK_DECLARE_USAGE (IDX)
STACK_DECLARE_USAGE (U16)
STACK_DECLARE_USAGE (U8)
STACK_PUSH (U8, STACK_SIZE (U16));
parse_bitwise_or_expression ();
skip_newlines ();
while (true)
{
if (token_is (TOK_DOUBLE_AND))
{
STACK_PUSH (U16, OPCODE_COUNTER ());
DUMP_OPCODE_3 (is_false_jmp_down, ID (1), INVALID_VALUE, INVALID_VALUE);
NEXT (bitwise_or_expression);
DUMP_OPCODE_3 (logical_and, ID (2), ID (2), ID (1));
STACK_DROP (IDX, 1);
}
else
{
lexer_save_token (TOK ());
break;
}
skip_newlines ();
}
for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (U16); i++)
{
REWRITE_COND_JMP (STACK_ELEMENT (U16, i), is_false_jmp_down, OPCODE_COUNTER () - STACK_ELEMENT (U16, i));
}
STACK_DROP (U16, STACK_SIZE (U16) - STACK_TOP (U8));
STACK_DROP (U8, 1);
STACK_CHECK_USAGE (U16);
STACK_CHECK_USAGE (U8);
STACK_CHECK_USAGE_LHS ();
}
/* logical_or_expression
: logical_and_expression (LT!* '||' LT!* logical_and_expression)*
; */
PARSE_OF (logical_or_expression, logical_and_expression, DOUBLE_OR, logical_or)
static void
parse_logical_or_expression (void)
{
STACK_DECLARE_USAGE (IDX)
STACK_DECLARE_USAGE (U16)
STACK_DECLARE_USAGE (U8)
STACK_PUSH (U8, STACK_SIZE (U16));
parse_logical_and_expression ();
skip_newlines ();
while (true)
{
if (token_is (TOK_DOUBLE_OR))
{
STACK_PUSH (U16, OPCODE_COUNTER ());
DUMP_OPCODE_3 (is_true_jmp_down, ID (1), INVALID_VALUE, INVALID_VALUE);
NEXT (logical_and_expression);
DUMP_OPCODE_3 (logical_or, ID (2), ID (2), ID (1));
STACK_DROP (IDX, 1);
}
else
{
lexer_save_token (TOK ());
break;
}
skip_newlines ();
}
for (uint8_t i = STACK_TOP (U8); i < STACK_SIZE (U16); i++)
{
REWRITE_COND_JMP (STACK_ELEMENT (U16, i), is_true_jmp_down, OPCODE_COUNTER () - STACK_ELEMENT (U16, i));
}
STACK_DROP (U16, STACK_SIZE (U16) - STACK_TOP (U8));
STACK_DROP (U8, 1);
STACK_CHECK_USAGE (U16);
STACK_CHECK_USAGE (U8);
STACK_CHECK_USAGE_LHS ();
}
/* conditional_expression
: logical_or_expression (LT!* '?' LT!* assignment_expression LT!* ':' LT!* assignment_expression)?

36
tests/jerry/and_or.js Normal file
View File

@ -0,0 +1,36 @@
// Copyright 2014 Samsung Electronics Co., Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
function fail() {
assert (0);
return true;
}
if (false && fail()) {
assert (0);
}
if (true && false && fail()) {
assert (0);
}
if (true || fail()) {
} else {
assert (0);
}
if (false || true || fail()) {
} else {
assert (0);
}