summaryrefslogtreecommitdiff
path: root/py
diff options
context:
space:
mode:
Diffstat (limited to 'py')
-rw-r--r--py/compile.c30
-rw-r--r--py/emit.h5
-rw-r--r--py/emitcommon.c20
-rw-r--r--py/scope.c11
-rw-r--r--py/scope.h3
5 files changed, 23 insertions, 46 deletions
diff --git a/py/compile.c b/py/compile.c
index d6dec1b47..6db108a59 100644
--- a/py/compile.c
+++ b/py/compile.c
@@ -1180,8 +1180,8 @@ STATIC void compile_import_from(compiler_t *comp, mp_parse_node_struct_t *pns) {
}
}
-STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, bool added, id_info_t *id_info) {
- if (!added && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) {
+STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, id_info_t *id_info) {
+ if (id_info->kind != ID_INFO_KIND_UNDECIDED && id_info->kind != ID_INFO_KIND_GLOBAL_EXPLICIT) {
compile_syntax_error(comp, pn, "identifier redefined as global");
return;
}
@@ -1194,8 +1194,8 @@ STATIC void compile_declare_global(compiler_t *comp, mp_parse_node_t pn, bool ad
}
}
-STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, bool added, id_info_t *id_info) {
- if (added) {
+STATIC void compile_declare_nonlocal(compiler_t *comp, mp_parse_node_t pn, id_info_t *id_info) {
+ if (id_info->kind == ID_INFO_KIND_UNDECIDED) {
id_info->kind = ID_INFO_KIND_GLOBAL_IMPLICIT;
scope_check_to_close_over(comp->scope_cur, id_info);
if (id_info->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
@@ -1219,12 +1219,11 @@ STATIC void compile_global_nonlocal_stmt(compiler_t *comp, mp_parse_node_struct_
int n = mp_parse_node_extract_list(&pns->nodes[0], PN_name_list, &nodes);
for (int i = 0; i < n; i++) {
qstr qst = MP_PARSE_NODE_LEAF_ARG(nodes[i]);
- bool added;
- id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, &added);
+ id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qst, ID_INFO_KIND_UNDECIDED);
if (is_global) {
- compile_declare_global(comp, (mp_parse_node_t)pns, added, id_info);
+ compile_declare_global(comp, (mp_parse_node_t)pns, id_info);
} else {
- compile_declare_nonlocal(comp, (mp_parse_node_t)pns, added, id_info);
+ compile_declare_nonlocal(comp, (mp_parse_node_t)pns, id_info);
}
}
}
@@ -2836,9 +2835,8 @@ STATIC void compile_scope_func_lambda_param(compiler_t *comp, mp_parse_node_t pn
}
if (param_name != MP_QSTR_NULL) {
- bool added;
- id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, &added);
- if (!added) {
+ id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, param_name, ID_INFO_KIND_UNDECIDED);
+ if (id_info->kind != ID_INFO_KIND_UNDECIDED) {
compile_syntax_error(comp, pn, "argument name reused");
return;
}
@@ -3034,10 +3032,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
// so we use the blank qstr.
qstr qstr_arg = MP_QSTR_;
if (comp->pass == MP_PASS_SCOPE) {
- bool added;
- id_info_t *id_info = scope_find_or_add_id(comp->scope_cur, qstr_arg, &added);
- assert(added);
- id_info->kind = ID_INFO_KIND_LOCAL;
+ scope_find_or_add_id(comp->scope_cur, qstr_arg, ID_INFO_KIND_LOCAL);
scope->num_pos_args = 1;
}
@@ -3077,10 +3072,7 @@ STATIC void compile_scope(compiler_t *comp, scope_t *scope, pass_kind_t pass) {
assert(MP_PARSE_NODE_STRUCT_KIND(pns) == PN_classdef);
if (comp->pass == MP_PASS_SCOPE) {
- bool added;
- id_info_t *id_info = scope_find_or_add_id(scope, MP_QSTR___class__, &added);
- assert(added);
- id_info->kind = ID_INFO_KIND_LOCAL;
+ scope_find_or_add_id(scope, MP_QSTR___class__, ID_INFO_KIND_LOCAL);
}
compile_load_id(comp, MP_QSTR___name__);
diff --git a/py/emit.h b/py/emit.h
index 84972dd69..3c42bdf14 100644
--- a/py/emit.h
+++ b/py/emit.h
@@ -159,7 +159,10 @@ typedef struct _emit_method_table_t {
int mp_native_type_from_qstr(qstr qst);
-void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst);
+static inline void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst) {
+ scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT);
+}
+
void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst);
void mp_emit_common_id_op(emit_t *emit, const mp_emit_method_table_id_ops_t *emit_method_table, scope_t *scope, qstr qst);
diff --git a/py/emitcommon.c b/py/emitcommon.c
index 149e0b0f1..791bf398a 100644
--- a/py/emitcommon.c
+++ b/py/emitcommon.c
@@ -30,26 +30,10 @@
#if MICROPY_ENABLE_COMPILER
-void mp_emit_common_get_id_for_load(scope_t *scope, qstr qst) {
- // name adding/lookup
- bool added;
- id_info_t *id = scope_find_or_add_id(scope, qst, &added);
- if (added) {
- id->kind = ID_INFO_KIND_GLOBAL_IMPLICIT;
- }
-}
-
void mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst) {
// name adding/lookup
- bool added;
- id_info_t *id = scope_find_or_add_id(scope, qst, &added);
- if (added) {
- if (SCOPE_IS_FUNC_LIKE(scope->kind)) {
- id->kind = ID_INFO_KIND_LOCAL;
- } else {
- id->kind = ID_INFO_KIND_GLOBAL_IMPLICIT;
- }
- } else if (SCOPE_IS_FUNC_LIKE(scope->kind) && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
+ id_info_t *id = scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT);
+ if (SCOPE_IS_FUNC_LIKE(scope->kind) && id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
// rebind as a local variable
id->kind = ID_INFO_KIND_LOCAL;
}
diff --git a/py/scope.c b/py/scope.c
index 8adb85b80..d996731f8 100644
--- a/py/scope.c
+++ b/py/scope.c
@@ -64,10 +64,9 @@ void scope_free(scope_t *scope) {
m_del(scope_t, scope, 1);
}
-id_info_t *scope_find_or_add_id(scope_t *scope, qstr qst, bool *added) {
+id_info_t *scope_find_or_add_id(scope_t *scope, qstr qst, scope_kind_t kind) {
id_info_t *id_info = scope_find(scope, qst);
if (id_info != NULL) {
- *added = false;
return id_info;
}
@@ -82,11 +81,10 @@ id_info_t *scope_find_or_add_id(scope_t *scope, qstr qst, bool *added) {
// handled by the compiler because it adds arguments before compiling the body
id_info = &scope->id_info[scope->id_info_len++];
- id_info->kind = 0;
+ id_info->kind = kind;
id_info->flags = 0;
id_info->local_num = 0;
id_info->qst = qst;
- *added = true;
return id_info;
}
@@ -110,9 +108,8 @@ STATIC void scope_close_over_in_parents(scope_t *scope, qstr qst) {
assert(scope->parent != NULL); // we should have at least 1 parent
for (scope_t *s = scope->parent;; s = s->parent) {
assert(s->parent != NULL); // we should not get to the outer scope
- bool added;
- id_info_t *id = scope_find_or_add_id(s, qst, &added);
- if (added) {
+ id_info_t *id = scope_find_or_add_id(s, qst, ID_INFO_KIND_UNDECIDED);
+ if (id->kind == ID_INFO_KIND_UNDECIDED) {
// variable not previously declared in this scope, so declare it as free and keep searching parents
id->kind = ID_INFO_KIND_FREE;
} else {
diff --git a/py/scope.h b/py/scope.h
index d51bb90bb..ba07c3949 100644
--- a/py/scope.h
+++ b/py/scope.h
@@ -30,6 +30,7 @@
#include "py/emitglue.h"
enum {
+ ID_INFO_KIND_UNDECIDED,
ID_INFO_KIND_GLOBAL_IMPLICIT,
ID_INFO_KIND_GLOBAL_EXPLICIT,
ID_INFO_KIND_LOCAL, // in a function f, written and only referenced by f
@@ -90,7 +91,7 @@ typedef struct _scope_t {
scope_t *scope_new(scope_kind_t kind, mp_parse_node_t pn, qstr source_file, mp_uint_t emit_options);
void scope_free(scope_t *scope);
-id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, bool *added);
+id_info_t *scope_find_or_add_id(scope_t *scope, qstr qstr, scope_kind_t kind);
id_info_t *scope_find(scope_t *scope, qstr qstr);
id_info_t *scope_find_global(scope_t *scope, qstr qstr);
void scope_check_to_close_over(scope_t *scope, id_info_t *id);