Fix bugs, update interface, update README.

This commit is contained in:
yukirij 2023-08-18 12:05:02 -07:00
parent 7addefd634
commit ac28278830
9 changed files with 275 additions and 37 deletions

192
README.md
View File

@ -90,6 +90,8 @@ Copy the contents of an objcet to another location, keeping the original.
---
## Encoding
Encoding converts data between runtime memory and binary serialization.
`encode(refer:Reference) -> Vec<u8>`
`encode_raw(refer:Reference) -> Vec<u8>`
@ -138,6 +140,12 @@ let b = Boolean::with(true);
```
---
`detatch()`
Prevents an allocated object from being dropped when the interface goes out of scope.
---
`*Dereference -> Reference`
```
@ -151,7 +159,7 @@ Stores a value of any other type.
`is_null() -> bool`
Specifies whether or not the variable contains a object.
Indicates whether or not the variable contains a object.
---
@ -175,6 +183,12 @@ var.set(*Sequence::with("Hello!"));
```
---
`clear()`
Removes the contained object.
---
## Boolean
Stores the value true or false.
@ -249,16 +263,26 @@ value.set(-273);
```
---
## Decimal
Stores a constant-magnitude number with whole and decimal components.
> Not implemented.
## Significant
Stores a fixed-precision, variable-magnitude number.
> Not implemented.
`get() -> f64`
Returns the contained value.
---
`set(value:f64)`
Replaces the contained value.
---
@ -267,61 +291,129 @@ Constant-sized series of bytes.
`new(size:usize) -> Block`
Produces a
---
`length() -> usize`
`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.
`length() -> usize`
`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, ordered collection of items.
`new(size:usize, type_id:usize) -> Array`
`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, refer:Reference)`
`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.
---
@ -331,96 +423,170 @@ Variable-sized, ordered collection of items.
`new(type_id:usize) -> List`
---
`length() -> usize`
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`
---
`set(index:usize, refer:Reference)`
Returns the object at the given index or a null reference if out of bounds.
---
`insert(index:usize, refer:Reference)`
`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.
---
## Schema
Definition of an abstract structure composed of named items.
`with(members:Vec<(&str, usize)>) -> Schema`
Produces a schema with the provided member assignments.
---
`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 schema to the
---
## Record
Instance of a schema.
`new(schema_id:usize) -> Record`
`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.
---

View File

@ -35,10 +35,10 @@ impl Schema {
}
}
pub fn with(data:Vec<(&str, usize)>) -> Self
pub fn with(members:Vec<(&str, usize)>) -> Self
{
let mut obj = Self::new();
for binding in data {
for binding in members {
let (key, type_id) = binding;
obj.assign(key, type_id);
}

View File

@ -2,7 +2,7 @@ use crate::runtime::{
Reference,
acquire, release,
type_key,
sequence_length,
sequence_capacity, sequence_length,
sequence_clear, sequence_reserve,
sequence_get,
sequence_insert,
@ -43,7 +43,6 @@ impl Sequence {
pub fn with(data:&str) -> Self
{
let mut obj = Self::new();
println!("a");
obj.set(data);
return obj;
}
@ -59,6 +58,11 @@ impl Sequence {
unsafe { release(self.addr); }
}
pub fn capacity(&self) -> usize
{
unsafe {sequence_capacity(self.addr)}
}
pub fn size(&self) -> usize
{
unsafe {sequence_length(self.addr)}
@ -67,7 +71,6 @@ impl Sequence {
pub fn set_raw(&mut self, data:Vec<u8>)
{
unsafe { sequence_clear(self.addr); }
println!("c {}", data.len());
if data.len() > 0 {
unsafe { sequence_reserve(self.addr, data.len()); }
for i in 0..data.len() {
@ -85,7 +88,6 @@ impl Sequence {
{
let length = unsafe {sequence_length(self.addr)};
let mut result = Vec::<u8>::new();
println!("d {}", length);
if length > 0 {
result.reserve_exact(length);

View File

@ -10,12 +10,14 @@ pub fn release(addr:runtime::Reference)
unsafe {runtime::release(addr)}
}
pub fn copy(_dst:runtime::Reference, _src:runtime::Reference) -> Result<(),()>
pub fn copy(dst:runtime::Reference, src:runtime::Reference) -> Result<(),()>
{
Err(())
if unsafe {runtime::copy(dst, src)} { Ok(()) }
else { Err(()) }
}
pub fn transfer(_dst:runtime::Reference, _src:runtime::Reference) -> Result<(),()>
pub fn transfer(dst:runtime::Reference, src:runtime::Reference) -> Result<(),()>
{
Err(())
if unsafe {runtime::transfer(dst, src)} { Ok(()) }
else { Err(()) }
}

View File

@ -3,6 +3,7 @@ use crate::runtime::{
acquire, release,
type_key,
varying_get, varying_set,
varying_clear,
};
use crate::tag;
use super::varying;
@ -51,6 +52,11 @@ impl Varying {
unsafe { varying_set(self.addr, source); }
}
pub fn clear(&mut self)
{
unsafe { varying_clear(self.addr); }
}
pub fn get(&self) -> Reference
{
unsafe { varying_get(self.addr) }

View File

@ -19,7 +19,7 @@ pub fn test() {
("rec", record(9)),
]).bind(10);
let out = encode(*Record::with(10, vec![
let rec = Record::with(10, vec![
("str", *Sequence::with("hello!")),
("int", *Integer::with(-70)),
("bool", *Boolean::with(true)),
@ -27,7 +27,14 @@ pub fn test() {
("nat", *Natural::with(8)),
("pass", *Block::with(6, vec![1, 2, 3, 4, 5, 6])),
]).unwrap()),
]).unwrap());
]).unwrap();
let out = encode(*rec);
print!("[{}]: ", out.len());
for byte in &out {
print!("{:02x} ", *byte);
} println!("\n");
match decode(&out, &mut 0) {
Ok(ty) => match ty {
Type::Record(rec) => {

View File

@ -129,7 +129,10 @@ extern "C" size_t type_hasinner(size_t type_id)
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
{
std::string str(reinterpret_cast<const char*>(bytes), length);
return DB_NAME.indexof(str);
if(str.size() > 0) {
return DB_NAME.indexof(str);
}
return 0;
}
extern "C" Str name_keyof(size_t index)
@ -243,7 +246,7 @@ extern "C" void release(Reference addr)
}
}
bool copy(Reference src, Reference dst)
extern "C" bool copy(Reference dst, Reference src)
{
if(src.address != dst.address) {
Reference source = src;
@ -271,6 +274,8 @@ bool copy(Reference src, Reference dst)
// copy data into destination
if(source.type == destination.type) {
drop(destination);
switch(type_key(destination.type)) {
case Type::Tag::Null: { } break;
@ -288,11 +293,12 @@ bool copy(Reference src, Reference dst)
rawlist_clear(dst_seq.data);
rawlist_reserve(dst_seq.data, sizeof(uint8_t), src_seq.data.length);
memcpy(dst_seq.data.data, src_seq.data.data, sizeof(uint8_t) * src_seq.data.length);
dst_seq.data.length = src_seq.data.length;
} break;
case Type::Tag::Array: {
for(size_t i = 0; i < array_length(source); ++i) {
copy(array_cell(source, i), array_cell(destination, i));
copy(array_cell(destination, i), array_cell(source, i));
}
} break;
@ -300,12 +306,11 @@ bool copy(Reference src, Reference dst)
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
auto& dst_list = *reinterpret_cast<Type::List*>(destination.address);
drop(destination);
rawlist_reserve(dst_list.data, type_size(type_inner(source.type)), src_list.data.capacity);
dst_list.data.length = src_list.data.length;
for(size_t i = 0; i < src_list.data.length; ++i) {
copy(list_at(source, i), list_at(destination, i));
copy(list_at(destination, i), list_at(source, i));
}
} break;
@ -316,7 +321,7 @@ bool copy(Reference src, Reference dst)
for(size_t i = 0; i < binding->data.size(); ++i) {
auto src_cell = record_cell(source, i);
auto dst_cell = record_cell(destination, i);
copy(src_cell, dst_cell);
copy(dst_cell, src_cell);
}
}
} break;
@ -354,6 +359,43 @@ bool copy(Reference src, Reference dst)
return false;
}
extern "C" bool transfer(Reference dst, Reference src)
{
if(src.address != dst.address) {
Reference source = src;
Reference destination = dst;
// dereference varying data
if(type_key(src.type) == Type::Tag::Varying) {
source = *reinterpret_cast<Reference*>(src.address);
}
// prepare destination for varying data
if(type_key(dst.type) == Type::Tag::Varying) {
auto& dest_ref = *reinterpret_cast<Reference*>(dst.address);
// determine if memory can be reused, otherwise free and reallocate
if(source.type != dest_ref.type) {
if(dest_ref.address != nullptr) {
free(dest_ref.address);
dest_ref.type = Type::Tag::Null;
dest_ref.address = nullptr;
}
dest_ref = acquire(source.type);
}
}
// copy data into destination
if(source.type == destination.type) {
drop(destination);
memcpy(destination.address, source.address, type_size(source.type));
memset(source.address, 0, type_size(source.type));
return true;
}
}
return false;
}
Reference resolve_addr(Reference addr)
{
Reference result = addr;
@ -394,7 +436,7 @@ extern "C" void varying_set(Reference addr, Reference source)
var.address = allocate(source.type, 1);
}
copy(source, var);
copy(var, source);
}
extern "C" void varying_clear(Reference addr)
@ -476,6 +518,12 @@ extern "C" void block_set(Reference addr, size_t index, uint8_t value)
// Sequence //
extern "C" size_t sequence_capacity(Reference addr)
{
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
return seq.data.capacity;
}
extern "C" size_t sequence_length(Reference addr)
{
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
@ -567,7 +615,7 @@ extern "C" void array_update(Reference addr, size_t index, Reference source)
varying_set(cell, source);
}
else {
copy(source, cell);
copy(cell, source);
}
}
@ -658,7 +706,7 @@ extern "C" void list_insert(Reference addr, size_t index, Reference source)
varying_set(list_cell(addr, index), source);
}
else {
copy(source, list_cell(addr, index));
copy(list_cell(addr, index), source);
}
}
@ -684,7 +732,7 @@ extern "C" void list_update(Reference addr, size_t index, Reference source)
varying_set(list_cell(addr, index), source);
}
else {
copy(source, list_cell(addr, index));
copy(list_cell(addr, index), source);
}
}
}
@ -784,7 +832,7 @@ extern "C" void record_update(Reference addr, size_t index, Reference source)
if(index < binding->data.size()) {
destination.type = binding->data[index].type;
destination.address = addr.address + binding->data[index].offset;
copy(source, destination);
copy(destination, source);
}
}
}

View File

@ -27,6 +27,7 @@ extern "C" size_t type_key(size_t id);
extern "C" size_t type_innerkey(size_t id);
extern "C" size_t type_size(size_t type_id);
size_t type_alignment(size_t type_id);
extern "C" size_t kind_hasinner(size_t kind);
extern "C" size_t type_hasinner(size_t type_id);
@ -37,7 +38,8 @@ extern "C" Str name_keyof(size_t index);
uint8_t* allocate(size_t type_id, size_t count);
extern "C" Reference acquire(size_t type_id);
extern "C" void release(Reference id);
extern "C" bool copy(Reference src, Reference dst);
extern "C" bool copy(Reference dst, Reference src);
extern "C" bool transfer(Reference dst, Reference src);
Reference resolve_addr(Reference addr);
@ -64,6 +66,7 @@ extern "C" uint8_t block_get(Reference addr, size_t index);
extern "C" void block_set(Reference addr, size_t index, uint8_t value);
// String //
extern "C" size_t sequence_capacity(Reference addr);
extern "C" size_t sequence_length(Reference addr);
extern "C" uint8_t sequence_get(Reference addr, size_t index);
extern "C" void sequence_clear(Reference addr);

View File

@ -34,6 +34,9 @@ extern "C" {
pub fn acquire(type_id:usize) -> Reference;
pub fn release(addr:Reference);
pub fn copy(dst:Reference, src:Reference) -> bool;
pub fn transfer(dst:Reference, src:Reference) -> bool;
pub fn type_outer(type_id:usize, key:usize) -> usize;
pub fn type_inner(type_id:usize) -> usize;
pub fn type_key(type_id:usize) -> usize;
@ -64,6 +67,7 @@ extern "C" {
pub fn block_set(addr:Reference, index:usize, data:u8);
pub fn block_get(addr:Reference, index:usize) -> u8;
pub fn sequence_capacity(addr:Reference) -> usize;
pub fn sequence_length(addr:Reference) -> usize;
pub fn sequence_get(addr:Reference, index:usize) -> u8;
pub fn sequence_clear(addr:Reference);