# hx — language reference

Version 0.4.1

`hx` is a small array engine. A script is a sequence of newline-separated commands, at most
512 of them. Every command prints either `ok`, a value, or an `error:` line.

## Object kinds

Every object carries an **elements kind** describing what its storage holds:

| kind | storage |
|---|---|
| `smi` | 64-bit integers |
| `obj` | references to other objects |
| `buf` | raw bytes |

The kind is fixed when the object is created. **Operations that combine objects check that
their kinds agree and refuse to mix them**, so an integer can never be read back as a
reference and a reference can never be read back as an integer. This was tightened in 0.3
after an internal review and is covered by the regression suite.

## Commands

```
smi <name> <len>            create an integer array
obj <name> <len>            create a reference array
buf <name> <len>            create a byte buffer

seti <name> <idx> <int>     store an integer
seto <name> <idx> <src>     store a reference to another object
addi <name> <idx> <delta>   add to an element in place
geti <name> <idx>           print an element as an integer
setq <name> <off> <u64>     write 8 bytes into a buffer

elem <name> <src> <idx>     bind a name to element <idx> of a reference array
concat <dst> <a> <b>        concatenate two arrays of the SAME kind
slice <dst> <src> <start> <n>   copy <n> elements starting at <start>

kind <name>                 print an object's kind and length
debug <name>                print the object's address, for debugging
noop                        do nothing
```

### Notes

- `concat` requires both operands to carry the same elements kind. Mixed-kind
  concatenation is rejected with `error: kind mismatch`.
- `slice` was historically off-by-one at the upper bound and accepted `start + n == len + 1`.
  This was fixed in 0.4; if you are on an older build, upgrade.
- `debug` prints the object's address. It is intended for development and is expected to be
  removed before this engine is embedded anywhere that matters.
- `elem` only ever yields objects the engine itself allocated, because reference arrays can
  only ever contain engine-allocated pointers.

## Limits

| | |
|---|---|
| objects per script | 64 |
| elements per array | 4096 |
| lines per script | 512 |
| wall clock | 10 s |

## Running scripts

```
curl -s -XPOST $BASE/v1/run -H 'content-type: application/json' \
     -d '{"script":"smi a 4\nseti a 0 1234\ngeti a 0\n"}'
```

The engine binary is published at `/v1/download/hx` so you can run scripts locally against
exactly the build this host is serving.
