OBGX uses a standardized, language-independent textual notation to define and represent interfaces.
This notation is used by the OBGX specification. An implementation is not required to parse or execute the notation directly.
The notation of a type is defined on this page. The abstract meaning of that type is defined by the Type System, and behavior that occurs when an operation is performed is defined by Execution.
Lexical Structure
Spaces, horizontal tabs, carriage returns, and line feeds are whitespace. Whitespace may separate tokens and is otherwise ignored, except inside string literals and comments.
A line comment starts with // and ends before the next line ending or at the end of the document. A block comment starts with /* and ends at the next */. Block comments do not nest. Comments are treated as whitespace.
// Line comment
/*
Block comment
*/
Identifiers
Identifiers name types, objects, fields, functions, parameters, and enum members. They are case-sensitive and must match ^[A-Za-z_][A-Za-z0-9_]*$.
Types and enum members are usually named with PascalCase, while objects, fields, functions, and parameters are usually named with camelCase. These naming conventions are not enforced by OBGX.
Module identifiers and element identifiers use the separate schemes defined in Terminology.
Reserved Words
Declaration keywords type and enum are reserved and must not be used as user-defined identifiers.
Literals
A string literal is a sequence of Unicode scalar values enclosed in double quotation marks ("). A line ending is not permitted inside a string literal. \" represents a quotation mark and \\ represents a backslash; OBGX does not define other string escape sequences.
A positive integer literal is a sequence that matches ^[1-9][0-9]*$.
The boolean literals are true and false.
Type Expressions
A type expression is a named type, a fundamental type, an array or vector type, a function type, an opaque handle type, or the any wildcard. A type expression that contains any or * is a type pattern; any other type expression is a concrete type expression. Parentheses may group a type expression.
Named and Fundamental Types
A named type is written as its identifier. The fundamental type names are:
i8
i16
i32
i64
u8
u16
u32
u64
f32
f64
bool
string
id
refid
Wildcards and Type Patterns
A type pattern describes one or more admissible concrete types in an OBGX interface. The type wildcard is written as any:
The constant-value wildcard is written as *. It may appear only in a syntactic position that explicitly permits a compile-time constant parameter. In this version of OBGX, only the array-length position permits it. * is not an integer literal or a value expression.
Wildcards do not introduce names or bind later occurrences. Each occurrence is independent.
Array and Vector Types
An array type is written as an element type followed by a positive integer literal in square brackets:
Signs, digit separators, and expressions are not permitted in an array length.
In an array type pattern, * may replace the positive integer literal to match any valid array length:
any[any] is invalid because an array length is a compile-time integer parameter, not a type position.
A vector type is written as an element type followed by an empty pair of square brackets:
An empty pair of square brackets always denotes a vector. It does not denote an array with an unspecified length. Therefore, any[] is a pattern for any vector, while any[*] is a pattern for any array.
Array and vector suffixes bind to the type expression immediately to their left and are applied from left to right. Therefore, the following denotes an array of four vectors of i32:
Parentheses can make grouping explicit when a suffix applies to a function type or another nested type expression. Therefore, the following denotes an array of four functions that take an i32 and return a bool:
((value: i32) => bool)[4]
Function Types
A function type consists of a parenthesized, comma-separated parameter list, =>, and a return type. Each parameter has an identifier and a type expression. A return type is either a type expression or void:
(param1: type1, param2: type2) => returnType
A zero-parameter function type uses an empty parameter list:
void must appear only as the direct return type of a function type or function declaration. It must not appear in any other type position, and array or vector suffixes must not be applied to it.
A comma is not permitted after the last parameter.
Opaque Handle Types
An opaque handle type is written with hndl and a string literal that gives its semantic name:
Declarations
Object Declarations
An object declaration consists of an identifier, :, a type expression, and ;:
Compound Type Declarations
A compound type declaration starts with type, followed by the type identifier and a brace-delimited sequence of field declarations. Each field declaration must be followed by ;.
type TypeName {
field1: type1;
field2: type2;
}
An empty compound type is permitted:
Enum Declarations
An enum declaration starts with enum, followed by the type identifier and a non-empty, brace-delimited, comma-separated list of member identifiers. A trailing comma is not permitted.
enum EnumTypeName {
Value1,
Value2
}
A member identifier may be followed by a parenthesized type expression that gives the member's payload type:
enum EnumTypeName {
Value1,
Value2(PayloadType)
}
A member value is written as:
The payload of a member value is written as:
EnumTypeName.Value2.payload
Function Declarations
A function declaration consists of a function identifier, a parenthesized parameter list, :, and a return type. Parameters use the same form and comma rules as function types.
functionName(param1: type1, param2: type2): returnType
A zero-parameter function declaration uses an empty parameter list:
Field References
An object field may be referenced in specification text by joining the object identifier and field identifier with .:
This notation identifies a field; it does not define an expression language or runtime field-access behavior.