Add significant type, update README.
This commit is contained in:
parent
ac28278830
commit
360152a84f
1
.gitignore
vendored
1
.gitignore
vendored
@ -1 +1,2 @@
|
||||
/target
|
||||
/.vscode
|
||||
|
23
README.md
23
README.md
@ -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);
|
||||
```
|
||||
---
|
||||
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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)};
|
||||
|
67
src/interface/signfiicant.rs
Normal file
67
src/interface/signfiicant.rs
Normal 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)}; } }
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -62,6 +62,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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
Reference in New Issue
Block a user