尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
Forth 语言快速入门:基于 learnxinyminutes-docs 的栈式编程实战指南
文档教程【免费下载链接】learnxinyminutes-docsCode documentation written as code! How novel and totally my idea!项目地址https://gitcode.com/gh_mirrors/le/learnxinyminutes-docs点击查看免费下载Forth 是由 Charles H. Moore 在 20 世纪 70 年代设计的命令式、基于栈stack-based的编程语言与编程环境曾用于 Open Firmware 等固件项目也被 NASA 采用。本指南以 learnxinyminutes-docs 仓库中的 es/forth.md西班牙语翻译版为骨架对照英文原版 forth.md用可复制、可运行的 Gforth 示例带你从压栈、弹栈起步逐步掌握算术、栈操作、单词定义、条件、循环、内存与数组、返回栈及浮点运算最终能够独立阅读和编写简单的 Forth 程序。背景与文档定位本仓库README.md以以代码形式书写的文档为理念为每种语言提供一份带注释、可直接运行的教学代码。Forth 指南正是这一风格的典型代表整篇教程几乎全部由可执行的注释代码构成读者可以在 Gforth 交互式环境中逐行敲入验证。西班牙语版es/forth.md由 Horse M.D. 编写、Zach Larsen 翻译本文即以它为绝对主体英文原版forth.md用于校准行为细节与术语所有文档都带有 YAML frontmatter如contributors、translators、filename等元数据字段仓库通过 lint/frontmatter.py 对文档头部进行格式与键值校验保证教学文档的规范性。需要说明的是本指南聚焦Gforth这一主流的 Forth 实现但文中绝大部分内容在标准 Forth 系统如 ANS Forth 兼容实现中同样适用。运行环境进入 Gforth 交互式会话Gforth 是 GNU 项目下的 Forth 实现安装后在终端输入gforth即可进入交互式解释器REPL。每成功执行一条语句解释器都会回显ok提示符教程中的注释\ ok正是模拟了这一交互输出。在会话中常用的环境指令包括\ 加载一个 Forth 源文件 \ s archivodeforth.fs included \ 列出字典中所有已定义的单词输出量很大 \ words \ 清空屏幕 page \ 退出 Gforth bye注释语法Forth 支持两种注释写法\ 这是行注释反斜杠之后到行尾的内容都会被忽略 ( 这也是注释但通常只在定义单词时用来书写栈效应说明 )核心模型参数栈数据栈Forth 的全部编程活动几乎都围绕参数栈通常简称为栈展开。栈是后进先出LIFO的数据结构数值从左到右依次压入栈顶单词则从栈上取数、运算、再把结果压回栈。5 2 3 56 76 23 65 \ ok这一行把 6 个数字依次压栈栈底在左、栈顶在右。用.sshow stack显示栈可以查看当前栈的全部内容.s \ 7 5 2 3 56 76 23 65 ok尖括号中的7表示栈上共有 7 个元素。要点是在 Forth 中一切都是单词word或数字number——单词是已命名的可执行例程数字则是直接压栈的字面量。.读作 dot把栈顶元素弹出并打印5 4 \ ok . \ 9 ok.s与.的组合是调试 Forth 程序的常用手段先.s观察栈再.消费栈顶。基础算术算术运算事实上绝大多数需要数据的单词都是通过操作栈上的数据完成的。加、减、乘、除、取模对应 - * / mod6 7 * . \ 42 ok 1360 23 - . \ 1337 ok 12 12 / . \ 1 ok 13 2 mod . \ 1 ok注意13 2 mod的结果是1——这是整数除法求余。此外还有符号与极值运算99 negate . \ -99 ok -99 abs . \ 99 ok 52 23 max . \ 52 ok 52 23 min . \ 23 oknegate取栈顶元素的相反数abs取绝对值max/min取两个数中的较大者 / 较小者。栈操作基础dup、swap、rot、drop、nip处理栈时下面五个单词是最高频的基础工具3 dup - \ dup 复制栈顶3 - 3 2 5 swap / \ swap 交换前两个元素5 / 2 6 4 5 rot .s \ rot 把第三个元素旋转到栈顶4 5 6 4 0 drop 2 / \ drop 丢弃栈顶不打印4 / 2 1 2 3 nip .s \ nip 丢弃第二个元素类似 drop1 3逐个拆解dup复制栈顶元素原栈顶成为倒数第二、副本压栈3 dup -等价于3 3 -swap交换栈顶与第二个元素2 5 swap /变成5 2 /rot把第三个元素旋转到栈顶6 4 5 rot后栈为4 5 6drop直接丢弃栈顶元素而不打印4 0 drop后栈只剩4再压入2做除法得2nip丢弃第二个元素1 2 3 nip后栈为1 3注意与drop的方向相反它保顶弃二。进阶栈操作tuck、over、roll、pick处理更复杂的栈布局时还有四个进阶单词。讨论栈索引时索引从 0 开始0 表示栈顶1 2 3 4 tuck \ tuck 复制栈顶并插入到第二个槽位之下1 2 4 3 4 1 2 3 4 over \ over 复制第二个元素到栈顶1 2 3 4 3 1 2 3 4 2 roll \ roll 把指定位置的元素*移动*到栈顶1 3 4 2 1 2 3 4 2 pick \ pick 把指定位置的元素*复制*到栈顶1 2 3 4 2tuck栈1 2 3 4复制栈顶4并插到第二个槽位之下结果1 2 4 3 4over复制第二个元素3压到栈顶结果1 2 3 4 3n roll把索引n处的元素移动到栈顶其余元素依次下沉2 roll把索引 2 处的3移到栈顶得1 3 4 2n pick把索引n处的元素复制一份压到栈顶2 pick得1 2 3 4 2。roll与pick的唯一区别是前者移动原位置被清空后者复制原位置保留。定义新单词:与;Forth 的函数叫单词。:使 Forth 进入编译模式直到遇到;结束定义: cuadrado ( n -- n ) dup * ; \ ok 5 cuadrado . \ 25 okcuadrado是西班牙语平方——定义它接收一个数n用dup *复制自身再相乘返回n²括号中的( n -- n )是栈效应注释--左侧是输入栈右侧是输出栈约定俗成地标注了该单词对栈的净影响两个n分别指入参和返回值便于阅读与文档化定义完成后5 cuadrado就像内建单词一样被调用输出25。用see可以反汇编查看某个单词的内部结构see cuadrado \ : cuadrado dup * ; ok条件与布尔逻辑Forth 的布尔约定-1表示真0表示假任何非零值也通常被视为真。比较运算符会把结果以-1或0的形式压栈42 42 \ -1 ok 12 53 \ 0 okif是只能在编译期使用的单词compile-only典型结构为if 要做的事 then 程序其余部分: ?64 ( n -- n ) dup 64 if . ¡Más que 64! then ; \ ok 100 ?64 \ ¡Más que 64! okdup 64 复制入参并与 64 比较产生-1/0标志. ...输出后跟字符串. 之间无空格if ... then包围真分支。带else的完整分支: ?64 ( n -- n ) dup 64 if . ¡Más que 64! else . ¡Menos que 64! then ; 100 ?64 \ ¡Más que 64! ok 20 ?64 \ ¡Menos que 64! ok循环有限循环do ... loopdo同样是编译期单词它从栈上取两个数结束值不含与起始值含即区间[start, end): miloop ( -- ) 5 0 do cr . ¡Hola! loop ; \ ok miloop \ ¡Hola! \ ¡Hola! \ ¡Hola! \ ¡Hola! \ ¡Hola! ok5 0 do从 0 迭代到 4共 5 次每次cr换行并输出¡Hola!。循环体内用i取得当前索引值: uno-a-12 ( -- ) 12 0 do i . loop ; \ ok uno-a-12 \ 0 1 2 3 4 5 6 7 8 9 10 11 ok注意do的上界是排除的12 0 do输出 0 到 11。英文原版 forth.md 还特别提醒若do的起止值恰好相等会形成无限循环直到算术下溢因此遇到起止相同也要跳过循环的需求应使用?do。条件循环?do?do与do类似但若起始值与结束值相等则直接跳过循环体: cuadrados ( n -- ) 0 ?do i cuadrado . loop ; \ ok 10 cuadrados \ 0 1 4 9 16 25 36 49 64 81 ok这里循环体把索引i的平方逐个打印得到前 10 个平方数0、1、4、9、16、25、36、49、64、81。自定义步长looploop允许在每次迭代末尾加上一个任意增量含负数实现步进: treces ( n n -- ) ?do i . 3 loop ; \ ok 15 0 treces \ 0 3 6 9 12 ok15 0 treces从 0 开始、每步 3、小于 15 时继续输出 0、3、6、9、12。不定循环begin ... until当循环次数无法预知时使用begin 要做的事 标志 untilbegin标记循环起点until弹出标志标志为真非零时退出循环: death ( -- ) begin . ¿Ya hemos llegado? 0 until ; \ ok这里标志恒为0假因此是一个永真循环——正如西班牙语单词名death死亡暗示的那样它会一直输出¿Ya hemos llegado?。变量、常量与内存variable声明一个变量它会在字典中创建名字并分配一个 cell一个地址单元的内存variable edad \ ok用!store存储把值写入变量地址用fetch读取把变量地址处的值压栈用?一步完成读取并打印21 edad ! \ ok edad . \ 21 ok edad ? \ 21 ok与?的区别在于只取值压栈后续可继续参与运算?则是与.的组合直接输出。常量constant与变量类似但无需关心内存地址——它在编译期把名字直接绑定到数值上100 constant PUNTA-QUE-AQUA-HIERVA \ ok PUNTA-QUE-AQUA-HIERVA . \ 100 ok这里PUNTA-QUE-AQUA-HIERVA水的沸点对应英文原版的WATER-BOILING-POINT一经定义即代表 100压栈时不会消耗任何运行时内存访问。数组连续内存与索引创建数组与创建变量类似但需要分配更多内存。allot在变量之后追加分配指定字节数cells返回一个 cell 的字节数因此2 cells allot额外分配 2 个 cell加上变量自带的 1 个 cell共 3 个 cellvariable minumeros 2 cells allot \ okerase把指定区域清零参数顺序地址、字节数minumeros 3 cells erase \ ok或者用fill参数顺序地址、字节数、填充值填充minumeros 3 cells 0 fill更直接的方式是用create,comma在编译期把具体值依次写入连续内存——注意最后一个,必不可少create minumeros 64 , 9001 , 1337 , \ ok (¡el último , es importante!)create minumeros 64 , 9001 , 1337 ,等价于手工向每个索引写入64 minumeros 0 cells ! \ ok 9001 minumeros 1 cells ! \ ok 1337 minumeros 2 cells ! \ ok读取指定索引的值时用cells 计算地址偏移0 cells minumeros ? \ 64 ok 1 cells minumeros ? \ 9001 ok每次都写cells 很啰嗦因此文档封装了一个辅助单词把索引 × cell 大小 基地址的偏移计算收敛起来: de-arr ( n n -- n ) cells ; \ ok minumeros 2 de-arr ? \ 1337 ok它同样可用于写入20 minumeros 1 de-arr ! \ ok minumeros 1 de-arr ? \ 20 ok返回栈嵌套执行的指针仓库返回栈return stack用于在单词执行其他单词如循环时暂存指针与临时数据其读写与参数栈完全独立。循环中的i本质上就是读取返回栈顶i等价于rreturn-fetch: miloop ( -- ) 5 0 do r . loop ; \ ok除了读取还可以用rto-return把参数栈顶压入返回栈、用rfrom-return弹回参数栈5 6 4 r swap r .s \ 6 5 4 ok逐步分析栈5 6 4→r把4送进返回栈参数栈剩5 6→swap得6 5→r把4取回参数栈最终栈为6 5 4。重要约定由于 Forth 用返回栈保存单词的返回指针调用地址r必须始终与后续的r配对否则会破坏控制流、导致程序崩溃或行为异常。浮点运算大多数 Forth 实现倾向于回避浮点运算历史上常用于资源受限的嵌入式环境但 Gforth 提供完整的浮点支持。浮点字面量以e结尾相关单词通常以f前缀命名8.3e 0.8e f f. \ 9.1 okf浮点加法对应整数栈上的f.弹出浮点栈顶并打印。浮点数据使用独立的浮点栈因此存储到变量时要配套使用f!/fvariable miflotantevar \ ok 4.4e miflotantevar f! \ ok miflotantevar f f. \ 4.4 ok实用收尾命令最后是一些日常有用的系统级单词\ 输入不存在的单词会清空参数栈不过也有专门的清栈单词 clearstack \ 清空屏幕 page \ 列出字典中所有单词列表会非常长 \ words \ 退出 Gforth \ bye进一步学习本指南的完整可执行源码即是仓库中的 es/forth.md英文原版见 forth.md两者互为对照可逐行在 Gforth 中运行验证仓库根目录的 README.md 说明了该系列教程以带注释的可运行代码讲解语言的文档理念与贡献方式参见 CONTRIBUTING.md原文档Listo Para Más准备了解更多部分推荐了经典读物Starting Forth、Simple Forth与Thinking Forth——前者适合从零入门后两者分别侧重简洁实现与编程思想是深入理解 Forth 哲学最小化、词表驱动、栈机模型的进阶路径。至此你已经走完了从往栈上放数到定义单词、控制流程、操作内存、使用返回栈与浮点栈的完整闭环。下一步不妨把教程中的示例逐条敲进gforth再尝试用: ... ;组合出自己的第一个 Forth 单词。赞分享文档教程【免费下载链接】learnxinyminutes-docsCode documentation written as code! How novel and totally my idea!项目地址https://gitcode.com/gh_mirrors/le/learnxinyminutes-docs点击查看免费下载相关推荐Chart.js 线性渐变实战指南用 CanvasGradient 与 Scriptable Options 打造动态渐变折线图Chart.js 线性渐变实战指南用 CanvasGradient 与 Scriptable Options 打造动态渐变折线图 在 Chart.js 中颜文档教程Go 语言快速入门实战指南基于 learnxinyminutes-docs 的完整语法、并发与 Web 编程详解Go 语言快速入门实战指南基于 learnxinyminutes docs 的完整语法、并发与 Web 编程详解 GoGolang是一门为解决实际问题而生文档教程APL 快速入门符号化数组编程语法精讲基于 learnxinyminutes-docs 指南APL 快速入门符号化数组编程语法精讲基于 learnxinyminutes docs 指南 APL 是一门以符号为核心、以数组为原生数据结构的编程语言文档教程上一篇message-pusher灾备方案数据中心故障应对下一篇为什么选择ChartyJetpack Compose图表库性能对比与优势分析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED

