Language structure
OSL source is a sequence of top-level declarations and removals. Whitespace separates entries. Blocks do not use semicolons, and lists do not use commas. Function arguments are the exception: commas separate arguments inside parentheses.
condition readiness [not_ready ready]
entity "van-110" {
traits [vehicle van]
}
drop entity "retired-van"
The current lexer does not support comments. A marker such as # or //
produces an unknown-token diagnostic.
Identifiers and identities
An identifier starts with an ASCII letter or underscore. Later characters can also be digits.
vehicle
payload_mass
ready_2
Conditions and mutation roles use identifiers. Entities, mutations, and tasks use quoted string identities.
condition readiness [ready]
entity "van-110" {}
mutation "transport-payload" {}
task "deliver-cargo-42" {}
The lexer accepts backslash escapes inside quoted strings. Decoding and validation of those escapes during change generation are incomplete, so avoid escaped identities and description values for now.
Numbers and quantities
Numbers contain digits and can have a decimal fraction. A leading sign is a unary operator rather than part of the number token.
0
59.3293
-18.0686
A quantity is a number, whitespace, and a unit. A compound unit can contain slash-separated identifier segments without spaces around the slash.
800 kg
0.08 l/km
70 km/h
Change generation stores the numeric value, decimal scale, and unit label. It does not convert units or check dimensional compatibility. Unary quantities are parsed but are not safe to lower yet.
Blocks and lists
Curly braces contain named sections or expressions. Square brackets contain identifiers or reference paths, depending on the section.
entity "cargo-42" {
properties {
mass = 120 kg
}
traits [cargo]
}
Inside supported sections, prefix an entry with drop to request removal of
that entry. Whitespace is sufficient between entries. OSL does not yet have a
formatter or canonical formatting rule.
Source order and context
The parser preserves source order. Current change generation does not resolve declarations against one another, collect forward declarations, or accept a separate base source. References remain symbolic for later engine validation.