# APX IDL v1.2 This is the specification for the APX Interface Definition Language (IDL) v1.2. ## Definition files APX IDL is used when writing *definition files* that use the `.apx` file extension. Preferably these files should be generated by a toolchain, but they can also be written by hand. Each file shall be used to describe one *APX node*. Placing multiple node declarations in the same file is not permitted. ### Line endings The only acceptable line ending (EOL) is the UNIX line ending (`\n`). If you are a Windows developer, remember to convert your APX definition file to UNIX line endings before use. ### Structure of an APX Definition File 1. [APX Header](#apx-header) 2. [Node Declaration](#node-declarations) 3. [Type Declaration(s)](#type-declarations) (Optional) 4. [Port Declaration(s)](#port-declarations) **Example:** ```yaml APX/1.2 N"Example" T"VehicleSpeed_T"S T"EngineSpeed_T"S P"VehicleSpeed"T[0]:=65535 P"EngineSpeed"T[1]:=65535 ``` ## APX Header The first line of the definition file must contain an APX header. Inspired by HTTP headers, it consists of the prefix `APX/` followed by the IDL version number. **Example:** ```yaml APX/1.2 ``` ## Statements and specifiers Following the APX header line are one or more APX statement lines. The first letter of each line selects the statement type: | Statement Specifier | Statement Type | |:---|:---| | **N** | [Node Declaration](#node-declarations) | | **T** | [Type Declaration](#type-declarations) | | **R** | [Require-Port Declaration](#require-port-declaration) | | **P** | [Provide-Port Declaration](#provide-port-declaration) | There can be at most one statement per line; there is no statement separator in APX IDL other than the end-of-line (EOL) character. ## Node Declarations A *node declaration* begins a new APX *node*. All subsequent lines belong to that node. Each node has a name (string literal enclosed in quotes) that must be unique within the APX client. There can only be a single node declaration per definition file. A Node declaration does not have an attribute section. **Example:** ```yaml N"MyNode" ``` ## Type Declarations A type declaration statement creates a new named type that can be referenced later by one or more [port declarations](#port-declarations). {bdg-primary}`'T'` {bdg-success}`Name` {bdg-danger}`Data-Signature` **Example:** ```yaml # Type "VehicleSpeed_T" with type uint16 T"VehicleSpeed_T"S ``` You can also include an optional type attribute section separated by a `:` character: {bdg-primary}`'T'` {bdg-success}`Name` {bdg-danger}`Data-Signature` {bdg-secondary}`:` {bdg-info}`Type-Attribute` **Example:** ```yaml # Type "OffOn_T" with type uint8, range 0..3 and ValueTable T"OffOn_T"C(0,3):VT("OffOn_Off", "OffOn_On", "OffOn_Error", "OffOn_NotAvailable") ``` ## Data Signatures ### Primitive Type Codes APX uses single-letter primitive type codes. In general, lowercase letters represent *signed* types and uppercase letters represent *unsigned* types. | Type Code | Platform Type | Bits | Lower Limit | Upper Limit | |:---|:---|:---|:---|:---| | **c** | int8 | 8 | -128 | 127 | | **s** | int16 | 16 | -32768 | 32767 | | **l** | int32 | 32 | -2147483648 | 2147483647 | | **u** | int64 | 64 | -(2^63) | (2^63)-1 | | **C** | uint8 | 8 | 0 | 255 | | **S** | uint16 | 16 | 0 | 65535 | | **L** | uint32 | 32 | 0 | 4294967295 | | **U** | uint64 | 64 | 0 | (2^64)-1 | | **a** | unsigned char | 8 | 0 | 255 | ### Array Types Any primitive type code can be followed by `[n]`, where `n` is the number of array elements. **Examples:** ```yaml C[3] # type: uint8, array-length: 3, memory-size: 3 bytes S[4] # type: uint16, array-length: 4, memory-size: 8 bytes ``` ### Strings Declaring an array using the `a` type code turns the type into a string. The array length declares how many bytes the string can contain (at most). APX allows writing of strings whose length is shorter than or equal to the maximum number of array elements (bytes). In that case, APX automatically sets the remaining bytes to null (`\0`). **Examples:** ```yaml a[10] # type string, array-length: 10, memory-size: 10 bytes a[40] # type string, array-length: 40, memory-size: 40 bytes ``` ### Data Limits All primitive type codes can have an optional lower/upper limit by appending `(Lower, Upper)` immediately after the type code: - **Lower**: Lower data limit (decimal integer) - **Upper**: Upper data limit (decimal integer) When combined with an array declaration, the limit is placed before the array brackets. **Examples:** ```yaml C(0,1) # type: uint8, lower-limit: 0, upper-limit: 1 C(0,3) # type: uint8, lower-limit: 0, upper-limit: 3 S(0,10000) # type: uint16, lower-limit: 0, upper-limit: 10000 C # type: uint8, lower-limit: 0 (implicit), upper-limit: 255 (implicit) S # type: uint16, lower-limit: 0 (implicit), upper-limit: 65535 (implicit) C(0,3)[10] # type: uint8 array, length: 10, limits: 0..3 for each element ``` ### Record Types Record types (structs) are declared in APX by wrapping the data signature in braces `{}`. Each record element consists of two parts: - Element name: String literal enclosed in quotes - Element signature: [Data Signature](#data-signatures) Record elements are placed consecutively without whitespace or separators. **Examples:** ```yaml # Record with 2 elements: "UserId" (uint32) and "UserName" (string of max 64 bytes) {"UserId"L"UserName"a[64]} # Record with 3 uint8 elements {"Red"C"Green"C"Blue"C} ``` *Note:* For APX IDL v1.2, implementations are not required to support nested records. APX IDL v1.3 introduces that conformance requirement. ### Type References Data signatures can reference a type definition using the capital letter `T` followed by the numeric type index enclosed in brackets `[]`. **Example:** ```yaml T"VehicleSpeed_T"S # This type has index 0 T"EngineSpeed_T"S # This type has index 1 P"VehicleSpeed"T[0]:=65535 # References VehicleSpeed_T P"EngineSpeed"T[1]:=65535 # References EngineSpeed_T ``` *Note:* This version of the IDL does not support type reference by name (see [APX IDL v1.3](apx_idl_13.md)). ## Type Attributes In APX IDL v1.2 there is only a single type attribute, the ValueTable. ### Value Table A ValueTable maps enumeration names onto a data type. It uses the `VT(...)` syntax with a comma-separated list of string literals: **Example:** ```yaml VT("OffOn_Off", "OffOn_On", "OffOn_Error", "OffOn_NotAvailable") ``` ## Port Declarations There are two types of ports in APX: - **Require-ports (`R`)**: Input ports receiving data into the node. - **Provide-ports (`P`)**: Output ports transmitting data from the node. ### Require-port Declaration A Require-port declaration starts with capital letter `R` followed by its name and data signature: {bdg-primary}`'R'` {bdg-success}`Name` {bdg-danger}`Data-Signature` ```yaml # Require-port "VehicleSpeed" with data type uint16 R"VehicleSpeed"S # Require-port "EngineSpeed" with type reference 1 R"EngineSpeed"T[1] ``` Optional port attributes are appended after a colon `:` separator: {bdg-primary}`'R'` {bdg-success}`Name` {bdg-danger}`Data-Signature` {bdg-secondary}`:` {bdg-info}`Port-Attributes` ```yaml # Require-port with init-value R"VehicleSpeed"S:=65535 ``` ### Provide-port Declaration A Provide-port declaration starts with capital letter `P` followed by its name and data signature: {bdg-primary}`'P'` {bdg-success}`Name` {bdg-danger}`Data-Signature` ```yaml # Provide-port "VehicleSpeed" with data type uint16 P"VehicleSpeed"S # Provide-port with init-value P"VehicleSpeed"S:=65535 ``` ## Port Attributes Port attributes appear after the colon `:` separator in a port declaration. Multiple attributes are separated by commas. ### Init-Value The init-value attribute sets the initial value of the port data. If no init-value exists, the port data defaults to zero. APX accepts four forms of initializers: #### Decimal and Hexadecimal Initializers ```yaml =7 # Decimal init-value =255 # Decimal init-value =0xff # Hexadecimal init-value =0xffff # Hexadecimal init-value ``` #### String Initializer ```yaml ="" # Empty string initializer ``` #### Record Initializer ```yaml ={255, 255, 255} # Record initializer for data signature containing 3 members ``` ## Full Language Specification ```yaml Document ApxHeader '\n' Statements ApxHeader 'APX/1.2' Statements Statement '\n' Statement '\n' Statement Statement NodeDeclaration TypeDeclaration RequirePortDeclaration ProvidePortDeclaration NodeDeclaration 'N' Name TypeDeclaration 'T' Name TypeSignature 'T' Name TypeSignature ':' TypeAttributes RequirePortDeclaration 'R' Name TypeSignature 'R' Name TypeSignature ':' PortAttributes ProvidePortDeclaration 'P' Name TypeSignature 'P' Name TypeSignature ':' PortAttributes Name '"' NameChars '"' Names Name Name ',' Names NameChars NameChar NameChar NameChars NameChar 'a' . 'z' 'A' . 'Z' '0' . '9' '_' '-' TypeSignature PrimitiveType PrimitiveType '[' OneNine Digits ']' 'T[' Digits ']' '{' RecordElements '}' PrimitiveType c s l u C S L U RecordElements Name TypeSignature Name TypeSignature ',' RecordElements TypeAttributes TypeAttribute TypeAttribute ',' TypeAttributes TypeAttribute VT(Names) PortAttributes PortAttribute PortAttributes ',' PortAttributes PortAttribute '=' Integer '=' StringLiteral Integer Digit OneNine Digits '-' Digit '-' OneNine Digits '0x' HexDigits Digits Digit Digit Digits Digit '0' OneNine OneNine '1' . '9' HexDigits HexDigit HexDigit HexDigits HexDigit Digit 'a' . 'f' 'A' . 'F' StringLiteral '"' '"' '"' Characters '"' Characters character character characters character '0020' . '007F' - '"' ```