相关推荐

QtScrcpy 投屏控制实操手册:USB 与无线连接、多设备批量操作、键鼠映射一次讲透

QtScrcpy 投屏控制实操手册:USB 与无线连接、多设备批量操作、键鼠映射一次讲透

QtScrcpy 投屏控制实操手册:USB 与无线连接、多设备批量操作、键鼠映射一次讲透 【免费下载链接】QtScrcpy Android real-time display control software 项目地址: https://gitcode.com/GitHub_Trending/qt/QtScrcpy QtScrcpy 是一款跨平台(Wind…

📅 2026/10/6 7:29:58
DLSS Swapper 完整指南:不等游戏更新,切换 DLSS、FSR、XeSS 版本

DLSS Swapper 完整指南:不等游戏更新,切换 DLSS、FSR、XeSS 版本

DLSS Swapper 完整指南:不等游戏更新,切换 DLSS、FSR、XeSS 版本 【免费下载链接】dlss-swapper 项目地址: https://gitcode.com/GitHub_Trending/dl/dlss-swapper 游戏的 DLSS 版本停在旧版,你却等不了正式更新?DLSS Swa…

📅 2026/10/6 7:24:58
FasterTransformer GPT-NeoX 推理指南:20B 模型部署、权重转换与多卡并行实践

