From 360152a84f678e4500a7f2b62db6ebeb48c364bd Mon Sep 17 00:00:00 2001 From: yukirij Date: Fri, 18 Aug 2023 14:01:12 -0700 Subject: [PATCH] Add significant type, update README. --- .gitignore | 1 + README.md | 23 ++++++- src/interface/builder.rs | 1 + src/interface/mod.rs | 1 + src/interface/sequence.rs | 12 +++- src/interface/signfiicant.rs | 67 ++++++++++++++++++ src/runtime/lib.cc | 128 +++++++++++++++++++---------------- src/runtime/lib.h | 4 ++ src/runtime/mod.rs | 3 + src/runtime/type.h | 2 + src/tag.rs | 2 +- 11 files changed, 179 insertions(+), 65 deletions(-) create mode 100644 src/interface/signfiicant.rs diff --git a/.gitignore b/.gitignore index ea8c4bf..81cf465 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/.vscode diff --git a/README.md b/README.md index d21a84c..1817d95 100644 --- a/README.md +++ b/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); +``` --- diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 25e432f..be89c7e 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -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 { diff --git a/src/interface/mod.rs b/src/interface/mod.rs index 406b9ea..d216692 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -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; diff --git a/src/interface/sequence.rs b/src/interface/sequence.rs index cf8bd4d..9a2484f 100644 --- a/src/interface/sequence.rs +++ b/src/interface/sequence.rs @@ -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) { 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 { let length = unsafe {sequence_length(self.addr)}; diff --git a/src/interface/signfiicant.rs b/src/interface/signfiicant.rs new file mode 100644 index 0000000..3db0c0a --- /dev/null +++ b/src/interface/signfiicant.rs @@ -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 + { + 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)}; } } +} diff --git a/src/runtime/lib.cc b/src/runtime/lib.cc index 7e9be48..6317c43 100644 --- a/src/runtime/lib.cc +++ b/src/runtime/lib.cc @@ -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(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(source.address); auto& dst_seq = *reinterpret_cast(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(addr.address)) = value; +} + +extern "C" Type::Significant significant_get(Reference addr) +{ + return *(reinterpret_cast(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(addr.address)); + if(id > 0) { + Type::SchemaBinding binding {0}; + auto& object = (*reinterpret_cast(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(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(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(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(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; } diff --git a/src/runtime/lib.h b/src/runtime/lib.h index 3c06dde..afe58d3 100644 --- a/src/runtime/lib.h +++ b/src/runtime/lib.h @@ -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); diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index 590bbb0..f7689d2 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -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); diff --git a/src/runtime/type.h b/src/runtime/type.h index 49ea4ab..cfea37f 100644 --- a/src/runtime/type.h +++ b/src/runtime/type.h @@ -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; diff --git a/src/tag.rs b/src/tag.rs index 9d95957..6ae084e 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -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;