REXX Language implementation
crexx-contract exports a compiled Level B operation as a deterministic,
machine-readable JSON contract. It is a build-time integration tool: it does
not add runtime reflection, change RXBIN, publish a C ABI, or prescribe an RPC
transport.
The public boundary is the emitted crexx.operation-contract/1 document. The
current exporter obtains type facts from CREXX’s private RXBIN semantic graph,
but consumers must not depend on that graph or its numeric IDs. A future
annotation or reflection facility may replace the metadata adapter while the
contract document and consumers remain unchanged.
Declare the operation and its payloads as Level B interfaces. The operation is one abstract interface method. Each abstract, zero-argument method on a payload interface is one read-only field:
options levelb
namespace example_contract expose operationcontract requestcontract resultcontract errorcontract
operationcontract: interface
execute: method = .resultcontract
arg request = .requestcontract, correlation = ""
requestcontract: interface
query: method = .string
tags: method = .string[]
resultcontract: interface
ok: method = .boolean
problem: method = .errorcontract
errorcontract: interface
code: method = .string
message: method = .string
Payload factories, concrete classes, default/final methods, and payload methods with arguments are rejected. Concrete classes may implement the interfaces at runtime, but their private attributes are never exported.
Compile and assemble the source, then identify the operation and its supplemental contract facts explicitly:
rxc -x -o example_contract example_contract.crexx
rxas -o example_contract example_contract.rxas
crexx-contract \
--rxbin example_contract.rxbin \
--operation example_contract.operationcontract.execute \
--contract-version 1.0.0 \
--nullable example_contract.resultcontract.problem \
--optional-field example_contract.errorcontract.details \
--error example_contract.errorcontract \
--output example_contract.rxcontract.json
--nullable TYPE.FIELD, --optional-field TYPE.FIELD, and --error TYPE are
repeatable. Every named field must be reachable from the operation or an error
type; a misspelling fails the command. Optional operation arguments come from
their compiled Level B default declarations. Omission and JSON null are
independent: fields and required inputs are present and non-null unless stated
otherwise. Format 1 does not make operation inputs or the result nullable.
Use --previous old.rxcontract.json to enforce the evolution rules before the
new output is written. Both versions must use MAJOR.MINOR.PATCH.
An installed CREXX package provides CREXX::crexx-contract and
crexx_add_operation_contract():
find_package(CREXX CONFIG REQUIRED)
crexx_add_operation_contract(
TARGET example_operation_contract
RXBIN "${CMAKE_CURRENT_BINARY_DIR}/example_contract.rxbin"
OPERATION example_contract.operationcontract.execute
CONTRACT_VERSION 1.0.0
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/example_contract.rxcontract.json"
PREVIOUS "${CMAKE_CURRENT_SOURCE_DIR}/released.rxcontract.json"
NULLABLE example_contract.resultcontract.problem
OPTIONAL_FIELDS example_contract.errorcontract.details
ERROR_TYPES example_contract.errorcontract)
TARGET, RXBIN, OPERATION, CONTRACT_VERSION, and OUTPUT are required.
PREVIOUS is optional. The helper creates the named build target and sets
<TARGET>_OUTPUT in the caller’s scope. The RXBIN may itself be the output of a
custom command; the generated contract then follows that dependency without a
source-tree fallback.
Every UTF-8 document has these top-level members, in deterministic order:
| Member | Meaning |
|---|---|
format |
Always crexx.operation-contract |
formatVersion |
Always 1 for this grammar |
contractVersion |
Caller-owned semantic version for the operation |
operation |
Fully qualified interface and method identity |
input |
Ordered operation parameters with required, nullable, and schema |
result |
Result schema |
errors |
Sorted structured error schemas |
types |
Sorted closed set of referenced interface-record definitions |
Record fields are sorted by their UTF-8 names. Operation inputs retain call order. Optimized and non-optimized builds of the same declarations produce the same document.
The format-1 type mapping is:
| Level B type | JSON contract schema |
|---|---|
.string |
{"kind":"string"} |
.boolean |
{"kind":"boolean"} |
.int |
integer with signed 64-bit minimum and maximum |
.float |
finite number; NaN and infinities are outside the contract |
.decimal |
string with encoding: "crexx-decimal" to retain exact spelling |
.binary |
string with contentEncoding: "base64" |
.T[] |
ordered homogeneous array with the recursively mapped item schema |
| payload interface | record referring to its fully qualified type name |
.void |
void, for an operation result only |
Only one-dimensional dynamic arrays are accepted. Fixed, bounded, or
multidimensional arrays; references/exposed parameters; varargs; .object;
.unknown; concrete payload classes; and ambiguous relative type names fail
closed. Interface inheritance is flattened into the derived record and
conflicting inherited field definitions are rejected.
formatVersion changes only when the JSON document grammar changes.
contractVersion describes one operation:
The document describes typed input, result, and structured error payloads. It does not define HTTP status codes, an invocation envelope, ownership of a transport buffer, or runtime error dispatch; those remain responsibilities of the selected host adapter.