Compact language version 0.13.0.
Notational note: In the grammar productions below, ellipses are used to specify repetition. The notation X ... X, where X is a grammar symbol, represents zero or more occurrences of X. The notation X s ... s X, where X is a grammar symbol and s is a separator such as a comma or or semicolon, represents zero or more occurrences of X separated by s. In either case, when the ellipsis is marked with the superscript 1, the notation represents a sequence containing at least one X. For example, id … id represents zero or more ids, and expr , …¹ , expr represents one or more comma-separated exprs.
identifiers have the same syntax as Typescript identifiers
identifier that names one of the Ledger ADTs
a field literal is 0 or a natural number formed from a sequence of digits starting with 1-9, e.g. 723, whose value does not exceed the maximum field value
a string literal has the same syntax as a Typescript string
a version literal takes the form nat or nat.nat or nat.nat.nat, e.g., 1.2 or 1.2.3, representing major, minor, and bugfix versions
program | → | pelt … pelt |
pelt | → | pragma |
→ | incld | |
→ | mdefn | |
→ | idecl | |
→ | xdecl | |
→ | ldecl | |
→ | lconstructor | |
→ | cdefn | |
→ | edecl | |
→ | wdecl | |
→ | ecdecl | |
→ | struct | |
→ | enumdef |
pragma | → | pragma id version-expr ; |
version-expr | → | version-expr || version-term |
→ | version-expr && version-term | |
→ | version-term |
version-term | → | version-atom |
→ | ! version-term | |
→ | < version-atom | |
→ | <= version-atom | |
→ | >= version-atom | |
→ | > version-atom | |
→ | ( version-expr ) |
version-atom | → | nat |
→ | version |
incld | → | include file ; |
mdefn | → | exportopt module module-name tparamsopt { pelt … pelt } |
tparams | → | < type-param , … , type-param > |
type-param | → | # tvar-name |
→ | tvar-name |
idecl | → | import import-name targsopt prefixopt ; |
import-name | → | id |
→ | file |
targs | → | < targ , … , targ > |
prefix | → | prefix id |
export | → | export |
sealed | → | sealed |
pure | → | pure |
xdecl | → | export { id , … , id } ;opt |
ldecl | → | exportopt sealedopt ledger id : ledger-adt ; |
lconstructor | → | constructor ( arg , … , arg ) block ;opt |
cdefn | → | exportopt pureopt circuit function-name tparamsopt ( arg , … , arg ) : return-type block |
edecl | → | exportopt circuit id tparamsopt ( arg , … , arg ) : return-type ; |
wdecl | → | exportopt witness id tparamsopt ( arg , … , arg ) : return-type ; |
ecdecl | → | exportopt contract contract-name { ecdecl-circuit … ecdecl-circuit } ;opt |
ecdecl-circuit | → | pureopt circuit id ( arg , … , arg ) : return-type ; |
struct | → | exportopt struct struct-name tparamsopt { arg ; … ; arg ;opt } |
→ | exportopt struct struct-name tparamsopt { arg , … , arg ,opt } |
enumdef | → | exportopt enum enum-name { id , …¹ , id ,opt } |
Midnight ledger ADTs are described here.
ledger-adt | → | adt-name adt-argsopt |
adt-args | → | < ledger-adt-arg , …¹ , ledger-adt-arg > |
ledger-adt-arg | → | nat |
→ | adt-type |
adt-type | → | type |
→ | ledger-adt |
arg | → | id : type |
return-type | → | Void |
→ | type |
type | → | tref |
→ | Boolean | |
→ | Field | |
→ | Uint < tsize > | |
→ | Uint < tsize .. tsize > | |
→ | Bytes < tsize > | |
→ | Opaque < str > | |
→ | Vector < tsize , type > |
tref | → | id targsopt |
tsize | → | nat |
→ | id |
targ | → | nat |
→ | type |
block | → | { stmt … stmt } |
stmt | → | expr = expr ; |
→ | expr += expr ; | |
→ | expr -= expr ; | |
→ | expr-seq ; | |
→ | return expr-seq ; | |
→ | return ; | |
→ | if ( expr-seq ) stmt else stmt | |
→ | if ( expr-seq ) stmt | |
→ | for id = nat to nat do stmt | |
→ | for id in expr-seq do stmt | |
→ | assert expr str ; | |
→ | const id = expr ; | |
→ | const id : adt-type = expr ; | |
→ | block |
expr-seq | → | expr |
→ | expr , …¹ , expr , expr |
expr | → | expr0 ? expr : expr |
→ | expr0 |
fun | → | id targsopt |
→ | ( var-or-arg , … , var-or-arg ) return-type-declopt => block | |
→ | ( var-or-arg , … , var-or-arg ) return-type-declopt => expr | |
→ | ( fun ) |
return-type-decl | → | : return-type |
var-or-arg | → | id |
→ | arg |
expr0 | → | expr0 || expr1 |
→ | expr0 && expr1 | |
→ | expr0 == expr1 | expr0 != expr1 | |
→ | expr1 < expr1 | expr1 > expr1 | expr1 <= expr1 | expr1 >= expr1 | |
→ | expr1 |
expr1 | → | expr2 tail-expr1 |
tail-expr1 | → | (empty) |
→ | as type tail-expr1 |
expr2 | → | expr2 + expr3 | expr2 - expr3 |
→ | expr2 * expr3 | |
→ | expr3 |
expr3 | → | ! expr3 |
→ | expr4 |
expr4 | → | term tail-expr4 |
tail-expr4 | → | (empty) |
→ | [ nat ] tail-expr4 | |
→ | . id tail-expr4 | |
→ | . id ( expr , … , expr ) tail-expr4 |
term | → | lit |
→ | id | |
→ | default < type > | |
→ | default < ledger-adt > | |
→ | map ( fun , expr , …¹ , expr ) | |
→ | fold ( fun , expr , expr , …¹ , expr ) | |
→ | fun ( expr , … , expr ) | |
→ | tref { new-field , … , new-field } | |
→ | [ expr , … , expr ,opt ] | |
→ | ( expr-seq ) |
new-field | → | expr |
→ | id : expr | |
→ | ... expr |
lit | → | true |
→ | false | |
→ | nat | |
→ | str | |
→ | pad ( nat , str ) |