Merge pull request #138 from chipaca/unify_bops
Merge RT_COMPARE_OPs with RT_BINARY_OPs.
This commit is contained in:
commit
683466e55f
1
py/bc0.h
1
py/bc0.h
|
@ -66,7 +66,6 @@
|
|||
|
||||
#define MP_BC_UNARY_OP (0x60) // byte
|
||||
#define MP_BC_BINARY_OP (0x61) // byte
|
||||
#define MP_BC_COMPARE_OP (0x62) // byte
|
||||
|
||||
#define MP_BC_BUILD_TUPLE (0x70) // uint
|
||||
#define MP_BC_BUILD_LIST (0x71) // uint
|
||||
|
|
26
py/compile.c
26
py/compile.c
|
@ -1464,9 +1464,9 @@ void compile_for_stmt_optimised_range(compiler_t *comp, mp_parse_node_t pn_var,
|
|||
compile_node(comp, pn_var);
|
||||
compile_node(comp, pn_end);
|
||||
if (MP_PARSE_NODE_LEAF_ARG(pn_step) >= 0) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_LESS);
|
||||
EMIT(binary_op, RT_COMPARE_OP_LESS);
|
||||
} else {
|
||||
EMIT(compare_op, RT_COMPARE_OP_MORE);
|
||||
EMIT(binary_op, RT_COMPARE_OP_MORE);
|
||||
}
|
||||
EMIT(pop_jump_if_true, top_label);
|
||||
|
||||
|
@ -1610,7 +1610,7 @@ void compile_try_except(compiler_t *comp, mp_parse_node_t pn_body, int n_except,
|
|||
}
|
||||
EMIT(dup_top);
|
||||
compile_node(comp, pns_exception_expr);
|
||||
EMIT(compare_op, RT_COMPARE_OP_EXCEPTION_MATCH);
|
||||
EMIT(binary_op, RT_COMPARE_OP_EXCEPTION_MATCH);
|
||||
EMIT(pop_jump_if_false, end_finally_label);
|
||||
}
|
||||
|
||||
|
@ -1925,29 +1925,29 @@ void compile_comparison(compiler_t *comp, mp_parse_node_struct_t *pns) {
|
|||
EMIT(rot_three);
|
||||
}
|
||||
if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_LESS)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_LESS);
|
||||
EMIT(binary_op, RT_COMPARE_OP_LESS);
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_MORE)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_MORE);
|
||||
EMIT(binary_op, RT_COMPARE_OP_MORE);
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_DBL_EQUAL)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_EQUAL);
|
||||
EMIT(binary_op, RT_COMPARE_OP_EQUAL);
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_LESS_EQUAL)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_LESS_EQUAL);
|
||||
EMIT(binary_op, RT_COMPARE_OP_LESS_EQUAL);
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_MORE_EQUAL)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_MORE_EQUAL);
|
||||
EMIT(binary_op, RT_COMPARE_OP_MORE_EQUAL);
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_OP_NOT_EQUAL)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_NOT_EQUAL);
|
||||
EMIT(binary_op, RT_COMPARE_OP_NOT_EQUAL);
|
||||
} else if (MP_PARSE_NODE_IS_TOKEN_KIND(pns->nodes[i], MP_TOKEN_KW_IN)) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_IN);
|
||||
EMIT(binary_op, RT_COMPARE_OP_IN);
|
||||
} else if (MP_PARSE_NODE_IS_STRUCT(pns->nodes[i])) {
|
||||
mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)pns->nodes[i];
|
||||
int kind = MP_PARSE_NODE_STRUCT_KIND(pns2);
|
||||
if (kind == PN_comp_op_not_in) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_NOT_IN);
|
||||
EMIT(binary_op, RT_COMPARE_OP_NOT_IN);
|
||||
} else if (kind == PN_comp_op_is) {
|
||||
if (MP_PARSE_NODE_IS_NULL(pns2->nodes[0])) {
|
||||
EMIT(compare_op, RT_COMPARE_OP_IS);
|
||||
EMIT(binary_op, RT_COMPARE_OP_IS);
|
||||
} else {
|
||||
EMIT(compare_op, RT_COMPARE_OP_IS_NOT);
|
||||
EMIT(binary_op, RT_COMPARE_OP_IS_NOT);
|
||||
}
|
||||
} else {
|
||||
// shouldn't happen
|
||||
|
|
|
@ -85,7 +85,6 @@ typedef struct _emit_method_table_t {
|
|||
void (*pop_except)(emit_t *emit);
|
||||
void (*unary_op)(emit_t *emit, rt_unary_op_t op);
|
||||
void (*binary_op)(emit_t *emit, rt_binary_op_t op);
|
||||
void (*compare_op)(emit_t *emit, rt_compare_op_t op);
|
||||
void (*build_tuple)(emit_t *emit, int n_args);
|
||||
void (*build_list)(emit_t *emit, int n_args);
|
||||
void (*list_append)(emit_t *emit, int list_stack_index);
|
||||
|
|
|
@ -531,11 +531,6 @@ static void emit_bc_binary_op(emit_t *emit, rt_binary_op_t op) {
|
|||
emit_write_byte_1_byte(emit, MP_BC_BINARY_OP, op);
|
||||
}
|
||||
|
||||
static void emit_bc_compare_op(emit_t *emit, rt_compare_op_t op) {
|
||||
emit_pre(emit, -1);
|
||||
emit_write_byte_1_byte(emit, MP_BC_COMPARE_OP, op);
|
||||
}
|
||||
|
||||
static void emit_bc_build_tuple(emit_t *emit, int n_args) {
|
||||
assert(n_args >= 0);
|
||||
emit_pre(emit, 1 - n_args);
|
||||
|
@ -762,7 +757,6 @@ const emit_method_table_t emit_bc_method_table = {
|
|||
emit_bc_pop_except,
|
||||
emit_bc_unary_op,
|
||||
emit_bc_binary_op,
|
||||
emit_bc_compare_op,
|
||||
emit_bc_build_tuple,
|
||||
emit_bc_build_list,
|
||||
emit_bc_list_append,
|
||||
|
|
10
py/emitcpy.c
10
py/emitcpy.c
|
@ -579,15 +579,6 @@ static void emit_cpy_binary_op(emit_t *emit, rt_binary_op_t op) {
|
|||
case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: printf("INPLACE_TRUE_DIVIDE\n"); break;
|
||||
case RT_BINARY_OP_INPLACE_MODULO: printf("INPLACE_MODULO\n"); break;
|
||||
case RT_BINARY_OP_INPLACE_POWER: printf("INPLACE_POWER\n"); break;
|
||||
default: assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_cpy_compare_op(emit_t *emit, rt_compare_op_t op) {
|
||||
emit_pre(emit, -1, 3);
|
||||
if (emit->pass == PASS_3) {
|
||||
switch (op) {
|
||||
case RT_COMPARE_OP_LESS: printf("COMPARE_OP <\n"); break;
|
||||
case RT_COMPARE_OP_MORE: printf("COMPARE_OP >\n"); break;
|
||||
case RT_COMPARE_OP_EQUAL: printf("COMPARE_OP ==\n"); break;
|
||||
|
@ -863,7 +854,6 @@ const emit_method_table_t emit_cpython_method_table = {
|
|||
emit_cpy_pop_except,
|
||||
emit_cpy_unary_op,
|
||||
emit_cpy_binary_op,
|
||||
emit_cpy_compare_op,
|
||||
emit_cpy_build_tuple,
|
||||
emit_cpy_build_list,
|
||||
emit_cpy_list_append,
|
||||
|
|
|
@ -1013,31 +1013,6 @@ static void emit_native_binary_op(emit_t *emit, rt_binary_op_t op) {
|
|||
}
|
||||
}
|
||||
|
||||
static void emit_native_compare_op(emit_t *emit, rt_compare_op_t op) {
|
||||
vtype_kind_t vtype_lhs, vtype_rhs;
|
||||
emit_pre_pop_reg_reg(emit, &vtype_rhs, REG_ARG_3, &vtype_lhs, REG_ARG_2);
|
||||
if (vtype_lhs == VTYPE_INT && vtype_rhs == VTYPE_INT) {
|
||||
assert(op == RT_COMPARE_OP_LESS);
|
||||
#if N_X64
|
||||
asm_x64_xor_r64_to_r64(emit->as, REG_RET, REG_RET);
|
||||
asm_x64_cmp_r64_with_r64(emit->as, REG_ARG_3, REG_ARG_2);
|
||||
asm_x64_setcc_r8(emit->as, JCC_JL, REG_RET);
|
||||
#elif N_THUMB
|
||||
asm_thumb_cmp_reg_reg(emit->as, REG_ARG_2, REG_ARG_3);
|
||||
asm_thumb_ite_ge(emit->as);
|
||||
asm_thumb_movs_rlo_i8(emit->as, REG_RET, 0); // if r0 >= r1
|
||||
asm_thumb_movs_rlo_i8(emit->as, REG_RET, 1); // if r0 < r1
|
||||
#endif
|
||||
emit_post_push_reg(emit, VTYPE_BOOL, REG_RET);
|
||||
} else if (vtype_lhs == VTYPE_PYOBJ && vtype_rhs == VTYPE_PYOBJ) {
|
||||
emit_call_with_imm_arg(emit, RT_F_COMPARE_OP, rt_compare_op, op, REG_ARG_1);
|
||||
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||
} else {
|
||||
printf("ViperTypeError: can't do comparison between types %d and %d\n", vtype_lhs, vtype_rhs);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void emit_native_build_tuple(emit_t *emit, int n_args) {
|
||||
// for viper: call runtime, with types of args
|
||||
// if wrapped in byte_array, or something, allocates memory and fills it
|
||||
|
@ -1297,7 +1272,6 @@ const emit_method_table_t EXPORT_FUN(method_table) = {
|
|||
emit_native_pop_except,
|
||||
emit_native_unary_op,
|
||||
emit_native_binary_op,
|
||||
emit_native_compare_op,
|
||||
emit_native_build_tuple,
|
||||
emit_native_build_list,
|
||||
emit_native_list_append,
|
||||
|
|
|
@ -187,5 +187,4 @@ const emit_method_table_t emit_pass1_method_table = {
|
|||
(void*)emit_pass1_dummy,
|
||||
(void*)emit_pass1_dummy,
|
||||
(void*)emit_pass1_dummy,
|
||||
(void*)emit_pass1_dummy,
|
||||
};
|
||||
|
|
2
py/obj.h
2
py/obj.h
|
@ -155,7 +155,6 @@ struct _mp_obj_type_t {
|
|||
/*
|
||||
What we might need to add here:
|
||||
|
||||
compare_op
|
||||
store_subscr list dict
|
||||
|
||||
len str tuple list map
|
||||
|
@ -241,6 +240,7 @@ extern const mp_obj_type_t none_type;
|
|||
|
||||
// bool
|
||||
extern const mp_obj_type_t bool_type;
|
||||
#define MP_BOOL(x) (x ? mp_const_true : mp_const_false)
|
||||
|
||||
// cell
|
||||
mp_obj_t mp_obj_cell_get(mp_obj_t self_in);
|
||||
|
|
|
@ -99,6 +99,12 @@ mp_obj_t mp_obj_float_binary_op(int op, mp_float_t lhs_val, mp_obj_t rhs_in) {
|
|||
*/
|
||||
case RT_BINARY_OP_TRUE_DIVIDE:
|
||||
case RT_BINARY_OP_INPLACE_TRUE_DIVIDE: lhs_val /= rhs_val; break;
|
||||
|
||||
case RT_COMPARE_OP_LESS: return MP_BOOL(lhs_val < rhs_val);
|
||||
case RT_COMPARE_OP_MORE: return MP_BOOL(lhs_val > rhs_val);
|
||||
case RT_COMPARE_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val);
|
||||
case RT_COMPARE_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val);
|
||||
|
||||
return NULL; // op not supported
|
||||
}
|
||||
return mp_obj_new_float(lhs_val);
|
||||
|
|
|
@ -143,8 +143,8 @@ static void mp_quicksort(mp_obj_t *head, mp_obj_t *tail, mp_obj_t key_fn, bool r
|
|||
mp_obj_t *t = tail;
|
||||
mp_obj_t v = key_fn == NULL ? tail[0] : rt_call_function_1(key_fn, tail[0]); // get pivot using key_fn
|
||||
for (;;) {
|
||||
do ++h; while (rt_compare_op(op, key_fn == NULL ? h[0] : rt_call_function_1(key_fn, h[0]), v) == mp_const_true);
|
||||
do --t; while (h < t && rt_compare_op(op, v, key_fn == NULL ? t[0] : rt_call_function_1(key_fn, t[0])) == mp_const_true);
|
||||
do ++h; while (rt_binary_op(op, key_fn == NULL ? h[0] : rt_call_function_1(key_fn, h[0]), v) == mp_const_true);
|
||||
do --t; while (h < t && rt_binary_op(op, v, key_fn == NULL ? t[0] : rt_call_function_1(key_fn, t[0])) == mp_const_true);
|
||||
if (h >= t) break;
|
||||
mp_obj_t x = h[0];
|
||||
h[0] = t[0];
|
||||
|
|
75
py/runtime.c
75
py/runtime.c
|
@ -514,6 +514,10 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||
lhs_val = ans;
|
||||
break;
|
||||
}
|
||||
case RT_COMPARE_OP_LESS: return MP_BOOL(lhs_val < rhs_val); break;
|
||||
case RT_COMPARE_OP_MORE: return MP_BOOL(lhs_val > rhs_val); break;
|
||||
case RT_COMPARE_OP_LESS_EQUAL: return MP_BOOL(lhs_val <= rhs_val); break;
|
||||
case RT_COMPARE_OP_MORE_EQUAL: return MP_BOOL(lhs_val >= rhs_val); break;
|
||||
|
||||
default: assert(0);
|
||||
}
|
||||
|
@ -525,25 +529,7 @@ mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||
} else if (MP_OBJ_IS_TYPE(rhs, &complex_type)) {
|
||||
return mp_obj_complex_binary_op(op, lhs_val, 0, rhs);
|
||||
}
|
||||
} else if (MP_OBJ_IS_OBJ(lhs)) {
|
||||
mp_obj_base_t *o = lhs;
|
||||
if (o->type->binary_op != NULL) {
|
||||
mp_obj_t result = o->type->binary_op(op, lhs, rhs);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO specify in error message what the operator is
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
|
||||
"unsupported operand types for binary operator: '%s', '%s'",
|
||||
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
|
||||
}
|
||||
|
||||
mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
||||
DEBUG_OP_printf("compare %d %p %p\n", op, lhs, rhs);
|
||||
|
||||
} else {
|
||||
// deal with == and !=
|
||||
if (op == RT_COMPARE_OP_EQUAL || op == RT_COMPARE_OP_NOT_EQUAL) {
|
||||
if (mp_obj_equal(lhs, rhs)) {
|
||||
|
@ -573,49 +559,21 @@ mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs) {
|
|||
}
|
||||
}
|
||||
|
||||
// deal with small ints
|
||||
if (MP_OBJ_IS_SMALL_INT(lhs) && MP_OBJ_IS_SMALL_INT(rhs)) {
|
||||
mp_small_int_t lhs_val = MP_OBJ_SMALL_INT_VALUE(lhs);
|
||||
mp_small_int_t rhs_val = MP_OBJ_SMALL_INT_VALUE(rhs);
|
||||
int cmp;
|
||||
switch (op) {
|
||||
case RT_COMPARE_OP_LESS: cmp = lhs_val < rhs_val; break;
|
||||
case RT_COMPARE_OP_MORE: cmp = lhs_val > rhs_val; break;
|
||||
case RT_COMPARE_OP_LESS_EQUAL: cmp = lhs_val <= rhs_val; break;
|
||||
case RT_COMPARE_OP_MORE_EQUAL: cmp = lhs_val >= rhs_val; break;
|
||||
default: assert(0); cmp = 0;
|
||||
if (MP_OBJ_IS_OBJ(lhs)) {
|
||||
mp_obj_base_t *o = lhs;
|
||||
if (o->type->binary_op != NULL) {
|
||||
mp_obj_t result = o->type->binary_op(op, lhs, rhs);
|
||||
if (result != NULL) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
if (cmp) {
|
||||
return mp_const_true;
|
||||
} else {
|
||||
return mp_const_false;
|
||||
}
|
||||
}
|
||||
|
||||
#if MICROPY_ENABLE_FLOAT
|
||||
// deal with floats
|
||||
if (MP_OBJ_IS_TYPE(lhs, &float_type) || MP_OBJ_IS_TYPE(rhs, &float_type)) {
|
||||
mp_float_t lhs_val = mp_obj_get_float(lhs);
|
||||
mp_float_t rhs_val = mp_obj_get_float(rhs);
|
||||
int cmp;
|
||||
switch (op) {
|
||||
case RT_COMPARE_OP_LESS: cmp = lhs_val < rhs_val; break;
|
||||
case RT_COMPARE_OP_MORE: cmp = lhs_val > rhs_val; break;
|
||||
case RT_COMPARE_OP_LESS_EQUAL: cmp = lhs_val <= rhs_val; break;
|
||||
case RT_COMPARE_OP_MORE_EQUAL: cmp = lhs_val >= rhs_val; break;
|
||||
default: assert(0); cmp = 0;
|
||||
}
|
||||
if (cmp) {
|
||||
return mp_const_true;
|
||||
} else {
|
||||
return mp_const_false;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// not implemented
|
||||
assert(0);
|
||||
return mp_const_none;
|
||||
// TODO specify in error message what the operator is
|
||||
nlr_jump(mp_obj_new_exception_msg_varg(MP_QSTR_TypeError,
|
||||
"unsupported operand types for binary operator: '%s', '%s'",
|
||||
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
|
||||
}
|
||||
|
||||
mp_obj_t rt_make_function_from_id(int unique_code_id) {
|
||||
|
@ -956,7 +914,6 @@ void *const rt_fun_table[RT_F_NUMBER_OF] = {
|
|||
rt_call_function_n,
|
||||
rt_call_method_n,
|
||||
rt_binary_op,
|
||||
rt_compare_op,
|
||||
rt_getiter,
|
||||
rt_iternext,
|
||||
};
|
||||
|
|
|
@ -11,7 +11,6 @@ void rt_store_name(qstr qstr, mp_obj_t obj);
|
|||
void rt_store_global(qstr qstr, mp_obj_t obj);
|
||||
mp_obj_t rt_unary_op(int op, mp_obj_t arg);
|
||||
mp_obj_t rt_binary_op(int op, mp_obj_t lhs, mp_obj_t rhs);
|
||||
mp_obj_t rt_compare_op(int op, mp_obj_t lhs, mp_obj_t rhs);
|
||||
mp_obj_t rt_make_function_from_id(int unique_code_id);
|
||||
mp_obj_t rt_make_function_0(mp_fun_0_t f);
|
||||
mp_obj_t rt_make_function_1(mp_fun_1_t f);
|
||||
|
|
|
@ -31,9 +31,6 @@ typedef enum {
|
|||
RT_BINARY_OP_INPLACE_TRUE_DIVIDE,
|
||||
RT_BINARY_OP_INPLACE_MODULO,
|
||||
RT_BINARY_OP_INPLACE_POWER,
|
||||
} rt_binary_op_t;
|
||||
|
||||
typedef enum {
|
||||
RT_COMPARE_OP_LESS,
|
||||
RT_COMPARE_OP_MORE,
|
||||
RT_COMPARE_OP_EQUAL,
|
||||
|
@ -45,7 +42,7 @@ typedef enum {
|
|||
RT_COMPARE_OP_IS,
|
||||
RT_COMPARE_OP_IS_NOT,
|
||||
RT_COMPARE_OP_EXCEPTION_MATCH,
|
||||
} rt_compare_op_t;
|
||||
} rt_binary_op_t;
|
||||
|
||||
typedef enum {
|
||||
RT_F_LOAD_CONST_DEC = 0,
|
||||
|
@ -71,7 +68,6 @@ typedef enum {
|
|||
RT_F_CALL_FUNCTION_N,
|
||||
RT_F_CALL_METHOD_N,
|
||||
RT_F_BINARY_OP,
|
||||
RT_F_COMPARE_OP,
|
||||
RT_F_GETITER,
|
||||
RT_F_ITERNEXT,
|
||||
RT_F_NUMBER_OF,
|
||||
|
|
|
@ -266,11 +266,6 @@ void mp_show_byte_code(const byte *ip, int len) {
|
|||
printf("BINARY_OP " UINT_FMT, unum);
|
||||
break;
|
||||
|
||||
case MP_BC_COMPARE_OP:
|
||||
unum = *ip++;
|
||||
printf("COMPARE_OP " UINT_FMT, unum);
|
||||
break;
|
||||
|
||||
case MP_BC_BUILD_TUPLE:
|
||||
DECODE_UINT;
|
||||
printf("BUILD_TUPLE " UINT_FMT, unum);
|
||||
|
|
7
py/vm.c
7
py/vm.c
|
@ -355,13 +355,6 @@ bool mp_execute_byte_code_2(const byte **ip_in_out, mp_obj_t *fastn, mp_obj_t **
|
|||
SET_TOP(rt_binary_op(unum, obj1, obj2));
|
||||
break;
|
||||
|
||||
case MP_BC_COMPARE_OP:
|
||||
unum = *ip++;
|
||||
obj2 = POP();
|
||||
obj1 = TOP();
|
||||
SET_TOP(rt_compare_op(unum, obj1, obj2));
|
||||
break;
|
||||
|
||||
case MP_BC_BUILD_TUPLE:
|
||||
DECODE_UINT;
|
||||
obj1 = rt_build_tuple(unum, sp);
|
||||
|
|
Loading…
Reference in New Issue