Skip to content

Commit a5190a7

Browse files
committed
py: Fix typing of viper locals; allow default types in annotation.
1 parent 2ac4af6 commit a5190a7

File tree

4 files changed

+50
-17
lines changed

4 files changed

+50
-17
lines changed

py/compile.c

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3017,7 +3017,7 @@ STATIC void compile_scope_func_annotations(compiler_t *comp, mp_parse_node_t pn)
30173017
qstr arg_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
30183018
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ARG, id_info->local_num, arg_type);
30193019
} else {
3020-
compile_syntax_error(comp, pn_annotation, "annotation must be an identifier");
3020+
compile_syntax_error(comp, pn_annotation, "parameter annotation must be an identifier");
30213021
}
30223022
}
30233023
#endif // MICROPY_EMIT_NATIVE
@@ -3155,17 +3155,20 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
31553155
apply_to_single_or_list(comp, pns->nodes[1], PN_typedargslist, compile_scope_func_annotations);
31563156

31573157
// pns->nodes[2] is return/whole function annotation
3158-
#if MICROPY_EMIT_NATIVE
3159-
if (scope->emit_options == MP_EMIT_OPT_VIPER) {
3160-
// nodes[2] can be null or a test-expr
3161-
if (MP_PARSE_NODE_IS_ID(pns->nodes[2])) {
3162-
qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pns->nodes[2]);
3163-
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type);
3164-
} else {
3165-
compile_syntax_error(comp, pns->nodes[2], "annotation must be an identifier");
3158+
mp_parse_node_t pn_annotation = pns->nodes[2];
3159+
if (!MP_PARSE_NODE_IS_NULL(pn_annotation)) {
3160+
#if MICROPY_EMIT_NATIVE
3161+
if (scope->emit_options == MP_EMIT_OPT_VIPER) {
3162+
// nodes[2] can be null or a test-expr
3163+
if (MP_PARSE_NODE_IS_ID(pn_annotation)) {
3164+
qstr ret_type = MP_PARSE_NODE_LEAF_ARG(pn_annotation);
3165+
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_RETURN, 0, ret_type);
3166+
} else {
3167+
compile_syntax_error(comp, pn_annotation, "return annotation must be an identifier");
3168+
}
31663169
}
3170+
#endif // MICROPY_EMIT_NATIVE
31673171
}
3168-
#endif // MICROPY_EMIT_NATIVE
31693172
}
31703173

31713174
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
36253628
comp->emit_method_table = &emit_native_thumb_method_table;
36263629
#endif
36273630
comp->emit = emit_native;
3628-
comp->emit_method_table->set_native_type(comp->emit, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0);
3631+
EMIT_ARG(set_native_type, MP_EMIT_NATIVE_TYPE_ENABLE, s->emit_options == MP_EMIT_OPT_VIPER, 0);
36293632

36303633
// native emitters need an extra pass to compute stack size
36313634
compile_scope(comp, s, MP_PASS_STACK_SIZE);

py/emitnative.c

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -241,12 +241,19 @@ STATIC void emit_native_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scop
241241

242242
// set default type for return and arguments
243243
emit->return_vtype = VTYPE_PYOBJ;
244-
for (int i = 0; i < emit->local_vtype_alloc; i++) {
244+
for (mp_uint_t i = 0; i < emit->scope->num_pos_args; i++) {
245245
emit->local_vtype[i] = VTYPE_PYOBJ;
246246
}
247-
for (int i = 0; i < emit->stack_info_alloc; i++) {
247+
248+
// local variables begin unbound, and have unknown type
249+
for (mp_uint_t i = emit->scope->num_pos_args; i < emit->local_vtype_alloc; i++) {
250+
emit->local_vtype[i] = VTYPE_UNBOUND;
251+
}
252+
253+
// values on stack begin unbound
254+
for (mp_uint_t i = 0; i < emit->stack_info_alloc; i++) {
248255
emit->stack_info[i].kind = STACK_VALUE;
249-
emit->stack_info[i].vtype = VTYPE_PYOBJ;
256+
emit->stack_info[i].vtype = VTYPE_UNBOUND;
250257
}
251258

252259
#if N_X64
@@ -844,7 +851,6 @@ STATIC void emit_native_load_subscr(emit_t *emit) {
844851
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
845852
} else {
846853
printf("ViperTypeError: can't do subscr of types %d and %d\n", vtype_lhs, vtype_rhs);
847-
assert(0);
848854
}
849855
}
850856

@@ -1212,7 +1218,7 @@ STATIC void emit_native_binary_op(emit_t *emit, mp_binary_op_t op) {
12121218
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
12131219
} else {
12141220
printf("ViperTypeError: can't do binary op between types %d and %d\n", vtype_lhs, vtype_rhs);
1215-
assert(0);
1221+
emit_post_push_reg(emit, VTYPE_PYOBJ, REG_RET);
12161222
}
12171223
}
12181224

tests/micropython/viper.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,32 @@ def f(x:int, y:int) -> int:
1010
def g(x:object, y:object) -> object:
1111
return x + y
1212

13+
# a local (should have automatic type int)
14+
@micropython.viper
15+
def h(x:int) -> int:
16+
y = 4
17+
return x + y
18+
19+
# without type annotation, types should default to object
20+
@micropython.viper
21+
def i(x, y):
22+
return x * y
23+
24+
# a for loop
25+
@micropython.viper
26+
def viper_sum(a:int, b:int) -> int:
27+
total = 0
28+
for x in range(a, b):
29+
total += x
30+
return total
31+
1332
# this doesn't work at the moment
1433
#@micropython.viper
1534
#def g() -> uint:
1635
# return -1
1736

1837
print(f(1, 2))
1938
print(g(1, 2))
20-
#print(h())
39+
print(h(3))
40+
print(i(4, 5))
41+
print(viper_sum(10, 10000))

tests/micropython/viper.py.exp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
6
22
3
3+
7
4+
20
5+
49994955

0 commit comments

Comments
 (0)