예제 #1
0
id_info_t *scope_find_or_add_id(scope_t *scope, qstr qst, bool *added) {
    id_info_t *id_info = scope_find(scope, qst);
    if (id_info != NULL) {
        *added = false;
        return id_info;
    }

    // make sure we have enough memory
    if (scope->id_info_len >= scope->id_info_alloc) {
        scope->id_info = m_renew(id_info_t, scope->id_info, scope->id_info_alloc, scope->id_info_alloc + MICROPY_ALLOC_SCOPE_ID_INC);
        scope->id_info_alloc += MICROPY_ALLOC_SCOPE_ID_INC;
    }

    // add new id to end of array of all ids; this seems to match CPython
    // important thing is that function arguments are first, but that is
    // 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->flags = 0;
    id_info->local_num = 0;
    id_info->qst = qst;
    *added = true;
    return id_info;
}
예제 #2
0
id_info_t *scope_find_local_in_parent(scope_t *scope, qstr qst) {
    if (scope->parent == NULL) {
        return NULL;
    }
    for (scope_t *s = scope->parent; s->parent != NULL; s = s->parent) {
        id_info_t *id = scope_find(s, qst);
        if (id != NULL) {
            return id;
        }
    }
    return NULL;
}
예제 #3
0
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) {
    // assumes pass is greater than 1, ie that all identifiers are defined in the scope

    id_info_t *id = scope_find(scope, qst);
    assert(id != NULL);

    // call the emit backend with the correct code
    if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
        emit_method_table->name(emit, qst);
    } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
        emit_method_table->global(emit, qst);
    } else if (id->kind == ID_INFO_KIND_LOCAL) {
        emit_method_table->fast(emit, qst, id->local_num);
    } else {
        assert(id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE);
        emit_method_table->deref(emit, qst, id->local_num);
    }
}
예제 #4
0
void emit_common_delete_id(emit_t *emit, const emit_method_table_t *emit_method_table, scope_t *scope, qstr qst) {
    // assumes pass is greater than 1, ie that all identifiers are defined in the scope

    id_info_t *id = scope_find(scope, qst);
    assert(id != NULL); // TODO can this ever fail?

    // call the emit backend with the correct code
    if (id == NULL || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
        EMIT(delete_name, qst);
    } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
        EMIT(delete_global, qst);
    } else if (id->kind == ID_INFO_KIND_LOCAL) {
        EMIT(delete_fast, qst, id->local_num);
    } else if (id->kind == ID_INFO_KIND_CELL || id->kind == ID_INFO_KIND_FREE) {
        EMIT(delete_deref, qst, id->local_num);
    } else {
        assert(0);
    }
}
예제 #5
0
id_info_t *scope_find_global(scope_t *scope, qstr qst) {
    while (scope->parent != NULL) {
        scope = scope->parent;
    }
    return scope_find(scope, qst);
}