This repository has been archived on 2025-03-27. You can view files and clone it, but cannot push or open issues or pull requests.
szun-old/README.md

752 lines
14 KiB
Markdown

# Suzu Runtime / Notation
Szun is a library for defining, manipulating, and formatting structured, dynamically-typed data.
## Runtime
The Szun runtime provides an interface for constructing and modfying data objects.
## Encoding
Szun uses a tag-prefixed, hierarchical, binary encoding with variable-sized values to produce serializations of reduced size.
## Language
Szun notation provides a human-readable format for structures and data to be defined.
The notation may be parsed and loaded at runtime or compiled directly into encoded format.
# Runtime Documentation
## Conventions
### Namespacing
Examples in this documentation will assume inclusion of the szun namespace.
Practical examples should use `szun::` or `use szun::{...};` in limited scopes.
### Interface Usage
While the runtime provides methods for directly acquring and releasing memory, it is recommended that developers use typed interfaces to ensure memory is freed upon leaving scope.
## Data Types
|Type|Code|Parameters|Description|
|---|---|---|---|
|Undefined|x00|--|Data is not defined|
|Varying|x01|--|Stores any data type|
|Boolean|x02|--|True or false|
|Natural|x10|--|Non-negative integers|
|Integer|x11|--|Integers|
|Significant|x13|--|Fixed-precision, variable-magnitude numbers|
|Block|x1e|size|Constant-sized series of bytes|
|Sequence|x1f|--|Variable-sized series of bytes|
|Array|x22|size, type|Constant-sized, ordered collection|
|List|x23|type|Variable-sized, ordered collection|
|Record|x7e|schema|Instance of a schema|
|Schema|x7f|--|Definition of abstract structure|
### Type Building
Type building functions are used to generate identifiers used in the construction of complex data types.
* `varying()`
* `boolean()`
* `natural()`
* `integer()`
* `significant()`
* `block(size)`
* `sequence()`
* `array(size, type)`
* `list(type)`
* `record(schema)`
* `schema()`
#### Example
This example produces an identifier representing a block of 4 bytes, which can be used to construct a list containing that type.
```
let type_id = block(4);
let list = List::new(type_id);
```
## Code Examples
### Example 1
```
const VEC3F :usize = 0x200;
const VEC3U :usize = 0x201;
const MESH :usize = 0x202;
fn vec3f(x:f64, y:f64, z:f64) -> szun::Record
{
use szun::*;
Record::with_values(VEC3F, vec![
*Significant::with(x),
*Significant::with(y),
*Significant::with(z),
]).unwrap()
}
fn vec3u(x:u64, y:u64, z:u64) -> szun::Record
{
use szun::*;
Record::with_values(VEC3U, vec![
*Natural::with(x),
*Natural::with(y),
*Natural::with(z),
]).unwrap()
}
fn main()
{
use szun::*;
// Vec3f
Schema::with(vec![
("x", significant()),
("y", significant()),
("z", significant()),
]).bind(VEC3F);
// Vec3u
Schema::with(vec![
("x", natural()),
("y", natural()),
("z", natural()),
]).bind(VEC3U);
// Mesh
Schema::with(vec![
("vertices", list(record(VEC3F))),
("faces", list(record(VEC3U))),
]).bind(MESH);
let pyramid = Record::with(MESH, vec![
("vertices", *List::with(record(VEC3F), vec![
*vec3f(0.0, 2.0, 0.0),
*vec3f(1.0, 0.0, 1.0),
*vec3f(1.0, 0.0, -1.0),
*vec3f(-1.0, 0.0, -1.0),
*vec3f(-1.0, 0.0, 1.0),
])),
("faces", *List::with(record(VEC3U), vec![
*vec3u(0, 1, 2),
*vec3u(0, 2, 3),
*vec3u(0, 3, 4),
*vec3u(0, 4, 1),
*vec3u(1, 2, 3),
*vec3u(1, 3, 4),
])),
]).unwrap();
}
```
## Global Functions
`acquire(type) -> Reference`
Allocate a new instance of the provided type.
```
let refer = acquire(list(integer()));
```
---
`release(refer:Reference)`
Destruct and deallocate an object.
```
release(refer);
```
---
`transfer(dst:Reference, src:Reference) -> Result<(),()>`
Move an object from one location to another, clearing the original.
```
let original = Sequence::with("Hello, world!");
let target = Sequence::new();
println!("{}", original.get()); // prints "Hello, world!"
println!("{}", target.get()); // prints ""
transfer(target, original).ok();
println!("{}", original.get()); // prints ""
println!("{}", target.get()); // prints "Hello, world!"
```
---
`copy(dst:Reference, src:Reference) -> Result<(),()>`
Copy the contents of an object to another location, keeping the original.
```
let original = Sequence::with("Hello, world!");
let target = Sequence::new();
println!("{}", original.get()); // prints "Hello, world!"
println!("{}", target.get()); // prints ""
copy(target, original).ok();
println!("{}", original.get()); // prints "Hello, world!"
println!("{}", target.get()); // prints "Hello, world!"
```
---
## Encoding
Encoding converts data between runtime memory and binary serialization.
`encode(refer:Reference) -> Vec<u8>`
`encode_raw(refer:Reference) -> Vec<u8>`
`encode_tag(refer:Reference) -> Vec<u8>`
Serializes an object into binary encoding.
The raw variant does not produce a tag prefix for the root object.
The tag variant only produces a tag prefix.
---
`decode(data:&Vec<u8>, index:&mut usize) -> Result<Type,()>`
`decode_raw(data:&Vec<u8>, type_id:usize, index:&mut usize) -> Result<Type,()>`
`decode_tag(data:&Vec<u8>, index:&mut usize) -> Result<usize,()>`
Parses a valid binary encoding and produces the represented object.
The raw variant does not decode a tag prefix on the root object.
The tag variant only decodes a tag prefix.
---
## Language Compiler
> Not implemented
## Common Methods
`new() -> Self`
```
let value = Integer::new();
```
---
`from(refer:Reference) -> Result<Self,()>`
```
match Integer::from(list.at(0)) {
Ok(int) => { println!("Integer: {}", int.get()); }
Err(_) => { println!("Not Integer"); }
}
```
---
`*Dereference -> Reference`
```
let refer = *Integer::new();
```
---
## Varying
Stores a value of any other type.
`is_null() -> bool`
Indicates whether or not the variable contains a object.
---
`get() -> Reference`
Returns a reference to the contained object.
```
let var = Varying::with(*Boolean::with(true));
let value = Boolean::from(var.get()).unwrap();
```
---
`set(refer:Reference)`
Replaces the contained object.
```
let var = Varying::new();
var.set(*Sequence::with("Hello!"));
```
---
`clear()`
Removes the contained object.
---
## Boolean
Stores the value true or false.
`get() -> bool`
Returns the contained value.
```
let value = Boolean::with(true);
if value.get() {
println!("True");
}
```
---
`set(value:bool)`
Replaces the contained value.
```
let mut value = Boolean::new();
value.set(true);
```
---
## Natural
Stores a non-negative integer value.
`get() -> u64`
Returns the contained value.
```
let value = Integer::with(-1);
println!("{}", value.get());
```
---
`set(value:u64)`
Replaces the contained value.
```
let mut value = Integer::new();
value.set(-273);
```
---
## Integer
Stores a signed integer value.
`get() -> i64`
Returns the contained value.
```
let value = Integer::with(-1);
println!("{}", value.get());
```
---
`set(value:i64)`
Replaces the contained value.
```
let mut value = Integer::new();
value.set(-273);
```
---
## Decimal
Stores a constant-magnitude number with whole and decimal components.
> Not implemented.
## Significant
Stores a fixed-precision, variable-magnitude number.
> Encode/decode not implemented.
`get() -> f64`
Returns the contained value.
---
`set(value:f64)`
Replaces the contained value.
---
## Block
Constant-sized series of bytes.
`new(size:usize) -> Block`
Produces a new block of the specified size.
---
`size() -> usize`
Returns the size of the allocated block.
---
`get() -> Vec<u8>`
Returns the contents of the block.
---
`at(index:usize) -> u8`
Returns the byte at the specified index or zero if out of bounds.
---
`set(data:Vec<u8>)`
Replaces the contents of the block up to the length of the parameter.
---
`set_at(index:usize, data:u8)`
Replaces the byte at the given index.
---
## Sequence
Variable-sized series of bytes.
`capacity() -> usize`
Returns the memory capacity of the sequeunce.
---
`size() -> usize`
Returns the length of the series.
---
`get() -> String`
Returns a UTF-8 string representation of the series.
---
`get_raw() -> Vec<u8>`
Returns the contents of the series.
---
`at(index:usize) -> u8`
Returns the byte at the specified index or zero if out of bounds.
---
`set(data:&str)`
Replaces the contents with the byte representation of a string.
---
`set_raw(data:Vec<u8>)`
Replaces the contents with a series of bytes.
---
`set_at(index:usize, data:u8)`
Replaces a byte at the given index.
---
`reserve(capacity:usize)`
Reallocates the sequeunce to have capacity not less than the specified size.
---
## Array
Constant-sized, indexed collection of items.
`new(length:usize, type_id:usize) -> Array`
Produces a new array of given type and length.
---
`length() -> usize`
Returns the length of the array.
---
`at(index:usize) -> Reference`
Returns a reference to the element at the given index or a null reference if out of bounds.
---
`set(index:usize, source:Reference)`
Replaces the element at the given index with a copy of the source.
---
`kindof() -> usize`
Returns the type identifier of the contents.
---
## List
Variable-sized, indexed collection of items.
`new(type_id:usize) -> List`
Produces a new list of the given type.
---
`capacity() -> usize`
Returns the allocated capacity of the list.
---
`length() -> usize`
Returns the length of the list.
---
`at(index:usize) -> Reference`
Returns the object at the given index or a null reference if out of bounds.
---
`set(index:usize, source:Reference)`
Replaces the object at the given index with a copy of the source.
---
`insert(index:usize, source:Reference)`
Inserts a copy of the source at a given index.
---
`remove(index:usize)`
Removes the object at the given index from the list.
---
`reserve(capacity:usize)`
Reallocates the list to have capacity not less than the specified size.
---
`clear()`
Removes all elements from the list.
---
## Sparse
List of discontinuous indicies.
`length() -> usize`
Returns the number of elements in the collection.
---
`at(index:usize) -> Reference`
Returns a reference to the item at the specified index.
---
`has(key:usize) -> bool`
Returns whether the specified key is assigned.
---
`get(key:usize) -> Reference`
Returns a reference to the item at the specified key.
---
`set(key:usize, source:Reference)`
Adds or updates an element at the specified key.
---
`unset(key:usize)`
Removes an element from the collection.
---
`clear()`
Removes all elements from the collection.
---
`indexof(index:usize) -> usize`
Returns the key of the element at the specified index.
---
## Schema
Definition of an abstract structure composed of named items.
> Encode/decode not implemented.
`with(members:Vec<(&str, usize)>) -> Schema`
Produces a schema with the provided member assignments.
```
let schema_rgba = Schema::with(vec![
("r", significant()),
("g", significant()),
("b", significant()),
("a", significant()),
]);
```
---
`get(index:usize) -> usize`
Returns the type identifier of the given index or zero if out of bounds.
---
`add(type_id:usize) -> usize`
Appends a member of the specified type to the schema.
---
`remove(index:usize)`
Removes the member at the given index from the schema.
---
`assign(key:&str, type_id:usize) -> usize`
Appends a member of the specified type to the schema and maps the provided string to that index.
---
`map(key:&str, index:usize)`
Maps a string to the specified index.
---
`unmap(key:&str)`
Removes a mapping of the specified string from the schema.
---
`clear()`
Removes all members and mappings from the schema.
---
`bind(id:usize)`
Submits the template to the schema database under the provided identifier.
> Note: zero is used as a wildcard identifier and is not a valid parameter.
```
let vec3i = Schema::with(vec![
("x", integer()),
("y", integer()),
("z", integer()),
]).bind(0x100);
```
---
## Record
Instance of a schema.
`new(schema_id:usize) -> Result<Record,()>`
Produces a new record of the provided schema.
---
`with(schema_id:usize, data:Vec<(&str, Reference)>) -> Result<Record,()>`
Produces a record of the provided schema and keyed assignments.
---
`with_values(schema_id:usize, data:Vec<Reference>) -> Result<Record,()>`
Produces a record of the provided schema and indexed assignments.
---
`length() -> usisze`
Returns the number of elements in the record.
---
`at(index:usize) -> Reference`
Returns a reference to the member at the given index.
---
`set(index:usize, source:Reference)`
Replaces the member at the given index with a copy of the source.
---
`keyof(index:usize) -> String`
Returns the string mapped to the specified index or an empty string if no mapping exists.
---
`indexof(key:&str) -> usize`
Returns the index of a mapped string or the number of elements in the record if no mapping exists.
---
`kindof(index:usize) -> usize`
Returns the type identifier of the given index.
---