Skip to main content

Interpretation (-r, -i)

Run programs for development and testing without producing WebAssembly.

The -r (run) and -i (interactive) flags interpret Sector9 programs directly, bypassing the WebAssembly compilation step. This enables rapid testing of logic during development, debugging with print statements, and interactive exploration of your code.

Basic Usage

Run Mode (-r)

Execute a program and exit:

sector9 -r file.sr9

The program runs to completion, printing output to stdout. The command exits with code 0 on success or 1 on runtime error (assertion failure, trap, etc.).

Interactive Mode (-i)

Start an interactive REPL (Read-Eval-Print Loop):

sector9 -i file.sr9

This loads your file, then enters an interactive session where you can type expressions and declarations at the > prompt. The REPL maintains state across inputs, so you can build up definitions incrementally.

What Interpretation Does

The interpretation pipeline performs these steps:

  1. Parsing - Tokenizes and parses source code
  2. Import resolution - Loads library dependencies
  3. Type checking - Full type inference and validation
  4. Desugaring - Converts to intermediate representation
  5. Execution - Runs the program in the abstract interpreter

This uses the normal frontend type checking, followed by direct execution. If the program imports local packages such as mo:core/..., pass the same --package flags you use for checking.

What Interpretation Does NOT Do

  • Does not compile to WebAssembly
  • Does not invoke the SMT solver for verification
  • Does not prove contracts (runtime assertions only)
  • Does not deploy to the Internet Computer

For formal verification, use --verify. For deployment, use -c to compile.

-r vs -i

Aspect-r-i
Execution modeBatchInteractive
Input sourceFiles onlyFiles, then stdin
State after runExitsPreserved in REPL
Banner printedNoYes (version info)
Use caseTesting, scriptsExploration, debugging

Interpreting Ghost Code

Ghost declarations are still visible to the source interpreter:

ghost var count : Nat = 0;

public func increment() {
ghost { count := count + 1 };
};

When you run this with -r, the ghost variable updates in the interpreter. This differs from compilation and runtime projection, where ghost code is erased.

Assertion Behavior

The interpreter distinguishes assertion types:

AssertionBehavior
assert exprStatic verification assertion; not a deployed runtime check
runtime:assert exprEvaluated; traps if false
trap exprEvaluated; traps if true

Runtime assertions execute and can cause traps. Static assertions are skipped entirely.

Exit Codes

CodeMeaning
0Success - program completed normally
1Failure - runtime error, assertion failure, or trap
2Invalid arguments - missing files or conflicting flags

Common Flags

Verbose Output

Show phase timings and intermediate steps:

sector9 -r -v file.sr9

Tracing

Enable trace output for debugging:

sector9 -r -t file.sr9

Control how deeply nested values are printed:

# Set print depth to 10 levels
sector9 -r -p 10 file.sr9

Hide Warnings

Suppress warning messages:

sector9 -r --hide-warnings file.sr9

Interactive REPL Features

Multi-line Input

When entering incomplete expressions, the REPL continues reading with a (two-space) prompt:

> let record = {
name = "Alice";
age = 30
};
record : {age : Nat; name : Text} = {age = 30; name = "Alice"}

State Preservation

The REPL preserves state across syntax and type errors:

> let x = 42;
x : Nat = 42
> let x = "invalid" *;
stdin:1.16: syntax error [M0001], unexpected token ';', expected one of token or <phrase> sequence...
> runtime:assert (x == 42);
() : ()

After the syntax error, x still holds 42.

Importing Modules

Import modules interactively:

> import Prim "mo:⛔";
> Prim.natToText(42);
"42" : Text

Evaluating Expressions

Type expressions directly to see their values:

> 1 + 2 * 3;
7 : Nat
> #Monday;
#Monday : \{#Monday}
> [1, 2, 3];
[1, 2, 3] : [Nat]

Limitations

Declaration-Only Functions

Functions without bodies (verification-only declarations) cannot be interpreted:

// This will fail with M0336
func spec_only(x : Nat) : Nat
ensures result > x;

Error: declaration-only functions are verification-only; add a body before compiling or running

Add a body to run:

func spec_only(x : Nat) : Nat
ensures result > x;
{
x + 1
}

Actor Imports

IDL-based actor imports are not supported in the interpreter:

// This will trap: "actor import"
import SomeActor "canister:some_actor";

Mixins

Include directives (mixins) are not yet supported:

// This will trap: "Mixins are not yet supported in the interpreter"
include SomeMixin;

Actor Class Configuration

Only basic actor class instantiation works. Advanced configuration is unsupported:

// Only "new" with default settings works
// Custom settings will trap

Runtime Errors

Assertion Failure

file.sr9:10.4-10.25: execution error, assertion failure

A runtime:assert evaluated to false.

Pattern Match Failure

file.sr9:15.4-15.30: execution error, switch value #Unknown does not match any case

A switch expression had no matching case.

Array Index Out of Bounds

file.sr9:8.4-8.15: execution error, array index out of bounds

Accessed an array with an invalid index.

Arithmetic Overflow

file.sr9:12.4-12.20: execution error, arithmetic overflow

A fixed-width integer operation overflowed.

IR Interpretation (-iR)

For debugging compiler transformations, interpret the lowered IR:

sector9 -r -iR file.sr9

This runs the program after applying IR lowering passes (async/await transformations, tailcall optimization). Combine with other flags:

# IR interpretation without await lowering
sector9 -r -iR -no-await file.sr9

# IR interpretation without async lowering
sector9 -r -iR -no-async file.sr9

This is primarily useful for compiler development and debugging.

Interpretation vs Verification

AspectInterpretation (-r)Verification (--verify)
ExecutionConcrete runtimeSymbolic analysis
Assertionsruntime:assert executesAll become proof obligations
Ghost codeExecutes at runtimeDrives verification
Paths exploredSingle executionAll possible paths
SpeedFastSlower (SMT solving)
GuaranteesThis run workedAll inputs satisfy contracts

Typical Workflow

# 1. Quick testing during development
sector9 --package core ./core/src -r my_module.sr9

# 2. Interactive exploration
sector9 --package core ./core/src -i my_module.sr9

# 3. Type checking when ready
sector9 --package core ./core/src --check my_module.sr9

# 4. Full verification before deployment
sector9 --package core ./core/src --verify my_module.sr9

Summary

  • -r executes programs in batch mode for testing
  • -i provides an interactive REPL for exploration
  • Ghost code executes at runtime (unlike compilation)
  • Only runtime:assert runs; static assert is skipped
  • State persists across errors in interactive mode
  • Declaration-only functions require bodies to run
  • Use -iR for debugging compiler IR transformations
  • Add --package <name> <path> when interpreted files import local packages