# nonterminal
# alternative
# ...
#
# * indicates zero or more items
# <n>* indicates N or more items
# [optional] items are bracketed
# /.../ indicates a regex rule
#
# Whitespace is ignored.
#
# Invariants:
#
# - A set of "in" and "out" parameters is only supported with the "call" IPC
# method (call foo{a, b, c; d, e, f}(...)).
# - Result types using "options" may include up to one "type" (or void), any
# number of unit types, and any number of error types (or "error" for any
# error).
# - All names must be unique
#
# ABI:
#
# Each interface is assigned a unique ID by taking the FNV-32 of its name
#
# A message label is iface << 16 | serial, where serial is assigned from 0 for
# each method in order of appearance.
#
# Each IPC message has two result registers: the label of the message tag, and
# the IPC register.
#
# The label selects the result type from among the options and has the
# following 48-bit format:
#
# 0000000000000000HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
#
# If the result is a primitive or enum type, all bits are set to zero. For unit
# and error results, H is set to the FNV-32 hash of the fully qualified
# identifier of the unit or error in question. All of the 0 bits are reserved.
#
# A side-effect of this design is that errors and unit types have a 32-bit
# identifier equal to their Hare type ID.
#
# The actual value of a nominal reply is stored in register two as the
# appropriate type (e.g. uint). Errors which include a value store this value in
# register two as well.
document
"namespace" identifier ";" *import 1*member
import
"use" identifier ";"
member
unit ";"
error ";"
enum ";"
interface ";"
unit
"unit" word ["=" uint]
enum
"enum" word "{" 1*enum-members "}"
enum-members
word ","
word "=" uint ","
word "=" uint "<<" uint ","
error
"error" word ["=" uint] [":" type]
interface
"interface" word ["=" uint] ["::" parents] "{" *method "}"
"interface" word "::" parents
parent
identifier [","]
identifier "," parent
method
call
send
recv
call
"call" word [cap-list] "(" [param-list] ")" result
send
"send" word [cap-list] "(" [param-list] ")"
recv
"recv" word [cap-list] "(" [param-list] ")"
cap-list
"{" capabilities ["..."] [";" capabilities ["..."]] "}"
capabilities
capability [","]
capability "," capabilities
capability
word
word ":" identifier
param-list
params ["..."]
params
param [","]
param "," params
param
word ":" type
type
enum-name
"uint"
"u8"
"u16"
"u32"
"u64"
"int"
"i8"
"i16"
"i32"
"i64"
"size"
"uintptr"
result
result-type
result-type "|" error-list
error-list
error-type
error-list "," error-type
error-type
error-name
error-name "::" "*"
result-type
type
unit-name
enum-name
"void"
options
result-type ["|"]
result-type "|" options
identifier
word
identifier "::" word
uint
/[0-9]+/
/0x[0-9a-zA-Z]+/
/0o[0-8]+/
/0b[01]+/
word
/[a-zA-Z][a-zA-Z0-9_]*/
enum-name
identifier
unit-name
identifier
error-name
identifier