Add significant type, update README.

This commit is contained in:
yukirij 2023-08-18 14:01:12 -07:00
parent ac28278830
commit 360152a84f
11 changed files with 179 additions and 65 deletions

1
.gitignore vendored
View File

@ -1 +1,2 @@
/target /target
/.vscode

View File

@ -271,7 +271,7 @@ Stores a constant-magnitude number with whole and decimal components.
## Significant ## Significant
Stores a fixed-precision, variable-magnitude number. Stores a fixed-precision, variable-magnitude number.
> Not implemented. > Encode not implemented.
`get() -> f64` `get() -> f64`
@ -291,7 +291,7 @@ Constant-sized series of bytes.
`new(size:usize) -> Block` `new(size:usize) -> Block`
Produces a Produces a new block of the specified size.
--- ---
@ -483,6 +483,14 @@ Definition of an abstract structure composed of named items.
Produces a schema with the provided member assignments. 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` `get(index:usize) -> usize`
@ -529,8 +537,17 @@ Removes all members and mappings from the schema.
`bind(id:usize)` `bind(id:usize)`
Submits the schema to the 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);
```
--- ---

View File

@ -9,6 +9,7 @@ pub fn null() -> usize { unsafe { runtime::type_outer(0, tag::NULL) } }
pub fn boolean() -> usize { unsafe { runtime::type_outer(0, tag::BOOLEAN) } } pub fn boolean() -> usize { unsafe { runtime::type_outer(0, tag::BOOLEAN) } }
pub fn natural() -> usize { unsafe { runtime::type_outer(0, tag::NATURAL) } } pub fn natural() -> usize { unsafe { runtime::type_outer(0, tag::NATURAL) } }
pub fn integer() -> usize { unsafe { runtime::type_outer(0, tag::INTEGER) } } pub fn integer() -> usize { unsafe { runtime::type_outer(0, tag::INTEGER) } }
pub fn significant() -> usize { unsafe { runtime::type_outer(0, tag::SIGNIFICANT) } }
pub fn block(size:usize) -> usize { pub fn block(size:usize) -> usize {
unsafe { unsafe {

View File

@ -8,6 +8,7 @@ mod varying; pub use varying::Varying;
mod boolean; pub use boolean::Boolean; mod boolean; pub use boolean::Boolean;
mod natural; pub use natural::Natural; mod natural; pub use natural::Natural;
mod integer; pub use integer::Integer; mod integer; pub use integer::Integer;
mod signfiicant; pub use signfiicant::Significant;
mod block; pub use block::Block; mod block; pub use block::Block;
mod sequence; pub use sequence::Sequence; mod sequence; pub use sequence::Sequence;
mod array; pub use array::Array; mod array; pub use array::Array;

View File

@ -5,7 +5,7 @@ use crate::runtime::{
sequence_capacity, sequence_length, sequence_capacity, sequence_length,
sequence_clear, sequence_reserve, sequence_clear, sequence_reserve,
sequence_get, sequence_get,
sequence_insert, sequence_insert, sequence_set,
}; };
use crate::tag; use crate::tag;
use super::sequence; use super::sequence;
@ -68,6 +68,11 @@ impl Sequence {
unsafe {sequence_length(self.addr)} unsafe {sequence_length(self.addr)}
} }
pub fn set_at(&mut self, index:usize, value:u8)
{
unsafe { sequence_set(self.addr, index, value); }
}
pub fn set_raw(&mut self, data:Vec<u8>) pub fn set_raw(&mut self, data:Vec<u8>)
{ {
unsafe { sequence_clear(self.addr); } unsafe { sequence_clear(self.addr); }
@ -84,6 +89,11 @@ impl Sequence {
self.set_raw(Vec::from(data.as_bytes())); self.set_raw(Vec::from(data.as_bytes()));
} }
pub fn get_at(&self, index:usize) -> u8
{
unsafe {sequence_get(self.addr, index)}
}
pub fn get_raw(&self) -> Vec<u8> pub fn get_raw(&self) -> Vec<u8>
{ {
let length = unsafe {sequence_length(self.addr)}; let length = unsafe {sequence_length(self.addr)};

View File

@ -0,0 +1,67 @@
use crate::runtime::{
Reference,
acquire, release,
type_key,
significant_get, significant_set
};
use crate::tag;
use super::significant;
pub struct Significant {
managed:bool,
addr:Reference,
}
impl Significant {
pub fn new() -> Self
{
Self {
managed:true,
addr:unsafe {acquire(significant())},
}
}
pub fn from(addr:Reference) -> Result<Self,()>
{
return if(unsafe {type_key(addr.class)} == tag::SIGNIFICANT) {
Ok(Self { managed:false, addr:addr })
}
else {
Err(())
}
}
pub fn with(value:f64) -> Self
{
let mut obj = Self::new();
obj.set(value);
return obj;
}
pub fn detach(&mut self)
{
self.managed = false;
}
pub fn release(mut self)
{
self.detach();
unsafe { release(self.addr); }
}
pub fn set(&mut self, value:f64)
{
unsafe { significant_set(self.addr, value) };
}
pub fn get(&self) -> f64
{
unsafe { significant_get(self.addr) }
}
}
impl std::ops::Deref for Significant {
type Target = Reference;
fn deref(&self) -> &Self::Target { return &self.addr; }
}
impl Drop for Significant {
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
}

View File

@ -39,6 +39,7 @@ extern "C" size_t type_size(size_t type_id)
case Type::Tag::Boolean: return sizeof(Type::Boolean); case Type::Tag::Boolean: return sizeof(Type::Boolean);
case Type::Tag::Natural: return sizeof(Type::Natural); case Type::Tag::Natural: return sizeof(Type::Natural);
case Type::Tag::Integer: return sizeof(Type::Integer); case Type::Tag::Integer: return sizeof(Type::Integer);
case Type::Tag::Significant: return sizeof(Type::Integer);
case Type::Tag::Block: return type_innerkey(type_id); case Type::Tag::Block: return type_innerkey(type_id);
case Type::Tag::Sequence: return sizeof(Type::Sequence); case Type::Tag::Sequence: return sizeof(Type::Sequence);
@ -91,6 +92,7 @@ size_t type_alignment(size_t type_id)
case Type::Tag::Boolean: return sizeof(Type::Boolean); case Type::Tag::Boolean: return sizeof(Type::Boolean);
case Type::Tag::Natural: return sizeof(Type::Natural); case Type::Tag::Natural: return sizeof(Type::Natural);
case Type::Tag::Integer: return sizeof(Type::Integer); case Type::Tag::Integer: return sizeof(Type::Integer);
case Type::Tag::Significant: return sizeof(Type::Significant);
case Type::Tag::Block: return sizeof(uint8_t); case Type::Tag::Block: return sizeof(uint8_t);
case Type::Tag::Sequence: return sizeof(size_t); case Type::Tag::Sequence: return sizeof(size_t);
case Type::Tag::Array: return type_inner(type_id); case Type::Tag::Array: return type_inner(type_id);
@ -189,12 +191,6 @@ void drop(Reference addr)
{ {
if(addr.address != nullptr) { if(addr.address != nullptr) {
switch(type_key(addr.type)) { switch(type_key(addr.type)) {
case Type::Tag::Boolean:
case Type::Tag::Natural:
case Type::Tag::Integer:
case Type::Tag::Block:
break;
case Type::Tag::Varying: { case Type::Tag::Varying: {
auto& var = *reinterpret_cast<Reference*>(addr.address); auto& var = *reinterpret_cast<Reference*>(addr.address);
if(var.address != nullptr) { if(var.address != nullptr) {
@ -279,13 +275,6 @@ extern "C" bool copy(Reference dst, Reference src)
switch(type_key(destination.type)) { switch(type_key(destination.type)) {
case Type::Tag::Null: { } break; case Type::Tag::Null: { } break;
case Type::Tag::Boolean:
case Type::Tag::Natural:
case Type::Tag::Integer:
case Type::Tag::Block: {
memcpy(destination.address, source.address, type_size(source.type));
} break;
case Type::Tag::Sequence: { case Type::Tag::Sequence: {
auto& src_seq = *reinterpret_cast<Type::Sequence*>(source.address); auto& src_seq = *reinterpret_cast<Type::Sequence*>(source.address);
auto& dst_seq = *reinterpret_cast<Type::Sequence*>(destination.address); auto& dst_seq = *reinterpret_cast<Type::Sequence*>(destination.address);
@ -351,6 +340,10 @@ extern "C" bool copy(Reference dst, Reference src)
} }
} }
} break; } break;
default: {
memcpy(destination.address, source.address, type_size(source.type));
} break;
} }
return true; return true;
@ -361,7 +354,7 @@ extern "C" bool copy(Reference dst, Reference src)
extern "C" bool transfer(Reference dst, Reference src) extern "C" bool transfer(Reference dst, Reference src)
{ {
if(src.address != dst.address) { if(src.address != dst.address && src.type != 0 && dst.type != 0) {
Reference source = src; Reference source = src;
Reference destination = dst; Reference destination = dst;
@ -491,6 +484,19 @@ extern "C" Type::Integer integer_get(Reference addr)
} }
// Significant //
extern "C" void significant_set(Reference addr, Type::Significant value)
{
*(reinterpret_cast<Type::Significant*>(addr.address)) = value;
}
extern "C" Type::Significant significant_get(Reference addr)
{
return *(reinterpret_cast<Type::Significant*>(addr.address));
}
// Block // // Block //
extern "C" size_t block_length(Reference addr) extern "C" size_t block_length(Reference addr)
@ -995,56 +1001,58 @@ extern "C" size_t schema_keyof(Reference addr, size_t index)
extern "C" size_t schema_bind(Reference addr, size_t id) extern "C" size_t schema_bind(Reference addr, size_t id)
{ {
Type::SchemaBinding binding {0}; if(id > 0) {
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address)); Type::SchemaBinding binding {0};
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
// prepare binding // prepare binding
binding.binding = id; binding.binding = id;
for(size_t i = 0; i < object.data.length; ++i) { for(size_t i = 0; i < object.data.length; ++i) {
Type::SchemaBinding::Row row {0}; Type::SchemaBinding::Row row {0};
size_t type_id = *reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), i)); size_t type_id = *reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), i));
size_t size = type_size(type_id); size_t size = type_size(type_id);
size_t alignment = type_alignment(type_id); size_t alignment = type_alignment(type_id);
binding.alignment = std::max(alignment, binding.alignment); binding.alignment = std::max(alignment, binding.alignment);
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1)); size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
binding.size = size + position; binding.size = size + position;
row.type = type_id; row.type = type_id;
row.offset = position; row.offset = position;
binding.data.push_back(row); binding.data.push_back(row);
}
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
binding.references = 0;
for(size_t i = 0; i < object.map.length; ++i) {
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
binding.map.set(cell->key, cell->index);
binding.data[cell->index].key = cell->key;
}
/* printf("[Binding]\n");
printf(" Id: %zu\n", binding.binding);
printf(" Size: %zu\n", binding.size);
printf(" Align: %zu\n", binding.alignment);
printf(" Data:\n");
for(size_t i = 0; i < binding.data.size(); ++i) {
printf(" - %zu {%#x} (%zu)\n",
binding.data[i].type,
type_key(binding.data[i].type),
binding.data[i].offset
);
}
printf(" Map:\n");
for(size_t key : binding.map.indices()) {
printf(" - %zu -> %zu\n",
key,
*binding.map.get(key)
);
} */
// add binding to pool
DB_SCHEMA.set(id, binding);
} }
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
binding.references = 0;
for(size_t i = 0; i < object.map.length; ++i) {
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
binding.map.set(cell->key, cell->index);
binding.data[cell->index].key = cell->key;
}
/* printf("[Binding]\n");
printf(" Id: %zu\n", binding.binding);
printf(" Size: %zu\n", binding.size);
printf(" Align: %zu\n", binding.alignment);
printf(" Data:\n");
for(size_t i = 0; i < binding.data.size(); ++i) {
printf(" - %zu {%#x} (%zu)\n",
binding.data[i].type,
type_key(binding.data[i].type),
binding.data[i].offset
);
}
printf(" Map:\n");
for(size_t key : binding.map.indices()) {
printf(" - %zu -> %zu\n",
key,
*binding.map.get(key)
);
} */
// add binding to pool
DB_SCHEMA.set(id, binding);
return id; return id;
} }

View File

@ -60,6 +60,10 @@ extern "C" Type::Natural natural_get(Reference addr);
extern "C" void integer_set(Reference addr, Type::Integer value); extern "C" void integer_set(Reference addr, Type::Integer value);
extern "C" Type::Integer integer_get(Reference addr); extern "C" Type::Integer integer_get(Reference addr);
// Significant //
extern "C" void significant_set(Reference addr, Type::Significant value);
extern "C" Type::Significant significant_get(Reference addr);
// Block // // Block //
extern "C" size_t block_length(Reference addr); extern "C" size_t block_length(Reference addr);
extern "C" uint8_t block_get(Reference addr, size_t index); extern "C" uint8_t block_get(Reference addr, size_t index);

View File

@ -62,6 +62,9 @@ extern "C" {
pub fn integer_set(addr:Reference, data:i64); pub fn integer_set(addr:Reference, data:i64);
pub fn integer_get(addr:Reference) -> i64; pub fn integer_get(addr:Reference) -> i64;
pub fn significant_set(addr:Reference, data:f64);
pub fn significant_get(addr:Reference) -> f64;
pub fn block_length(addr:Reference) -> usize; pub fn block_length(addr:Reference) -> usize;
pub fn block_set(addr:Reference, index:usize, data:u8); pub fn block_set(addr:Reference, index:usize, data:u8);

View File

@ -18,6 +18,7 @@ namespace Tag {
Natural = 0x10, Natural = 0x10,
Integer = 0x11, Integer = 0x11,
//Decimal = 0x12, //Decimal = 0x12,
Significant = 0x13,
Block = 0x1e, Block = 0x1e,
Sequence = 0x1f, Sequence = 0x1f,
Array = 0x22, Array = 0x22,
@ -31,6 +32,7 @@ namespace Tag {
typedef bool Boolean; typedef bool Boolean;
typedef uint64_t Natural; typedef uint64_t Natural;
typedef int64_t Integer; typedef int64_t Integer;
typedef double Significant;
struct Sequence { struct Sequence {
RawList data; RawList data;

View File

@ -6,7 +6,7 @@ pub const BOOLEAN :usize = 0x02;
pub const NATURAL :usize = 0x10; pub const NATURAL :usize = 0x10;
pub const INTEGER :usize = 0x11; pub const INTEGER :usize = 0x11;
//pub const DECIMAL :usize = 0x12; //pub const DECIMAL :usize = 0x12;
//pub const FLOAT :usize = 0x13; pub const SIGNIFICANT :usize = 0x13;
//pub const COMPLEX :usize = 0x14; //pub const COMPLEX :usize = 0x14;
//pub const RANGE :usize = 0x1c; //pub const RANGE :usize = 0x1c;
//pub const CHAR :usize = 0x1d; //pub const CHAR :usize = 0x1d;