Skip to content

Toit syntax fundamentals#

This document describes the basics of the Toit language. To learn about Toit's documentation convention, see the Language documentation convention section.

Whitespace and indentation#

Toit uses whitespace and indentation to construct the code structure: comment. For example:

// Defines globals first, and then uses main function to print out something.
i := 1
j := 10

main:
  while i < j:
    print i
    i = i + 1

Comments#

In Toit, a single line comment begins with a double slash // followed by the comment. For example:

// This is a single line comment in Toit.

For multiline comments, use */.

/*
some multiline
comment
*/

Identifiers and keywords#

Identifiers are names that identify globals, locals, functions, classes, modules, and other objects in Toit.

  • Identifiers names can contain only letters, numbers, and underscores (_), but cannot contain spaces.
  • Identifiers need to start with a letter or an underscore (_), but not with a number. The following characters can be alphanumeric or underscore.
  • Toit identifiers are case-sensitive.
  • Identifiers names cannot the same as keywords and built-in functions in Toit.

The following Toit keywords cannot be used for naming identifiers:

as          abstract       assert
break       class          continue
else        false          finally
for         if             import
export      null           return
static      true           try
while       or     and     not

In addition to these keywords, there are some "pseudo keywords" - like constructor - that cannot be used in certain contexts. Trying these pseudo-keywords as globals name will generally give an error message in the IDE.

Another example of pseudo-keyword is operator that is allowed as local but cannot be the name of a function. Similarly, string can be used like a normal global but would shadow the string type.

String and character literals#

Toit uses only double quotes " to denote a string literal. It is possible to use single-quotes for characters, where 'char' is equivalent to writing the integer value of the corresponding unicode rune (unicode codepoint).

If a string contains a double quote, you can use the backslash \ to escape it. For example:

message := "It is a \"valid\" string"

For strings that span multiple lines, use triple-quotes “””…”””.

help_message := """
  Toit CLI command
      -h help
      -d device name
      -p prefix
  """
main:
  print help_message
This program will output the following if you execute the program:
Toit CLI command
    -h help
    -d device name
    -p prefix

Note that Toit removes the first newline if it is immediately after the """.

Toit strings are immutable.

The operator $ is used for string interpolation.

Toit globals and constants#

The := operator introduces a new global variable with the name of the given identifier (here "global_name").

global_name := 103

If the global is final (that is, can't be assigned to), then you can use ::= as in:

global2 ::= 42
Note that this in this case, global2 is actually a constant, and should thus be written in capital characters:
CONSTANT ::= 42
A final global that isn't a constant would (generally) be something that is mutable itself, such as
some_global ::= []
In this case the global is initialized with an empty list. The content of the list can change, but it will always be the same list.

When you name a global, you need to adhere to rules defined earlier about identifiers.

To use globals in a string, you use the operator $ for string interpolation:

name := "John"
message := "Hi $name"

main:
  print message

Toit will replace $name with the value of the name global.

To concatenate strings and string globals, you can also use the operator + as in example 2 here:

kind := "Good"
time := "Afternoon"
greeting := "$kind $time!"
greeting2 := kind + " " + time + "!"

main:
  print greeting2

Accessing string elements#

Since a string is a sequence of characters, you can access its elements using square brackets [] and indexes. The first character in the string has an index of zero.

str := "Toit String"

main:
  print str[0]

This small program outputs 84, because in Toit, characters are equivalent to integers, so the output is the unicode value of the character at that position. To print the letter instead, you can use string formatting

str := "Toit String"

main:
  print "$(%c str[0])"

Learn more about string formatting in the description of the class string.

Getting the length of a string#

To get the string length, you use the size method of the string class. For example:

str_len := str.size
main:
    print str_len

Substrings#

You can get a substring from a string by using the copy function of the string class.

main:
  print
    str.copy 0 2
It is also possible to write it as print (str.copy 0 2).

Both return a substring that includes the character from the index 0 (included) to 2 (excluded). If you omit the end, it defaults to the full string.

Escaping#

Toit uses the backslash \ as escape character. A combination of a backslash followed by (usually) one character has a special meaning and is replaced by with the corresponding meaning.

Toit supports the following escape sequences (see the ASCII control code chart for the list of names):

Control code chart names Unicode character
\0 Null NUL
\a Alert (Beep, Bell) BEL
\b Backspace BS
\f Form feed FF
\n Line Feed or Newline LF
\r Carriage Return CR
\t Horizontal Tab HT
\v Vertical Tab VT
\$ $ (escaping a dollar sign $ is needed because the $ operator is used for string interpolation)
\" "
\' '
\uXXXX (where X is a hex char) Unicode rune
\u{X...} (where X... are hex chars) Unicode rune
\xXX (where X is a hex char) Unicode rune
\x{X...} (where X... are hex chars) Unicode rune

Example of strings containing special characters. For two-digit runes using \x, the curly braces are optional if there are exactly two hex digits. For \u they are optional if there are exactly 4.

main:
  s5/string := "S\xf8en s\x{e5} s\u{00e6}r ud."
  print s5  // => "Søen så sær ud".

Example of printing Unicode rune in Toit.

unicoderune

In multiline strings:

\ followed by a newline (\n) Removes a newline in a multiline string.
\ followed by a a carriage return (\r) Removes a newline in a multiline string. If followed by a newline, that one is removed as well.
\s Space (see below for a detailed explanation).

Toit removes the indentation of a multiline string. It looks for the biggest indentation of each line and removes that one for each line.

If a space (or several spaces) are needed in front of each line, use \s to indicate to the compiler that this space shouldn't be seen as indentation.

main:
  str1 := """
    foo"""
  str2 := """
    \sfoo"""
  print "*$str1*"
  print "*$str2*"
space

Note that multiline strings frequently end with a newline anyway, in which case the last line can be used to indicate how much the indentation is:

main:
  print """
    foo
    bar
  """ // <== indented less than the previous lines. As such it gives the indentation for the other lines.

  print """
    foo
    bar
    """
  print str
indentation

This only works, if the string contains a newline at the end.

Continuation of statements#

Toit uses a newline character to separate statements. It places each statement on one line. However, a long statement can span multiple lines by using the backslash () character.

The following example illustrates how to use the backslash () character to continue a statement in the second line:

// A method with many parameters.
foo a b c d e f g h i j: ...

main:
  some_long_local1 := 1
  some_long_local2 := 2
  some_long_local3 := 3
  some_long_local4 := 4
  some_long_local5 := 5
  some_long_local6 := 6
  some_long_local7 := 7
  some_long_local8 := 8
  some_long_local9 := 9
  some_long_local10 := 10
  // Once there is a newline, all further arguments must be on their own line:
  foo some_long_local1
    some_long_local2
    some_long_local3
    some_long_local4
    some_long_local5
    some_long_local6
    some_long_local7
    some_long_local8
    some_long_local9
    some_long_local10
  // We can also write all of them in one line:
  foo some_long_local1 some_long_local2 some_long_local3 some_long_local4 some_long_local5 some_long_local6 some_long_local7 some_long_local8 some_long_local9 some_long_local10
  // But that becomes hard to read fast.
  // If we want to cut the line at some point we need a `\` to conceptually continue the first line:
  foo some_long_local1 some_long_local2 some_long_local3 \
      some_long_local4 some_long_local5 some_long_local6 \
      some_long_local7 some_long_local8 some_long_local9 \
      some_long_local10