Status. This is the implemented bootstrap surface for programs whose file extension is .kina. The compiler still accepts the older S-expression core through Sexpr_parser (see 02-surface-kina.md). The roadmap’s Phase 7 surface (frozen grammar, inference, LSP) has not happened; this page documents what the Menhir parser actually accepts.
Pipeline. Text → Kina_parser_wrapper.parse_kina_program → Ast_surface.expr → Type_formation.check_program → optional Ad_pass.transform_ad → Emitter.emit_tensor_program (MLIR).
Limits visitors hit. Tensor payloads in { … } are parsed and discarded; a tensor<F32, [2, 3], @host> { 1.0 } is still a typed placeholder. There is no packaged standard library. See 03-current-status.md.
Grammar and Syntactic Conventions
Lexical Rules
- Comments: Support for
//(single-line comments) and/* ... */(multi-line comments). - Dimensions: Separated by commas inside brackets, e.g.,
[B, S, D]. Static dimensions are integers≥ 1; symbolic dimensions are variables starting with a letter. - Named Parameters: Certain methods use explicit parameter names to verify usage correctness (e.g.,
axis=1).
Syntax Mapping Reference
The following table maps the older S-expression core to the bootstrap .kina syntax:
| Feature / Operation | S-expression core | Bootstrap .kina |
|---|---|---|
| Requires Program | (requires (= B B_prime) (= K K_prime) body) |
requires [B = B_prime, K = K_prime] compute { body } |
| Tensor Literal (Host) | (tensor F32 [2 3]) |
tensor<F32, [2, 3], @host> |
| Tensor Literal (Device) | (tensor F32 [2 3] @device(0)) |
tensor<F32, [2, 3], @device(0)> |
| Pointwise Add | (add x y) |
x + y |
| Pointwise Mul | (mul x y) |
x * y |
| Pointwise Sub | (sub x y) |
x - y |
| Pointwise Div | (div x y) |
x / y |
| Pointwise Pow | (pow x y) |
x ** y |
| Pointwise Eq | (eq x y) |
x == y |
| Pointwise Ne | (ne x y) |
x != y |
| Pointwise Lt | (lt x y) |
x < y |
| Pointwise Le | (le x y) |
x <= y |
| Pointwise Gt | (gt x y) |
x > y |
| Pointwise Ge | (ge x y) |
x >= y |
| Bitwise And | (bitwise_and x y) |
x & y |
| Bitwise Or | (bitwise_or x y) |
`x |
| Bitwise Xor | (bitwise_xor x y) |
x ^ y |
| Integer Remainder | (rem x y) |
x % y |
| Float Remainder | (frem x y) |
x frem y |
| Matrix Multiply | (matmul x y) |
x @ y |
| Unary Ops (generic) | (unary relu x) |
relu(x) |
| Unary Negation | (unary neg x) |
-x |
| Bitwise / Logical Not | (unary bitwise_not x) |
!x |
| Cast Type | (cast I32 x) |
x.cast(I32) |
| Transpose Axes | (transpose [1 0] x) |
x.transpose([1, 0]) |
| Reshape Tensors | (reshape x [6 1]) |
x.reshape([6, 1]) |
| Broadcast Shapes | (broadcast [2 3] x) |
x.broadcast([2, 3]) |
| Slice Axis | (slice 0 0 1 x) |
x.slice(axis=0, start=0, stop=1) |
| Concat Tensors | (concat 0 x y) |
x.concat(axis=0, y) |
| Gather Tensors | (gather x indices) |
x.gather(indices) |
| Softmax | (softmax x 1) |
x.softmax(axis=1) |
| Log-softmax | (log_softmax x 2) |
x.log_softmax(axis=2) |
| Take along axis | (take_along_axis x idx 2) |
x.take_along_axis(idx, axis=2) |
| Repeat Interleave | (repeat_interleave 0 2 x) |
x.repeat_interleave(axis=0, reps=2) |
| Reduce (Standard) | (reduce sum 1 x) |
x.reduce(op=sum, axis=1) (defaults keepdims=false) |
| Reduce Keep Dimensions | (reduce_keep mean 0 x) |
x.reduce_keep(op=mean, axis=0) or x.reduce(op=mean, axis=0, keepdims=true) |
| Copy to Device | (copy_to_device 0 x) |
x.to_device(0) |
| Copy to Host | (copy_to_host x) |
x.to_host() |
Detailed Syntax Examples
The parser also accepts fn / let / if / while, effect rows (!{…}), perform, and handle. Those forms are early Phase 2 surface, not a completed effect system. A destructuring let (y, g) = e in … names components of a flat tuple (Section 13); it is not a tensor operator. Restricted reverse-mode VJPs for reshape, variadic-batch matmul, and 2D gather are Section 14; there is no surface scatter_add. NLL ∘ decoder plus multi-weight SGD is Section 15 composition, not a new form. Functional AdamW is Section 16 composition (pow, sqrt, broadcast), not a new form. Host argmax is the existing reduce form x.reduce(op=argmax, axis=…) (Section 17); the result dtype is I64. Seeded sampling is Section 18 composition (host Uniform, log / neg, Gumbel-max, argmax), not a new form. KV-cache append is Section 19 composition (concat on the sequence axis plus rank-4 attention), not a new form. The host generation loop is Section 20 composition (static-S decode plus Section 17 argmax), not a new form. Prefill → decode handoff is Section 21 composition (forward returns Kᵀ/V; Phase 0 slice on last logits), not a new form.
1. 2D Matrix Multiplication
- S-expression core:
(matmul (tensor F32 [2 3]) (tensor F32 [3 4])) - Bootstrap
.kina:tensor<F32, [2, 3], @host> @ tensor<F32, [3, 4], @host>
2. Constraint validation with requires
- S-expression core:
(requires (= B B_prime) (= K K_prime) (matmul (tensor F32 [B M K]) (tensor F32 [B_prime K_prime N]))) - Bootstrap
.kina:requires [B = B_prime, K = K_prime] compute { tensor<F32, [B, M, K], @host> @ tensor<F32, [B_prime, K_prime, N], @host> }
3. Reductions & Keepdims
- S-expression core:
(reduce_keep mean 1 (tensor F32 [2 3])) - Bootstrap
.kina:tensor<F32, [2, 3], @host>.reduce_keep(op=mean, axis=1)
4. Slicing & Concatenating Tensors
- S-expression core:
(slice 0 0 1 (tensor F32 [2 3])) - Bootstrap
.kina:tensor<F32, [2, 3], @host>.slice(axis=0, start=0, stop=1)
5. Reshaping, Transposing & Broadcasting
- S-expression core:
(transpose [1 0] (tensor F32 [2 3])) - Bootstrap
.kina:tensor<F32, [2, 3], @host>.transpose([1, 0])