FasterTransformer GPT-NeoX 推理指南:20B 模型部署、权重转换与多卡并行实践

推理引擎算子库大模型 【免费下载链接】FasterTransformer Transformer related optimization, including BERT, GPT 项目地址: https://gitcode.com/gh_mirrors/fa/FasterTransformer 点击查看 免费下载 导读 本文围绕 FasterTransformer 仓库中的 docs/gptneox_…

📅 2026/10/6 7:24:58
MORE NEWS

更多资讯

📰

GEMM 与 BLAS 全解:Tensor Core、CUDA、Transformer 的关系,各家 GPU 与框架的实现逻辑,以及投资机会

GEMM 与 BLAS 全解:Tensor Core、CUDA、Transformer 的关系,各家 GPU 与框架的实现逻辑,以及投资机会声明:本文作为笔者个人备忘的文章,不喜勿喷。本文由AI辅助生成,技术参数与市场信息整理自公开资料&…

📰

广州中小型企业如何做通勤班车

中小型广州企业做通勤班车,更现实的做法不是自购车辆,而是先算清需求,再用“固定线路加弹性运力”的组合向外采购服务,把车辆、司机、调度和应急交给专业运营方,自己只保留需求管理和成本审核两项职责。 判断标准可以用…

📰

2026上海企业员工班车租赁需要自有车辆吗

