Overview
The .kry language is a path-based, virtual filesystem language. Every value is accessed through a path, and operations are performed by writing to device files. It compiles to compact .krb bytecode.
Example
const meta {
title "Inner Breeze"
ver "alpha"
by "waozi"
id "xyz.waozi.inbe"
}
var env {
w 200
h 400
pause 0
}
def window {
write /dev/wctl [ new 0 0 %size[0] %size[1] %title ]
}
def button {
write /dev/draw [ rect %pos[0] %pos[1] %size[0] %size[1] 0xCCCCCC ]
fn center {
if %value {
write /dev/draw [
%cmd
[ + %pos[0] [ / %size[0] 2 ] ]
[ + %pos[1] [ / %size[1] 2 ] ]
50 50
%value
%color
]
}
}
center {
cmd text
pos %pos
size %size
value %label
color 0x000000
}
listen /dev/mouse {
bounds [ %pos[0] %pos[1] %size[0] %size[1] ]
enter { write /dev/cursor 2 }
exit { write /dev/cursor 1 }
down { %action }
}
}
window {
title /meta/title
size [ /env/w /env/h ]
button {
pos [ 50 250 ]
size [ 80 30 ]
label "Click Me"
action {
write /dev/cons "Button clicked!\n"
}
}
}
Syntax Rules
- Whitespace: Spaces, tabs, and newlines are insignificant
- Strings: Double-quoted:
"hello"— Strings are only for literal text, not paths - Numbers: Decimal integers:
50,-1, hex colors:0xFF0000 - Blocks: Defined with curly braces:
{ ... } - Arrays: Bracketed lists:
[ 1 2 3 ] - Paths: Not strings — use paths directly:
/dev/draw,./radius
Paths
Paths are the primary way to access data in Kryon. Paths are not strings.
Absolute Paths
Root-level paths start with /:
/dev/draw
/dev/wctl
/dev/mouse
/dev/timer
/dev/cons
/meta/title
/env/w
Relative Paths
Paths starting with ./ refer to the current VFS node:
./radius
./dir
./color
Parent Paths
Paths starting with ../ refer to the parent VFS node:
../speed
../size
../title
Path Context
The command position determines whether a path is read or written:
write /dev/draw [ text 5 5 /meta/title 0x000000 ] // write to /dev/draw
write ./radius [ + ./radius ./dir ] // write to ./radius
listen /dev/mouse { ... } // read from /dev/mouse
Root Blocks
Top-level blocks define the structure of your program.
const
Compile-time constants. Creates a read-only VFS folder.
const meta {
title "Inner Breeze"
ver "alpha"
by "waozi"
id "xyz.waozi.inbe"
}
Accessible at: /meta/title, /meta/ver, etc.
var
Mutable runtime variables. Creates a read-write VFS folder.
var env {
w 200
h 400
breaths 30
rounds 3
pause 0
}
Accessible at: /env/w, /env/h, etc.
const for Data Structures
You can define complex data structures like sprites/glyphs:
const glyph {
play [
[ . . . . . . . . ]
[ . # . . . . . . ]
[ . # # . . . . . ]
[ . # # # . . . . ]
[ . # # # # . . . ]
[ . # # # . . . . ]
[ . # # . . . . . ]
[ . # . . . . . . ]
]
pause [
[ . . . . . . . . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . . . . . . . . ]
]
}
Accessible at: /glyph/play, /glyph/pause.
Definitions and Functions
def
Creates a real VFS instance folder when called. Each invocation creates a new numbered instance.
def button {
write /dev/draw [ rect %pos[0] %pos[1] %size[0] %size[1] 0xCCCCCC ]
}
Calling it creates numbered instances:
button { pos [ 10 10 ] size [ 80 30 ] } // Creates /0
button { pos [ 10 50 ] size [ 80 30 ] } // Creates /1
fn
Expands inline and does not create a VFS folder. Use for helper code.
fn center {
if %value {
write /dev/draw [
%cmd
[ + %pos[0] [ / %size[0] 2 ] ]
[ + %pos[1] [ / %size[1] 2 ] ]
50 50
%value
%color
]
}
}
Parameters
Parameters use the %name syntax and are passed into def and fn blocks.
Common Parameters
%pos // Position [x y]
%size // Size [w h] or single value
%label // Text label
%icon // Glyph/sprite reference
%action // Action block
%value // Generic value
%color // Color value
Nil Handling
Missing parameters default to nil. Use if to check:
if %icon {
write /dev/draw [ mask ... %icon ... ]
}
Current and Parent Paths
Use relative paths within definitions to access local state.
def circle {
write /dev/draw [ circ %center[0] %center[1] ./radius %color ]
%logic
}
circle {
center [ 100 100 ]
radius 40
color 0xFF0000
dir 1
logic {
listen /dev/timer {
tick ../speed {
write ./radius [ + ./radius ./dir ]
if [ >= ./radius 60 ] {
write ./dir -1
}
if [ <= ./radius 40 ] {
write ./dir 1
}
}
}
}
}
Control blocks like action, logic, tick, enter, exit, down do not create folders, so ./radius inside an action still refers to the parent circle.
Device Files
Device files provide I/O operations. Write to them to perform actions.
| Device | Purpose | Operations |
|---|---|---|
/dev/wctl | Window control | new, size, title |
/dev/draw | Drawing commands | rect, circ, text, mask |
/dev/mouse | Mouse/touch input | listen with bounds, enter, exit, down |
/dev/timer | Timer events | listen with tick |
/dev/cons | Console output | write for debug output |
/dev/cursor | Cursor control | write cursor ID |
/dev/wctl - Window Control
write /dev/wctl [ new 0 0 200 400 "My Window" ]
/dev/draw - Drawing
// Draw rectangle
write /dev/draw [ rect x y w h color ]
// Draw circle
write /dev/draw [ circ center_x center_y radius color ]
// Draw text
write /dev/draw [ text x y string color ]
// Draw glyph mask
write /dev/draw [ mask x y 50 50 glyph_ref color ]
/dev/mouse - Mouse/Touch Input
listen /dev/mouse {
bounds [ x y w h ]
enter { write /dev/cursor 2 } // hand cursor
exit { write /dev/cursor 1 } // arrow cursor
down { %action }
}
/dev/timer - Timer Events
listen /dev/timer {
tick 100 { // every 100ms
write ./radius [ + ./radius 1 ]
}
}
Commands
write
Write data to a path.
write /dev/draw [ rect 10 10 50 50 0xFF0000 ]
write ./radius [ + ./radius 1 ]
write /dev/cons "Debug output\n"
listen
Listen for events on a device.
listen /dev/mouse {
bounds [ %pos[0] %pos[1] %size[0] %size[1] ]
down { %action }
}
listen /dev/timer {
tick 50 { ... }
}
if
Conditional execution.
if [ >= ./radius 60 ] {
write ./dir -1
}
if %value {
write /dev/draw [ ... ]
}
Operations and Expressions
Operations are written in bracketed prefix notation.
Arithmetic
[ + a b ] // Addition
[ - a b ] // Subtraction
[ * a b ] // Multiplication
[ / a b ] // Division
Comparison
[ >= a b ] // Greater than or equal
[ <= a b ] // Less than or equal
[ == a b ] // Equal
[ != a b ] // Not equal
Nested Operations
[ + %pos[0] [ / %size[0] 2 ] ] // pos[0] + (size[0] / 2)
write ./radius [ + ./radius ./dir ]
Array Indexing
%pos[0] // First element of pos array
%size[1] // Second element of size array
/env/w // Access const/var value
Colors
Colors are specified as hexadecimal values.
0xFF0000 // Red
0x00FF00 // Green
0x0000FF // Blue
0xFFFFFF // White
0x000000 // Black
0xCCCCCC // Gray
Animations with Timers
Animations are created by listening to timer events and updating values.
Pulsing Circle
def circle {
write /dev/draw [ circ %center[0] %center[1] ./radius %color ]
%logic
}
circle {
center [ 100 100 ]
radius 40
color 0xFF0000
dir 1
logic {
listen /dev/timer {
tick 50 {
write ./radius [ + ./radius ./dir ]
if [ >= ./radius 60 ] {
write ./dir -1
}
if [ <= ./radius 40 ] {
write ./dir 1
}
}
}
}
}
Multi-Property Animation
var env {
w 200
h 400
}
window {
speed 50
size [ /env/w /env/h ]
circle {
center [ 100 100 ]
radius 30
color 0xFF0000
red_dir 1
green_dir 0
blue_dir 0
logic {
listen /dev/timer {
tick ../speed {
// Animate through colors
if [ == ./red_dir 1 ] {
write ./color [ + ./color 0x000100 ]
if [ >= ./color 0x00FF00 ] { write ./red_dir 0; write ./green_dir 1 }
}
if [ == ./green_dir 1 ] {
write ./color [ + ./color 0x000001 ]
if [ >= ./color 0x0000FF ] { write ./green_dir 0; write ./blue_dir 1 }
}
}
}
}
}
}
Complete Grammar
file ::= (root_block | def | fn)*
root_block ::= 'const' identifier block
| 'var' identifier block
def ::= 'def' identifier block
fn ::= 'fn' identifier block
block ::= '{' stmt* '}'
stmt ::= path value? // property assignment
| 'def' identifier block // nested definition
| 'fn' identifier block // nested function
| 'write' path array // write command
| 'listen' path block // event listener
| 'if' path block // conditional
| control_block // action, logic, tick, etc.
path ::= '/' path_segment+
| './' path_segment+
| '../' path_segment+
path_segment ::= identifier
| '[' expression ']' // array index
expression ::= path
| number
| string
| '[' op expression+ ']' // operation
op ::= '+' | '-' | '*' | '/' | '>=' | '<=' | '==' | '!='
array ::= '[' (expression|array)* ']'
control_block ::= 'action' block
| 'logic' block
| 'tick' number block
| 'enter' block
| 'exit' block
| 'down' block
number ::= [0-9]+ | '0x' [0-9A-Fa-f]+
string ::= '"' [^"]* '"'
identifier ::= [a-zA-Z_][a-zA-Z0-9_]*
Complete Example: Breathing App
const meta {
title "Inner Breeze"
ver "alpha"
by "waozi"
id "xyz.waozi.inbe"
}
const glyph {
play [
[ . . . . . . . . ]
[ . # . . . . . . ]
[ . # # . . . . . ]
[ . # # # . . . . ]
[ . # # # # . . . ]
[ . # # # . . . . ]
[ . # # . . . . . ]
[ . # . . . . . . ]
]
pause [
[ . . . . . . . . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . # # . . # # . ]
[ . . . . . . . . ]
]
}
var env {
w 200
h 400
breaths 30
rounds 3
pause 0
}
def window {
write /dev/wctl [ new 0 0 %size[0] %size[1] %title ]
}
def center {
if %value {
write /dev/draw [
%cmd
[ + %pos[0] [ / %size[0] 2 ] ]
[ + %pos[1] [ / %size[1] 2 ] ]
50 50
%value
%color
]
}
}
def button {
write /dev/draw [ rect %pos[0] %pos[1] %size[0] %size[1] 0xCCCCCC ]
center {
cmd text
pos %pos
size %size
value %label
color 0x000000
}
center {
cmd mask
pos %pos
size %size
value %icon
color 0x000000
}
listen /dev/mouse {
bounds [ %pos[0] %pos[1] %size[0] %size[1] ]
enter { write /dev/cursor 2 }
exit { write /dev/cursor 1 }
down { %action }
}
}
def circle {
write /dev/draw [ circ %center[0] %center[1] ./radius %color ]
%logic
}
window {
title /meta/title
speed 50
size [ /env/w /env/h ]
circle {
center [ 100 100 ]
radius 40
color 0xFF0000
dir 1
logic {
listen /dev/timer {
tick ../speed {
write ./radius [ + ./radius ./dir ]
if [ >= ./radius 60 ] {
write ./dir -1
}
if [ <= ./radius 40 ] {
write ./dir 1
}
}
}
}
}
cent_x [ / /env/w 2 ]
button {
pos [ [ - ../cent_x 40 ] 250 ]
size [ 20 20 ]
action {
write /dev/cons "hello world\n"
}
icon /glyph/play
}
button {
pos [ [ - ../cent_x 10 ] 250 ]
size [ 20 20 ]
action {
if [ == /env/pause 0 ] {
write /env/pause 1
write ./icon /glyph/play
} else {
write /env/pause 0
write ./icon /glyph/pause
}
}
icon /glyph/pause
}
}