py: Fix typing of viper locals; allow default types in annotation.
This commit is contained in:
parent
2ac4af6946
commit
a5190a7dac
25
py/compile.c
25
py/compile.c
@ -3017,7 +3017,7 @@ STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn)
|
|||||||
qstr arg_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
|
qstr arg_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
|
||||||
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ARG, id_info->local_num, arg_type);
|
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ARG, id_info->local_num, arg_type);
|
||||||
} else {
|
} else {
|
||||||
compile_syntax_error(comp, pn_annotation, "annotation must be an identifier");
|
compile_syntax_error(comp, pn_annotation, "parameter annotation must be an identifier");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif // MICROPY_EMIT_NATIVE
|
#endif // MICROPY_EMIT_NATIVE
|
||||||
@ -3155,17 +3155,20 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
|
|||||||
apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_annotations);
|
apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_annotations);
|
||||||
|
|
||||||
// pns->nodes[2] is return/whole function annotation
|
// pns->nodes[2] is return/whole function annotation
|
||||||
#if MICROPY_EMIT_NATIVE
|
mp_parse_node_t pn_annotation = pns->nodes[2];
|
||||||
if (scope->emit_options == MP_EMIT_OPT_VIPER) {
|
if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) {
|
||||||
// nodes[2] can be null or a test-expr
|
#if MICROPY_EMIT_NATIVE
|
||||||
if (MP_PARSE_NODE_IS_ID(pns->nodes[2])) {
|
if (scope->emit_options == MP_EMIT_OPT_VIPER) {
|
||||||
qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
|
// nodes[2] can be null or a test-expr
|
||||||
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type);
|
if (MP_PARSE_NODE_IS_ID(pn_annotation)) {
|
||||||
} else {
|
qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
|
||||||
compile_syntax_error(comp, pns->nodes[2], "annotation must be an identifier");
|
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type);
|
||||||
|
} else {
|
||||||
|
compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
#endif // MICROPY_EMIT_NATIVE
|
||||||
}
|
}
|
||||||
#endif // MICROPY_EMIT_NATIVE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
compile_node(comp, pns->nodes[3]); // 3 is function body
|
compile_node(comp, pns->nodes[3]); // 3 is function body
|
||||||
@ -3625,7 +3628,7 @@ mp_obj_t mp_compile(mp_parse_node_t pn, qstr source_file, uint emit_opt, bool is
|
|||||||
comp->emit_method_table = &emit_native_thumb_method_table;
|
comp->emit_method_table = &emit_native_thumb_method_table;
|
||||||
#endif
|
#endif
|
||||||
comp->emit = emit_native;
|
comp->emit = emit_native;
|
||||||
comp->emit_method_table->set_native_type(comp->emit, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0);
|
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0);
|
||||||
|
|
||||||
// native emitters need an extra pass to compute stack size
|
// native emitters need an extra pass to compute stack size
|
||||||
compile_scope(comp, s, MP_PASS_STACK_SIZE);
|
compile_scope(comp, s, MP_PASS_STACK_SIZE);
|
||||||
|
@ -241,12 +241,19 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
|
|||||||
|
|
||||||
// set default type for return and arguments
|
// set default type for return and arguments
|
||||||
emit->return_vtype = VTYPE_PYOBJ;
|
emit->return_vtype = VTYPE_PYOBJ;
|
||||||
for (int i = 0; i < emit->local_vtype_alloc; i++) {
|
for (mp_uint_t i = 0; i < emit->scope->num_pos_args; i++) {
|
||||||
emit->local_vtype[i] = VTYPE_PYOBJ;
|
emit->local_vtype[i] = VTYPE_PYOBJ;
|
||||||
}
|
}
|
||||||
for (int i = 0; i < emit->stack_info_alloc; i++) {
|
|
||||||
|
// local variables begin unbound, and have unknown type
|
||||||
|
for (mp_uint_t i = emit->scope->num_pos_args; i < emit->local_vtype_alloc; i++) {
|
||||||
|
emit->local_vtype[i] = VTYPE_UNBOUND;
|
||||||
|
}
|
||||||
|
|
||||||
|
// values on stack begin unbound
|
||||||
|
for (mp_uint_t i = 0; i < emit->stack_info_alloc; i++) {
|
||||||
emit->stack_info[i].kind = STACK_VALUE;
|
emit->stack_info[i].kind = STACK_VALUE;
|
||||||
emit->stack_info[i].vtype = VTYPE_PYOBJ;
|
emit->stack_info[i].vtype = VTYPE_UNBOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if N_X64
|
#if N_X64
|
||||||
@ -844,7 +851,6 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
|
|||||||
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||||
} else {
|
} else {
|
||||||
printf("ViperTypeError: can't do subscr of types %d and %d\n", vtype_lhs, vtype_rhs);
|
printf("ViperTypeError: can't do subscr of types %d and %d\n", vtype_lhs, vtype_rhs);
|
||||||
assert(0);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1212,7 +1218,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
|
|||||||
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||||
} else {
|
} else {
|
||||||
printf("ViperTypeError: can't do binary op between types %d and %d\n", vtype_lhs, vtype_rhs);
|
printf("ViperTypeError: can't do binary op between types %d and %d\n", vtype_lhs, vtype_rhs);
|
||||||
assert(0);
|
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,25 @@ def f(x:int, y:int) -> int:
|
|||||||
def g(x:object, y:object) -> object:
|
def g(x:object, y:object) -> object:
|
||||||
return x + y
|
return x + y
|
||||||
|
|
||||||
|
# a local (should have automatic type int)
|
||||||
|
@micropython.viper
|
||||||
|
def h(x:int) -> int:
|
||||||
|
y = 4
|
||||||
|
return x + y
|
||||||
|
|
||||||
|
# without type annotation, types should default to object
|
||||||
|
@micropython.viper
|
||||||
|
def i(x, y):
|
||||||
|
return x * y
|
||||||
|
|
||||||
|
# a for loop
|
||||||
|
@micropython.viper
|
||||||
|
def viper_sum(a:int, b:int) -> int:
|
||||||
|
total = 0
|
||||||
|
for x in range(a, b):
|
||||||
|
total += x
|
||||||
|
return total
|
||||||
|
|
||||||
# this doesn't work at the moment
|
# this doesn't work at the moment
|
||||||
#@micropython.viper
|
#@micropython.viper
|
||||||
#def g() -> uint:
|
#def g() -> uint:
|
||||||
@ -17,4 +36,6 @@ def g(x:object, y:object) -> object:
|
|||||||
|
|
||||||
print(f(1, 2))
|
print(f(1, 2))
|
||||||
print(g(1, 2))
|
print(g(1, 2))
|
||||||
#print(h())
|
print(h(3))
|
||||||
|
print(i(4, 5))
|
||||||
|
print(viper_sum(10, 10000))
|
||||||
|
@ -1,2 +1,5 @@
|
|||||||
6
|
6
|
||||||
3
|
3
|
||||||
|
7
|
||||||
|
20
|
||||||
|
49994955
|
||||||
|
Loading…
x
Reference in New Issue
Block a user