Oska AST export

oskac parse <file.osk> --format=json writes the syntax tree as JSON. Agents and tools can build on this format.

Envelope

{
  "ast_version": 1,
  "file": "examples/hello.osk",
  "items": [ ... ]
}

Prelude mode

The prelude is Oska source embedded in the checker. It is parsed in prelude mode (parse_prelude in oska-syntax), which accepts two things user code cannot write. Both appear in the export like any other node.

Stability

Nodes

Every node is a JSON object with:

Diagnostics

When parsing fails, --format=json prints one diagnostic object instead of the envelope:

{
  "code": "E0151",
  "message": "an `impl` block cannot be `pub`; ...",
  "span": {"start": 0, "end": 3},
  "fix": {
    "message": "remove `pub`",
    "edits": [{"span": {"start": 0, "end": 4}, "replacement": ""}]
  }
}

Diagnostics that carry a fix:

CodeFix
E0005remove a ; at the end of a line
E0112remove var from an ordinary parameter
E0120insert the missing ,
E0143remove the , after a match arm, when the next arm is already on its own line
E0151, E0162, E0163, E0164remove pub
E0170remove the #[capability] attribute (prelude mode only)

Node schema

Conventions:

Items

Every item node starts with the same two fields, before its own fields:

FieldTypeNotes
publicbooldeclared pub
attributesarray of Attributein source order; empty when there are none

An item's span starts at its first attribute, if it has one, and otherwise at pub or its keyword. The tables below list only each item's own fields.

public is always false for UseItem (pub use is error E0164, because re-exports are not defined in v0), TestItem (pub test is error E0163), ImplItem (error E0151), and the methods of a TraitItem (error E0162).

FnItem

A function declaration: fn name<generics>(params) -> T requires ... ensures |r| ... { body }. The contract clauses sit between the return type and the body, and may each start a new line. The same node is used for the methods of ImplItem and TraitItem.

A self or var self receiver is allowed only on a method in an impl or trait block. On a module-level function it is error E0150.

FieldTypeNotes
nameIdent
genericsarray of GenericParamin source order
receiverSelfParamoptional; present for methods taking self or var self
paramsarray of Paramin source order, excluding the receiver
return_typetype nodeoptional; absent means ()
requiresarray of RequiresClausein source order
ensuresarray of EnsuresClausein source order
bodyBlockoptional; absent only for a trait method without a default body, or for a function or method in the prelude (see Prelude mode)

UseItem

An import: use a.b or use a.b.{X, y}. Glob imports (use a.*, error E0130) and renaming imports (use a.b as c, error E0131) are rejected, so every imported name is written out. An import is never pub (error E0164): re-exports are not defined in v0.

FieldTypeNotes
patharray of Identthe dotted path, without the brace group
namesarray of Identoptional; the names in the brace group, absent without one

ConstItem

A module-level constant: const NAME: T = expr.

FieldTypeNotes
nameIdent
typetype node
valueexpression node

TestItem

A test: test "a descriptive name" { body }. Tests that need real capabilities carry #[integration]. A test is never pub (error E0163).

FieldTypeNotes
nameStrExprthe name as written; its parts are a single StrText, because a name with an interpolation hole is error E0161
bodyBlock

StructItem

A struct declaration: struct Point { x: Int, y: Int } (named fields) or struct Meters(Int) (positional fields). Fields are separated by commas, and a trailing comma is allowed.

FieldTypeNotes
capbooldeclared cap struct: a capability-bearing type
nameIdent
genericsarray of GenericParamin source order; empty when not generic, as in struct Pair<A, B> { ... }
formstring"named" or "positional"
fieldsarray of Fieldin source order

EnumItem

An enum (sum type) declaration: enum Shape { Circle { radius: Int }, Rect(Int, Int), Empty }. Variants are separated by commas, and a trailing comma is allowed.

FieldTypeNotes
capbooldeclared cap enum: a capability-bearing type
nameIdent
genericsarray of GenericParamin source order; empty when not generic, as in enum Option<T> { ... }
variantsarray of Variantin source order

TraitItem

A trait declaration: trait Name<generics> { methods }. Methods are separated by line breaks. A method either ends after its signature (its FnItem has no body) or has a default body. A trait method takes its visibility from the trait, so it is never pub (error E0162) and its public is always false. Trait objects (dyn), associated types, and where clauses are not part of v0.

