Toit
- Documentation
- Toit Language
- SDK Reference
- The
core
module is automatically imported into every file. It contains common classes, likeint
,string
andList
- The
- The Toit Console
- Github Repositories
CLI
toit
toit doctor
- health check of local systemtoit doctor fix
- install or update the SDKtoit doctor -v
- show version information
toit exec <file>
- execute the program without a device
The toit SDK installation is placed in ~/.cache/toit
Toit Language
- Language comparison for Toit vs. Java, etc.
Toit Terms
Variables
- locals - a variable declared within a function or passed to a function
- globals - a variable declared outside the scope of a class or function
- constants - special case of globals defined by a
::=
assignment. By convention constants should have an ALL_CAPS_NAME
Classes
- Constructor
- Named Constructor
- Factory - a named constructor with a return
- Static functions and fields - marked with the keyword
static
- Methods and instance fields
Basic Types
- Numbers
- String
- Boolean
- Common conversions list conversions from numbers to strings, etc.
Toit Types
Types are optional.
A variable is typed if followed by a /type-name
.
By default types are non-nullable, which means null is not a valid value.
class Coordinate:
// An instance field that must be initialized by
// constructors.
// By writing `:= ?` we indicate that all constructors
// must initialize the field.
x /int := ?
y /int := ?
// We don't need to specify the type for constructor
// arguments that are written directly to a typed field.
constructor .x .y:
main:
a := Coordinate 0 0
// Error! The types of the fields (and therefore the
// constructor arguments) are non-nullable, so null is not
// a valid argument here:
b := Coordinate null null // Error!
Nullable types are defined using a ?
after the type name.
class Foo:
bar /Bar? := null
any
/none
- Two special types exists:
any
- any value is acceptednone
- no value is accepted
Return types
The return type is defined with -> type
// A function that doesn't return anything.
foo -> none:
print "not returning anything"
// A function that takes an int and returns an int.
bar x/int -> int:
return x + 1
Operator Precendence
See definition of operators on the classes for int, float and num
Functions
// simple function definition with 2 arguments, argumment 2 has a default value
some_fct argument1 argument2="default value":
print "arguments: '$argument1' '$argument2'"
main:
// showing calls to the 'some_fct' function
some_fct "test 1"
some_fct "test 1" "test 2"
Classes
// simple *class* definition
class SimpleAdder:
addend1_ := null // private by convention as ending in '_'
addend2_ := null // private by convention as ending in '_'
// the constructor assigning addend1 and addend2, defaults to 0
constructor .addend1_=0 .addend2_=0:
sum:
return addend1_ + addend2_
main:
// creating an instance and calling 'sum'
simple_adder := SimpleAdder 13 17
print "the first sum is $simple_adder.sum"
// creating an instance where addend2 is default value (0)
simple_adder_noop := SimpleAdder 13
print "the second sum is $simple_adder_noop.sum"
Toit also supports interfaces
and abstract classes
The Advanced Constructor Topics details how an object is constructed and how the sequence is split into an initialization and an instance part.
Named Arguments
// function with named argument
say_hi name --greeting="Hello ":
// Greet everyone individually!
print "$greeting $name"
main:
// calling a function with a named argument
say_hi "Peter"
say_hi "Berit" --greeting="Hi"
Loops and if..else
// loop using number.`repeat`
print_n_numbers n:
// using repeat on number
n.repeat: print it // `it` is an *automatic* variable that gives the iteration count
// traditional for loop
for i := 0; i < n; i++: print i
// traditional while
i := 0
while i < n: print i++
// define a list and loop over it, using the `do` method available on all collections
print_list:
list := [ "Horse", "Fish", "Radish", "Baboon" ]
list.do: print it // `it` is an *automatic* variable that gives the element
print (list.join ",")
// if..else
print_even_or_odd n:
if n % 2 == 0: print "$n is even"
else: print "$n is odd"
Maps and Sets
list_of_something := [] // empty list
map_of_x_to_y := {:} // empty map
set_of_something := {} // empty set
Iterating a map iterates the key value pairs - see block arguments
main:
map ::= {
1234: "Siri",
2345: "John",
3456: "Sue"
}
map.do: | id name |
print "$name has ID $id"
Blocks
do
and repeat
looks like they are built in to the language like if
and for
, but they are normal methods on the List
and Integer
classes
class List:
// ...
do [block]:
size.repeat: block.call this[it]
class Integer:
// ...
repeat [block]:
for i := 0; i < this; i++:
block.call i
As blocks are stack-allocated there are some restrictions on blocks.
Concurrency - tasks
Toit uses Cooperative scheduling where all tasks / fibers runs on the same heap and only switch task on yield points.
A task is started with task::
syntax (double :
)
import gpio
// The red LED is connected to pin 17.
LED1 ::= gpio.Pin.out 17
// The green LED is connected to pin 18.
LED2 ::= gpio.Pin.out 18
main:
// Note the double `::` on the next two lines.
// Start a task that runs the my_task_1 function.
task:: my_task_1
// Start a second task that runs my_task_2.
task:: my_task_2
my_task_1:
while true:
sleep --ms=500
LED1.set 1
sleep --ms=500
LED1.set 0
my_task_2:
while true:
sleep --ms=123
LED2.set 1
sleep --ms=123
LED2.set 0
Synchronization Methods
Synchronization between tasks is possible using the monitor
library
- latch
- channel
- semaphore
- mutex
- mailbox
Exception Handling
try .. finally
catch
- implemented as a function that takes the possibly throwing code as a block.
my_function:
my_exception := catch --trace:
code_that_might_throw 42 103
if my_exception:
code_to_run_when_an_exception_was_thrown "foo" "bar"
Hardware - ESP32
GPIO (General Purpose I/O)
GPIO pins are globally acquired
import gpio
main:
pin := gpio.Pin 21 // Acquired system-wide.
// ...
pin.close // Released, can be used by other applications now.
Two different modes:
Running apps on the Device
- run - run once
- deploy - deploy with a
.yaml
app specification file
Simulator Device
toit simulator start --alias TestDevice # start a simulator device named 'TestDevice'
toit run -d TestDevice hello.toit # run the hello program once
toit deploy -d TestDevice hello.yaml # deploy the hello app to the device
toit device -d TestDevice ps # list apps on the device
toit device -d TestDevice logs -f 10m # attach to the logs from 10 minutes ago and tail
toit simulator stop TestDevice # stop the device
Pubsub Communication
Asynchronous message communication between apps.
topic is a named resource which is used when messages are published.
- Device topic: A topic that enables intra-communication on a device. These topics are prefixed with:
device:
- Cloud topic: A topic that enables inter-communication between devices and external systems. These topics are prefixed with:
cloud: