Skip to main content

Reserved keywords

FunC reserves the following symbols and words. These cannot be used as identifiers.

Symbols

+   -*/ %?:, ;()[ ]{}= _<>& |^~== !=<=>=<=> <<>>~>>^>> ~/^/~%^% /%+=-=*= /=~/=^/=%= ~%=^%=<<=>>= ~>>=^>>=&=|= ^=->

Words

returnvarrepeatdo whileuntiltrycatch ififnotthenelse elseifelseifnotintcell slicebuilderconttuple typeforallexternglobal asmimpureinlineinline_ref auto_applymethod_idoperatorinfix infixlinfixrconst#pragma #include

Built-ins

This section covers extra language constructs that are not part of the core but are still important for functionality. Although they could be implemented in stdlib.fc, keeping them as built-in features allows the FunC optimizer to work more efficiently. In addition, FunC does not allow the built-in names in this section to be used as identifiers. However, there is an exception: built-ins with non-symbolic names can be used as identifiers for local variables.

Built-ins with symbolic names

_+__-_-__*_ _/__~/__^/__%_ _~%__^%__/%__<<_ _>>__~>>__^>>__&_ _|__^_~_^_+=_ ^_-=_^_*=_^_/=_^_~/=_ ^_^/=_^_%=_^_~%=_^_^%=_ ^_<<=_^_>>=_^_~>>=_^_^>>=_ ^_&=_^_|=_^_^=__==_ _!=__<__>__<=_ _>=__<=>_ Each one of the above names is a function wrapping the corresponding operator. For example, _+_ can be understood as wrapping the + operator:
These functions are useful when operators need to be passed as arguments to functions, or assigned to variables. For example, in the following snippet, function apply receives as argument a function f of type (int, int) -> int and applies it on the arguments 2 and 3:
Then, it is possible to invoke apply by passing _+_:
Attempting to pass the operator + directly does not compile:

Built-ins with non-symbolic names

divmod~divmodmoddiv~moddiv muldivmuldivrmuldivcmuldivmod truefalsenilNil null?throwthrow_ifthrow_unless throw_argthrow_arg_ifthrow_arg_unlessload_int load_uintpreload_intpreload_uintstore_int store_uint~store_int~store_uintload_bits preload_bitsint_atcell_atslice_at tuple_atattouch~touch touch2~touch2~dump~strdump run_method0run_method1run_method2run_method3

divmod

divmod takes two integers as input and returns the quotient and remainder of their division dividend / divisor.

~divmod

Same as divmod, but allows using modifying notation. Example:

moddiv

moddiv takes two integers as input and returns the remainder and quotient of their division dividend / divisor.

~moddiv

Same as moddiv, but allows using modifying notation. Example:

muldiv

muldiv performs a multiply-then-divide operation (factor1 * factor2) / divisor, where / is the division operator. It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.

muldivr

muldivr performs a multiply-then-divide operation (factor1 * factor2) ~/ divisor, where ~/ is the rounding division operator. It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.

muldivc

muldivc performs a multiply-then-divide operation (factor1 * factor2) ^/ divisor, where ^/ is the ceiling division operator. It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.

muldivmod

muldivmod performs a multiply-then-divide operation (factor1 * factor2) / divisor, where / is the division operator, and returns the quotient and remainder of such division. It uses a 513-bit intermediate result to prevent overflow if the final result fits within 257 bits.

true

true is an alias for -1.

false

false is an alias for 0.

nil

nil is an alias for the null value.

Nil

Nil is an alias for the empty tuple [].

null?

null? checks if the given argument is null. Returns 0 if the argument is not null, and -1 otherwise. For more info, see null values.

throw

Triggers an exception, which interrupts the execution flow. throw takes only one argument, the error code. See TVM error codes for details about error codes.

throw_if

Triggers an exception only if the provided condition is true, i.e., if the condition is -1. It receives two arguments: the error code, which defines the exception type, and the condition. See TVM error codes for details about error codes.

throw_unless

Triggers an exception only if the provided condition is false, i.e., if the condition is 0. It receives two arguments: the error code, which defines the exception type, and the condition. See TVM error codes for details about error codes.

throw_arg

