Fift

**Fift** is a stack-based programming language optimized for creating, debugging, and managing Telegram Open Network (TON) Blockchain smart contracts. The name is derived by analogy with the Forth language, which resembles it in its ideology.

## Purpose

Fift has been specifically designed to interact with the TON Virtual Machine (TON VM or TVM) and the TON Blockchain.

## Description

When Fift is invoked (usually by executing a binary file called fift), it interprets one or several source files indicated in the command line, or enters the interactive mode and interprets Fift commands read from the standard input. There is also a “script mode”, activated by command line switch -s, in which all command line arguments except the first one are passed to the Fift program by means of the variables $n and $#. In this way, Fift can be used both for interactive experimentation and debugging as well as for writing simple scripts.

All data manipulated by Fift is kept in a (LIFO - Last In, First Out) stack. Each stack entry is supplemented by a type tag, which unambiguously determines the type of the value kept in the corresponding stack entry. In addition to the data types shared with TVM (such as Integer, Cell, Slice, and Builder), Fift introduces some unique data types, such as Bytes (arbitrary byte sequences), String (UTF-8 strings), WordList, and WordDef (used by Fift to create new “words” and manipulate their definitions). In fact, Fift can be extended to manipulate arbitrary “objects” (represented by the generic type Object), provided they are derived from C++ class td::CntObject in the current implementation.

Fift source files and libraries are usually kept in text files with the suffix .fif. A search path for libraries and included files is passed to the Fift executable either in a -I command line argument or in the FIFTPATH environment variable. If neither is set, the default library search path /usr/lib/fift is used. On startup, the standard Fift library is read from the file Fift.fif before interpreting any other sources. It must be present in the library search path, otherwise Fift execution will fail.

A fundamental Fift data structure is its global dictionary, containing words or, more precisely, word definitions that correspond both to builtin primitives and functions and to user-defined functions. A word can be executed in Fift simply by typing its name (a UTF-8 string without space characters) in interactive mode. When Fift starts up, some words (primitives) are already defined (by some C++ code in the current implementation); other words are defined in the standard library Fift.fif. In addition, the user may extend the dictionary by defining new words or redefining old ones.

The Fift parser for input source files and for the standard input (in the interactive mode) is rather simple: the input is read line-by-line, then blank characters are skipped, and the longest prefix of the remaining line that is (the name of) a dictionary word is detected and removed from the input line. After that, the word thus found is executed, and the process repeats until the end of the line. When the input line is exhausted, a subsequent line is read from the current input file or the standard input.

In order to be detected, most words require a blank character or an end of-line immediately after them; this is reflected by appending a space to their names in the dictionary. Other words, called prefix words, do not require a blank character immediately after them. If no word is found, the string consisting of the first remaining characters of the input line until the next blank or end-of-line character is interpreted as an Integer and pushed into the stack. For instance, if we invoke Fift, type 2 3 + . (and press Enter), Fift first pushes an Integer constant equal to 2 into its stack, followed by another integer constant equal to 3. After that, the built-in primitive “+” is parsed and found in the dictionary; when invoked, it takes the two topmost elements from the stack and replaces them with their sum (5 in our example). Finally, “.” is a primitive that prints the decimal representation of the top-of-stack Integer, followed by a space. As a result, we observe “5 ok” printed by the Fift interpreter into the standard output. The string “ok” is printed by the interpreter whenever it finishes interpreting a line read from the standard input in the interactive mode.

## List of Fift stack value types

* **Integer** — a signed 257-bit integer. Usually denoted by x, y, or z in the stack notation (when the stack effect of a Fift word is described).
* **Cell** — a TVM cell, consisting of up to 1023 data bits and up to 4 references to other cells. Usually denoted by c or its variants, such as c’ or c’2.
* **Slice** — a partial view of a TVM cell, used for parsing data from Cells. Usually denoted by s.
* **Builder** — a partially built Cell, containing up to 1023 data bits and up to four references; can be used to create new Cells. Usually denoted by b.
* **String** — a (usually printable) UTF-8 string. Usually denoted by S.
* **Bytes** — an arbitrary sequence of 8-bit bytes, typically used to represent binary data. Usually denoted by B.
* **WordList** — a (partially created) list of word references, used for creating new Fift word definitions. Usually denoted by l.
* **WordDef** — an execution token, usually representing the definition of an existing Fift word. Usually denoted by e.
* **Object** — an arbitrary C++ object of any class derived from base class td::CntObject; may be used by Fift extensions to manipulate other data types and interface with other C++ libraries.

## Syntax

The code consists of words separated by spaces or line breaks (special case: some words do not require a separator after themselves).

Any word is a case-sensitive sequence of characters that corresponds to some definition (roughly, what the interpreter should do when it encounters that word). If there is no word definition, the interpreter tries to parse it as a number and put it on the stack.

Numbers are 257-bit integers, and fractions are formed from integers: the numerator and denominator of a rational fraction.

