Draxl Docs

Syntax

Stable ids, ranks, anchors, and the current Rust profile surface.

Draxl Rust profile source uses metadata prefixes on supported syntax nodes. The metadata sits next to the syntax it identifies, so the editable source itself carries stable machine addresses.

Metadata Prefix

The canonical metadata form is:

@id[rank]->anchor

Supported compact forms:

@x1
@x1[a]
@x1->y2
@x1[a]->y2

Canonical formatting always emits metadata in the same order: id, rank, anchor.

Stable Ids

@id gives the next supported node a stable identity.

Examples of identified nodes in the current Rust profile:

  • modules, imports, structs, enums, functions, fields, and variants
  • function parameters, statements, match arms, and modeled expressions
  • path types, patterns, integer literals, and string literals
  • doc comments and line comments

Ids are opaque strings. They need to be unique within a file. The spelling carries no kind, ownership, or scope.

Ranks

[rank] orders siblings inside ranked slots. A ranked slot is a list where concurrent insertion order matters.

Ranked slots currently include:

  • module items
  • struct fields
  • enum variants
  • function parameters
  • block statements
  • match arms

Ranks are opaque strings compared lexicographically. This source:

@s1[a] @e1 fetch();
@s2[am] @e2 log();
@s3[b] @e3 validate();

leaves room for a later insert between a and am:

insert @f1.body[ah]: @s4 @e4 trace();

The inserted statement has a concrete destination independent of line numbers.

Anchors

->anchor attaches detached docs or comments to an existing sibling node id.

Doc comments and line comments attach implicitly to the next semantic sibling when an explicit anchor is absent:

@d1 /// Add one to x.
@f1[a] fn add_one(@p1[a] x: @t1 i64) -> @t2 i64 {
  @c1 // Cache the intermediate value.
  @s1[a] let @p2 y = @e1 (@e2 x + @l1 1);
  @s2[b] @e3 y
}

Use an explicit anchor when layout separates a doc or comment from the node it describes:

@d2->f1 /// Public entrypoint.

The validator rejects anchors that point at missing ids and detached trivia with no following sibling attachment target.

Complete Example

@m1 mod demo {
  @d1 /// Add one to x.
  @f1[a] fn add_one(@p1[a] x: @t1 i64) -> @t2 i64 {
    @c1 // Cache the intermediate value.
    @s1[a] let @p2 y = @e1 (@e2 x + @l1 1);
    @s2[b] @e3 y
  }
}

Lowered Rust:

mod demo {
    /// Add one to x.
    fn add_one(x: i64) -> i64 {
        // Cache the intermediate value.
        let y = (x + 1);
        y
    }
}

Supported Rust Profile

The current profile supports:

  • mod, use, struct, enum, and fn
  • parameters, path types, integer literals, and string literals
  • blocks, let statements, and expression statements
  • path expressions, grouped expressions, calls, and selected binary operators
  • unary minus
  • match expressions and match arms
  • grouped use trees, self, and glob imports
  • doc comments and line comments

The current binary operator set includes +, -, and <.

Validation

Parsing accepts supported syntax and builds the Draxl tree. Validation checks the invariants that patching and merge analysis rely on:

  • every node id is unique within the file
  • ranked children have ranks
  • ranks are unique within a ranked slot
  • anchors resolve to valid sibling nodes
  • docs and comments have an implicit or explicit attachment target

Use the validator before lowering or patching:

cargo run -p draxl-cli -- validate examples/01_add.rs.dx

On this page