mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Generate bytecode while parsing
This commit is contained in:
parent
9a0b54313d
commit
efb7009cfb
@ -166,6 +166,11 @@ OP_CODE_DECL (b_xor, T_IDX_IDX_IDX,
|
||||
var_left,
|
||||
var_right)
|
||||
|
||||
/** dst = ~ R */
|
||||
OP_CODE_DECL (b_not, T_IDX_IDX,
|
||||
dst,
|
||||
var_right)
|
||||
|
||||
// Binary logical operators.
|
||||
// Operands are booleans.
|
||||
// Return boolean.
|
||||
@ -182,6 +187,11 @@ OP_CODE_DECL (logical_or, T_IDX_IDX_IDX,
|
||||
var_left,
|
||||
var_right)
|
||||
|
||||
/** dst = ! R */
|
||||
OP_CODE_DECL (logical_not, T_IDX_IDX,
|
||||
dst,
|
||||
var_right)
|
||||
|
||||
// Equality operations.
|
||||
|
||||
/** dst = L == R. */
|
||||
@ -234,6 +244,18 @@ OP_CODE_DECL (greater_or_equal_than, T_IDX_IDX_IDX,
|
||||
var_left,
|
||||
var_right)
|
||||
|
||||
/** dst = L instanceof R. */
|
||||
OP_CODE_DECL (instanceof, T_IDX_IDX_IDX,
|
||||
dst,
|
||||
var_left,
|
||||
var_right)
|
||||
|
||||
/** dst = L in R. */
|
||||
OP_CODE_DECL (in, T_IDX_IDX_IDX,
|
||||
dst,
|
||||
var_left,
|
||||
var_right)
|
||||
|
||||
// Assignment operators.
|
||||
// Assign value to LEFT operand based on value of RIGHT operand.
|
||||
|
||||
@ -244,22 +266,43 @@ OP_CODE_DECL (assignment, T_IDX_IDX,
|
||||
|
||||
// Functions calls, declarations and argument handling
|
||||
|
||||
/** name(arg1); */
|
||||
OP_CODE_DECL (call_1, T_IDX_IDX,
|
||||
/** a = name(); */
|
||||
OP_CODE_DECL (call_0, T_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx)
|
||||
|
||||
/** a = name(arg1); */
|
||||
OP_CODE_DECL (call_1, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx)
|
||||
|
||||
/** name(arg1, arg2); */
|
||||
OP_CODE_DECL (call_2, T_IDX_IDX_IDX,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx,
|
||||
arg2_lit_idx)
|
||||
|
||||
/** name(arg1, arg2, ... */
|
||||
/** a = name(arg1, ... */
|
||||
OP_CODE_DECL (call_n, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx,
|
||||
arg2_lit_idx)
|
||||
arg1_lit_idx)
|
||||
|
||||
/** a = new name(); */
|
||||
OP_CODE_DECL (construct_0, T_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx)
|
||||
|
||||
/** a = new name(arg1); */
|
||||
OP_CODE_DECL (construct_1, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx)
|
||||
|
||||
/** a = new name(arg1, ... */
|
||||
OP_CODE_DECL (construct_n, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx)
|
||||
|
||||
/** name(); */
|
||||
OP_CODE_DECL (func_decl_0, T_IDX,
|
||||
name_lit_idx)
|
||||
|
||||
/** name(arg1); */
|
||||
OP_CODE_DECL (func_decl_1, T_IDX_IDX,
|
||||
@ -278,19 +321,27 @@ OP_CODE_DECL (func_decl_n, T_IDX_IDX_IDX,
|
||||
arg1_lit_idx,
|
||||
arg2_lit_idx)
|
||||
|
||||
/** ..., arg1, ... */
|
||||
OP_CODE_DECL (varg_1, T_IDX,
|
||||
/** a = name(); */
|
||||
OP_CODE_DECL (func_expr_0, T_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx)
|
||||
|
||||
/** a = name(arg1); */
|
||||
OP_CODE_DECL (func_expr_1, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx)
|
||||
|
||||
/** a = name(arg1, ... */
|
||||
OP_CODE_DECL (func_expr_n, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name_lit_idx,
|
||||
arg1_lit_idx)
|
||||
|
||||
/** ..., arg1); */
|
||||
OP_CODE_DECL (varg_1_end, T_IDX,
|
||||
arg1_lit_idx)
|
||||
|
||||
/** ..., arg1, arg2, ... */
|
||||
OP_CODE_DECL (varg_2, T_IDX_IDX,
|
||||
arg1_lit_idx,
|
||||
arg2_lit_idx)
|
||||
|
||||
/** ..., arg1, arg2); */
|
||||
OP_CODE_DECL (varg_2_end, T_IDX_IDX,
|
||||
arg1_lit_idx,
|
||||
@ -356,26 +407,91 @@ OP_CODE_DECL (loop_postcond, T_IDX_IDX,
|
||||
condition,
|
||||
body_root)
|
||||
|
||||
///** for vars...in iter, state, ctl */
|
||||
//OP_CODE_DECL (loop_init, T_IDX_IDX_IDX,
|
||||
// start_idx, stop_idx, step_idx)
|
||||
///** loop (condition) */
|
||||
//OP_CODE_DECL (loop_cond_pre_begin, T_IDX_IDX,
|
||||
// condition, body_root)
|
||||
///** i++;*/
|
||||
//OP_CODE_DECL (loop_cond_pre_end, T_IDX,
|
||||
// iterator, body_root)
|
||||
/** a = [] */
|
||||
OP_CODE_DECL (array_0, T_IDX,
|
||||
lhs)
|
||||
|
||||
// Property accessors (array, objects, strings)
|
||||
/** Array ops for ILMIR*/
|
||||
//OP_CODE_DECL (array_copy, T_IDX_IDX, /** L = R */
|
||||
// var_left, var_right)
|
||||
//OP_CODE_DECL (array_set, T_IDX_IDX_IDX, /** array[index] = src */
|
||||
// dst, var_left, var_right)
|
||||
//OP_CODE_DECL (array_get, T_IDX_IDX_IDX, /** dst = array[index] */
|
||||
// dst, array, index)
|
||||
/** a = [b] */
|
||||
OP_CODE_DECL (array_1, T_IDX_IDX,
|
||||
lhs,
|
||||
elem1)
|
||||
|
||||
//// TODO
|
||||
/** a = [b, c] */
|
||||
OP_CODE_DECL (array_2, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
elem1,
|
||||
elem2)
|
||||
|
||||
/** a = [b, c ... */
|
||||
OP_CODE_DECL (array_n, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
elem1,
|
||||
elem2)
|
||||
|
||||
/** a = b : c */
|
||||
OP_CODE_DECL (prop, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
name,
|
||||
value)
|
||||
|
||||
/** a = b.c OR a = b[c] */
|
||||
OP_CODE_DECL (prop_access, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
obj,
|
||||
prop)
|
||||
|
||||
/** a = get prop () */
|
||||
OP_CODE_DECL (prop_get_decl, T_IDX_IDX,
|
||||
lhs,
|
||||
prop)
|
||||
|
||||
/** a = set prop (arg) */
|
||||
OP_CODE_DECL (prop_set_decl, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
prop,
|
||||
arg)
|
||||
|
||||
/** a = { } */
|
||||
OP_CODE_DECL (obj_0, T_IDX,
|
||||
lhs)
|
||||
|
||||
/** a = { b } */
|
||||
OP_CODE_DECL (obj_1, T_IDX_IDX,
|
||||
lhs,
|
||||
arg1)
|
||||
|
||||
/** a = { b, c } */
|
||||
OP_CODE_DECL (obj_2, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
arg1,
|
||||
arg2)
|
||||
|
||||
/** a = { b, c ... */
|
||||
OP_CODE_DECL (obj_n, T_IDX_IDX_IDX,
|
||||
lhs,
|
||||
arg1,
|
||||
arg2)
|
||||
|
||||
/** a = this */
|
||||
OP_CODE_DECL (this, T_IDX,
|
||||
lhs)
|
||||
|
||||
/** a = delete b */
|
||||
OP_CODE_DECL (delete, T_IDX_IDX,
|
||||
lhs,
|
||||
obj)
|
||||
|
||||
/** a = delete b */
|
||||
OP_CODE_DECL (typeof, T_IDX_IDX,
|
||||
lhs,
|
||||
obj)
|
||||
|
||||
/** with (b) { */
|
||||
OP_CODE_DECL (with, T_IDX,
|
||||
expr)
|
||||
|
||||
/** } */
|
||||
OP_CODE_DECL_VOID (end_with)
|
||||
|
||||
// Variable declaration
|
||||
OP_CODE_DECL (decl_var, T_IDX,
|
||||
|
||||
@ -22,19 +22,42 @@ void opfunc_loop_init_num (OPCODE opdata __unused, struct __int_data *int_data _
|
||||
void opfunc_loop_precond_begin_num (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_loop_precond_end_num (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_loop_postcond (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_call_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_call_0 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_call_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_construct_0 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_construct_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_construct_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_decl_0 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_decl_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_decl_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_decl_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_varg_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_expr_0 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_expr_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_func_expr_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_varg_1_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_varg_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_varg_2_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_varg_3 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_varg_3_end (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_retval (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_ret (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_array_0 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_array_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_array_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_array_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_obj_0 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_obj_1 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_obj_2 (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_obj_n (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_prop (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_prop_access (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_prop_get_decl (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_prop_set_decl (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_this (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_delete (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_typeof (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_with (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_end_with (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_decl_var (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_nop (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_equal_value (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_not_equal_value (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
@ -44,6 +67,8 @@ void opfunc_less_than (OPCODE opdata __unused, struct __int_data *int_data __unu
|
||||
void opfunc_greater_than (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_less_or_equal_than (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_greater_or_equal_than (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_instanceof (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_in (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
|
||||
void
|
||||
opfunc_assignment(OPCODE opdata __unused,
|
||||
@ -54,9 +79,11 @@ opfunc_assignment(OPCODE opdata __unused,
|
||||
|
||||
void opfunc_logical_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_logical_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_logical_not (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_and (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_or (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_xor (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_not (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_shift_left (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_shift_right (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
void opfunc_b_shift_uright (OPCODE opdata __unused, struct __int_data *int_data __unused) { JERRY_UNREACHABLE (); }
|
||||
@ -124,8 +151,10 @@ GETOP_IMPL_3 (b_shift_uright, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (b_and, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (b_or, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (b_xor, dst, var_left, var_right)
|
||||
GETOP_IMPL_2 (b_not, dst, var_right)
|
||||
GETOP_IMPL_3 (logical_and, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (logical_or, dst, var_left, var_right)
|
||||
GETOP_IMPL_2 (logical_not, dst, var_right)
|
||||
GETOP_IMPL_3 (equal_value, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (not_equal_value, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (equal_value_type, dst, var_left, var_right)
|
||||
@ -134,16 +163,23 @@ GETOP_IMPL_3 (less_than, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (greater_than, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (less_or_equal_than, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (greater_or_equal_than, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (instanceof, dst, var_left, var_right)
|
||||
GETOP_IMPL_3 (in, dst, var_left, var_right)
|
||||
GETOP_IMPL_2 (assignment, value_left, value_right)
|
||||
GETOP_IMPL_2 (call_1, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_3 (call_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
|
||||
GETOP_IMPL_3 (call_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
|
||||
GETOP_IMPL_2 (call_0, lhs, name_lit_idx)
|
||||
GETOP_IMPL_3 (call_1, lhs, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_3 (call_n, lhs, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_2 (construct_0, lhs, name_lit_idx)
|
||||
GETOP_IMPL_3 (construct_1, lhs, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_3 (construct_n, lhs, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_1 (func_decl_0, name_lit_idx)
|
||||
GETOP_IMPL_2 (func_decl_1, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_3 (func_decl_2, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
|
||||
GETOP_IMPL_3 (func_decl_n, name_lit_idx, arg1_lit_idx, arg2_lit_idx)
|
||||
GETOP_IMPL_1 (varg_1, arg1_lit_idx)
|
||||
GETOP_IMPL_2 (func_expr_0, lhs, name_lit_idx)
|
||||
GETOP_IMPL_3 (func_expr_1, lhs, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_3 (func_expr_n, lhs, name_lit_idx, arg1_lit_idx)
|
||||
GETOP_IMPL_1 (varg_1_end, arg1_lit_idx)
|
||||
GETOP_IMPL_2 (varg_2, arg1_lit_idx, arg2_lit_idx)
|
||||
GETOP_IMPL_2 (varg_2_end, arg1_lit_idx, arg2_lit_idx)
|
||||
GETOP_IMPL_3 (varg_3, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx)
|
||||
GETOP_IMPL_3 (varg_3_end, arg1_lit_idx, arg2_lit_idx, arg3_lit_idx)
|
||||
@ -155,4 +191,22 @@ GETOP_IMPL_3 (loop_init_num, start, stop, step)
|
||||
GETOP_IMPL_2 (loop_precond_begin_num, condition, after_loop_op)
|
||||
GETOP_IMPL_3 (loop_precond_end_num, iterator, step, precond_begin)
|
||||
GETOP_IMPL_2 (loop_postcond, condition, body_root)
|
||||
GETOP_IMPL_1 (array_0, lhs)
|
||||
GETOP_IMPL_2 (array_1, lhs, elem1)
|
||||
GETOP_IMPL_3 (array_2, lhs, elem1, elem2)
|
||||
GETOP_IMPL_3 (array_n, lhs, elem1, elem2)
|
||||
GETOP_IMPL_3 (prop, lhs, name, value)
|
||||
GETOP_IMPL_3 (prop_access, lhs, obj, prop)
|
||||
GETOP_IMPL_2 (prop_get_decl, lhs, prop)
|
||||
GETOP_IMPL_3 (prop_set_decl, lhs, prop, arg)
|
||||
GETOP_IMPL_1 (obj_0, lhs)
|
||||
GETOP_IMPL_2 (obj_1, lhs, arg1)
|
||||
GETOP_IMPL_3 (obj_2, lhs, arg1, arg2)
|
||||
GETOP_IMPL_3 (obj_n, lhs, arg1, arg2)
|
||||
GETOP_IMPL_1 (this, lhs)
|
||||
GETOP_IMPL_2 (delete, lhs, obj)
|
||||
GETOP_IMPL_2 (typeof, lhs, obj)
|
||||
GETOP_IMPL_1 (with, expr)
|
||||
GETOP_IMPL_0 (end_with)
|
||||
GETOP_IMPL_1 (decl_var, variable)
|
||||
|
||||
|
||||
@ -42,21 +42,46 @@ typedef void (*opfunc)(OPCODE, struct __int_data *);
|
||||
op(loop_postcond)
|
||||
|
||||
#define OP_CALLS_AND_ARGS(op) \
|
||||
op(call_0) \
|
||||
op(call_1) \
|
||||
op(call_2) \
|
||||
op(call_n) \
|
||||
op(construct_0) \
|
||||
op(construct_1) \
|
||||
op(construct_n) \
|
||||
op(func_decl_0) \
|
||||
op(func_decl_1) \
|
||||
op(func_decl_2) \
|
||||
op(func_decl_n) \
|
||||
op(varg_1) \
|
||||
op(func_expr_0) \
|
||||
op(func_expr_1) \
|
||||
op(func_expr_n) \
|
||||
op(varg_1_end) \
|
||||
op(varg_2) \
|
||||
op(varg_2_end) \
|
||||
op(varg_3) \
|
||||
op(varg_3_end) \
|
||||
op(retval) \
|
||||
op(ret)
|
||||
|
||||
#define OP_INITS(op) \
|
||||
op(array_0) \
|
||||
op(array_1) \
|
||||
op(array_2) \
|
||||
op(array_n) \
|
||||
op(prop) \
|
||||
op(prop_access) \
|
||||
op(prop_get_decl) \
|
||||
op(prop_set_decl) \
|
||||
op(obj_0) \
|
||||
op(obj_1) \
|
||||
op(obj_2) \
|
||||
op(obj_n) \
|
||||
op(this) \
|
||||
op(delete) \
|
||||
op(typeof) \
|
||||
op(with) \
|
||||
op(end_with) \
|
||||
op(decl_var)
|
||||
|
||||
#define OP_ASSIGNMENTS(op) \
|
||||
op(assignment)
|
||||
|
||||
@ -68,11 +93,13 @@ typedef void (*opfunc)(OPCODE, struct __int_data *);
|
||||
#define OP_B_BITWISE(op) \
|
||||
op(b_and) \
|
||||
op(b_or) \
|
||||
op(b_xor)
|
||||
op(b_xor) \
|
||||
op(b_not)
|
||||
|
||||
#define OP_B_LOGICAL(op) \
|
||||
op(logical_and) \
|
||||
op(logical_or)
|
||||
op(logical_or) \
|
||||
op(logical_not)
|
||||
|
||||
#define OP_EQUALITY(op) \
|
||||
op(equal_value) \
|
||||
@ -84,7 +111,9 @@ typedef void (*opfunc)(OPCODE, struct __int_data *);
|
||||
op(less_than) \
|
||||
op(greater_than) \
|
||||
op(less_or_equal_than) \
|
||||
op(greater_or_equal_than)
|
||||
op(greater_or_equal_than) \
|
||||
op(instanceof) \
|
||||
op(in)
|
||||
|
||||
#define OP_ARITHMETIC(op) \
|
||||
op(addition) \
|
||||
@ -106,6 +135,7 @@ typedef void (*opfunc)(OPCODE, struct __int_data *);
|
||||
#define OP_LIST(op) \
|
||||
OP_LOOPS(op) \
|
||||
OP_CALLS_AND_ARGS(op) \
|
||||
OP_INITS(op) \
|
||||
OP_ASSIGNMENTS(op) \
|
||||
OP_B_LOGICAL(op) \
|
||||
OP_B_BITWISE(op) \
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
/* This allocator only allocates a memmory and doesn't free it.
|
||||
Use it only in dedicated parser, otherwise use jerry fixed pool allocator. */
|
||||
#ifndef ALLOCATOR_H
|
||||
#define ALLOCATOR_H
|
||||
|
||||
#include "../globals.h"
|
||||
|
||||
#define ALLOCATION_BUFFER_SIZE 4096
|
||||
|
||||
char allocation_buffer[ALLOCATION_BUFFER_SIZE];
|
||||
char *free_memory;
|
||||
|
||||
static void *
|
||||
geppetto_allocate_memory (size_t size)
|
||||
{
|
||||
void *res;
|
||||
if (!free_memory)
|
||||
free_memory = allocation_buffer;
|
||||
|
||||
res = free_memory;
|
||||
free_memory += size;
|
||||
JERRY_ASSERT (free_memory - allocation_buffer < ALLOCATION_BUFFER_SIZE);
|
||||
return res;
|
||||
}
|
||||
|
||||
static inline void *
|
||||
malloc (size_t size)
|
||||
{
|
||||
return geppetto_allocate_memory (size);
|
||||
}
|
||||
|
||||
static inline void
|
||||
free (void *mem __unused)
|
||||
{
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
|
||||
#endif // ALLOCATOR_H
|
||||
@ -1,418 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#include "bytecode-generator.h"
|
||||
#include "globals.h"
|
||||
#include "libcoreint/opcodes.h"
|
||||
#include "libruntime/serializer.h"
|
||||
#include "libruntime/jerry-libc.h"
|
||||
|
||||
static uint8_t opcode_index;
|
||||
|
||||
#define MAX_STACK_SIZE 10
|
||||
|
||||
static uint8_t opcode_stack[10];
|
||||
static uint8_t stack_head;
|
||||
|
||||
static void
|
||||
push_opcode (uint8_t opcode)
|
||||
{
|
||||
JERRY_ASSERT (stack_head < MAX_STACK_SIZE);
|
||||
opcode_stack[stack_head++] = opcode;
|
||||
}
|
||||
|
||||
static uint8_t
|
||||
pop_opcode (void)
|
||||
{
|
||||
return opcode_stack[--stack_head];
|
||||
}
|
||||
|
||||
void
|
||||
generator_init (void)
|
||||
{
|
||||
opcode_index = 0;
|
||||
stack_head = 0;
|
||||
}
|
||||
|
||||
void
|
||||
generator_dump_strings (const char **strings, uint8_t num)
|
||||
{
|
||||
uint8_t len = num, i;
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
{
|
||||
serializer_dump_data (&len, 1);
|
||||
len = (uint8_t) (len + __strlen (strings[i]));
|
||||
}
|
||||
|
||||
for (i = 0; i < num; i++)
|
||||
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 = getop_nop ();
|
||||
JERRY_STATIC_ASSERT (sizeof (OPCODE) <= sizeof (uint32_t));
|
||||
|
||||
switch (stmt.type)
|
||||
{
|
||||
case STMT_EMPTY:
|
||||
break;
|
||||
|
||||
case STMT_WHILE:
|
||||
if (!is_assignment (stmt))
|
||||
{
|
||||
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:
|
||||
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));
|
||||
if (!is_operand_empty (expr.args.ops[1]))
|
||||
JERRY_UNREACHABLE ();
|
||||
if (expr.args.ops[0].is_literal)
|
||||
JERRY_UNREACHABLE ();
|
||||
opcode = getop_call_1 (expr.name, expr.args.ops[0].data.name);
|
||||
}
|
||||
break;
|
||||
|
||||
case STMT_END_WHILE:
|
||||
opcode = getop_jmp (pop_opcode ());
|
||||
break;
|
||||
|
||||
default:
|
||||
__printf (" generator_dump_statement: %d ", stmt.type);
|
||||
JERRY_UNREACHABLE ();
|
||||
}
|
||||
}
|
||||
@ -1,25 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef BYTECODE_GENERATOR_H
|
||||
#define BYTECODE_GENERATOR_H
|
||||
|
||||
#include "parser.h"
|
||||
|
||||
void generator_init (void);
|
||||
void generator_dump_strings (const char **, uint8_t);
|
||||
void generator_dump_statement (statement);
|
||||
|
||||
#endif // BYTECODE_GENERATOR_H
|
||||
@ -13,14 +13,14 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "allocator.h"
|
||||
#include "mem-allocator.h"
|
||||
#include "globals.h"
|
||||
#include "jerry-libc.h"
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
|
||||
static token saved_token;
|
||||
static token empty_token = { .type = TOK_EMPTY, .data.none = NULL };
|
||||
static token empty_token = { .type = TOK_EMPTY, .data.uid = 0 };
|
||||
|
||||
typedef struct
|
||||
{
|
||||
@ -45,7 +45,7 @@ static string_and_token keyword_tokens[] =
|
||||
{ .str = "enum", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "export", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "extends", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "false", .tok = { .type = TOK_BOOL, .data.is_true = false } },
|
||||
{ .str = "false", .tok = { .type = TOK_BOOL, .data.uid = false } },
|
||||
{ .str = "finally", .tok = { .type = TOK_KEYWORD, .data.kw = KW_FINALLY } },
|
||||
{ .str = "for", .tok = { .type = TOK_KEYWORD, .data.kw = KW_FOR } },
|
||||
{ .str = "function", .tok = { .type = TOK_KEYWORD, .data.kw = KW_FUNCTION } },
|
||||
@ -57,7 +57,7 @@ static string_and_token keyword_tokens[] =
|
||||
{ .str = "implements", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "let", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "new", .tok = { .type = TOK_KEYWORD, .data.kw = KW_NEW } },
|
||||
{ .str = "null", .tok = { .type = TOK_NULL, .data.none = NULL } },
|
||||
{ .str = "null", .tok = { .type = TOK_NULL, .data.uid = 0 } },
|
||||
{ .str = "package", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "private", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
{ .str = "protected", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } },
|
||||
@ -68,7 +68,7 @@ static string_and_token keyword_tokens[] =
|
||||
{ .str = "switch", .tok = { .type = TOK_KEYWORD, .data.kw = KW_SWITCH } },
|
||||
{ .str = "this", .tok = { .type = TOK_KEYWORD, .data.kw = KW_THIS } },
|
||||
{ .str = "throw", .tok = { .type = TOK_KEYWORD, .data.kw = KW_THROW } },
|
||||
{ .str = "true", .tok = { .type = TOK_BOOL, .data.is_true = true } },
|
||||
{ .str = "true", .tok = { .type = TOK_BOOL, .data.uid = true } },
|
||||
{ .str = "try", .tok = { .type = TOK_KEYWORD, .data.kw = KW_TRY } },
|
||||
{ .str = "typeof", .tok = { .type = TOK_KEYWORD, .data.kw = KW_TYPEOF } },
|
||||
{ .str = "var", .tok = { .type = TOK_KEYWORD, .data.kw = KW_VAR } },
|
||||
@ -78,10 +78,25 @@ static string_and_token keyword_tokens[] =
|
||||
{ .str = "yield", .tok = { .type = TOK_KEYWORD, .data.kw = KW_RESERVED } }
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int num;
|
||||
token tok;
|
||||
}
|
||||
num_and_token;
|
||||
|
||||
#define MAX_NAMES 100
|
||||
#define MAX_NUMS 25
|
||||
|
||||
static string_and_token seen_names[MAX_NAMES];
|
||||
static uint8_t seen_names_num;
|
||||
static uint8_t seen_names_count = 0;
|
||||
|
||||
static num_and_token seen_nums[MAX_NAMES] =
|
||||
{
|
||||
[0] = { .num = 0, .tok = { .type = TOK_INT, .data.uid = 0 } },
|
||||
[1] = { .num = 1, .tok = { .type = TOK_INT, .data.uid = 1 } }
|
||||
};
|
||||
static uint8_t seen_nums_count = 2;
|
||||
|
||||
static bool
|
||||
is_empty (token tok)
|
||||
@ -114,7 +129,7 @@ get_char (size_t i)
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
buffer = (char *) malloc (BUFFER_SIZE);
|
||||
buffer = (char *) mem_HeapAllocBlock (BUFFER_SIZE, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
error = __fread (buffer, 1, BUFFER_SIZE, file);
|
||||
if (error == 0)
|
||||
return '\0';
|
||||
@ -184,7 +199,7 @@ decode_keyword (void)
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
if (!__strncmp (keyword_tokens[i].str, token_start, __strlen (keyword_tokens[i].str)))
|
||||
if (!__strncmp (keyword_tokens[i].str, token_start, (size_t) (buffer - token_start)))
|
||||
return keyword_tokens[i].tok;
|
||||
}
|
||||
|
||||
@ -196,9 +211,9 @@ convert_seen_name_to_token (void)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < seen_names_num; i++)
|
||||
for (i = 0; i < seen_names_count; i++)
|
||||
{
|
||||
if (!__strncmp (seen_names[i].str, token_start, __strlen (seen_names[i].str)))
|
||||
if (!__strncmp (seen_names[i].str, token_start, (size_t) (buffer - token_start)))
|
||||
return seen_names[i].tok;
|
||||
}
|
||||
|
||||
@ -206,12 +221,33 @@ convert_seen_name_to_token (void)
|
||||
}
|
||||
|
||||
static void
|
||||
add_to_seen_tokens (string_and_token snt)
|
||||
add_name_to_seen_tokens (string_and_token snt)
|
||||
{
|
||||
JERRY_ASSERT (seen_names_num < MAX_NAMES);
|
||||
JERRY_ASSERT (seen_names_count < MAX_NAMES);
|
||||
|
||||
snt.tok.data.name = (string_id) seen_names_num;
|
||||
seen_names[seen_names_num++] = snt;
|
||||
seen_names[seen_names_count++] = snt;
|
||||
}
|
||||
|
||||
static token
|
||||
convert_seen_num_to_token (int num)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < seen_nums_count; i++)
|
||||
{
|
||||
if (seen_nums[i].num == num)
|
||||
return seen_nums[i].tok;
|
||||
}
|
||||
|
||||
return empty_token;
|
||||
}
|
||||
|
||||
static void
|
||||
add_num_to_seen_tokens (num_and_token nat)
|
||||
{
|
||||
JERRY_ASSERT (seen_nums_count < MAX_NUMS);
|
||||
|
||||
seen_nums[seen_nums_count++] = nat;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
@ -219,20 +255,32 @@ lexer_get_strings (const char **strings)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < seen_names_num; i++)
|
||||
strings[i] = seen_names[i].str;
|
||||
if (strings)
|
||||
for (i = 0; i < seen_names_count; i++)
|
||||
strings[i] = seen_names[i].str;
|
||||
|
||||
return seen_names_num;
|
||||
return seen_names_count;
|
||||
}
|
||||
|
||||
const char *
|
||||
lexer_get_string_by_id (string_id id)
|
||||
lexer_get_string_by_id (uint8_t id)
|
||||
{
|
||||
JERRY_ASSERT (id < seen_names_num);
|
||||
JERRY_ASSERT (id < seen_names_count);
|
||||
|
||||
return seen_names[id].str;
|
||||
}
|
||||
|
||||
uint8_t
|
||||
lexer_get_nums (int *nums)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < seen_nums_count; i++)
|
||||
nums[i] = seen_nums[i].num;
|
||||
|
||||
return seen_nums_count;
|
||||
}
|
||||
|
||||
static void
|
||||
new_token (void)
|
||||
{
|
||||
@ -254,7 +302,7 @@ current_token (void)
|
||||
JERRY_ASSERT (token_start);
|
||||
JERRY_ASSERT (token_start <= buffer);
|
||||
size_t length = (size_t) (buffer - token_start);
|
||||
char *res = (char *) malloc (length + 1);
|
||||
char *res = (char *) mem_HeapAllocBlock (length + 1, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
__strncpy (res, token_start, length);
|
||||
res[length] = '\0';
|
||||
token_start = NULL;
|
||||
@ -265,7 +313,7 @@ current_token (void)
|
||||
do \
|
||||
{ \
|
||||
buffer += NUM; \
|
||||
return (token) { .type = TOK, .data.none = NULL }; \
|
||||
return (token) { .type = TOK, .data.uid = 0 }; \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
@ -338,9 +386,9 @@ parse_name (void)
|
||||
}
|
||||
|
||||
string = current_token ();
|
||||
known_token = (token) { .type = TOK_NAME, .data.name = seen_names_num };
|
||||
known_token = (token) { .type = TOK_NAME, .data.uid = seen_names_count };
|
||||
|
||||
add_to_seen_tokens ((string_and_token) { .str = string, .tok = known_token });
|
||||
add_name_to_seen_tokens ((string_and_token) { .str = string, .tok = known_token });
|
||||
|
||||
return known_token;
|
||||
}
|
||||
@ -387,6 +435,7 @@ parse_number (void)
|
||||
bool is_exp = false;
|
||||
size_t tok_length = 0, i;
|
||||
int res = 0;
|
||||
token known_token;
|
||||
|
||||
JERRY_ASSERT (__isdigit (c) || c == '.');
|
||||
|
||||
@ -423,7 +472,14 @@ parse_number (void)
|
||||
res = (res << 4) + hex_to_int (token_start[i]);
|
||||
|
||||
token_start = NULL;
|
||||
return (token) { .type = TOK_INT, .data.num = res };
|
||||
|
||||
known_token = convert_seen_num_to_token (res);
|
||||
if (!is_empty (known_token))
|
||||
return known_token;
|
||||
|
||||
known_token = (token) { .type = TOK_INT, .data.uid = seen_nums_count };
|
||||
add_num_to_seen_tokens ((num_and_token) { .num = res, .tok = known_token });
|
||||
return known_token;
|
||||
}
|
||||
|
||||
JERRY_ASSERT (!is_hex && !is_exp);
|
||||
@ -475,7 +531,8 @@ parse_number (void)
|
||||
{
|
||||
float res = __strtof (token_start, NULL);
|
||||
token_start = NULL;
|
||||
return (token) { .type = TOK_FLOAT, .data.fp_num = res };
|
||||
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS (res);
|
||||
return empty_token;
|
||||
}
|
||||
|
||||
tok_length = (size_t) (buffer - token_start);;
|
||||
@ -484,7 +541,13 @@ parse_number (void)
|
||||
|
||||
token_start = NULL;
|
||||
|
||||
return (token) { .type = TOK_INT, .data.num = res };
|
||||
known_token = convert_seen_num_to_token (res);
|
||||
if (!is_empty (known_token))
|
||||
return known_token;
|
||||
|
||||
known_token = (token) { .type = TOK_INT, .data.uid = seen_nums_count };
|
||||
add_num_to_seen_tokens ((num_and_token) { .num = res, .tok = known_token });
|
||||
return known_token;
|
||||
}
|
||||
|
||||
static char
|
||||
@ -513,7 +576,7 @@ parse_string (void)
|
||||
char *tok = NULL;
|
||||
char *index = NULL;
|
||||
const char *i;
|
||||
size_t length;
|
||||
size_t length, num;
|
||||
token res = empty_token;
|
||||
|
||||
JERRY_ASSERT (c == '\'' || c == '"');
|
||||
@ -553,7 +616,7 @@ parse_string (void)
|
||||
}
|
||||
|
||||
length = (size_t) (buffer - token_start);
|
||||
tok = (char *) malloc (length);
|
||||
tok = (char *) mem_HeapAllocBlock (length, MEM_HEAP_ALLOC_SHORT_TERM);
|
||||
index = tok;
|
||||
|
||||
for (i = token_start; i < buffer; i++)
|
||||
@ -581,9 +644,18 @@ parse_string (void)
|
||||
// Eat up '"'
|
||||
consume_char ();
|
||||
|
||||
res = (token) { .type = TOK_STRING, .data.str = seen_names_num };
|
||||
for (num = 0; num < seen_names_count; num++)
|
||||
{
|
||||
if (!__strncmp (seen_names[num].str, tok, __strlen (tok)))
|
||||
{
|
||||
mem_HeapFreeBlock ((uint8_t*) tok);
|
||||
return seen_names[num].tok;
|
||||
}
|
||||
}
|
||||
|
||||
add_to_seen_tokens ((string_and_token) { .str = tok, .tok = res });
|
||||
res = (token) { .type = TOK_STRING, .data.uid = seen_names_count };
|
||||
|
||||
add_name_to_seen_tokens ((string_and_token) { .str = tok, .tok = res });
|
||||
|
||||
return res;
|
||||
}
|
||||
@ -593,7 +665,7 @@ grobble_whitespaces (void)
|
||||
{
|
||||
char c = LA (0);
|
||||
|
||||
while ((__isspace (c) && c != '\n') || c == '\0')
|
||||
while ((__isspace (c) && c != '\n'))
|
||||
{
|
||||
consume_char ();
|
||||
c = LA (0);
|
||||
@ -685,11 +757,11 @@ lexer_next_token (void)
|
||||
if (c == '\n')
|
||||
{
|
||||
consume_char ();
|
||||
return (token) { .type = TOK_NEWLINE, .data.none = NULL };
|
||||
return (token) { .type = TOK_NEWLINE, .data.uid = 0 };
|
||||
}
|
||||
|
||||
if (c == '\0')
|
||||
return (token) { .type = TOK_EOF, .data.none = NULL };;
|
||||
return (token) { .type = TOK_EOF, .data.uid = 0 };;
|
||||
|
||||
if (c == '\'' || c == '"')
|
||||
return parse_string ();
|
||||
@ -708,7 +780,7 @@ lexer_next_token (void)
|
||||
if (c == '/' && LA (1) == '*')
|
||||
{
|
||||
if (replace_comment_by_newline ())
|
||||
return (token) { .type = TOK_NEWLINE, .data.none = NULL };
|
||||
return (token) { .type = TOK_NEWLINE, .data.uid = 0 };
|
||||
else
|
||||
return
|
||||
#ifdef __HOST
|
||||
@ -803,11 +875,11 @@ lexer_next_token (void)
|
||||
token tok = lexer_next_token_private ();
|
||||
if (tok.type == TOK_NEWLINE)
|
||||
return tok;
|
||||
// if (tok.type == TOK_CLOSE_BRACE)
|
||||
if (tok.type == TOK_CLOSE_PAREN)
|
||||
{
|
||||
// if (i == 300)
|
||||
__fprintf (lexer_debug_log, "lexer_next_token(%d): type=0x%x, data=%p\n", i, tok.type, tok.data.none);
|
||||
i++;
|
||||
__fprintf (lexer_debug_log, "lexer_next_token(%d): type=%d, data=%d\n", i, tok.type, tok.data.uid);
|
||||
i++;
|
||||
}
|
||||
return tok;
|
||||
}
|
||||
@ -816,10 +888,10 @@ lexer_next_token (void)
|
||||
void
|
||||
lexer_save_token (token tok)
|
||||
{
|
||||
#ifdef __HOST
|
||||
// if (tok.type == TOK_CLOSE_BRACE)
|
||||
__fprintf (lexer_debug_log, "lexer_save_token(%d): type=0x%x, data=%p\n", i, tok.type, tok.data.none);
|
||||
#endif
|
||||
#ifdef __HOST
|
||||
if (tok.type == TOK_CLOSE_PAREN)
|
||||
__fprintf (lexer_debug_log, "lexer_save_token(%d): type=%d, data=%d\n", i, tok.type, tok.data.uid);
|
||||
#endif
|
||||
saved_token = tok;
|
||||
}
|
||||
|
||||
|
||||
@ -18,121 +18,120 @@
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
typedef uint8_t string_id;
|
||||
|
||||
/* Keywords. */
|
||||
typedef enum
|
||||
{
|
||||
/* Not a keyword. */
|
||||
KW_NONE = 0,
|
||||
/* Future reserved keyword. */
|
||||
KW_RESERVED,
|
||||
typedef uint8_t keyword;
|
||||
|
||||
KW_BREAK,
|
||||
KW_CASE,
|
||||
KW_CATCH,
|
||||
KW_CONTINUE,
|
||||
KW_DEBUGGER,
|
||||
KW_DEFAULT,
|
||||
KW_DELETE,
|
||||
/* Not a keyword. */
|
||||
#define KW_NONE 0
|
||||
/* Future reserved keyword. */
|
||||
#define KW_RESERVED 1
|
||||
#define KW_BREAK 2
|
||||
#define KW_CASE 3
|
||||
#define KW_CATCH 4
|
||||
|
||||
KW_DO,
|
||||
KW_ELSE,
|
||||
KW_FINALLY,
|
||||
KW_FOR,
|
||||
KW_FUNCTION,
|
||||
KW_IF,
|
||||
KW_IN,
|
||||
#define KW_CONTINUE 5
|
||||
#define KW_DEBUGGER 6
|
||||
#define KW_DEFAULT 7
|
||||
#define KW_DELETE 8
|
||||
#define KW_DO 9
|
||||
|
||||
KW_INSTANCEOF,
|
||||
KW_NEW,
|
||||
KW_RETURN,
|
||||
KW_SWITCH,
|
||||
KW_THIS,
|
||||
KW_THROW,
|
||||
KW_TRY,
|
||||
#define KW_ELSE 10
|
||||
#define KW_FINALLY 11
|
||||
#define KW_FOR 12
|
||||
#define KW_FUNCTION 13
|
||||
#define KW_IF 14
|
||||
|
||||
#define KW_IN 15
|
||||
#define KW_INSTANCEOF 16
|
||||
#define KW_NEW 17
|
||||
#define KW_RETURN 18
|
||||
#define KW_SWITCH 19
|
||||
|
||||
#define KW_THIS 20
|
||||
#define KW_THROW 21
|
||||
#define KW_TRY 22
|
||||
#define KW_TYPEOF 23
|
||||
#define KW_VAR 24
|
||||
|
||||
#define KW_VOID 25
|
||||
#define KW_WHILE 26
|
||||
#define KW_WITH 27
|
||||
|
||||
KW_TYPEOF,
|
||||
KW_VAR,
|
||||
KW_VOID,
|
||||
KW_WHILE,
|
||||
KW_WITH
|
||||
}
|
||||
keyword;
|
||||
|
||||
/* Type of tokens. */
|
||||
typedef enum
|
||||
{
|
||||
TOK_EOF = 0x0, // End of file
|
||||
TOK_NAME = 0x1, // Identifier
|
||||
TOK_KEYWORD = 0x2, // Keyword
|
||||
TOK_INT = 0x3,
|
||||
TOK_FLOAT = 0x4,
|
||||
TOK_NULL = 0x5,
|
||||
TOK_BOOL = 0x6,
|
||||
TOK_NEWLINE = 0x7,
|
||||
TOK_STRING = 0x8,
|
||||
typedef uint8_t token_type;
|
||||
|
||||
/* Punctuators. */
|
||||
TOK_OPEN_BRACE = 0x9, // {
|
||||
TOK_CLOSE_BRACE = 0xa, // }
|
||||
TOK_OPEN_PAREN = 0xb, // (
|
||||
TOK_CLOSE_PAREN = 0xc, // )
|
||||
TOK_OPEN_SQUARE, // [
|
||||
TOK_CLOSE_SQUARE, // [
|
||||
#define TOK_EOF 0 // End of file
|
||||
#define TOK_NAME 1 // Identifier
|
||||
#define TOK_KEYWORD 2 // Keyword
|
||||
#define TOK_INT 3
|
||||
#define TOK_FLOAT 4
|
||||
|
||||
TOK_DOT, // .
|
||||
TOK_SEMICOLON, // ;
|
||||
TOK_COMMA, // ,
|
||||
TOK_LESS, // <
|
||||
TOK_GREATER, // >
|
||||
TOK_LESS_EQ, // <=
|
||||
#define TOK_NULL 5
|
||||
#define TOK_BOOL 6
|
||||
#define TOK_NEWLINE 7
|
||||
#define TOK_STRING 8
|
||||
#define TOK_OPEN_BRACE 9 // {
|
||||
|
||||
TOK_GREATER_EQ, // <=
|
||||
TOK_DOUBLE_EQ, // ==
|
||||
TOK_NOT_EQ, // !=
|
||||
TOK_TRIPLE_EQ, // ===
|
||||
TOK_NOT_DOUBLE_EQ, // !==
|
||||
#define TOK_CLOSE_BRACE 10 // }
|
||||
#define TOK_OPEN_PAREN 11 // (
|
||||
#define TOK_CLOSE_PAREN 12 // )
|
||||
#define TOK_OPEN_SQUARE 13 // [
|
||||
#define TOK_CLOSE_SQUARE 14 // [
|
||||
|
||||
TOK_PLUS, // +
|
||||
TOK_MINUS, // -
|
||||
TOK_MULT, // *
|
||||
TOK_MOD, // %
|
||||
TOK_DOUBLE_PLUS, // ++
|
||||
TOK_DOUBLE_MINUS, // --
|
||||
#define TOK_DOT 15 // .
|
||||
#define TOK_SEMICOLON 16 // ;
|
||||
#define TOK_COMMA 17 // ,
|
||||
#define TOK_LESS 18 // <
|
||||
#define TOK_GREATER 19 // >
|
||||
|
||||
TOK_LSHIFT, // <<
|
||||
TOK_RSHIFT, // >>
|
||||
TOK_RSHIFT_EX, // >>>
|
||||
TOK_AND, // &
|
||||
TOK_OR, // |
|
||||
TOK_XOR, // ^
|
||||
#define TOK_LESS_EQ 20 // <=
|
||||
#define TOK_GREATER_EQ 21 // <=
|
||||
#define TOK_DOUBLE_EQ 22 // ==
|
||||
#define TOK_NOT_EQ 23 // !=
|
||||
#define TOK_TRIPLE_EQ 24 // ===
|
||||
|
||||
TOK_NOT, // !
|
||||
TOK_COMPL, // ~
|
||||
TOK_DOUBLE_AND, // &&
|
||||
TOK_DOUBLE_OR, // ||
|
||||
TOK_QUERY, // ?
|
||||
TOK_COLON, // :
|
||||
#define TOK_NOT_DOUBLE_EQ 25 // !==
|
||||
#define TOK_PLUS 26 // +
|
||||
#define TOK_MINUS 27 // -
|
||||
#define TOK_MULT 28 // *
|
||||
#define TOK_MOD 29 // %
|
||||
|
||||
TOK_EQ, // =
|
||||
TOK_PLUS_EQ, // +=
|
||||
TOK_MINUS_EQ, // -=
|
||||
TOK_MULT_EQ, // *=
|
||||
TOK_MOD_EQ, // %=
|
||||
TOK_LSHIFT_EQ, // <<=
|
||||
#define TOK_DOUBLE_PLUS 30 // ++
|
||||
#define TOK_DOUBLE_MINUS 31 // --
|
||||
#define TOK_LSHIFT 32 // <<
|
||||
#define TOK_RSHIFT 33 // >>
|
||||
#define TOK_RSHIFT_EX 34 // >>>
|
||||
|
||||
TOK_RSHIFT_EQ, // >>=
|
||||
TOK_RSHIFT_EX_EQ, // >>>=
|
||||
TOK_AND_EQ, // &=
|
||||
TOK_OR_EQ, // |=
|
||||
TOK_XOR_EQ, // ^=
|
||||
#define TOK_AND 35 // &
|
||||
#define TOK_OR 36 // |
|
||||
#define TOK_XOR 37 // ^
|
||||
#define TOK_NOT 38 // !
|
||||
#define TOK_COMPL 39 // ~
|
||||
|
||||
#define TOK_DOUBLE_AND 40 // &&
|
||||
#define TOK_DOUBLE_OR 41 // ||
|
||||
#define TOK_QUERY 42 // ?
|
||||
#define TOK_COLON 43 // :
|
||||
#define TOK_EQ 44 // =
|
||||
|
||||
#define TOK_PLUS_EQ 45 // +=
|
||||
#define TOK_MINUS_EQ 46 // -=
|
||||
#define TOK_MULT_EQ 47 // *=
|
||||
#define TOK_MOD_EQ 48 // %=
|
||||
#define TOK_LSHIFT_EQ 49 // <<=
|
||||
|
||||
#define TOK_RSHIFT_EQ 50 // >>=
|
||||
#define TOK_RSHIFT_EX_EQ 51 // >>>=
|
||||
#define TOK_AND_EQ 52 // &=
|
||||
#define TOK_OR_EQ 53 // |=
|
||||
#define TOK_XOR_EQ 54 // ^=
|
||||
|
||||
#define TOK_DIV 55 // /
|
||||
#define TOK_DIV_EQ 56 // /=
|
||||
#define TOK_EMPTY 57
|
||||
|
||||
TOK_DIV, // /
|
||||
TOK_DIV_EQ, // /=
|
||||
TOK_EMPTY
|
||||
}
|
||||
token_type;
|
||||
|
||||
/* Represents the contents of a token. */
|
||||
typedef struct
|
||||
@ -140,17 +139,12 @@ typedef struct
|
||||
token_type type;
|
||||
|
||||
union
|
||||
{
|
||||
void *none;
|
||||
keyword kw;
|
||||
string_id name;
|
||||
bool is_true;
|
||||
int num;
|
||||
float fp_num;
|
||||
string_id str;
|
||||
}
|
||||
{
|
||||
keyword kw;
|
||||
uint8_t uid;
|
||||
}
|
||||
data;
|
||||
}
|
||||
} __packed
|
||||
token;
|
||||
|
||||
#ifdef __HOST
|
||||
@ -160,11 +154,9 @@ void lexer_set_source (const char *);
|
||||
#endif
|
||||
token lexer_next_token (void);
|
||||
void lexer_save_token (token);
|
||||
|
||||
void lexer_dump_buffer_state (void);
|
||||
|
||||
uint8_t lexer_get_strings (const char **);
|
||||
|
||||
const char *lexer_get_string_by_id (string_id id);
|
||||
const char *lexer_get_string_by_id (uint8_t);
|
||||
uint8_t lexer_get_nums (int *);
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -18,427 +18,8 @@
|
||||
|
||||
#include "globals.h"
|
||||
|
||||
#define null_string 255
|
||||
#define MAX_PARAMS 5
|
||||
#define MAX_EXPRS 2
|
||||
#define MAX_PROPERTIES 5
|
||||
#define MAX_DECLS 5
|
||||
#define MAX_SUFFIXES 2
|
||||
|
||||
/** Represents list of parameters. */
|
||||
typedef struct formal_parameter_list
|
||||
{
|
||||
/** Identifiers of a parameter. Next after last parameter is NULL. */
|
||||
uint8_t names[MAX_PARAMS];
|
||||
}
|
||||
formal_parameter_list;
|
||||
|
||||
static const formal_parameter_list
|
||||
empty_formal_parameter_list =
|
||||
{
|
||||
.names = { [0] = null_string }
|
||||
};
|
||||
|
||||
bool is_formal_parameter_list_empty (formal_parameter_list);
|
||||
|
||||
/** @function_declaration represents both declaration and expression of a function.
|
||||
After this parser must return a block of statements. */
|
||||
typedef struct
|
||||
{
|
||||
/** Identifier: name of a function. Can be NULL for anonimous functions. */
|
||||
uint8_t name;
|
||||
/** List of parameter of a function. Can be NULL. */
|
||||
formal_parameter_list params;
|
||||
}
|
||||
function_declaration;
|
||||
|
||||
typedef function_declaration function_expression;
|
||||
|
||||
/** Types of literals: null, bool, decimal and string.
|
||||
Decimal type is represented by LIT_INT and supports only double-word sized integers. */
|
||||
typedef enum
|
||||
{
|
||||
LIT_NULL,
|
||||
LIT_BOOL,
|
||||
LIT_INT,
|
||||
LIT_STR
|
||||
}
|
||||
literal_type;
|
||||
|
||||
/** Represents different literals, contains a data of them. */
|
||||
typedef struct
|
||||
{
|
||||
/** Type of a literal. */
|
||||
literal_type type;
|
||||
|
||||
/** Value of a literal. */
|
||||
union
|
||||
{
|
||||
/** Used by null literal, always NULL. */
|
||||
void *none;
|
||||
/** String literal value. */
|
||||
uint8_t str;
|
||||
/** Number value. */
|
||||
int num;
|
||||
/** Boolean value. */
|
||||
bool is_true;
|
||||
}
|
||||
data;
|
||||
}
|
||||
literal;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool is_literal;
|
||||
|
||||
union
|
||||
{
|
||||
void *none;
|
||||
literal lit;
|
||||
uint8_t name;
|
||||
}
|
||||
data;
|
||||
}
|
||||
operand;
|
||||
|
||||
typedef operand property_name;
|
||||
|
||||
static const operand
|
||||
empty_operand =
|
||||
{
|
||||
.is_literal = false,
|
||||
.data.none = NULL
|
||||
};
|
||||
|
||||
bool is_operand_empty (operand);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
operand op1, op2;
|
||||
}
|
||||
operand_pair;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
operand ops[MAX_PARAMS];
|
||||
}
|
||||
operand_list;
|
||||
|
||||
static const operand_list
|
||||
empty_operand_list =
|
||||
{
|
||||
.ops = { [0] = { .is_literal = false, .data.none = NULL } }
|
||||
};
|
||||
|
||||
bool is_operand_list_empty (operand_list);
|
||||
|
||||
typedef operand_list array_literal;
|
||||
typedef operand_list argument_list;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t name;
|
||||
argument_list args;
|
||||
}
|
||||
call_expression;
|
||||
|
||||
/** Represents a single property. */
|
||||
typedef struct
|
||||
{
|
||||
/** Name of property. */
|
||||
property_name name;
|
||||
/** Value of property. */
|
||||
operand value;
|
||||
}
|
||||
property;
|
||||
|
||||
static const property empty_property =
|
||||
{
|
||||
.name = { .is_literal = false, .data.none = NULL },
|
||||
.value = { .is_literal = false, .data.none = NULL }
|
||||
};
|
||||
|
||||
bool is_property_empty (property);
|
||||
|
||||
/** List of properties. Represents ObjectLiteral. */
|
||||
typedef struct
|
||||
{
|
||||
/** Properties. */
|
||||
property props[MAX_PROPERTIES];
|
||||
}
|
||||
property_list;
|
||||
|
||||
static const property_list
|
||||
empty_property_list =
|
||||
{
|
||||
.props =
|
||||
{ [0] =
|
||||
{ .name =
|
||||
{ .is_literal = false, .data.none = NULL },
|
||||
.value =
|
||||
{ .is_literal = false, .data.none = NULL }}}
|
||||
};
|
||||
|
||||
bool is_property_list_empty (property_list);
|
||||
|
||||
typedef property_list object_literal;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
AO_NONE,
|
||||
AO_EQ,
|
||||
AO_MULT_EQ,
|
||||
AO_DIV_EQ,
|
||||
AO_MOD_EQ,
|
||||
AO_PLUS_EQ,
|
||||
AO_MINUS_EQ,
|
||||
AO_LSHIFT_EQ,
|
||||
AO_RSHIFT_EQ,
|
||||
AO_RSHIFT_EX_EQ,
|
||||
AO_AND_EQ,
|
||||
AO_XOR_EQ,
|
||||
AO_OR_EQ
|
||||
}
|
||||
assignment_operator;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ET_NONE,
|
||||
ET_LOGICAL_OR,
|
||||
ET_LOGICAL_AND,
|
||||
ET_BITWISE_OR,
|
||||
ET_BITWISE_XOR,
|
||||
ET_BITWISE_AND,
|
||||
ET_DOUBLE_EQ,
|
||||
ET_NOT_EQ,
|
||||
ET_TRIPLE_EQ,
|
||||
ET_NOT_DOUBLE_EQ,
|
||||
ET_LESS,
|
||||
ET_GREATER,
|
||||
ET_LESS_EQ,
|
||||
ET_GREATER_EQ,
|
||||
ET_INSTANCEOF,
|
||||
ET_IN,
|
||||
ET_LSHIFT,
|
||||
ET_RSHIFT,
|
||||
ET_RSHIFT_EX,
|
||||
ET_PLUS,
|
||||
ET_MINUS,
|
||||
ET_MULT,
|
||||
ET_DIV,
|
||||
ET_MOD,
|
||||
ET_UNARY_DELETE,
|
||||
ET_UNARY_VOID,
|
||||
ET_UNARY_TYPEOF,
|
||||
ET_UNARY_INCREMENT,
|
||||
ET_UNARY_DECREMENT,
|
||||
ET_UNARY_PLUS,
|
||||
ET_UNARY_MINUS,
|
||||
ET_UNARY_COMPL,
|
||||
ET_UNARY_NOT,
|
||||
ET_POSTFIX_INCREMENT,
|
||||
ET_POSTFIX_DECREMENT,
|
||||
ET_CALL,
|
||||
ET_NEW,
|
||||
ET_INDEX,
|
||||
ET_PROP_REF,
|
||||
ET_OBJECT,
|
||||
ET_FUNCTION,
|
||||
ET_ARRAY,
|
||||
ET_SUBEXPRESSION,
|
||||
ET_LITERAL,
|
||||
ET_IDENTIFIER
|
||||
}
|
||||
expression_type;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
assignment_operator oper;
|
||||
expression_type type;
|
||||
|
||||
/** NUllable. */
|
||||
uint8_t var;
|
||||
|
||||
union
|
||||
{
|
||||
void *none;
|
||||
operand_pair ops;
|
||||
call_expression call_expr;
|
||||
array_literal arr_lit;
|
||||
object_literal obj_lit;
|
||||
function_expression func_expr;
|
||||
}
|
||||
data;
|
||||
}
|
||||
assignment_expression;
|
||||
|
||||
static const assignment_expression
|
||||
empty_expression =
|
||||
{
|
||||
.oper = AO_NONE,
|
||||
.type = ET_NONE,
|
||||
.data.none = NULL
|
||||
};
|
||||
|
||||
bool is_expression_empty (assignment_expression);
|
||||
|
||||
/** Represents expression, array literal and list of argument. */
|
||||
typedef struct
|
||||
{
|
||||
/** Single assignment expression. Cannot be NULL for expression and list of arguments.
|
||||
But can be NULL for array literal. */
|
||||
assignment_expression exprs[MAX_EXPRS];
|
||||
}
|
||||
expression_list;
|
||||
|
||||
typedef expression_list expression;
|
||||
|
||||
/* Statements. */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t name;
|
||||
assignment_expression assign_expr;
|
||||
}
|
||||
variable_declaration;
|
||||
|
||||
static const variable_declaration
|
||||
empty_variable_declaration =
|
||||
{
|
||||
.name = null_string,
|
||||
.assign_expr = { .oper = AO_NONE, .type = ET_NONE, .data.none = NULL }
|
||||
};
|
||||
|
||||
bool is_variable_declaration_empty (variable_declaration);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
variable_declaration decls[MAX_DECLS];
|
||||
}
|
||||
variable_declaration_list;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool is_decl;
|
||||
|
||||
union
|
||||
{
|
||||
expression expr;
|
||||
variable_declaration_list decl_list;
|
||||
}
|
||||
data;
|
||||
}
|
||||
for_statement_initialiser_part;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
for_statement_initialiser_part init;
|
||||
assignment_expression limit, incr;
|
||||
}
|
||||
for_statement;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool is_decl;
|
||||
|
||||
union
|
||||
{
|
||||
assignment_expression left_hand_expr;
|
||||
variable_declaration decl;
|
||||
}
|
||||
data;
|
||||
}
|
||||
for_in_statement_initializer_part;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
for_in_statement_initializer_part init;
|
||||
expression list_expr;
|
||||
}
|
||||
for_in_statement;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
bool is_for_in;
|
||||
|
||||
union
|
||||
{
|
||||
for_statement for_stmt;
|
||||
for_in_statement for_in_stmt;
|
||||
}
|
||||
data;
|
||||
}
|
||||
for_or_for_in_statement;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
STMT_NULL,
|
||||
STMT_VARIABLE,
|
||||
STMT_EMPTY,
|
||||
STMT_IF,
|
||||
STMT_ELSE,
|
||||
STMT_ELSE_IF,
|
||||
STMT_END_IF,
|
||||
STMT_DO_WHILE,
|
||||
STMT_END_DO_WHILE,
|
||||
STMT_WHILE,
|
||||
|
||||
STMT_END_WHILE,
|
||||
STMT_FOR_OR_FOR_IN,
|
||||
STMT_END_FOR_OR_FOR_IN,
|
||||
STMT_CONTINUE,
|
||||
STMT_BREAK,
|
||||
STMT_RETURN,
|
||||
STMT_WITH,
|
||||
STMT_END_WITH,
|
||||
STMT_LABELLED,
|
||||
STMT_SWITCH,
|
||||
|
||||
STMT_END_SWITCH,
|
||||
STMT_CASE,
|
||||
STMT_THROW,
|
||||
STMT_TRY,
|
||||
STMT_CATCH,
|
||||
STMT_END_CATCH,
|
||||
STMT_FINALLY,
|
||||
STMT_END_FINALLY,
|
||||
STMT_EXPRESSION,
|
||||
STMT_END_SUBEXPRESSION,
|
||||
|
||||
STMT_FUNCTION,
|
||||
STMT_END_FUNCTION,
|
||||
STMT_EOF
|
||||
}
|
||||
statement_type;
|
||||
|
||||
typedef struct statement
|
||||
{
|
||||
statement_type type;
|
||||
|
||||
union
|
||||
{
|
||||
void *none;
|
||||
variable_declaration_list var_stmt;
|
||||
assignment_expression expr;
|
||||
for_or_for_in_statement for_stmt;
|
||||
uint8_t name;
|
||||
function_declaration fun_decl;
|
||||
}
|
||||
data;
|
||||
}
|
||||
statement;
|
||||
|
||||
static const statement
|
||||
null_statement =
|
||||
{
|
||||
.type = STMT_NULL,
|
||||
.data.none = NULL
|
||||
};
|
||||
|
||||
bool is_statement_null (statement);
|
||||
|
||||
void parser_init (void);
|
||||
statement parser_parse_statement (void);
|
||||
void parser_parse_program (void);
|
||||
|
||||
void parser_fatal (jerry_Status_t code);
|
||||
|
||||
|
||||
@ -69,9 +69,9 @@ jerry_Exit( jerry_Status_t code) /**< status code */
|
||||
case ERR_GENERAL:
|
||||
__printf("ERR_GENERAL\n");
|
||||
break;
|
||||
default:
|
||||
__printf( "Return code is zero");
|
||||
}
|
||||
|
||||
jerry_AssertFail( "Return code is zero", __FILE__, __LINE__);
|
||||
}
|
||||
#endif /* !JERRY_NDEBUG */
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,28 +0,0 @@
|
||||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef PRETTY_PRINTER_H
|
||||
#define PRETTY_PRINTER_H
|
||||
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
|
||||
void pp_reset (void);
|
||||
void pp_finish (void);
|
||||
void pp_token (token);
|
||||
void pp_keyword (keyword);
|
||||
void pp_statement (statement);
|
||||
|
||||
#endif
|
||||
@ -22,4 +22,6 @@ void serializer_init (void);
|
||||
|
||||
void serializer_dump_data (const void *, size_t);
|
||||
|
||||
void serializer_rewrite_data (const int8_t, const void *, size_t);
|
||||
|
||||
#endif // SERIALIZER_H
|
||||
@ -15,17 +15,39 @@
|
||||
|
||||
#include "serializer.h"
|
||||
#include "jerry-libc.h"
|
||||
#include "opcodes.h"
|
||||
|
||||
FILE *dump;
|
||||
|
||||
#define OPCODE_STR(op) \
|
||||
#op,
|
||||
|
||||
static char* massive[] = {
|
||||
OP_LIST (OPCODE_STR)
|
||||
""
|
||||
};
|
||||
|
||||
void
|
||||
serializer_init (void)
|
||||
{
|
||||
}
|
||||
|
||||
static int opcode_counter = 0;
|
||||
|
||||
void
|
||||
serializer_dump_data (const void *data, size_t size)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
__putchar (((char *) data)[i]);
|
||||
__printf ("%03d: %20s ", opcode_counter++, massive[(int)((char*)data)[0]]);
|
||||
for (i = 1; i < size; i++)
|
||||
__printf ("%4d ", ((char*)data)[i]);
|
||||
|
||||
__printf ("\n");
|
||||
}
|
||||
|
||||
void
|
||||
serializer_rewrite_data (const int8_t offset __unused, const void *data __unused, size_t size __unused)
|
||||
{
|
||||
TODO (implement);
|
||||
}
|
||||
104
src/main.c
104
src/main.c
@ -35,8 +35,6 @@
|
||||
#include "jerry-libc.h"
|
||||
#include "lexer.h"
|
||||
#include "parser.h"
|
||||
#include "pretty-printer.h"
|
||||
#include "bytecode-generator.h"
|
||||
|
||||
#define DUMP_TOKENS (1u << 0)
|
||||
#define DUMP_AST (1u << 1)
|
||||
@ -99,27 +97,9 @@ fake_exit (void)
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void
|
||||
check_for_several_dumps (uint8_t dump)
|
||||
{
|
||||
bool was_bit = 0;
|
||||
for (; dump; dump >>= 1)
|
||||
{
|
||||
if (dump & 1u)
|
||||
{
|
||||
if (was_bit)
|
||||
jerry_Exit (ERR_SEVERAL_FILES);
|
||||
else
|
||||
was_bit = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
statement st;
|
||||
uint8_t dump = 0;
|
||||
#ifdef __HOST
|
||||
const char *file_name = NULL;
|
||||
FILE *file = NULL;
|
||||
@ -127,27 +107,15 @@ main (int argc, char **argv)
|
||||
|
||||
mem_Init ();
|
||||
|
||||
if (argc > 0)
|
||||
for (int i = 1; i < argc; i++)
|
||||
{
|
||||
if (!__strcmp ("-t", argv[i]))
|
||||
dump |= DUMP_TOKENS;
|
||||
else if (!__strcmp ("-a", argv[i]))
|
||||
dump |= DUMP_AST;
|
||||
else if (!__strcmp ("-b", argv[i]))
|
||||
dump |= DUMP_BYTECODE;
|
||||
#ifdef __HOST
|
||||
else if (file_name == NULL)
|
||||
file_name = argv[i];
|
||||
#endif
|
||||
if (argc > 0)
|
||||
{
|
||||
if (file_name == NULL)
|
||||
file_name = argv[1];
|
||||
else
|
||||
jerry_Exit (ERR_SEVERAL_FILES);
|
||||
}
|
||||
|
||||
check_for_several_dumps (dump);
|
||||
|
||||
if (!dump)
|
||||
dump |= DUMP_BYTECODE;
|
||||
#endif
|
||||
|
||||
#ifdef __HOST
|
||||
if (file_name == NULL)
|
||||
@ -165,60 +133,26 @@ main (int argc, char **argv)
|
||||
lexer_set_source (generated_source);
|
||||
#endif
|
||||
|
||||
if (dump & DUMP_AST)
|
||||
{
|
||||
parser_init ();
|
||||
st = parser_parse_statement ();
|
||||
JERRY_ASSERT (!is_statement_null (st));
|
||||
while (st.type != STMT_EOF)
|
||||
{
|
||||
pp_statement (st);
|
||||
st = parser_parse_statement ();
|
||||
JERRY_ASSERT (!is_statement_null (st));
|
||||
}
|
||||
}
|
||||
// const char *strings[MAX_STRINGS];
|
||||
// uint8_t strings_num;
|
||||
// First run parser to fill list of strings
|
||||
token tok = lexer_next_token ();
|
||||
while (tok.type != TOK_EOF)
|
||||
tok = lexer_next_token ();
|
||||
|
||||
if (dump & DUMP_TOKENS)
|
||||
{
|
||||
token tok = lexer_next_token ();
|
||||
while (tok.type != TOK_EOF)
|
||||
{
|
||||
pp_token (tok);
|
||||
tok = lexer_next_token ();
|
||||
}
|
||||
}
|
||||
// strings_num = lexer_get_strings (strings);
|
||||
|
||||
if (dump & DUMP_BYTECODE)
|
||||
{
|
||||
const char *strings[MAX_STRINGS];
|
||||
uint8_t strings_num;
|
||||
// First run parser to fill list of strings
|
||||
token tok = lexer_next_token ();
|
||||
while (tok.type != TOK_EOF)
|
||||
tok = lexer_next_token ();
|
||||
|
||||
strings_num = lexer_get_strings (strings);
|
||||
|
||||
// Reset lexer
|
||||
// Reset lexer
|
||||
#ifdef __HOST
|
||||
__rewind (file);
|
||||
lexer_set_file (file);
|
||||
__rewind (file);
|
||||
lexer_set_file (file);
|
||||
#else
|
||||
lexer_set_source (generated_source);
|
||||
lexer_set_source (generated_source);
|
||||
#endif
|
||||
|
||||
parser_init ();
|
||||
generator_init ();
|
||||
generator_dump_strings (strings, strings_num);
|
||||
st = parser_parse_statement ();
|
||||
JERRY_ASSERT (!is_statement_null (st));
|
||||
while (st.type != STMT_EOF)
|
||||
{
|
||||
generator_dump_statement (st);
|
||||
st = parser_parse_statement ();
|
||||
JERRY_ASSERT (!is_statement_null (st));
|
||||
}
|
||||
}
|
||||
parser_init ();
|
||||
TODO (serializer_dump_data (strings strings_num));
|
||||
parser_parse_program ();
|
||||
|
||||
//gen_bytecode (generated_source);
|
||||
//gen_bytecode ();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user