Words usually interact with the values at the top of the stack. A separate type of word-prefix-does not use the stack, but the characters that follow them from the source file. For example, this is how string literals are implemented — the "quote" character ( " ) is a prefix word that searches for the next (closing) quote, and places a string between them on the stack. Single-line / / and multi-line /\* comments behave in the same way.

Everything else (including control structures) is defined as words (either internal, such as arithmetic operations and the definition of new words; or defined in the "standard library" Fift.fif, which lies in the crypto/fift folder along the path in the source files or /usr/lib/fift).

The word bye terminates the Fift interpreter with a zero exit code. If a non-zero exit code is required (for instance, in Fift scripts), one can use word halt, which terminates Fift with the given exit code (passed as an Integer at the top of the stack). In contrast, quit does not quit the operating system, but rather exits to the top level of the Fift interpreter.

## Stack manipulation words

Stack manipulation words rearrange one or several values near the top of the stack, regardless of their types, and leave all deeper stack values intact. Some of the most often used stack manipulation words are listed below:

* **dup (x – x x)**, duplicates the top-of-stack entry. If the stack is empty, it throws an exception.
* **drop (x – )**, removes the top-of-stack entry. Note that Fift word names are case-sensitive, so one cannot enter DUP instead of dup.
* **swap (x y – y x)**, interchanges the two topmost stack entries.
* **rot (x y z – y z x)**, rotates the three topmost stack entries.
* **-rot (x y z – z x y)**, rotates the three topmost stack entries in the opposite direction. Equivalent to rot rot.
* **over (x y – x y x)**, creates a copy of the second stack entry from the top over the top-of-stack entry.
* **tuck (x y – y x y)**, equivalent to swap over.
* **nip (x y – y)**, removes the second stack entry from the top. Equivalent to swap drop.
* **2dup (x y – x y x y)**, equivalent to over over.
* **2drop (x y – )**, equivalent to drop drop.
* **2swap (a b c d – c d a b)**, interchanges the two topmost pairs of stack entries.
* **pick (xn . . . x0 n – xn . . . x0 xn)**, creates a copy of the n-th entry from the top of the stack, where n ≥ 0 is also passed in the stack. In particular, 0 pick is equivalent to dup, and 1 pick to over.
* **roll (xn . . . x0 n – xn−1 . . . x0 xn)**, rotates the top n stack entries, where n ≥ 0 is also passed in the stack. In particular, 1 roll is equivalent to swap, and 2 roll to rot.
* **-roll (xn . . . x0 n – x0 xn . . . x1)**, rotates the top n stack entries in the opposite direction, where n ≥ 0 is also passed in the stack. In particular, 1 -roll is equivalent to swap, and 2 -roll to -rot.
* **exch (xn . . . x0 n – x0 . . . xn)**, interchanges the top of the stack with the n-th stack entry from the top, where n ≥ 0 is also taken from the stack. In particular, 1 exch is equivalent to swap, and 2 exch to swap rot.
* **exch2 (. . . n m – . . . )**, interchanges the n-th stack entry from the top with the m-th stack entry from the top, where n ≥ 0, m ≥ 0 are taken from the stack.
* **?dup (x – x x or 0)**, duplicates an Integer x, but only if it is non-zero. Otherwise leaves it intact.
* **.s**, prints the contents of the entire stack, starting from the deepest elements.

For instance:

`1 2 3 4 .s rot .s`

Prints:

`1 2 3 4 ok 1 3 4 2 ok`

## Defining new words

Defining new Fift words can be done using “{”, “}”, and “:”.

For instance:

`{ dup * } : square`

Now: `5 square` outputs `"25 ok"`

## String manipulation

Fift works with the following words which can be used to manipulate strings:

* **"hstringi"** ( – S), pushes a String literal into the stack.
* **."hstringi"** ( – ), prints a constant string into the standard output.
* **type (S – )**, prints a string taken from the top of the stack.
* **cr ( – )**, outputs a carriage return (or a newline character).
* **emit (x – )**, prints a UTF-8 encoded character.
* **space ( – )**, prints one space.
* **$+ (S S0 – S.S0 )**, concatenates two strings.
* **$len (S – x)**, computes the byte length of a string.

## True and False

Fift does not have a separate value type for representing boolean values.

true - any Integer, false - 0

## Other features of Fift

* integer comparison
* string comparison
* named and unnamed variables
* tuples and arrays
* lists
* atoms
* blocks
* loops
* conditionals (including recursion)
* exceptions
* working with TVM cells
* TON-specific actions (Ed25519 cryptography, smart-contract address parser, etc.)

## Links

Fift: A Brief Introduction - Nikolay Durov, February 6, 2020

be:Fift
bg:Fift
de:Fift
el:Fift
fr:Fift
hi:फिफ्त (Fift)
hu:Fift
it:Fift
pt:Fift
ru:Fift
uk:Fift