248 lines
6.0 KiB
Markdown
248 lines
6.0 KiB
Markdown
# tricu Host ABI
|
|
|
|
This document specifies the first host-facing ABI for self-hosted Arboricx execution.
|
|
|
|
The ABI is intentionally small. A host language should only need to implement Tree Calculus construction/reduction plus a tiny set of canonical payload codecs. Higher-level execution policy lives in Tree Calculus.
|
|
|
|
## Goals
|
|
|
|
- Keep host-language implementations small and auditable.
|
|
- Preserve canonical Tree Calculus representations for payloads.
|
|
- Provide a stable tagged envelope so hosts do not need per-application result conventions.
|
|
- Reuse the existing `ok` / `err` result protocol.
|
|
- Support typed execution wrappers for common return types.
|
|
|
|
## Non-goals
|
|
|
|
- This ABI does not remove the need for host codecs entirely.
|
|
- This ABI does not define every possible application protocol.
|
|
- This ABI does not require auto-detecting arbitrary result types.
|
|
|
|
## Outer result protocol
|
|
|
|
Host ABI runners return the existing tricu result shape from `lib/binary.tri`:
|
|
|
|
```tricu
|
|
ok value rest = pair true (pair value rest)
|
|
err code rest = pair false (pair code rest)
|
|
```
|
|
|
|
On success, `value` is a host ABI value.
|
|
|
|
On failure, `code` is a canonical Tree Calculus number. The host may report the numeric code and optionally inspect `rest` for debugging.
|
|
|
|
## Host ABI value shape
|
|
|
|
A host ABI value is:
|
|
|
|
```tricu
|
|
pair tag payload
|
|
```
|
|
|
|
The `tag` says how the host should interpret `payload`.
|
|
|
|
The payload is always the canonical/raw Tree Calculus representation for that type. The ABI envelope tags the payload; it does not replace or recursively wrap canonical Tree Calculus data.
|
|
|
|
## Tags
|
|
|
|
Initial tags:
|
|
|
|
```tricu
|
|
hostTreeTag = 0
|
|
hostStringTag = 1
|
|
hostNumberTag = 2
|
|
hostBoolTag = 3
|
|
hostListTag = 4
|
|
hostBytesTag = 5
|
|
```
|
|
|
|
Planned/error tag, if needed later:
|
|
|
|
```tricu
|
|
hostErrorTag = 6
|
|
```
|
|
|
|
The first implementation keeps errors in the outer `err` result protocol rather than returning `hostError` inside `ok`.
|
|
|
|
## Constructors
|
|
|
|
The ABI constructors are:
|
|
|
|
```tricu
|
|
hostTree value
|
|
hostString bytes
|
|
hostNumber n
|
|
hostBool b
|
|
hostList xs
|
|
hostBytes bytes
|
|
```
|
|
|
|
Each constructor returns:
|
|
|
|
```tricu
|
|
pair tag payload
|
|
```
|
|
|
|
Examples:
|
|
|
|
```tricu
|
|
hostString "hello"
|
|
hostNumber 42
|
|
hostBool true
|
|
hostList [1 2 3]
|
|
hostTree (t t t)
|
|
```
|
|
|
|
## Payload conventions
|
|
|
|
Payloads use existing canonical tricu encodings:
|
|
|
|
| ABI value | Payload |
|
|
| --- | --- |
|
|
| `hostTree` | arbitrary raw Tree Calculus value |
|
|
| `hostString` | canonical string/byte-list representation |
|
|
| `hostNumber` | canonical tricu number |
|
|
| `hostBool` | canonical tricu bool (`false = t`, `true = t t`) |
|
|
| `hostList` | canonical tricu list (`t` empty, `pair head tail` cons) |
|
|
| `hostBytes` | canonical byte list |
|
|
|
|
`hostList` payloads are raw canonical lists, **not** lists of host ABI values.
|
|
|
|
## Accessors / matching
|
|
|
|
The first ABI should expose simple accessors:
|
|
|
|
```tricu
|
|
hostValueTag hostValue
|
|
hostValuePayload hostValue
|
|
```
|
|
|
|
A host can decode the envelope by destructuring the pair directly, but these helpers make the ABI explicit and testable.
|
|
|
|
## Validation predicates
|
|
|
|
Typed runners should validate that the raw application result can be interpreted as the requested type before wrapping it.
|
|
|
|
Initial predicates:
|
|
|
|
```tricu
|
|
hostNumber? value
|
|
hostBool? value
|
|
hostList? value
|
|
hostString? value
|
|
hostBytes? value
|
|
```
|
|
|
|
These predicates are structural checks over canonical encodings. They are not general semantic type inference.
|
|
|
|
Important ambiguity note:
|
|
|
|
Tree Calculus encodings are not globally disjoint. For example, `t` is also `false`, `0`, and `[]`. Typed runners intentionally interpret values according to the requested type.
|
|
|
|
## Error behavior
|
|
|
|
Typed ABI runners return an error if the application result does not match the requested type.
|
|
|
|
Initial error code:
|
|
|
|
```tricu
|
|
errHostCodecFailed = 14
|
|
```
|
|
|
|
Example:
|
|
|
|
```tricu
|
|
runArboricxToString bundle args
|
|
```
|
|
|
|
returns:
|
|
|
|
```tricu
|
|
ok (hostString resultBytes) rest
|
|
```
|
|
|
|
if `resultBytes` is string-like, otherwise:
|
|
|
|
```tricu
|
|
err errHostCodecFailed result
|
|
```
|
|
|
|
where `result` is the raw application result that failed validation.
|
|
|
|
## Execution wrappers
|
|
|
|
The base self-hosted Arboricx runners are defined in `lib/arboricx.tri`:
|
|
|
|
```tricu
|
|
runArboricxArgs bundleBytes args
|
|
runArboricxArgsByName nameBytes bundleBytes args
|
|
```
|
|
|
|
Host ABI wrappers layer typed output envelopes on top:
|
|
|
|
```tricu
|
|
runArboricxToTree bundleBytes args
|
|
runArboricxToString bundleBytes args
|
|
runArboricxToNumber bundleBytes args
|
|
runArboricxToBool bundleBytes args
|
|
runArboricxToList bundleBytes args
|
|
runArboricxToBytes bundleBytes args
|
|
```
|
|
|
|
Named-export variants:
|
|
|
|
```tricu
|
|
runArboricxByNameToTree nameBytes bundleBytes args
|
|
runArboricxByNameToString nameBytes bundleBytes args
|
|
runArboricxByNameToNumber nameBytes bundleBytes args
|
|
runArboricxByNameToBool nameBytes bundleBytes args
|
|
runArboricxByNameToList nameBytes bundleBytes args
|
|
runArboricxByNameToBytes nameBytes bundleBytes args
|
|
```
|
|
|
|
## Host usage
|
|
|
|
For a bundle whose default export is an unapplied function:
|
|
|
|
```tricu
|
|
append "hello "
|
|
```
|
|
|
|
A host that expects a string result evaluates:
|
|
|
|
```tricu
|
|
runArboricxToString bundleBytes ["james"]
|
|
```
|
|
|
|
On success, the result is:
|
|
|
|
```tricu
|
|
ok (hostString "hello james") rest
|
|
```
|
|
|
|
The host then:
|
|
|
|
1. unwraps `ok`,
|
|
2. checks `hostStringTag`,
|
|
3. decodes the canonical string payload.
|
|
|
|
## Implementation reference
|
|
|
|
- Tree constructors, numbers, strings, and lists: `src/Research.hs`
|
|
- Result protocol: `lib/binary.tri`
|
|
- Arboricx parser/executor: `lib/arboricx.tri`
|
|
- Host ABI implementation: `lib/host-abi.tri` or `lib/arboricx.tri`, depending on final organization
|
|
|
|
## First-pass invariants
|
|
|
|
Tests should cover these invariants:
|
|
|
|
1. Each constructor stores the correct tag and payload.
|
|
2. `hostValueTag` and `hostValuePayload` destructure values correctly.
|
|
3. `runArboricxToTree` always wraps successful raw results as `hostTree`.
|
|
4. `runArboricxToString` wraps string-like results as `hostString`.
|
|
5. `runArboricxToNumber` wraps number-like results as `hostNumber`.
|
|
6. `runArboricxToBool` wraps canonical booleans as `hostBool`.
|
|
7. A typed runner returns `errHostCodecFailed` when validation fails.
|
|
8. Named-export typed runners select the requested export before wrapping.
|