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
/.vscode

View File

@ -271,7 +271,7 @@ Stores a constant-magnitude number with whole and decimal components.
## Significant
Stores a fixed-precision, variable-magnitude number.
> Not implemented.
> Encode not implemented.
`get() -> f64`
@ -291,7 +291,7 @@ Constant-sized series of bytes.
`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.
```
let schema_rgba = Schema::with(vec![
("r", significant()),
("g", significant()),
("b", significant()),
("a", significant()),
]);
```
---
`get(index:usize) -> usize`
@ -529,8 +537,17 @@ Removes all members and mappings from the schema.
`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 natural() -> usize { unsafe { runtime::type_outer(0, tag::NATURAL) } }
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 {
unsafe {

View File

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

View File

@ -5,7 +5,7 @@ use crate::runtime::{
sequence_capacity, sequence_length,
sequence_clear, sequence_reserve,
sequence_get,
sequence_insert,
sequence_insert, sequence_set,
};
use crate::tag;
use super::sequence;
@ -68,6 +68,11 @@ impl Sequence {
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>)
{
unsafe { sequence_clear(self.addr); }
@ -84,6 +89,11 @@ impl Sequence {
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>
{
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::Natural: return sizeof(Type::Natural);
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::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::Natural: return sizeof(Type::Natural);
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::Sequence: return sizeof(size_t);
case Type::Tag::Array: return type_inner(type_id);
@ -189,12 +191,6 @@ void drop(Reference addr)
{
if(addr.address != nullptr) {
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: {
auto& var = *reinterpret_cast<Reference*>(addr.address);
if(var.address != nullptr) {
@ -279,13 +275,6 @@ extern "C" bool copy(Reference dst, Reference src)
switch(type_key(destination.type)) {
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: {
auto& src_seq = *reinterpret_cast<Type::Sequence*>(source.address);
auto& dst_seq = *reinterpret_cast<Type::Sequence*>(destination.address);
@ -351,6 +340,10 @@ extern "C" bool copy(Reference dst, Reference src)
}
}
} break;
default: {
memcpy(destination.address, source.address, type_size(source.type));
} break;
}
return true;
@ -361,7 +354,7 @@ extern "C" bool copy(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 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 //
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)
{
Type::SchemaBinding binding {0};
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
if(id > 0) {
Type::SchemaBinding binding {0};
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
// prepare binding
binding.binding = id;
for(size_t i = 0; i < object.data.length; ++i) {
Type::SchemaBinding::Row row {0};
// prepare binding
binding.binding = id;
for(size_t i = 0; i < object.data.length; ++i) {
Type::SchemaBinding::Row row {0};
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 alignment = type_alignment(type_id);
binding.alignment = std::max(alignment, binding.alignment);
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
binding.size = size + position;
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 alignment = type_alignment(type_id);
binding.alignment = std::max(alignment, binding.alignment);
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
binding.size = size + position;
row.type = type_id;
row.offset = position;
binding.data.push_back(row);
row.type = type_id;
row.offset = position;
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;
}

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" 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 //
extern "C" size_t block_length(Reference addr);
extern "C" uint8_t block_get(Reference addr, size_t index);

View File

@ -63,6 +63,9 @@ extern "C" {
pub fn integer_set(addr:Reference, data: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_set(addr:Reference, index:usize, data:u8);
pub fn block_get(addr:Reference, index:usize) -> u8;

View File

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

View File

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