MicroPython 是一种适用于微控制器和其他受限环境的 Python 编程语言的实现。它旨在提供与 Python 3 语言的紧密兼容,同时考虑到内存和计算资源的限制。MicroPython 库是这门语言的核心组成部分,提供了一系列的模块和函数,使得开发者能够在硬件上执行各种任务。
下面将通过系列文章,逐一解读microPython,以便让读者了解掌握microPython的整个核心逻辑.,以便读者可以透过这个Python的最小内核,掌握Python解析器的核心实现逻辑,学习世界上最优秀的源码设计之一.
microPython Python最小内核源码解析
NI-motion运动控制c语言示例代码解析
python编程示例系列 python编程示例系列二
python的Web神器Streamlit
这段代码是一个解析整数和浮点数的函数,它支持从字符串中解析出整数、浮点数以及复数。代码中包含了大量的注释,解释了每个步骤的目的和操作。这段代码是MicroPython的一部分,MicroPython是一个为嵌入式系统设计的Python解释器。
#include <stdbool.h> // 包含布尔类型的定义
#include <stdlib.h> // 包含标准库定义
// 引入MicroPython运行时环境的头文件
#include "py/runtime.h"
#include "py/parsenumbase.h"
#include "py/parsenum.h"
#include "py/smallint.h"
#if MICROPY_PY_BUILTINS_FLOAT
// 如果启用了浮点数支持,则包含数学库
#include <math.h>
#endif
/**
* 抛出异常,不返回。
* 如果传入的lexer非空,则说明是解析器调用的本函数,需要将异常类型从ValueError转换为SyntaxError,并添加追踪信息。
*/
static NORETURN void raise_exc(mp_obj_t exc, mp_lexer_t *lex) {
if (lex != NULL) {
((mp_obj_base_t *)MP_OBJ_TO_PTR(exc))->type = &mp_type_SyntaxError; // 将异常类型转换为语法错误
mp_obj_exception_add_traceback(exc, lex->source_name, lex->tok_line, MP_QSTRnull); // 添加追踪信息
}
nlr_raise(exc); // 抛出异常
}
/**
* 解析整数数值。
* @param str_ 要解析的字符串
* @param len 字符串的长度
* @param base 进制基数
* @param lex 词法分析器,可以为空
* @return 解析后的整数对象
*/
mp_obj_t mp_parse_num_integer(const char *restrict str_, size_t len, int base, mp_lexer_t *lex) {
const byte *restrict str = (const byte *)str_; // 将字符串转换为字节指针
const byte *restrict top = str + len; // 指向字符串的末尾
bool neg = false; // 标记是否有负号
mp_obj_t ret_val; // 解析结果
// 检查基数是否在有效范围内
if ((base != 0 && base < 2) || base > 36) {
mp_raise_ValueError(MP_ERROR_TEXT("int() arg 2 must be >= 2 and <= 36")); // 抛出值错误
}
// 跳过字符串前的空白字符
for (; str < top && unichar_isspace(*str); str++) {
}
// 解析可选的符号
if (str < top) {
if (*str == '+') {
str++;
} else if (*str == '-') {
str++;
neg = true; // 设置负号标志
}
}
// 解析可选的基数前缀
str += mp_parse_num_base((const char *)str, top - str, &base);
// 字符串应该是一个整数
mp_int_t int_val = 0; // 整数数值
const byte *restrict str_val_start = str; // 字符串数值的起始位置
for (; str < top; str++) {
// 获取下一个数字字符
mp_uint_t dig = *str;
if ('0' <= dig && dig <= '9') {
dig -= '0'; // 转换为0-9的数字
} else if (dig == '_') {
continue; // 跳过下划线字符
} else {
dig |= 0x20; // 将字符转换为小写
if ('a' <= dig && dig <= 'z') {
dig -= 'a' - 10; // 转换为10-35的数字
} else {
// 未知字符
break;
}
}
if (dig >= (mp_uint_t)base) {
break; // 数字超出基数范围
}
// 添加下一个数字并检查是否溢出
if (mp_small_int_mul_overflow(int_val, base)) {
goto overflow; // 溢出处理
}
int_val = int_val * base + dig;
if (!MP_SMALL_INT_FITS(int_val)) {
goto overflow; // 溢出处理
}
}
// 如果有负号,则取反数值
if (neg) {
int_val = -int_val;
}
// 创建小整数对象
ret_val = MP_OBJ_NEW_SMALL_INT(int_val);
have_ret_val:
// 检查是否解析了有效内容
if (str == str_val_start) {
goto value_error; // 未解析到有效内容,抛出值错误
}
// 跳过字符串后的空白字符
for (; str < top && unichar_isspace(*str); str++) {
}
// 检查是否到达字符串末尾
if (str != top) {
goto value_error; // 未到达末尾,抛出值错误
}
// 返回解析结果对象
return ret_val;
overflow:
// 整数溢出,使用长整型重新解析
{
const char *s2 = (const char *)str_val_start;
ret_val = mp_obj_new_int_from_str_len(&s2, top - str_val_start, neg, base); // 创建新的整数对象
str = (const byte *)s2; // 更新字符串指针
goto have_ret_val; // 跳转到解析结果
}
value_error:
// 抛出值错误
{
#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError,
MP_ERROR_TEXT("invalid syntax for integer")); // 创建值错误异常
raise_exc(exc, lex); // 抛出异常
#elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL
mp_obj_t exc = mp_obj_new_exception_msg_varg(&mp_type_ValueError,
MP_ERROR_TEXT("invalid syntax for integer with base %d"), base); // 创建带参数的值错误异常
raise_exc(exc, lex); // 抛出异常
#else
vstr_t vstr; // 可变字符串
mp_print_t print; // 打印结构体
vstr_init_print(&vstr, 50, &print); // 初始化可变字符串
mp_printf(&print, "invalid syntax for integer with base %d: ", base); // 打印错误信息
mp_str_print_quoted(&print, str_val_start, top - str_val_start, true); // 打印字符串
mp_obj_t exc = mp_obj_new_exception_arg1(&mp_type_ValueError,
mp_obj_new_str_from_utf8_vstr(&vstr)); // 创建异常对象
raise_exc(exc, lex); // 抛出异常
#endif
}
}
// 定义浮点数解析的状态枚举
enum {
REAL_IMAG_STATE_START = 0, // 初始状态
REAL_IMAG_STATE_HAVE_REAL = 1, // 已解析实部
REAL_IMAG_STATE_HAVE_IMAG = 2, // 已解析虚部
};
#if MICROPY_PY_BUILTINS_FLOAT
// 如果启用了浮点数支持,则定义相关常量和枚举
// DEC_VAL_MAX 用于在不溢出的情况下保留精度
// SMALL_NORMAL_VAL 是最小的正常浮点数的10的幂
// EXACT_POWER_OF_10 是可以在浮点数中精确表示的10的最大幂
#if MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_FLOAT
#define DEC_VAL_MAX 1e20F // 单精度浮点数的最大值
#define SMALL_NORMAL_VAL (1e-37F) // 单精度浮点数的最小正常值
#define SMALL_NORMAL_EXP (-37) // 单精度浮点数的最小指数
#define EXACT_POWER_OF_10 (9) // 单精度浮点数的精确10的幂的最大值
#elif MICROPY_FLOAT_IMPL == MICROPY_FLOAT_IMPL_DOUBLE
#define DEC_VAL_MAX 1e200 // 双精度浮点数的最大值
#define SMALL_NORMAL_VAL (1e-307) // 双精度浮点数的最小正常值
#define SMALL_NORMAL_EXP (-307) // 双精度浮点数的最小指数