summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--py/compile2.c106
1 files changed, 60 insertions, 46 deletions
diff --git a/py/compile2.c b/py/compile2.c
index 9db0c2f04d..188d0f3f5e 100644
--- a/py/compile2.c
+++ b/py/compile2.c
@@ -2932,7 +2932,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
comp->next_label = 1;
if (scope->kind != SCOPE_FUNCTION) {
- compile_syntax_error(comp, MP_PARSE_NODE_NULL, "inline assembler must be a function");
+ compile_syntax_error(comp, NULL, "inline assembler must be a function");
return;
}
@@ -2941,109 +2941,123 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
}
// get the function definition parse node
- assert(MP_PARSE_NODE_IS_STRUCT(scope->pn));
- mp_parse_node_struct_t *pns = (mp_parse_node_struct_t*)scope->pn;
- assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_funcdef);
+ const byte *p = scope->pn;
+ assert(pt_is_any_id(p));
+ p = pt_next(p); // skip the function name
- //qstr f_id = MP_PARSE_NODE_LEAF_ARG(pns->nodes[0]); // function name
-
- // parameters are in pns->nodes[1]
+ // parameters are in next node
if (comp->pass == MP_PASS_CODE_SIZE) {
- mp_parse_node_t *pn_params;
- int n_params = mp_parse_node_extract_list(&pns->nodes[1], PN_typedargslist, &pn_params);
- scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, n_params, pn_params);
+ const byte *pp = p;
+ const byte *pptop = mp_parse_node_extract_list(&pp, PN_typedargslist);
+ scope->num_pos_args = EMIT_INLINE_ASM_ARG(count_params, pp, pptop);
if (comp->compile_error != MP_OBJ_NULL) {
goto inline_asm_error;
}
}
- assert(MP_PARSE_NODE_IS_NULL(pns->nodes[2])); // type
+ p = pt_next(p); // skip the parameter list
+ p = pt_next(p); // skip the return type
- mp_parse_node_t pn_body = pns->nodes[3]; // body
- mp_parse_node_t *nodes;
- int num = mp_parse_node_extract_list(&pn_body, PN_suite_block_stmts, &nodes);
+ // get the list of statements within the body of the function
+ const byte *ptop = mp_parse_node_extract_list(&p, PN_suite_block_stmts);
- for (int i = 0; i < num; i++) {
- assert(MP_PARSE_NODE_IS_STRUCT(nodes[i]));
- mp_parse_node_struct_t *pns2 = (mp_parse_node_struct_t*)nodes[i];
- if (MP_PARSE_NODE_STRUCT_KIND(pns2) == PN_pass_stmt) {
+ for (const byte *p_instr = p; p_instr != ptop; p_instr = pt_next(p_instr)) {
+ p = p_instr;
+ if (pt_is_rule(p, PN_pass_stmt)) {
// no instructions
continue;
- } else if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_expr_stmt) {
+ } else if (!pt_is_rule(p, PN_expr_stmt)) {
// not an instruction; error
not_an_instruction:
- compile_syntax_error(comp, nodes[i], "expecting an assembler instruction");
+ compile_syntax_error(comp, p, "expecting an assembler instruction");
return;
}
// check structure of parse node
- assert(MP_PARSE_NODE_IS_STRUCT(pns2->nodes[0]));
- if (!MP_PARSE_NODE_IS_NULL(pns2->nodes[1])) {
+ const byte *p_expr_top;
+ const byte *p_expr = pt_rule_extract_top(p, &p_expr_top);
+ if (!pt_is_rule(p_expr, PN_power)) {
+ goto not_an_instruction;
+ }
+ if (pt_next(p_expr) != p_expr_top) {
goto not_an_instruction;
}
- pns2 = (mp_parse_node_struct_t*)pns2->nodes[0];
- if (MP_PARSE_NODE_STRUCT_KIND(pns2) != PN_power) {
+ p_expr = pt_rule_extract_top(p_expr, &p_expr_top);
+ if (!pt_is_any_id(p_expr)) {
goto not_an_instruction;
}
- if (!MP_PARSE_NODE_IS_ID(pns2->nodes[0])) {
+ const byte *p_expr_paren = pt_next(p_expr);
+ if (p_expr_paren == p_expr_top || !pt_is_rule(p_expr_paren, PN_trailer_paren)) {
goto not_an_instruction;
}
- if (!MP_PARSE_NODE_IS_STRUCT_KIND(pns2->nodes[1], PN_trailer_paren)) {
+ if (pt_next(p_expr_paren) != p_expr_top) {
goto not_an_instruction;
}
- assert(MP_PARSE_NODE_IS_NULL(pns2->nodes[2]));
// parse node looks like an instruction
// get instruction name and args
- qstr op = MP_PARSE_NODE_LEAF_ARG(pns2->nodes[0]);
- pns2 = (mp_parse_node_struct_t*)pns2->nodes[1]; // PN_trailer_paren
- mp_parse_node_t *pn_arg;
- int n_args = mp_parse_node_extract_list(&pns2->nodes[0], PN_arglist, &pn_arg);
+ qstr op;
+ pt_extract_id(p_expr, &op);
+
+ const byte *p_args = pt_rule_first(p_expr_paren);
+ const byte *p_args_top = mp_parse_node_extract_list(&p_args, PN_arglist);
+ uint n_args = pt_num_nodes(p_args, p_args_top);
// emit instructions
if (op == MP_QSTR_label) {
- if (!(n_args == 1 && MP_PARSE_NODE_IS_ID(pn_arg[0]))) {
- compile_syntax_error(comp, nodes[i], "'label' requires 1 argument");
+ if (!(n_args == 1 && pt_is_any_id(p_args))) {
+ compile_syntax_error(comp, p, "'label' requires 1 argument");
return;
}
uint lab = comp_next_label(comp);
if (pass > MP_PASS_SCOPE) {
- if (!EMIT_INLINE_ASM_ARG(label, lab, MP_PARSE_NODE_LEAF_ARG(pn_arg[0]))) {
- compile_syntax_error(comp, nodes[i], "label redefined");
+ qstr id;
+ pt_extract_id(p_args, &id);
+ if (!EMIT_INLINE_ASM_ARG(label, lab, id)) {
+ compile_syntax_error(comp, p, "label redefined");
return;
}
}
} else if (op == MP_QSTR_align) {
- if (!(n_args == 1 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
- compile_syntax_error(comp, nodes[i], "'align' requires 1 argument");
+ if (!(n_args == 1 && pt_is_small_int(p_args))) {
+ compile_syntax_error(comp, p, "'align' requires 1 argument");
return;
}
if (pass > MP_PASS_SCOPE) {
- EMIT_INLINE_ASM_ARG(align, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]));
+ EMIT_INLINE_ASM_ARG(align, pt_small_int_value(p_args));
}
} else if (op == MP_QSTR_data) {
- if (!(n_args >= 2 && MP_PARSE_NODE_IS_SMALL_INT(pn_arg[0]))) {
- compile_syntax_error(comp, nodes[i], "'data' requires at least 2 arguments");
+ if (!(n_args >= 2 && pt_is_small_int(p_args))) {
+ compile_syntax_error(comp, p, "'data' requires at least 2 arguments");
return;
}
if (pass > MP_PASS_SCOPE) {
- mp_int_t bytesize = MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[0]);
+ mp_int_t bytesize;
+ p_args = pt_get_small_int(p_args, &bytesize);
for (uint j = 1; j < n_args; j++) {
- if (!MP_PARSE_NODE_IS_SMALL_INT(pn_arg[j])) {
- compile_syntax_error(comp, nodes[i], "'data' requires integer arguments");
+ if (!pt_is_small_int(p_args)) {
+ compile_syntax_error(comp, p, "'data' requires integer arguments");
return;
}
- EMIT_INLINE_ASM_ARG(data, bytesize, MP_PARSE_NODE_LEAF_SMALL_INT(pn_arg[j]));
+ mp_int_t val;
+ p_args = pt_get_small_int(p_args, &val);
+ EMIT_INLINE_ASM_ARG(data, bytesize, val);
}
}
} else {
if (pass > MP_PASS_SCOPE) {
+ if (n_args > 3) {
+ goto not_an_instruction;
+ }
+ const byte *pn_arg[3];
+ pn_arg[0] = p_args;
+ pn_arg[1] = pt_next(pn_arg[0]);
+ pn_arg[2] = pt_next(pn_arg[1]);
EMIT_INLINE_ASM_ARG(op, op, n_args, pn_arg);
}
}
if (comp->compile_error != MP_OBJ_NULL) {
- pns = pns2; // this is the parse node that had the error
goto inline_asm_error;
}
}
@@ -3055,7 +3069,7 @@ STATIC void compile_scope_inline_asm(compiler_t *comp, scope_t *scope, pass_kind
if (comp->compile_error != MP_OBJ_NULL) {
// inline assembler had an error; set line for its exception
inline_asm_error:
- comp->compile_error_line = pns->source_line;
+ compile_error_set_line(comp, p);
}
}
#endif