Skip to content

compile

Compiles Do source to bytecode and describes what it declares.

Usage

let source = "let x = (1 + 2)"
let unit = compile "example.dol" $source
let bytecode = unit.emit()

Document nodes

A unit compiled with document: true also describes what the source declares, as a tree of Node objects reached through Unit.nodes. Most of a node's interesting text is reported as a Span rather than a string: the source is already in hand, so a span says where a name was written without copying it.

let unit = compile "example.dol" $source document: true
for id node = unit.nodes()
  echo $id $node.span

Types

TypeDescription
Alias A type alias.
Annotation An additional highlighted region attached to a Diagnostic.
AnyKeyTypeItem A **V, admitting symbol-keyed items of type V, or a ** alone, admitting any keyed items.
AnyPosTypeItem A * alone, admitting any positional items.
AppType Type arguments applied to a type, such as Array[Int].
Arm A match arm: its pattern, guard and body.
ArrayType An array type, such as [Int].
Bind A let or other binding.
Binder Supertype of binders: names standing for types within the function, method, or class that is their parent.
Block Supertype of the nodes that introduce a nested body.
Break A break. Its target is the loop broken out of.
Catch A catch handler.
Check Units and typelibs to check together, and the modules they need.
Checked The result of a Check.
Class A class declaration.
ConstType A constant, such as :TARGET: or nil.
Continue A continue. Its target is the loop continued.
Declaration Supertype of the nodes that bind a name.
Decorator A decorator.
Diagnostic A compiler diagnostic.
Else An else body.
ExpandTypeArg An expansion of a pack into further arguments, such as ...T.
Field A field declaration in a class body. Its class is its parent.
Finally A finally body.
For A for body.
ForElem A comprehension for.
Function A def at statement level.
FuncType A function type, such as (Int, ?Int) -> Int.
If An if or else if body.
IfElem A comprehension if.
ImplicitParam Supertype of the implicit parameters naming a strand's ambient channels.
Import Supertype of the nodes that bind a name to something imported.
ImportItem An item bound from a module, as in import foo: - bar.
ImportModule A module bound by import foo or import foo: bar.
InputParam The <T implicit parameter, giving the ambient input a function reads from.
KeyBinder A keyed binder, such as :K.
KeyParam A keyword parameter.
KeyRestBinder A rest binder for keyed items only, such as **R.
KeyRestParam A rest parameter for keyed items only, such as **rest.
KeyTypeArg A keyword argument, such as name: T.
KeyTypeItem A keyed item, such as name: T, ?name: T or *(K): V.
Lambda A do block.
Method A def in a class body. Its class is its parent.
MixedRestBinder A rest binder for positional and keyed items, such as ...R.
MixedRestParam A rest parameter for positional and keyed items, such as ...rest.
NameType A possibly dotted name, such as Str or time.Duration.
Node Supertype of every document node.
NodeId An opaque handle identifying one node within a Unit.
Note An auxiliary note attached to a Diagnostic.
OpenTypeItem A ... alone, admitting any items.
OutputParam The >T implicit parameter, giving the ambient output a function writes to.
Param Supertype of a function's parameters. The function is the parent.
ParensType A tuple or record type, such as (Int, Str) or (name: Str).
Patch A suggested source edit attached to a Diagnostic.
Pos A position within source text. All coordinates are zero-based.
PosBinder A positional binder, such as T.
PositionalParam A positional parameter.
PosRestBinder A rest binder for positional items only, such as *R.
PosRestParam A rest parameter for positional items only, such as *rest.
PosTypeArg A positional argument, such as T.
PosTypeItem A positional item, such as T, ?T, *T or ...S.
PreludeItem An item bound by the prelude.
PreludeModule A module bound by the prelude.
Reference Supertype of the nodes that name another node.
RestBinder Supertype of rest binders. Its subtype says which items it stands for.
RestParam Supertype of rest parameters. Its subtype says which items it takes, and its name is nil when it is anonymous.
Return A return. Its target is the function returned from.
Root The complete source document.
SchemaType A schema, such as {name: Str, ?port: Int}.
SelfParam The self parameter of a method.
SourceSpan Where part of a diagnostic applies: a span, and which unit it is in.
Span A region of source text: where it starts, and its length in characters.
SpecialMethod A method implementing a protocol, such as (init) or (next). Its class is its parent.
Token A syntactic token.
Try A try body.
Type A type in an annotation, return type, alias body, or superclass list.
TypeArg Supertype of the type arguments in the [] of an AppType. Its span leaves out a trailing ,.
TypeExpr Supertype of the forms a type takes.
TypeItem Supertype of the items of a SchemaType, ParensType, or FuncType. Its span includes a leading - and leaves out a trailing ,. An item carries the doc of the comment block directly above it, except the lone parameter of a function type written without parentheses.
Typelib A module's typelib: its declarations as check reads them, without its source.
UnionType A union, such as (Str | Path).
Unit A staged compilation unit.
While A while body.
Prelude Imports to bind before compiled source: a module name, an array of module names, or a dictionary of module names to their bindings. Positional dictionary entries import unaliased modules.
PreludeBinding What a prelude binds a module to: an alias, an array of items, or a dictionary of items to their aliases. Prefix an item name with @ to bind it only in types; aliases are written without the prefix.
TokenKind The kind of a Token.