一、先把问题问准:自有车辆指什么 行政或采购在立项时问“要不要自己买车”,往往混着三件事:车辆产权归谁、车辆由谁调度、司机由谁管理。三者可以拆开组合,不必捆在一起。 三者全部收进来,就是重资产自营;…

📰

面试官:实现异步的 8 种方式,你知道几个?

一、为什么面试官总爱问异步异步编程几乎是每个后端开发绕不开的话题。无论是多线程并发、接口超时优化、批量任务处理,还是高并发场景下的性能提升,异步都在其中扮演核心角色。面试官问「实现异步的 8 种方式」,表面上考的是语法和 API 掌握…

📰

电源去耦网络设计与PI仿真E07

电源去耦网络设计与PI仿真E07 电源去耦网络设计与PI仿真:从理论到实战的全频段优化方案 核心要点: 去耦网络要做到全频段分层覆盖,低频靠大电容,中频靠10μF~47μF电容,高频靠0.1μF及以下小电容贴近芯片; 电容选型不能只看容量,ESR、ESL和自谐振频率才是决定滤波性…

📰

AI 助手只会回文字?一行命令让它学会「发自拍」——Clawra 上手与原理拆解

你有没有遇到过这种尴尬:在 Telegram 或者 Discord 上跟自己的 AI 助手聊天,随口来一句「你现在在干嘛?发张图看看」,然后它一本正经地回你——「抱歉,我没有实体,无法拍照」。 聊得再投缘,它也…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