Start dumping assignment expressions to bytecode; revise bytecode instructions
This commit is contained in:
@@ -61,10 +61,134 @@ generator_dump_strings (const char **strings, uint8_t num)
|
||||
serializer_dump_data (strings[i], __strlen (strings[i]) + 1);
|
||||
}
|
||||
|
||||
static bool
|
||||
is_expression (statement stmt)
|
||||
{
|
||||
switch (stmt.type)
|
||||
{
|
||||
case STMT_IF:
|
||||
case STMT_ELSE_IF:
|
||||
case STMT_END_DO_WHILE:
|
||||
case STMT_WHILE:
|
||||
case STMT_RETURN:
|
||||
case STMT_WITH:
|
||||
case STMT_SWITCH:
|
||||
case STMT_CASE:
|
||||
case STMT_THROW:
|
||||
case STMT_EXPRESSION:
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
is_assignment (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (is_expression (stmt));
|
||||
return stmt.data.expr.oper != AO_NONE;
|
||||
}
|
||||
|
||||
static expression_type
|
||||
get_expression_type (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (is_expression (stmt));
|
||||
return stmt.data.expr.type;
|
||||
}
|
||||
|
||||
static bool
|
||||
expression_has_operands (statement stmt)
|
||||
{
|
||||
switch (get_expression_type (stmt))
|
||||
{
|
||||
case ET_OBJECT:
|
||||
case ET_FUNCTION:
|
||||
case ET_ARRAY:
|
||||
case ET_SUBEXPRESSION:
|
||||
case ET_NONE:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
static operand
|
||||
first_operand (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (expression_has_operands (stmt));
|
||||
return stmt.data.expr.data.ops.op1;
|
||||
}
|
||||
|
||||
static literal
|
||||
first_operand_as_literal (statement stmt)
|
||||
{
|
||||
operand oper = first_operand (stmt);
|
||||
|
||||
JERRY_ASSERT (oper.is_literal);
|
||||
|
||||
return oper.data.lit;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
first_operand_id (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (expression_has_operands (stmt));
|
||||
if (first_operand (stmt).is_literal)
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
return first_operand (stmt).data.name;
|
||||
}
|
||||
|
||||
static operand
|
||||
second_operand (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (expression_has_operands (stmt));
|
||||
return stmt.data.expr.data.ops.op2;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
second_operand_id (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (expression_has_operands (stmt));
|
||||
if (second_operand (stmt).is_literal)
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
return second_operand (stmt).data.name;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
lhs (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (is_assignment (stmt));
|
||||
|
||||
return stmt.data.expr.var;
|
||||
}
|
||||
|
||||
static void
|
||||
dump_opcode (OPCODE *opcode)
|
||||
{
|
||||
serializer_dump_data (opcode, sizeof (OPCODE));
|
||||
opcode_index++;
|
||||
}
|
||||
|
||||
static assignment_operator
|
||||
get_assignment_operator (statement stmt)
|
||||
{
|
||||
JERRY_ASSERT (is_assignment (stmt));
|
||||
|
||||
return stmt.data.expr.oper;
|
||||
}
|
||||
|
||||
static OPCODE
|
||||
generate_triple_address (OPCODE (*getop)(T_IDX, T_IDX, T_IDX), statement stmt)
|
||||
{
|
||||
return (*getop) (lhs (stmt), first_operand_id (stmt), second_operand_id (stmt));
|
||||
}
|
||||
|
||||
void
|
||||
generator_dump_statement (statement stmt)
|
||||
{
|
||||
OPCODE opcode;
|
||||
OPCODE opcode = getop_nop ();
|
||||
JERRY_STATIC_ASSERT (sizeof (OPCODE) <= sizeof (uint32_t));
|
||||
|
||||
switch (stmt.type)
|
||||
@@ -73,21 +197,205 @@ generator_dump_statement (statement stmt)
|
||||
break;
|
||||
|
||||
case STMT_WHILE:
|
||||
TODO (Supports only infinite loops);
|
||||
if (stmt.data.expr.oper == AO_NONE && stmt.data.expr.type == ET_NONE)
|
||||
if (!is_assignment (stmt))
|
||||
{
|
||||
operand op = stmt.data.expr.data.ops.op1;
|
||||
if (op.is_literal && op.data.lit.type == LIT_BOOL && op.data.lit.data.is_true)
|
||||
{
|
||||
opcode = getop_loop_inf ((uint8_t) (opcode_index + 1));
|
||||
push_opcode ((uint8_t) (opcode_index + 1));
|
||||
}
|
||||
literal lit;
|
||||
|
||||
switch (get_expression_type (stmt))
|
||||
{
|
||||
case ET_LITERAL:
|
||||
lit = first_operand_as_literal (stmt);
|
||||
if (lit.type == LIT_BOOL && lit.data.is_true)
|
||||
{
|
||||
opcode = getop_loop_inf ((uint8_t) (opcode_index + 1));
|
||||
push_opcode ((uint8_t) (opcode_index + 1));
|
||||
dump_opcode (&opcode);
|
||||
return;
|
||||
}
|
||||
else
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
break;
|
||||
|
||||
default:
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
}
|
||||
}
|
||||
else
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
break;
|
||||
|
||||
case STMT_EXPRESSION:
|
||||
TODO (Supports only calls);
|
||||
if (stmt.data.expr.oper == AO_NONE)
|
||||
if (is_assignment (stmt))
|
||||
{
|
||||
switch (get_expression_type (stmt))
|
||||
{
|
||||
case ET_NONE:
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
|
||||
case ET_LOGICAL_OR:
|
||||
opcode = generate_triple_address (getop_logical_or, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_LOGICAL_AND:
|
||||
opcode = generate_triple_address (getop_logical_and, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_BITWISE_OR:
|
||||
opcode = generate_triple_address (getop_b_or, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_BITWISE_XOR:
|
||||
opcode = generate_triple_address (getop_b_xor, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_BITWISE_AND:
|
||||
opcode = generate_triple_address (getop_b_and, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_DOUBLE_EQ:
|
||||
opcode = generate_triple_address (getop_equal_value, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_NOT_EQ:
|
||||
opcode = generate_triple_address (getop_not_equal_value, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_TRIPLE_EQ:
|
||||
opcode = generate_triple_address (getop_equal_value_type, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_NOT_DOUBLE_EQ:
|
||||
opcode = generate_triple_address (getop_not_equal_value_type, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_LESS:
|
||||
opcode = generate_triple_address (getop_less_than, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_GREATER:
|
||||
opcode = generate_triple_address (getop_greater_than, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_LESS_EQ:
|
||||
opcode = generate_triple_address (getop_less_or_equal_than, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_GREATER_EQ:
|
||||
opcode = generate_triple_address (getop_greater_or_equal_than, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_INSTANCEOF:
|
||||
case ET_IN:
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
break;
|
||||
|
||||
case ET_LSHIFT:
|
||||
opcode = generate_triple_address (getop_b_shift_left, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_RSHIFT:
|
||||
opcode = generate_triple_address (getop_b_shift_right, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_RSHIFT_EX:
|
||||
opcode = generate_triple_address (getop_b_shift_uright, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_PLUS:
|
||||
opcode = generate_triple_address (getop_addition, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_MINUS:
|
||||
opcode = generate_triple_address (getop_substraction, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_MULT:
|
||||
opcode = generate_triple_address (getop_multiplication, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_DIV:
|
||||
opcode = generate_triple_address (getop_division, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_MOD:
|
||||
opcode = generate_triple_address (getop_remainder, stmt);
|
||||
dump_opcode (&opcode);
|
||||
break;
|
||||
|
||||
case ET_UNARY_DELETE:
|
||||
case ET_UNARY_VOID:
|
||||
case ET_UNARY_TYPEOF:
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
break;
|
||||
|
||||
case ET_UNARY_INCREMENT:
|
||||
// opcode = getop_addition (first_operand_id (stmt), first_operand_id (stmt), INTEGER_ONE);
|
||||
case ET_UNARY_DECREMENT:
|
||||
case ET_UNARY_PLUS:
|
||||
case ET_UNARY_MINUS:
|
||||
case ET_UNARY_COMPL:
|
||||
case ET_UNARY_NOT:
|
||||
case ET_POSTFIX_INCREMENT:
|
||||
case ET_POSTFIX_DECREMENT:
|
||||
case ET_CALL:
|
||||
case ET_NEW:
|
||||
case ET_INDEX:
|
||||
case ET_PROP_REF:
|
||||
case ET_OBJECT:
|
||||
case ET_FUNCTION:
|
||||
case ET_ARRAY:
|
||||
case ET_SUBEXPRESSION:
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
break;
|
||||
|
||||
case ET_LITERAL:
|
||||
case ET_IDENTIFIER:
|
||||
switch (get_assignment_operator (stmt))
|
||||
{
|
||||
case AO_NONE:
|
||||
JERRY_UNREACHABLE ();
|
||||
break;
|
||||
|
||||
case AO_EQ:
|
||||
opcode = getop_assignment (lhs (stmt), first_operand_id (stmt));
|
||||
dump_opcode (&opcode);
|
||||
return;
|
||||
|
||||
default:
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
}
|
||||
JERRY_UNREACHABLE ();
|
||||
|
||||
default:
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
if (get_assignment_operator (stmt) != AO_EQ)
|
||||
JERRY_UNIMPLEMENTED ();
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
call_expression expr = stmt.data.expr.data.call_expr;
|
||||
JERRY_ASSERT (!is_operand_list_empty (expr.args));
|
||||
@@ -107,7 +415,4 @@ generator_dump_statement (statement stmt)
|
||||
__printf (" generator_dump_statement: %d ", stmt.type);
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
serializer_dump_data (&opcode, sizeof (OPCODE));
|
||||
opcode_index++;
|
||||
}
|
||||
@@ -541,7 +541,10 @@ parse_assigment_expression (void)
|
||||
assignment_expression res;
|
||||
|
||||
if (tok.type != TOK_NAME)
|
||||
goto parse_operands;
|
||||
{
|
||||
res.oper = AO_NONE;
|
||||
goto parse_operands;
|
||||
}
|
||||
|
||||
current_token_must_be (TOK_NAME);
|
||||
|
||||
@@ -813,7 +816,10 @@ parse_operator:
|
||||
default:
|
||||
lexer_save_token (tok);
|
||||
res.oper = AO_NONE;
|
||||
res.type = ET_NONE;
|
||||
if (res.data.ops.op1.is_literal)
|
||||
res.type = ET_LITERAL;
|
||||
else
|
||||
res.type = ET_IDENTIFIER;
|
||||
res.data.ops.op2 = empty_operand;
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user