FieldTypeNotes
nameIdent
genericsarray of GenericParamin source order
methodsarray of FnItemin source order

ImplItem

Methods for a type: impl<generics> Type { methods } for inherent methods and associated functions, or impl<generics> Trait for Type { methods } for a trait implementation. Methods are separated by line breaks, and each needs a body, except in the prelude. An impl block is never pub (error E0151), so public is always false; each method carries its own public.

FieldTypeNotes
genericsarray of GenericParamin source order, as in impl<T: Eq> Eq for List<T>
traittype nodeoptional; the implemented trait, present only for impl Trait for Type
targettype nodethe type the methods belong to
methodsarray of FnItemin source order

Shared nodes

Ident

A name as written in source, such as a function, parameter, or field name.

FieldTypeNotes
namestring

Param

A function parameter, name: Type. Capability parameters such as fs: FsRead are ordinary parameters, so a function's authority can be read from its params.

FieldTypeNotes
nameIdent
typetype node

SelfParam

A method's receiver: self, or var self for a mutating method. It can only be the first parameter. The span covers var when present.

FieldTypeNotes
mutablebooltrue for var self

GenericParam

A generic parameter with its inline bounds: T: Eq + Hash. There are no where clauses.

FieldTypeNotes
nameIdent
boundsarray of type nodesthe +-separated bounds; empty when unbounded

RequiresClause

A precondition, requires cond. The span covers the keyword and the condition.

FieldTypeNotes
condexpression node

EnsuresClause

A postcondition, ensures |r| cond, where r names the return value. The span covers the keyword and the condition.

FieldTypeNotes
bindingIdentthe name bound to the return value
condexpression node

Field

A declared field of a struct or enum variant: pub name: Type when named, or pub Type when positional. The span starts at pub when present.

FieldTypeNotes
publicbooldeclared pub; fields are private by default. Always false in enum variants, which do not accept pub
nameIdentoptional; absent for positional fields
typetype node

Variant

An enum variant: Some(T) (positional), Circle { radius: Int } (named), or None (unit).

FieldTypeNotes
nameIdent
formstring"named", "positional", or "unit"
fieldsarray of Fieldin source order; empty when form is "unit"

Block

A { ... } block. Its value is the value of its last statement if that statement is an ExprStmt.

FieldTypeNotes
stmtsarray of statement nodes

Arg

A call argument, optionally labelled: copy(src: a). The span covers the label and the value.

FieldTypeNotes
labelIdentoptional
valueexpression node

Attribute

An attribute on an item: #[name] or #[name(args)]. Names come from a fixed set, currently only integration; any other name is error E0132. #[integration] is allowed only on a TestItem; on any other item or method it is error E0165. The prelude may also use capability (see Prelude mode).

FieldTypeNotes
nameIdent
argsarray of Argempty when there are no parentheses

ClosureParam

A closure parameter with an optional type: |x: Int, y|.

FieldTypeNotes
nameIdent
typetype nodeoptional

StrText

Literal text inside a string. The span covers the raw source text, escapes included.

FieldTypeNotes
valuestringescapes resolved

StrHole

An interpolation hole such as {user.name}. The span includes the braces.

FieldTypeNotes
patharray of Identthe name, then any field names

Statements

LetStmt

let name: T = value, or var for a mutable binding. The initializer is required.

FieldTypeNotes
mutablebooltrue for var
nameIdent
typetype nodeoptional
valueexpression node

AssignStmt

target = value.

FieldTypeNotes
targetexpression nodea NameExpr, SelfExpr, or FieldExpr
valueexpression node

ReturnStmt

return, with an optional value.

FieldTypeNotes
valueexpression nodeoptional

BreakStmt

break.

No fields beyond kind and span.

ContinueStmt

continue.

No fields beyond kind and span.

ForStmt

for binding in iter { body }.

FieldTypeNotes
bindingIdent
iterexpression node
bodyBlock

WhileStmt

while cond { body }.

FieldTypeNotes
condexpression node
bodyBlock

ExprStmt

An expression used as a statement.

FieldTypeNotes
exprexpression node

Expressions

IntExpr

An integer literal.

FieldTypeNotes
valuestringthe digits as written, including _ separators

