microPython的源码解析之 emitcommon.c

本文深入探讨MicroPython的emitcommon.c文件,涉及字符串常量处理、对象比较、常量对象管理和标识符处理等功能,解析其执行逻辑流程,帮助读者理解MicroPython编译器的核心实现。同时,文章提供了多个C语言示例,涉及NI-Motion在运动控制领域的应用。
摘要由CSDN通过智能技术生成

MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.

#include <assert.h>

#include "py/emit.h"
#include "py/nativeglue.h"

#if MICROPY_ENABLE_COMPILER

// 如果启用了字节码编译器
#if MICROPY_EMIT_BYTECODE_USES_QSTR_TABLE
// 函数:mp_emit_common_use_qstr,用于在编译时查找或添加字符串常量
qstr_short_t mp_emit_common_use_qstr(mp_emit_common_t *emit, qstr qst) {
   
    // 在字符串映射中查找或添加字符串常量
    mp_map_elem_t *elem = mp_map_lookup(&emit->qstr_map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP_ADD_IF_NOT_FOUND);
    // 如果该值未被设置,则为其分配一个新的小整数索引
    if (elem->value == MP_OBJ_NULL) {
   
        elem->value = MP_OBJ_NEW_SMALL_INT(emit->qstr_map.used - 1);
    }
    // 返回字符串常量的索引
    return MP_OBJ_SMALL_INT_VALUE(elem->value);
}
#endif

// 函数:strictly_equal,用于比较两个对象是否类型和值完全相同
static bool strictly_equal(mp_obj_t a, mp_obj_t b) {
   
    // 如果两个对象的地址相同,则它们相等
    if (a == b) {
   
        return true;
    }

    #if MICROPY_EMIT_NATIVE
    // 如果对象是函数表,则它们不相等
    if (a == MP_OBJ_FROM_PTR(&mp_fun_table) || b == MP_OBJ_FROM_PTR(&mp_fun_table)) {
   
        return false;
    }
    #endif

    // 获取两个对象的类型
    const mp_obj_type_t *a_type = mp_obj_get_type(a);
    const mp_obj_type_t *b_type = mp_obj_get_type(b);
    // 如果类型不同,则对象不相等
    if (a_type != b_type) {
   
        return false;
    }
    // 如果类型是元组
    if (a_type == &mp_type_tuple) {
   
        // 获取元组对象
        mp_obj_tuple_t *a_tuple = MP_OBJ_TO_PTR(a);
        mp_obj_tuple_t *b_tuple = MP_OBJ_TO_PTR(b);
        // 如果元组长度不同,则不相等
        if (a_tuple->len != b_tuple->len) {
   
            return false;
        }
        // 比较元组中的每个元素
        for (size_t i = 0; i < a_tuple->len; ++i) {
   
            if (!strictly_equal(a_tuple->items[i], b_tuple->items[i])) {
   
                return false;
            }
        }
        // 所有元素都相等,元组相等
        return true;
    } else {
   
        // 使用标准的对象比较函数进行比较
        return mp_obj_equal(a, b);
    }
}

// 函数:mp_emit_common_use_const_obj,用于查找或添加常量对象
size_t mp_emit_common_use_const_obj(mp_emit_common_t *emit, mp_obj_t const_obj) {
   
    // 遍历常量对象列表
    for (size_t i = 0; i < emit->const_obj_list.len; ++i) {
   
        // 如果找到相同的对象,则返回其索引
        if (strictly_equal(emit->const_obj_list.items[i], const_obj)) {
   
            return i;
        }
    }
    // 将常量对象添加到列表末尾
    mp_obj_list_append(MP_OBJ_FROM_PTR(&emit->const_obj_list), const_obj);
    // 返回新添加对象的索引
    return emit->const_obj_list.len - 1;
}

// 函数:mp_emit_common_get_id_for_modification,用于获取或添加修改标识符信息
id_info_t *mp_emit_common_get_id_for_modification(scope_t *scope, qstr qst) {
   
    // 在作用域中查找或添加标识符
    id_info_t *id = scope_find_or_add_id(scope, qst, ID_INFO_KIND_GLOBAL_IMPLICIT);
    // 如果标识符是隐式全局的
    if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT) {
   
        // 如果作用域是函数类似的,则将其绑定为局部变量
        if (SCOPE_IS_FUNC_LIKE(scope->kind)) {
   
            id->kind = ID_INFO_KIND_LOCAL;
        } else {
   
            // 标记为已赋值,防止其被闭包捕获
            id->kind = ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED;
        }
    }
    // 返回标识符信息
    return id;
}

// 函数:mp_emit_common_id_op,用于根据标识符信息生成相应的代码
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) {
   
    // 确保所有标识符都在当前作用域中定义
    // 在作用域中查找标识符
    id_info_t *id = scope_find(scope, qst);
    assert(id != NULL);

    // 根据标识符的类型调用相应的代码生成函数
    if (id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT || id->kind == ID_INFO_KIND_GLOBAL_IMPLICIT_ASSIGNED) {
   
        // 生成全局变量的代码
        emit_method_table->global(emit, qst, MP_EMIT_IDOP_GLOBAL_NAME);
    } else if (id->kind == ID_INFO_KIND_GLOBAL_EXPLICIT) {
   
    
  • 17
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

openwin_top

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值