Fift 深入解析
Fift 是一种高级的基于栈的语言,用于本地操作cell和其他 TVM 原语,主要用于将 TVM 汇编代码转换为合约代码的cell包。
本节描述了与 TON 特有功能在非常低层级的交互。 需要对栈语言基础有深入理解。
简单算术
你可以使用 Fift 解释器作为计算器,以逆波兰表示法(reverse Polish notation)编写表达式。
6 17 17 * * 289 + .
2023 ok
标准输出
27 emit ."[30;1mgrey text" 27 emit ."[37m"
grey text ok
emit
从栈 顶取出数字,并将指定代码的 Unicode 字符打印到 stdout。
."..."
打印常量字符串。
定义函数(Fift words)
定义word的主要方式是将其效果括在大括号中,然后写 :
和word名称。
{ minmax drop } : min
{ minmax nip } : max
Fift.fif
不过,还有几个定义word的方法,不仅仅是 :
。它们的不同之处在于,用其中一些定义的word是active(在大括号内工作),而有些是prefix(不需要在它们之后有空格字符):
{ bl word 1 2 ' (create) } "::" 1 (create)
{ bl word 0 2 ' (create) } :: :
{ bl word 2 2 ' (create) } :: :_
{ bl word 3 2 ' (create) } :: ::_
{ bl word 0 (create) } : create
Fift.fif
条件执行
代码块(由大括号分隔)可以有条件或无条件地执行。
{ { ."true " } { ."false " } cond } : ?. 4 5 = ?. 4 5 < ?.
false true ok
{ ."hello " } execute ."world"
hello world ok
循环
// ( l c -- l') deletes first c elements from list l
{ ' safe-cdr swap times } : list-delete-first
GetOpt.fif
循环word times
接受两个参数 - 我们称它们为 cont
和 n
- 并执行 cont
n
次。
这里 list-delete-first
继承 safe-cdr
(从Lisp样式列表中删除head命令),将其放在 c
下面,然后 c
次从堆栈上的列表中删除head。
还有 while
和 until
循环word。
注释
{ 0 word drop 0 'nop } :: //
{ char " word 1 { swap { abort } if drop } } ::_ abort"
{ { bl word dup "" $= abort"comment extends after end of file" "*/" $= } until 0 'nop } :: /*
Fift.fif
注释在 Fift.fif
中定义。单行注释以 //
开始,一直到行尾;多行注释以 /*
开始,以 */
结束。
让我们理解它们为什么有效。
Fift 程序本质上是一系列word的序列,每个单词都以某种方式转换栈或定义新单词。Fift.fif
的第一行代码(上面所示)是新word //
的声明。注释必须在定义新word时也能工作,所以它们必须在嵌套环境中工作。这就是为什么它们被定义为active单词,通过 ::
实现。正在创建的单词的动作列在大括号中:
0
:零被推到栈上word
:此命令读取字符,直到达到栈顶的字符,并将读取的数据作为字符串推送。零是特殊情况:这里word
跳过前导空格,然后读取直到当前输入行的末尾。drop
:栈顶元素(注释数据)被丢弃。0
:再次将零推到栈上 - 结果的数量,因为word是用::
定义的。'nop
推送执行令牌在调用时什么也不做。这几乎等同于{ nop }
。