StrExpr

A string literal, split into text and interpolation holes.

FieldTypeNotes
partsarray of StrText and StrHolein source order; an empty string has one empty StrText

SinkStrExpr

A sink literal such as sql"...". It never contains holes.

FieldTypeNotes
tagstringsuch as sql
valuestringescapes resolved

BoolExpr

true or false.

FieldTypeNotes
valuebool

UnitExpr

The unit value ().

No fields beyond kind and span.

NameExpr

A bare name. Its span is the name's span, so the name is a plain string.

FieldTypeNotes
namestring

SelfExpr

The receiver self.

No fields beyond kind and span.

FieldExpr

base.name: a field, method, module member, or enum variant. The parser does not resolve which.

FieldTypeNotes
baseexpression node
nameIdent

CallExpr

callee(args). A method call is a call whose callee is a FieldExpr.

FieldTypeNotes
calleeexpression node
argsarray of Arg

UnaryExpr

A prefix operator.

FieldTypeNotes
opstring- or !
operandexpression node

BinaryExpr

A binary operator.

FieldTypeNotes
opstringas written: implies, ||, &&, ==, !=, <, <=, >, >=, +, -, *, /, %
lhsexpression node
rhsexpression node

TryExpr

Postfix ?.

FieldTypeNotes
operandexpression node

RangeExpr

start..end, which excludes end.

FieldTypeNotes
startexpression node
endexpression node

ListExpr

[a, b, c].

FieldTypeNotes
elementsarray of expression nodes

ClosureExpr

|params| body.

FieldTypeNotes
paramsarray of ClosureParam
bodyexpression node

IfExpr

if cond { ... } else ....

FieldTypeNotes
condexpression node
then_blockBlock
else_branchexpression nodeoptional; an IfExpr or a BlockExpr

BlockExpr

A block used as an expression. Its span is the block's span, so the statements sit directly on the node.

FieldTypeNotes
stmtsarray of statement nodes

ScopeExpr

scope |handle| { body }.

FieldTypeNotes
handleIdent
bodyBlock

MatchExpr

match scrutinee { arms }, with one arm per line and no commas between arms.

FieldTypeNotes
scrutineeexpression node
armsarray of MatchArmin source order; may be empty

MatchArm

One arm of a match: pattern if guard => body. The span runs from the pattern to the end of the body.

FieldTypeNotes
patternpattern node
guardexpression nodeoptional; the condition after if
bodyexpression node

Patterns

v0 has no or-patterns (A | B), range patterns (1..5), or @ bindings. The parser rejects them with E0140, E0141, and E0142.

WildcardPattern

_, which matches anything and binds nothing. It has no other fields.

LiteralPattern

A literal to compare against: an integer, a negated integer such as -1, a string, true, false, or ().

FieldTypeNotes
valueexpression nodean IntExpr, a UnaryExpr with op - around an IntExpr, a StrExpr, a BoolExpr, or a UnitExpr. A StrExpr here is a plain literal: a string pattern with an interpolation hole is error E0160

BindingPattern

A bare name, which binds the matched value. Its span is the name's span, so the name is a plain string. The parser cannot tell a binding from a unit variant or constant written as a bare name, such as None; name resolution decides that.

FieldTypeNotes
namestring

ConstructorPattern

A struct or enum variant pattern. It mirrors call-style construction (ADR 0004): positional Some(x), named Shape.Circle(radius: r), or a dotted path alone, such as Shape.Empty.

FieldTypeNotes
patharray of Identthe type or variant path, such as Shape, Circle
argsarray of PatternArgempty when written without parentheses or as ()

PatternArg

A constructor pattern argument, optionally labelled with a field name: radius: r. The span covers the label and the pattern.

FieldTypeNotes
labelIdentoptional
patternpattern node

Types

PathType

A named type, possibly qualified and generic: std.io.Error, Result<T, E>.

FieldTypeNotes
segmentsarray of Identthe dotted path
argsarray of type nodesgeneric arguments; empty when there are none

UnitType

().

No fields beyond kind and span.

FnType

fn(T) -> U, or cap fn(T) -> U when the function may capture capabilities.

FieldTypeNotes
capbool
paramsarray of type nodes
return_typetype nodeoptional; absent means ()