Triggers an exception, which interrupts the execution flow. The first argument can be of any type, and it is used to pass extra information about the error. This extra information can be processed in try..catch statements. Refer to the try..catch statement page for an example on how to use the first argument. The second argument is the error code. See TVM error codes for details about error codes.

throw_arg_if

Triggers an exception only if the provided condition is true, i.e., if the condition is -1. Similarly to throw_arg, the first argument can be of any type, and it is used to pass extra information about the error. This extra information can be processed in try..catch statements, in the same way as with throw_arg. The second argument is the error code. See TVM error codes for details about error codes. The third argument is the condition to check.

throw_arg_unless

Triggers an exception only if the provided condition is false, i.e., if the condition is 0. Similarly to throw_arg, the first argument can be of any type, and it is used to pass extra information about the error. This extra information can be processed in try..catch statements, in the same way as with throw_arg. The second argument is the error code. See TVM error codes for details about error codes. The third argument is the condition to check.

load_int

Reads a signed len-bit integer from slice s. Returns the modified slice and the obtained integer.

load_uint

Reads an unsigned len-bit integer from slice s. Returns the modified slice and the obtained unsigned integer.

preload_int

Reads a signed len-bit integer from slice s. Returns the obtained integer. This method does not modify slice s.

preload_uint

Reads an unsigned len-bit integer from slice s. Returns the obtained unsigned integer. This method does not modify slice s.

store_int

Stores a signed len-bit integer x in builder b. Returns the modified builder.

store_uint

Stores an unsigned len-bit integer x in builder b. Returns the modified builder.

~store_int

Same as store_int, but adapted to use modifying notation.

~store_uint

Same as store_uint, but adapted to use modifying notation.

load_bits

Loads the first len bits from slice s. It returns the modified slice and a slice containing the loaded bits.

preload_bits

Loads the first len bits from slice s. It returns a slice containing the loaded bits. This method does not modify slice s.

int_at

Returns the element at index index in tuple t, casted as an integer.

cell_at

Returns the element at index index in tuple t, casted as a cell.

slice_at

Returns the element at index index in tuple t, casted as a slice.

tuple_at

Returns the element at index index in tuple t, casted as a tuple.

at

Returns the element at index index in tuple t. The returned element can be of any type.

touch

Moves v to the top of the stack. It returns the argument v.

~touch

~touch is identical to touch, but adapted to use modifying notation.

touch2

Moves the components of the tensor t to the top of the stack; first component with type X and then component with type Y. It returns the argument tensor t.

~touch2

~touch2 is identical to touch2, but adapted to use modifying notation.

~dump

Outputs value value to the debug log. It returns the argument value and the unit value (). Modifying notation can be used on this function. In case value is a slice containing ASCII characters, it is preferable to use ~strdump if the intention is to print the ASCII string in the debug log. Otherwise, ~dump will print the slice’s contents as bits.

~strdump

Outputs to the debug log the ASCII string encoded in slice s. It returns the argument s and the unit value (). Modifying notation can be used on this function. If the argument s is not a slice containing ASCII characters, the debug log will show an error.

run_method0

Executes the 0 argument function with ID method_id. The function with ID method_id must have a signature of the form:
which receives 0 arguments and returns nothing. The run_method0 is useful for dynamically executing methods at run-time. For example, receiving the method ID to execute in the incoming internal message.

run_method1

Executes the 1 argument function with ID method_id, and passes arg1 as argument to the function. The function with ID method_id must have a signature of the form:
which receives 1 argument and returns nothing. Type T must coincide with the type of the argument arg1 provided in run_method1. For example, under the assumption that 1234 is the ID of function test, invoking:
requires that test has the signature:
As with run_method0, function run_method1 is useful for dynamically executing 1 argument methods at run-time.

run_method2

Executes the 2 argument function with ID method_id. The function with ID method_id must have a signature of the form:
which receives 2 arguments and returns nothing. Type T1 must coincide with the type of the argument arg1 provided in run_method2, and similarly for type T2. The same observations and warnings apply as with run_method1.

run_method3

Executes the 3 argument function with ID method_id. The function with ID method_id must have a signature of the form:
which receives 3 arguments and returns nothing. Type T1 must coincide with the type of the argument arg1 provided in run_method3, and similarly for types T2 and T3. The same observations and warnings apply as with run_method1.