Pseudocode DSL
Pseudocode DSL
Section titled “Pseudocode DSL”The pseudo-code DSL is a compact generation notation for executable sigMAX handlers.
It is not a general-purpose programming language and it is not a runtime interpreter. It is a controlled bridge between contracts, generated C subset code, WASM modules and the runtime primitives exposed by runtime/C/sigma.h.
The current runtime repository makes this boundary concrete through runtime/functions.toon, runtime/C/sigma.h, generated storage declarations and component contracts. Those files define what the DSL may express and what it must never invent.
What It Represents
Section titled “What It Represents”The DSL describes handler behavior at the level that matters for deterministic generation:
| DSL concern | Runtime counterpart |
|---|---|
| Read route/body input | input_get_param_string, input_read_object |
| Validate and normalize values | bounded string, conversion, URL, regex and math helpers |
| Call storage or services | primitive_call_typed with a declared target such as storage.invoice.get |
| Build public output | response status plus ObjectIR fields |
| Raise handled errors | status, structured error primitive, then return -1 |
| Stay inside policy | capabilities, bindings, generated storage and agreements |
This keeps the generated handler small enough to review while preserving the real execution constraints of the WASM runtime.
Generation Boundary
Section titled “Generation Boundary”The runtime repository validates a contract-first flow where generated business handlers call only sigMAX primitives:
| Step | Responsibility |
|---|---|
| Contract | Declares features, routes, storage intent, runtime primitives and required binary behavior. |
| Pseudocode DSL | Captures the handler algorithm using a constrained vocabulary. |
| C subset | Materializes the algorithm with sigma.h helpers and imports. |
| WASM | Runs inside the sigMAX runtime without direct host access. |
| Agreement | Records generated artifacts, storage operations, bindings and validation evidence. |
The DSL should therefore stay close to contract language, but every operation must have a deterministic lowering path.
Core Rules
Section titled “Core Rules”The runtime primitive catalog defines the safety rules that generated pseudo-code must preserve.
- Use only declared sigMAX primitives.
- Include only
runtime/sigma.hfrom generated C handlers. - Do not call Linux functions directly.
- Do not use libc
mallocorfree; usesx_mallocandsx_freeonly when stack buffers are not enough. - Do not use direct SQL, raw sockets, filesystem access,
system,execor process APIs. - Do not build public HTTP responses as raw JSON strings.
- Build responses through response and ObjectIR primitives.
- Initialize fixed-size structs with
sx_memzero. - Validate inputs before storage, HTTP or service calls.
- Return
0after a successful response. - For handled errors, set the status, emit the error and return
-1.
Return Convention
Section titled “Return Convention”Generated handlers follow the same convention as the C/WASM primitive surface.
| Result | Meaning |
|---|---|
>= 0 | Success, bytes written, boolean success marker or handle depending on the primitive. |
< 0 | sigMAX error code. |
-1 | Handled business/API error after the response status and structured error have been emitted. |
0 | Successful handler completion after the response has been generated. |
This convention is intentionally simple so validation can detect mismatched success/error paths.
Generated Format
Section titled “Generated Format”Generated pseudo-code is sigmax.pseudo/v0.1 text. It is not JSON, YAML, Markdown or C. A generated function starts with compact metadata lines: the first token is always the two-character key #S, followed by the full DSL schema version.
| Prefix | Required | Meaning |
|---|---|---|
#S | yes | Schema/version line. The first line is #S sigmax.pseudo/v0.1. |
#M | yes | Binary or route module name. |
#F | yes | Exported handler function and return type, such as handle_get_invoice -> i32. |
#C | optional | Contract path used to generate the pseudo-code. |
#D | optional | Short description. |
#V | optional | Additional generated artifact version. |
After metadata, executable operations use two-uppercase-letter DSL instructions. Inline @... aliases are reserved for explicit pseudo functions such as @string.len(...); raw C calls such as sx_strlen(...) stay forbidden in generated pseudo-code.
Instruction Equivalence
Section titled “Instruction Equivalence”The parser accepts the following V1 instruction shape. The generator should emit these instructions, then deterministic tooling lowers them to the C subset and runtime primitives.
| DSL | Equivalent lowering | Typical use |
|---|---|---|
VA | C variable declaration | Declare binary-contract variables or scalar temporaries. |
IN | sx_memzero or scalar zeroing | Initialize declared values before use. |
IP | input_get_param_string | Read a path parameter into a bounded field. |
IQ | input_get_param_string | Read a query parameter into a bounded field. |
IH | input_get_param_string | Read an allowed header into a bounded field. |
IB | input_read_object | Read a typed request body. |
OE | status plus error_validation or error_raise | Attach handled error behavior to the previous failable instruction. |
VR | string presence check plus validation error | Require a non-empty string field. |
VN | numeric minimum check plus validation error | Require a numeric field to be at least a minimum value. |
LE | scalar assignment | Compute into a declared scalar temporary. |
CP | bounded copy loop | Copy a fixed-size array field. |
AS | field assignment or bounded copy | Assign a scalar or structured field. |
CA | primitive_call_typed | Call a declared storage or service binding. |
HG | sx_http_get | Call a capability-controlled logical HTTP target. |
SH | sx_sha256_hex | Hash bounded data as SHA-256 hex. |
B6 | sx_base64_encode | Base64-encode bounded data. |
BD | sx_base64_decode | Base64-decode bounded data. |
RM | sx_regex_match | Match bounded input with a bounded regex. |
RR | sx_regex_remove | Remove regex matches from bounded input. |
JS | sx_json_get_string | Extract a string field from bounded JSON. |
JI | sx_json_get_i64 | Extract an int64 field from bounded JSON. |
JF | sx_json_get_f64 | Extract a float64 field from bounded JSON. |
JB | sx_json_get_bool | Extract a boolean field from bounded JSON. |
TN | sx_now_unix_ms | Read current time when allowed. |
TF | sx_format_unix_ms_iso8601 | Format a timestamp as UTC ISO-8601. |
UE | sx_url_encode | Percent-encode a URL component. |
UD | sx_url_decode | Decode a percent-encoded URL component. |
QE | sx_query_param_encode | Encode one query key/value pair. |
IF | C if block | Branch on a safe comparison. |
EL | C else block | Open the alternative branch. |
EN | block close | Close an IF or EL block. |
ST | response_status | Set the public HTTP status. |
EV | error_validation | Emit a validation error. |
ER | error_raise | Emit a structured runtime/API error. |
OB | obj_begin | Start ObjectIR output. |
OI | obj_field_i64 | Emit an integer ObjectIR field. |
OS | obj_field_string | Emit a string ObjectIR field. |
OX | obj_end | Close ObjectIR output. |
RE | C return | Return 0 or -1. |
Recognized but not implemented for V1 emission: CO, VX, VG, VL, VM, CV, FR, OF, OO, ON. Reserved and forbidden in V1: WH, GO, SW, BR, CT.
Generated Pseudocode Example
Section titled “Generated Pseudocode Example”The example below is representative pseudo-code for a generated GET /invoices/{id} handler. It is compact on purpose: every two-letter instruction has a deterministic lowering path.
#S sigmax.pseudo/v0.1#M get_invoice#F handle_get_invoice -> i32#C contracts/binary/get_invoice.contract.yamlVA req:GetInvoiceRequest invoice:InvoiceIN req invoiceIP id -> req.id max 32OE 400 EV id "Missing invoice id"CA storage.invoice.get req -> invoiceOE 503 ER STORAGE_UNAVAILABLE "Storage service unavailable"IF invoice.found == 0ST 404ER INVOICE_NOT_FOUND "Invoice not found"RE -1ENST 200OBOI invoice_id invoice.invoice_idOI total_cents invoice.total_centsOXRE 0This is not executable source by itself. The generator lowers it to C subset code using input_get_param_string, primitive_call_typed, response_status, ObjectIR primitives and the typed c_repr structures recorded by the contracts and agreements.
Equivalent C Lowering
Section titled “Equivalent C Lowering”The generated C shape below is representative of the deterministic lowering. Exact struct definitions and helper signatures come from the binary contract, generated c_repr files and runtime/C/sigma.h.
#include "runtime/sigma.h"
typedef struct { char id[32];} GetInvoiceRequest;
typedef struct { int32_t found; int64_t invoice_id; int64_t total_cents;} Invoice;
int32_t handle_get_invoice(void) { GetInvoiceRequest req; Invoice invoice; int32_t rc;
sx_memzero(&req, sizeof(req)); sx_memzero(&invoice, sizeof(invoice));
rc = input_get_param_string("id", req.id, sizeof(req.id)); if (rc < 0 || sx_is_blank(req.id, sizeof(req.id)) != 0) { response_status(400); error_validation("id", "Missing invoice id"); return -1; }
rc = primitive_call_typed( "storage.invoice.get", &req, sizeof(req), &invoice, sizeof(invoice) ); if (rc < 0) { response_status(503); error_raise("STORAGE_UNAVAILABLE", "Storage service unavailable"); return -1; }
if (invoice.found == 0) { response_status(404); error_raise("INVOICE_NOT_FOUND", "Invoice not found"); return -1; }
response_status(200); obj_begin(); obj_field_i64("invoice_id", invoice.invoice_id); obj_field_i64("total_cents", invoice.total_cents); obj_end(); return 0;}Equivalent Algorithmic Flow
Section titled “Equivalent Algorithmic Flow”Primitive Alias Catalog
Section titled “Primitive Alias Catalog”runtime/functions.toon also records compact @... aliases for primitive references. They are catalog vocabulary for generation and review; V1 executable pseudo-code should still use the two-letter instructions above, except for accepted inline pseudo functions such as @string.len(...).
| Alias | Lowers to | Alias | Lowers to |
|---|---|---|---|
@zero | sx_memzero | @mal | sx_malloc |
@free | sx_free | @gpar | input_get_param_string |
@body | input_read_object | @pcall | primitive_call_typed |
@stat | response_status | @verr | error_validation |
@err | error_raise | @obeg | obj_begin |
@oi64 | obj_field_i64 | @ostr | obj_field_string |
@oend | obj_end | @string.len | sx_strlen |
@stnln | sx_strnlen | @steq | sx_streq |
@stneq | sx_strneq | @empty | sx_is_empty |
@blank | sx_is_blank | @copy | sx_copy |
@cpyn | sx_copy_n | @trim | sx_trim |
@lower | sx_to_lower | @upper | sx_to_upper |
@pi64 | sx_parse_i64 | @i64s | sx_i64_to_string |
@add64 | sx_i64_add_checked | @mul64 | sx_i64_mul_checked |
@rmat | sx_regex_match | @rrem | sx_regex_remove |
@hget | sx_http_get | @hpost | sx_http_post_json |
@hreq | sx_http_request_json_ext | @jstr | sx_json_get_string |
@ji64 | sx_json_get_i64 | @jf64 | sx_json_get_f64 |
@jbool | sx_json_get_bool | @sha | sx_sha256_hex |
@b64e | sx_base64_encode | @b64d | sx_base64_decode |
@now | sx_now_unix_ms | @fmtms | sx_format_unix_ms_iso8601 |
@urlen | sx_url_encode | @urldc | sx_url_decode |
@qenc | sx_query_param_encode | @jbini | sx_json_builder_init |
@jbbo | sx_json_builder_begin_object | @jbs | sx_json_builder_field_string |
@jbi64 | sx_json_builder_field_i64 | @jbb | sx_json_builder_field_bool |
@jbeo | sx_json_builder_end_object | @jblen | sx_json_builder_len |
@hmac | sx_hmac_sha256_hex | @uuid | sx_uuid_v4 |
@rand | sx_random_bytes | @kvstr | sx_kv_find_string |
@kvi64 | sx_kv_find_i64 |
Primitive Families
Section titled “Primitive Families”The runtime catalog groups primitives by whether they are pure helpers or host-controlled imports.
| Family | Kind | DSL meaning |
|---|---|---|
| Runtime | core | memory zeroing, bounded allocation and shared return codes. |
| Input | host | read route parameters, headers, typed bodies or raw validated JSON. |
| Response and ObjectIR | host | produce public HTTP output in a structured way. |
| Storage and invocation | host | call a declared binding such as storage.invoice.create. |
| String, convert, math, URL, KV | pure | deterministic local helpers with bounded buffers. |
| Regex, JSON, HTTP, crypto, time | host | runtime-controlled helpers with capability and size checks. |
| JSON builder | pure | build small internal JSON payloads for allowed calls. |
| Secret and random | host | use host-managed secrets or randomness without exposing raw host state. |
Pure helpers can be used without capabilities. Host primitives require the capability and import declared by the contract or agreement.
Storage Calls
Section titled “Storage Calls”The runtime repository shows the intended storage model with generated/storage.yaml.
The WASM handler does not know PostgreSQL exists. It calls primitive_call_typed with a logical operation name such as storage.invoice.get or storage.invoice.create. The runtime resolves that target through route bindings, invokes the storage service, converts between JSON and c_repr, and returns a typed output buffer.
| Layer | Example |
|---|---|
| DSL | call declared storage operation |
| C subset | primitive_call_typed("storage.invoice.get", ...) |
| Runtime binding | route binding and capability check |
| Storage declaration | generated/storage.yaml operation |
| Storage service | generic select_one or insert_one interpreter |
| Public handler | maps storage result to ObjectIR and HTTP status |
This is why direct SQL is forbidden in generated handlers. SQL belongs to generated storage declarations and migration/init files, not to WASM business code.
Capability Rules
Section titled “Capability Rules”The DSL must make capability use explicit.
- HTTP targets are logical names, never arbitrary URLs.
- Unknown HTTP targets, methods, paths and headers are denied.
- Random and current time are denied unless the route declares the capability.
- Secret helpers receive a logical
secret_ref; they do not expose raw secret bytes. - Regex and JSON helpers are runtime-controlled and bounded.
- Every host import used by generated code must be allowed by the binary contract.
| Capability area | Example primitive |
|---|---|
| Input | input.body.read, input.params.read |
| Response | response.write, objectir.write |
| Storage/invocation | primitive.call |
| HTTP | http.get, http.post_json, http.request_json_ext |
| JSON | json.read |
| Regex | regex.match, regex.remove |
| Crypto | crypto.hash, crypto.base64 |
| Time/random/secret | time.now, random.uuid, secret.hmac_sha256 |
Bounded Limits
Section titled “Bounded Limits”The catalog records concrete default limits for generated code and validation.
| Area | Default limit |
|---|---|
| Regex pattern | 256 bytes |
| Regex input/output | 8192 bytes |
| HTTP response body | 8192 bytes |
| JSON input | 8192 bytes |
| JSON path | 256 bytes |
| Random bytes | 1024 bytes |
| UUID output | 37 bytes including null terminator |
| HMAC SHA-256 hex output | 65 bytes including null terminator |
Generated pseudo-code should treat those limits as design constraints, not implementation details.
Handler Shape
Section titled “Handler Shape”A generated handler should normally follow a predictable sequence.
- Read typed input or route parameters.
- Validate required fields and parse primitive values.
- Use pure helpers for deterministic transformations.
- Call host primitives only when declared by the route and binary contract.
- Build public output through ObjectIR.
- Set status before success or handled error output.
- Return
0on success,-1after handled errors, or a negative primitive error when the runtime cannot continue.
What The DSL Must Not Do
Section titled “What The DSL Must Not Do”| Forbidden behavior | Reason |
|---|---|
| Direct SQL in handler logic | Storage behavior belongs to generated storage declarations. |
| Direct filesystem access | WASM modules must not access host files. |
| Raw sockets or arbitrary URLs | Networking must go through policy-controlled logical targets. |
| libc allocation and unsafe string functions | Memory and buffers must remain bounded and inspectable. |
| Raw JSON public responses | Public output should use response/ObjectIR primitives. |
| Invented primitive names | The runtime can only register known imports in the sigmax namespace. |
Documentation Rule
Section titled “Documentation Rule”When documenting or generating pseudo-code, prefer the smallest expression that still preserves:
- the contract-level intent;
- the exact primitive or helper family;
- the required capability;
- the typed input and output boundary;
- the success and handled-error path;
- the agreement evidence that will prove what was generated.
That keeps the DSL readable for humans and strict enough for deterministic generation.