Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Assembler

The Assembler parses TEAL programs line by line:

  • Opcodes that only take Stack arguments appear on a line by themselves.

  • Opcodes that take immediate arguments are followed by their arguments on the same line, separated by whitespace.

Directives

The # character at the beginning of a line identifies preprocessor directives.

Pragma

The first line of a TEAL program may contain a special version directive #pragma version X (where X is an unsigned integer), which directs the Assembler to generate bytecode targeting a certain AVM Version.

📎 EXAMPLE

For instance, #pragma version 2 produces bytecode targeting Version 2. By default, the Assembler targets Version 1.

It is syntactically invalid to have a #pragma definition after the first program opcode.

Subsequent lines may contain other pragma declarations (i.e., #pragma <some-specification>), pertaining to checks the Assembler should perform before agreeing to emit the program bytecode, specific optimizations, etc. Those declarations are OPTIONAL and cannot alter the semantics as described in this document.

⚙️ IMPLEMENTATION

Pragma directive reference implementation.

Macro

A #define M M_def directive (where M is an identifier and M_def is a valid TEAL expression) is used to define a macro. This is syntactically equivalent to replacing each occurence of the M identifier for the corresponding definition M_def.

⚙️ IMPLEMENTATION

Macro directive reference implementation.

Comments

// prefixes a line comment.

Separators

Both ; and /n may be used interchangeably to separate statements.

Constants and Pseudo-Ops

A few pseudo-opcodes simplify writing code. The following pseudo-opcodes:

  • addr
  • method
  • int
  • byte

Followed by a constant record the constant to a intcblock or bytecblock at the beginning of code and insert an intc or bytec reference where the instruction appears to load that value.

addr

addr parses an Algorand account address base32 and converts it to a regular bytes constant.

method

method is passed a method signature and takes the first four bytes of the hash to convert it to the standard method selector defined in ARC4.

byte

byte constants are:

byte base64 AAAA...
byte b64 AAAA...
byte base64(AAAA...)
byte b64(AAAA...)
byte base32 AAAA...
byte b32 AAAA...
byte base32(AAAA...)
byte b32(AAAA...)
byte 0x0123456789abcdef...
byte "\x01\x02"
byte "string literal"

int

int constants may be:

  • 0x prefixed for hex,
  • 0o or 0 prefixed for octal,
  • 0b prefixed for binary,
  • Or decimal numbers.

intcblock and bytecblock

intcblock may be explicitly assembled. It will conflict with the assembler gathering int pseudo-ops into a intcblock program prefix, but may be used if code only has explicit intc references. intcblock should be followed by space separated int constants all on one line.

bytecblock may be explicitly assembled. It will conflict with the assembler if there are any byte pseudo-ops but may be used if only explicit bytec references are used. bytecblock should be followed with byte constants all on one line, either “encoding value” pairs (b64 AAA...) or 0x prefix or function-style values (base64(...)) or string literal values.

Labels and Branches

A label is defined by any string (that:

  • Is a valid identifier string,

  • Is not some other opcode or keyword,

  • Ends with in :.

A label without the trailing : can be an argument to a branching instruction.

📎 EXAMPLE

Here is an example of TEAL program that uses a bnz opcode with the safe label as an argument. Since a 1 is pushed into the Stack, the execution jumps to the pop instruction after the safe: label:

int 1
bnz safe
err
safe:
pop