Skip to main content

Coco Module

Module is a complete source code of a logic that can be compiled into a manifest. It contains one or more .coco files and a coco.nut configuration file. It can import packages, that are reusable collection of .coco and coco.nut files in their own folders.

Organization of a Module

Module in Coco is a collection of all .coco files in a folder that all start with the same coco <module_name> as the first line of the program. If a .coco file exists in the folder with a module name that's different from the others, compilation will fail.

coco.nut file in the folder is used to configure compilation and Cocolab and it's written in TOML format. It's created using coco nut init <module_name> CLI command so it will contain module name that matches coco <module_name> statements in .coco files in the same folder. The default value of coco.nut file is below, comments explain the meaning.

Show full coco.nut file
coco.nut
# Coco compiler version
[coco]
version = "0.7.0"

# Module name and some attributes
[module]
name = "Flipper"
version = "0.0.1"
license = []
repository = ""
authors = []

# Compilation target, MOI-PISA is the only supported target for now
[target]
os = "MOI"
arch = "PISA"

# Manifest format (YAML, JSON or POLO) and manifest name (flipper.yaml in this example)
[target.moi]
format = "YAML"
output = "flipper"

# Format of binary PISA code in the manifest (BIN, HEX or ASM) and PISA version
# Supported versions are 0.3.2, 0.4.0 and 0.5.0, assets are only supported in 0.5.0
# Coco syntax is partially dependent on PISA version, so this setting is very important
[target.pisa]
format = "BIN"
version = "0.5.0"

# Cocolab flags
[lab.render]
big_int_as_hex = true
bytes_as_hex = false

[lab.config.default]
env = "main"

# Cocolab scripts that can be run using `coco lab run test-toggle`
[lab.scripts]
test-toggle = ["engines", "users", "logics"]

# Compiler scripts that are run with `coco nut run test-script`
[scripts]
test-script = "coco compile .; pwd; uname -a"

The Module Superglobal

The name of the module is one of Coco’s superglobals. It can be used to access the state information of the module as well as other information about the logic module.

In the NumberStore module, the mutate value -> NumberStore.Logic.value statement is using the module superglobal to access the module’s state and mutate it with some value.

number_store.coco
coco NumberStore

state logic:
value U64

endpoint deploy Init(value U64):
mutate value -> NumberStore.Logic.value

endpoint LogicId() -> (id Identifier):
yield id Identifier(NumberStore)

Packages

While module contains the main Coco code of the logic, it can also import reusable packages. A package is source code that can be imported into any module. Coco 0.7.0 only supports local packages, i.e. packages whose source code resides on a local disk and can be imported using relative paths. E.g. if we have this folder structure

| main
| - main.coco
| | math
| | - math.coco

we can import package ./math into main.coco module. Functions or data structure in packages are accessed using scope with syntax scope::name, e.g. math::Point. Functions, classes and constants in the packages can be referenced.

Visibility of functions and data structures in packages is controlled byt using pub keyword, only pub elements can be referenced from modules that import packages.

Packages can be nested, i.e. packages can import other packages. Compiler detects circular dependencies when importing.

main.coco
// Module `main` imports package `./math`
coco main

imports:
"./math"

endpoint Len(point math::Point) -> (l U64):
if U64(point.coords[1]) != (four) <- math::four():
throw f"Not four: {point.coords[1]} {(four) <- math::four()}"
l = (dist) <- point.dist(other: math::Point{coords: [3]I64{I64(0),I64(0),I64(0)}})
math/math.coco
//Package `math` in subfolder can be imported and provides class `Point`.
coco package math

pub class Point:
field coords [3]I64

method dist(other Point) -> (dist U64):
memory dx = self.coords[0] - other.coords[0]
memory dy = self.coords[1] - other.coords[1]
memory dz = self.coords[2] - other.coords[2]
dist = (sqrt) <- Sqrt(n: U64(dx*dx + dy*dy + dz*dz))

pub function four() -> (four U64):
four = 4

coco.nut for packages

Packages have different coco.nut contents that are created using

coco nut init-package <package_name>
coco.nut
[coco]
version = "0.7.0"

[package]
name = "package_name"
version = "0.0.1"
license = []
repository = ""
authors = []

[package.targets]
supported = []
unsupported = []