Prelude

@let Prelude = $
  | Str
  | Sym
  | BaseArray[Str | Sym]
  | BaseDict[{*Str | Sym, *(Str | Sym): PreludeBinding}]

Imports to bind before compiled source: a module name, an array of module names, or a dictionary of module names to their bindings. Positional dictionary entries import unaliased modules.

PreludeBinding = (Str | Sym | BaseArray[Str | Sym] | BaseDict[Str | Sym, Str | Sym])

What a prelude binds a module to: an alias, an array of items, or a dictionary of items to their aliases. Prefix an item name with @ to bind it only in types; aliases are written without the prefix.

TokenKind

The kind of a Token.

TypeDescription
:ANNOTATION: An @ annotation marker
:BINDER: A type binder declaration
:COMMENT: A comment
:CONSTANT: A non-numeric, non-string constant such as nil or false
:DELIM: A delimiter such as (, [, etc
:ESCAPE: An escape within a string
:FIELD: A field, e.g. bar in foo.bar
:METHOD: A method declaration name
:KEY: A key such as foo:
:MODULE_NAME: A module name
:MODULE_ITEM: A module item
:KEYWORD: A keyword such as while, for, do, import
:LITERAL: A literal string, including non-escape, non-interpolated portions of quoted strings
:NUMBER: A numeric constant
:OPERATOR: A unary or binary operator such as + or -
:STRING_DELIM: A string delimiter (")
:TYPE: A name within a type expression
:TYPE_KEY: A keyed argument within a type expression
:VARIABLE: A variable
:SIGIL: A sigil like $ or ...

Functions

check units … -> Checked

Checks the types of units together: adds each of units to a Check and runs it.

A unit's imports of another unit's module are checked against that module. An import of a module that isn't among the units is an error, and the names it imports have unknown types. A unit that failed to compile is skipped; its own diagnostics report why.

A module may be given by its Typelib in place of a unit. Its declarations are checked, but not its bodies, and a diagnostic in it is located by line and column, without its source.

strand.PipeSender and strand.PipeReceiver are checked as the shell's pipes, proc.PipeSender and proc.PipeReceiver.

Parameters

NameTypeDescription
units Iterable[Unit | Typelib]
:typelibs? Bool Whether the result keeps what Checked.typelib writes. False by default.

Errors

Exception Condition
ValueError A unit was compiled without typecheck: true
ValueError Two units are compiled as the same module
StateError A unit was emitted, or a typelib is given twice

Example

let lib = compile "lib.dol" $lib_source module: lib typecheck: true
let main = compile "main.dol" $main_source typecheck: true
let result = check [lib, main]
for diag = result.diagnostics
  echo $diag.render()
let written = check [lib, main] typelibs: true
let again = check [Typelib(written.typelib(lib)), main]

compile path source … -> Unit

Parses and elaborates Do source into a staged compilation unit.

Parameters

NameTypeDescription
path Str Source path, used in debug information and diagnostics.
source Str Source code to compile.
:module? Str Compile in module mode under this name.
:prelude? Prelude Additional imports to bind before the source, in the shapes the LSP prelude settings take.
:recover? Bool Continue parsing after syntax errors. Defaults to false.
:document? Bool Build document nodes. Defaults to false.
:typecheck? Bool Prepare the unit for check. Defaults to false.
:strict? Bool Check the unit strictly, overriding its # dolang: strict or # dolang: nostrict directive. Defaults to what the directive says, or false without one.
:module

Without it the source is compiled as a script, and running the bytecode yields the value of the final expression or of an early return. In module mode, running it yields a module object holding the exported bindings, or the value of an early return.

:recover

Recovery is what lets a file be described while it is still being written, at the cost of a document that is missing whatever the compiler could not read. Check Unit.diagnostics before trusting one.

Returns

A Unit, which exposes diagnostics and, with document: true, document nodes before emission. Ordinary compiler diagnostics are reported through Unit.diagnostics rather than thrown.

Errors

ValueError if prelude is malformed.

Example

# Additional prelude modules
compile "test.dol" $source
  prelude:
    - sys
    - fs

# Module with alias
compile "test.dol" $source
  prelude:
    sys: shell

# Import specific items
compile "test.dol" $source
  prelude:
    sys:
      - echo
      - exit

# Checker-only items
compile "test.dol" $source
  prelude:
    std:
      - "@Seq"

# Items with aliases
compile "test.dol" $source
  prelude:
    sys:
      echo: echo_alias