尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Flipper Zero 上的 Brainfuck 解释器与编辑器:FlipperZeroBrainfuck 源码解析与实战指南

Flipper Zero 上的 Brainfuck 解释器与编辑器:FlipperZeroBrainfuck 源码解析与实战指南 Flipper Zero 上的 Brainfuck 解释器与编辑器FlipperZeroBrainfuck 源码解析与实战指南【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/FlipperFlipperZeroBrainfuck 是一个运行在 Flipper Zero 上的 Brainfuck 语言解释器与代码编辑器它允许用户在设备上直接编写、保存并运行.b格式的 Brainfuck 脚本支持文本输入,指令与文本输出.指令。本文将以 关联文档 为主体结合本仓库中的完整源码讲解该应用的场景架构、虚拟按键编辑器布局、解释器底层实现、缓冲区边界与已知限制帮助你理解其工作原理并快速上手使用。项目定位与源码布局FlipperZeroBrainfuck 位于本仓库 Applications/Official/source-OLDER/xMasterX/brainfuck 目录下属于旧版官方应用源码归档source-OLDER中的外部应用EXTERNAL即 FAP 插件。源码由一个非常精简的 C 工程构成brainfuck.c应用入口与资源分配/释放brainfuck_i.h核心数据结构与全部缓冲区常量定义worker.cBrainfuck 解释器本体8 条指令的执行逻辑views/bf_dev_env.c设备上的代码编辑环境虚拟键盘视图scenes/基于场景管理器Scene Manager的 6 个界面场景application.famFAP 应用构建元数据。值得注意的细节来自 brainfuck.c 顶部的注释作者坦言该应用是复制 picopass 应用骨架、掏空内部后用其躯壳搭建出来的这解释了为什么代码中出现了brainfuck_alloc()、brainfuck_free()等与经典 Flipper 应用模板一致的资源管理模式。应用元数据与构建方式application.fam 完整声明了应用的构建信息字段值说明appidBrainfuck应用唯一标识apptypeFlipperAppType.EXTERNAL外部插件编译为 .fap 文件entry_pointbrainfuck_app入口函数见 brainfuck.crequiresstorage,gui依赖 SD 卡存储与 GUI 子系统stack_size8 * 10248 KB任务栈大小fap_iconbfico.png应用图标fap_categoryMisc_Extra在应用菜单中的分类fap_icon_assetsicons附带图标资源目录由于它是 EXTERNAL 类型应用你可以像构建其他 FAP 插件一样使用 Flipper 固件的 fbt/ufbt 构建链将其编译为.fap插件文件再拷贝到 Flipper Zero 的 SD 卡上运行。应用启动与整体架构入口函数brainfuck_app()的流程brainfuck.c如下调用brainfuck_alloc()分配BFApp结构体初始化 ViewDispatcher 与 SceneManager注册全部视图Submenu、Popup、TextInput、TextBox、开发环境视图打开RECORD_GUI与RECORD_NOTIFICATION系统服务记录打开RECORD_STORAGE调用storage_simply_mkdir(storage, /ext/brainfuck)确保/ext/brainfuck目录存在——这是所有脚本文件的存放目录切换到起始场景并进入view_dispatcher_run()主循环。BFApp结构体brainfuck_i.h中与解释执行直接相关的成员是int dataSize; char dataBuffer[BF_INST_BUFFER_SIZE]; // 指令缓冲区2048 字节 char inputBuffer[BF_INPUT_BUFFER_SIZE]; // 输入缓冲区64 字节应用的全部界面由 brainfuck_scene_config.h 声明的 6 个场景驱动其跳转关系与职责如下场景文件名职责Startbrainfuck_scene_start.c主菜单New / Open / AboutFileCreatebrainfuck_scene_file_create.c输入新脚本名并创建文件FileSelectbrainfuck_scene_file_select.c通过系统文件浏览器选择.b脚本DevEnvbrainfuck_scene_dev.c开发环境编辑、输入、运行、保存ExecEnvbrainfuck_scene_exec.c执行结果展示TextBox 视图SetInputbrainfuck_scene_set_input.c编辑,指令的输入缓冲区文件系统约定/ext/brainfuck 与 .b 脚本脚本统一存放在 SD 卡/ext/brainfuck目录下扩展名为.b新建脚本brainfuck_scene_file_create.c进入 TextInput 场景输入脚本名后拼接为/ext/brainfuck/name.b先删除旧文件再以FSAM_WRITE FSOM_CREATE_ALWAYS写入一个空字节随后直接进入开发环境打开脚本brainfuck_scene_file_select.c使用系统DialogsApp文件浏览器browser_options限定扩展名.b、基础路径为/ext/brainfuck且不隐藏扩展名加载与清洗views/bf_dev_env.c进入开发环境时清空指令缓冲区、以只读方式打开文件读入缓冲区然后用strchr(bfChars, ...)把所有非 Brainfuck 指令字符换行、注释等统一替换为下划线_再定位缓冲区末尾作为编辑起点。这意味着注释与换行会被静默清洗掉加载后缓冲区中只剩 8 个有效指令字符与下划线占位。开发环境Dev Environment12 键虚拟键盘开发环境是 views/bf_dev_env.c 实现的自绘视图屏幕顶部用 3 行 × 24 字符的文本框显示当前代码超出 72 字符时只显示末尾 72 字符即dbOffset偏移逻辑下方是两组虚拟按键第一排8 个指令按键屏幕坐标 x 1, 17, 33, 49, 65, 81, 97, 113y 36按键序号字符含义0当前单元格加 11-当前单元格减 12数据指针左移3数据指针右移4[循环开始5]循环结束6.输出当前单元格字节7,从输入缓冲区读一个字节第二排4 个功能按键使用 icons 目录下的图标绘制y 52按键序号功能触发行为8Backspace删除缓冲区最后一个字符并置 0bf_dev_env.c9Input切换到 SetInput 场景编辑输入缓冲区10Run启动RUNNING...倒计时后执行解释器11Save删除旧文件并以FSAM_WRITE FSOM_CREATE_ALWAYS写回当前缓冲区按键间的上下左右跳转由buttonMappings[12]表驱动bf_dev_env.c结构为{up, down, left, right}。从源码可归纳出导航规律4 个功能键的上下方向分别映射到其正上方的 2 个指令键如 Backspace 上下对应/-Input 上下对应/Run 上下对应[/]Save 上下对应./,左右方向则在同一排内循环移动。所有指令按键在dataSize BF_INST_BUFFER_SIZE时向dataBuffer尾部追加对应字符实现连续输入。解释器核心实现worker.c 逐指令拆解解释器主体在 worker.c采用全局状态机运行状态status三态0空闲、1运行中、2失败worker.c。数据模型如下指令流inst指向app-dataBufferinstCount为指令数instPtr为当前指令指针数据栈bfStack为uint8_t数组一字节单元格符合标准 Brainfuck 语义初始容量BF_STACK_INITIAL_SIZE 128字节stackPtr为当前指针输出缓冲区wOutput容量BF_OUTPUT_SIZE 512字节输入缓冲区wInput指向app-inputBuffer最多 64 字节。主循环beginWorker()worker.c从instPtr 0开始以指令流中的0x00作为程序结束标记对 8 个有效字符执行 switch 分派其余字符如下划线直接忽略。每执行一条指令instPtr并做一次指针合法性校验。各指令的执行逻辑与边界行为指令函数行为与边界rShift()stackPtr越界检查失败置status2当指针超过当前容量时以realloc按BF_STACK_STEP_SIZE 32字节扩容并清零新区域同时更新stackSizeReal记录实际用到的最大深度lShift()stackPtr--stackPtr 0时置status2/-inc()/dec()当前单元格自增/自减uint8_t天然支持 0xFF→0x00 的循环回绕.print()将当前单元格字节写入输出缓冲区wOutputPtr BF_OUTPUT_SIZE - 1时回绕到 0输出环形覆盖,input()从输入缓冲区取字节写入当前单元格遇到0x00或指针到达 64 时输入指针回绕到 0worker.c[loop()当前单元格为 0 时向后跳过到匹配的]不为 0 则继续顺序执行进入循环体]endLoop()当前单元格不为 0 时向前回跳到匹配的[为 0 则跳出循环循环匹配worker.c通过计数嵌套括号实现loop()向后扫描时遇[计数加 1、遇]计数减 1直到计数归零即为匹配位置endLoop()同理反向扫描。循环跳转与指令指针越界都会触发status 2的失败终止。所有操作统一经过runOpCount计数可通过getOpCount()获取执行步数且整个解释过程是同步执行的——从 bf_dev_env.c 的绘制回调可以看到按 Run 后先绘制 3 帧RUNNING...随后直接调用initWorker()beginWorker()把workerGetOutput()写入 TextBox 并切换到执行结果场景。正因为同步阻塞式执行长时间运行的程序会卡住整个 UI——这正是 README 强调程序必须终止的根本原因。关键常量汇总brainfuck_i.h 定义了全部关键尺寸是理解该应用能力边界的基础宏值含义BF_INST_BUFFER_SIZE2048指令缓冲区容量单脚本最大字节数BF_OUTPUT_SIZE512输出缓冲区容量超出后循环覆盖BF_STACK_INITIAL_SIZE128数据栈初始容量字节BF_STACK_STEP_SIZE32数据栈每次扩容步长BF_INPUT_BUFFER_SIZE64,指令的输入缓冲区容量已知限制与使用注意事项原文档明确列出了该应用的三大限制结合源码可进一步确认其成因程序必须终止否则冻结在 RUNNING由于解释器在 UI 绘制回调中同步执行见上文一个死循环程序会无限占用主循环界面停留在RUNNING...状态且无法响应按键。README 明确警告 Major limitation is that programs MUST terminate, or it will freeze at RUNNING。对死循环无防护loop()/endLoop()没有任何循环次数上限或超时机制[/]不匹配的语法错误同样不会在运行前被检测。对语法错误无防护虽然 views/bf_dev_env.c 会在加载文件时把非法字符替换为下划线但括号配对、指针越界移出栈底、扩容失败等逻辑性错误只有在运行期才会通过status 2暴露——越界会直接失败退出而括号不匹配或死循环则可能造成冻结。实操建议编写脚本时保持括号成对、避免无界循环若程序需要较长运行时间请先在 PC 端模拟器验证逻辑后再上机。实战在设备上编写并运行第一个脚本下面以一个在标准 Brainfuck 中广泛使用的经典示例Hello World!106 字节远小于 2048 字节的指令缓冲区上限演示完整流程[[-]-[]-].---.....-...------.--------...操作步骤启动应用在主菜单选择New输入脚本名如hello应用会创建/ext/brainfuck/hello.b并进入开发环境在虚拟键盘上依次录入上述指令先录入、、[、]等指令键完成代码输入期间可用 Backspace 删除误输入按Input键进入Edit input buffer界面为,指令准备输入数据本例无输入需求可留空按Run键屏幕短暂显示RUNNING...后切换到执行结果视图.,等指令的输出会在 TextBox 中显示 Hello World!如需保存代码按Save键屏幕会显示SAVED提示代码写入/ext/brainfuck/hello.b。一个更简单的可验证示例是输出大写字母HASCII 72 9 × 8利用嵌套循环将第二个单元格累加到 72 后输出[-].其执行轨迹为先让单元格 0 从 0 累加到 9进入循环后每轮把单元格 1 加 8 并把单元格 0 减 1循环 9 轮后单元格 1 72指针右移后用.输出字符H。你可以在 worker.c 中逐步对照验证这一过程。相关资源索引应用自述文档README.md入口与资源管理brainfuck.c常量与数据结构定义brainfuck_i.h解释器实现worker.c编辑器视图实现views/bf_dev_env.c场景注册表scenes/brainfuck_scene_config.h构建元数据application.fam【免费下载链接】FlipperPlayground (and dump) of stuff I make or modify for the Flipper Zero项目地址: https://gitcode.com/GitHub_Trending/fl/Flipper创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表