01 / SHAPE
Node shape
The semantic fields are tag, props, and children. Values inside props and children follow the data model. Implementations may add metadata such as source positions, but must not change semantic values.
type MatraScalar = string | number | boolean | null
type MatraValue =
| MatraScalar
| MatraValue[]
| { [key: string]: MatraValue }
interface MatraAST {
tag: string
props: Record<string, MatraValue>
children: Array<MatraAST | MatraValue>
}
02 / CONVERSION
Convert to and from MatraJSON
The object form {tag, props, children} and MatraJSON [tag, props, children] must convert recursively without losing information. Preserve tag, values, scalar types, nested nodes, and child order. Copying mutable lists and maps is recommended to avoid accidental sharing.
{ tag: "item", props: {}, children: ["one"] }
// MatraJSON: ["item", {}, ["one"]]
03 / SOURCE POSITION
Positions are metadata
An AST node may carry a position. Start/end offsets are zero-based; line and column are one-based. Positions are excluded from document-value equality and omitted from the three-element MatraJSON form.
04 / VALIDATION
Validate nodes
A validator rejects nodes whose tag is not a string, props is not a string-keyed value map, children is not a list, or child is neither an AST node nor a model value.