From b4277d2c6facae16c357369288021cf6d06946a5 Mon Sep 17 00:00:00 2001 From: yukirij Date: Wed, 21 Jun 2023 12:04:41 -0700 Subject: [PATCH] Added runtime definitions, reorganized code structure. --- Cargo.lock | 7 ++ Cargo.toml | 1 + LICENSE.md | 1 + README.md | 33 +++++ build.rs | 6 + project.code-workspace | 9 +- src/bin/main.rs | 9 +- src/lib-old.rs | 216 +++++++++++++++++++++++++++++++ src/lib.rs | 279 +++++++++-------------------------------- src/runtime/lib.cc | 23 ++++ src/runtime/lib.h | 41 ++++++ src/runtime/mod.rs | 3 + src/runtime/nametree.h | 122 ++++++++++++++++++ src/runtime/type.h | 43 +++++++ src/runtime/typetree.h | 80 ++++++++++++ src/tag.rs | 29 +++++ src/util/memory.rs | 42 +++++++ src/util/mod.rs | 3 + src/util/typetree.rs | 96 ++++++++++++++ 19 files changed, 813 insertions(+), 230 deletions(-) create mode 100644 README.md create mode 100644 build.rs create mode 100644 src/lib-old.rs create mode 100644 src/runtime/lib.cc create mode 100644 src/runtime/lib.h create mode 100644 src/runtime/mod.rs create mode 100644 src/runtime/nametree.h create mode 100644 src/runtime/type.h create mode 100644 src/runtime/typetree.h create mode 100644 src/tag.rs create mode 100644 src/util/memory.rs create mode 100644 src/util/typetree.rs diff --git a/Cargo.lock b/Cargo.lock index c42c7e8..0924193 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,10 +2,17 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "cc" +version = "1.0.79" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" + [[package]] name = "szun" version = "0.1.0" dependencies = [ + "cc", "util", ] diff --git a/Cargo.toml b/Cargo.toml index c61de3d..762093f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,4 @@ publish = false [dependencies] stdu = { package = "util", git = "https://git.yukiri.dev/Yukiri/util.git" } +cc = "1.0" diff --git a/LICENSE.md b/LICENSE.md index e9ca222..ca15cb3 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1 +1,2 @@ +Project: Kirisame https://ykr.info/license/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..69e0f77 --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +# Suzu Data Notation + +## Types + +|Tag|Type|Data| +|---|---| +|**Tags**| | | +|01|Null|No data| +|02|Boolean|True (02) or False (03)| +|**Primitives**| | | +|10|Natural|Integer on [0, inf)| +|11|Integer|Integer on (-inf, inf)| +|12|Decimal|Floating-point number| +|13|Complex|Floating-point number with imaginary component| +|**Compounds**| | | +|1c|Range| | +|1d|Char|Natural representing character code| +|1e|Block|Fixed-length series of bytes| +|1f|String|Variable-length series of bytes| +|**Containers**| | | +|20|Option| | +|21|Set|Unordered, unique collection of elements| +|22|Array|Fixed-length, ordered collection of elements| +|23|List|Variable-length, ordered collection of elements| +|24|Sparse|Discontinuous, ordered collection of elements| +|25|Map|Mapping of elements onto elements| +|26|Trie|Mapping of string onto elements| +|27|Tree| | +|28|Graph| | +|**Objects**| | | +|3e|Record| | +|3f|Schema| | +|40+|User-defined| | diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..dfca516 --- /dev/null +++ b/build.rs @@ -0,0 +1,6 @@ +fn main() { + cc::Build::new() + .cpp(true) + .file("src/runtime/lib.cc") + .compile("lib_runtime.a"); +} diff --git a/project.code-workspace b/project.code-workspace index 732b176..9aacc8e 100644 --- a/project.code-workspace +++ b/project.code-workspace @@ -6,7 +6,14 @@ ], "settings": { "rust-analyzer.linkedProjects": [ + ".\\Cargo.toml", + ".\\Cargo.toml", + ".\\Cargo.toml", ".\\Cargo.toml" - ] + ], + "rust-analyzer.showUnlinkedFileNotification": false, + "files.associations": { + "xstring": "cpp" + } } } \ No newline at end of file diff --git a/src/bin/main.rs b/src/bin/main.rs index 26fbdc2..cdb8d73 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -1,9 +1,6 @@ fn main() { - /* let mut sz = szun::init(); - - let ob = sz.string("false"); - let enc = sz.encode(ob).unwrap(); - - for b in enc { print!("{:02x}", b); } print!("\n"); */ + let sz = szun::init(); + //let ptr = sz.boolean(); + } diff --git a/src/lib-old.rs b/src/lib-old.rs new file mode 100644 index 0000000..ccdc414 --- /dev/null +++ b/src/lib-old.rs @@ -0,0 +1,216 @@ +#![allow(dead_code)] + +mod util; +pub mod tag; + +type Handle = u64; +pub use tag::Class; + +pub fn init() -> Instance { Instance::new() } + +fn mask_tag (tag:Class) -> Handle { (tag as u64) << 56 } +fn unmask_tag (handle:Handle) -> Class { (handle >> 56) as Class } +fn handle_id (handle:Handle) -> usize { (handle & !mask_tag(0xff)) as usize } + +struct Container { + pub class:usize, + pub data:T, +} + +pub struct Instance { + scope:stdu::Trie, + type_tree:util::TypeTree, + pool_boolean:stdu::Pool, + pool_natural:stdu::Pool, + pool_integer:stdu::Pool, + pool_block:stdu::Pool>, + pool_string:stdu::Pool, + pool_option:stdu::Pool>>, + pool_array:stdu::Pool>>, + pool_list:stdu::Pool>>, + pool_sparse:stdu::Pool>>, +} +impl Instance { + pub(crate) fn new() -> Self + { + Self { + scope:stdu::Trie::::new(), + type_tree:util::TypeTree::new(), + pool_boolean:stdu::Pool::::new(), + pool_natural:stdu::Pool::::new(), + pool_integer:stdu::Pool::::new(), + pool_block:stdu::Pool::>::new(), + pool_string:stdu::Pool::::new(), + pool_option:stdu::Pool::>>::new(), + pool_array:stdu::Pool::>>::new(), + pool_list:stdu::Pool::>>::new(), + pool_sparse:stdu::Pool::>>::new(), + } + } + + + /* DATA CONSTRUCTORS */ + + pub fn boolean(&mut self, value:bool) -> Handle { + mask_tag(tag::BOOLEAN) + self.pool_boolean.add(value) as Handle + } + + pub fn natural(&mut self, value:u64) -> Handle { + mask_tag(tag::NATURAL) + self.pool_natural.add(value) as Handle + } + + pub fn integer(&mut self, value:i64) -> Handle { + mask_tag(tag::INTEGER) + self.pool_integer.add(value) as Handle + } + + pub fn block(&mut self, value:&Vec) -> Handle { + mask_tag(tag::BLOCK) + self.pool_block.add(value.clone()) as Handle + } + + pub fn string(&mut self, value:&str) -> Handle { + mask_tag(tag::STRING) + self.pool_string.add(value.to_string()) as Handle + } + + + /* ENCODING/DECODING */ + + fn encode_tags(tags:Vec) -> Vec + { + let mut encoded = Vec::::with_capacity(16); + for tag in tags { + encoded.append(&mut util::pack_natural(tag as u64)); + } + return encoded; + } + + fn encode_parts(&self, handle:Handle) -> Result<(Vec, Vec), ()> + { + let mut tags = Vec::::with_capacity(3); + let mut encoded = Vec::::with_capacity(64); + + match unmask_tag(handle) { + tag::NULL => { + tags.push(tag::NULL); + } + tag::BOOLEAN => match self.pool_boolean.get(handle_id(handle)) { + Some(value) => { + tags.push(tag::BOOLEAN + *value as Class); + + } + None => { return Err(()); } + } + tag::NATURAL => match self.pool_natural.get(handle_id(handle)) { + Some(value) => { + tags.push(tag::NATURAL); + encoded.append(&mut util::pack_natural(*value)); + } + None => { return Err(()); } + } + tag::INTEGER => match self.pool_integer.get(handle_id(handle)) { + Some(value) => { + tags.push(tag::INTEGER); + encoded.append(&mut util::pack_integer(*value)); + } + None => { return Err(()); } + } + tag::BLOCK => match self.pool_block.get(handle_id(handle)) { + Some(data) => { + tags.push(tag::BLOCK); + for b in data { + encoded.push(*b); + } + } + None => { return Err(()); } + } + tag::STRING => match self.pool_string.get(handle_id(handle)) { + Some(data) => { + tags.push(tag::STRING); + let mut bytes = Vec::::from(data.as_bytes()); + encoded.append(&mut util::pack_natural(bytes.len() as u64)); + encoded.append(&mut bytes); + } + None => { return Err(()); } + } + tag::ARRAY => match self.pool_array.get(handle_id(handle)) { + Some(_object) => { + tags.push(tag::ARRAY); + //tags.append(&mut object.class.clone()); + + } + None => { return Err(()); } + } + tag::LIST => match self.pool_list.get(handle_id(handle)) { + Some(_object) => { + tags.push(tag::LIST); + //tags.append(&mut object.class.clone()); + + } + None => { return Err(()); } + } + tag::SPARSE => match self.pool_sparse.get(handle_id(handle)) { + Some(_object) => { + tags.push(tag::SPARSE); + //tags.append(&mut object.class.clone()); + + // lookup table + + + // data table + + } + None => { return Err(()); } + } + _ => { return Err(()); } + } + Err(()) + } + + pub fn encode_data(&self, handle:Handle) -> Result,()> + { + match self.encode_parts(handle) { + Ok((_, encoded)) => Ok(encoded), + Err(_) => Err(()) + } + } + + pub fn encode(&self, handle:Handle) -> Result,()> + { + match self.encode_parts(handle) { + Ok((tags, data)) => { + let prefix = Self::encode_tags(tags); + let mut encoded = Vec::::with_capacity(prefix.len() + data.len()); + for b in prefix { encoded.push(b); } + for b in data { encoded.push(b); } + + Ok(encoded) + } + Err(_) => Err(()) + } + } + + fn decode_tags(data:&Vec, index:&mut usize) -> Vec + { + let mut tags = Vec::::new(); + while *index < data.len() { + let tag = util::unpack_natural(data, index) as Class; + tags.push(tag); + match tag { + tag::ARRAY | tag::LIST | tag::SPARSE |tag::RECORD => { } + _ => { break; } + } + } + return tags; + } + + pub fn decode(&mut self, data:&Vec) -> Result + { + let mut index :usize = 0; + let tags = Self::decode_tags(data, &mut index); + + for tag in tags { + println!("{}", tag); + } + + Err(()) + } +} diff --git a/src/lib.rs b/src/lib.rs index 53aefe7..dea91ed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,233 +1,66 @@ -#![allow(dead_code)] - mod util; +mod representation; -pub fn init() -> Interface { Interface::new() } +pub struct Instance { + classes:util::TypeTree, + schemas:stdu::Sparse, + memory:Vec, +} +impl Instance { + /* Constructors */ + // pub fn boolean(&mut self, data:bool) -> Result + // pub fn natural(&mut self, data:u64) -> Result + // pub fn integer(&mut self, data:i64) -> Result + // pub fn float(&mut self, data:f64) -> Result + // pub fn block(&mut self, size:usize, data:Vec) -> Result + // pub fn string(&mut self, data:String) -> Result -type Class = u8; -type Handle = u64; + /* Casters */ + // pub fn as_bool(&self, PTR) -> Result + // pub fn as_uint(&self, PTR) -> Result + // pub fn as_int(&self, PTR) -> Result + // pub fn as_float(&self, PTR) -> Result + // pub fn as_bytes(&self, PTR) -> Result,ERR> + // pub fn as_string(&self, PTR) -> Result + // pub fn as_list(&self, PTR) -> Result,ERR> -const TAG_UNDEFINED :Class = 0x00; -const TAG_NULL :Class = 0x01; -const TAG_BOOLEAN :Class = 0x02; -//... -const TAG_NATURAL :Class = 0x10; -const TAG_INTEGER :Class = 0x11; -const TAG_DECIMAL :Class = 0x12; -//... -const TAG_BLOCK :Class = 0x1e; -const TAG_STRING :Class = 0x1f; -const TAG_OPTION :Class = 0x20; -const TAG_SET :Class = 0x21; -const TAG_ARRAY :Class = 0x22; -const TAG_LIST :Class = 0x23; -const TAG_SPARSE :Class = 0x24; -const TAG_MAP :Class = 0x25; -const TAG_TREE :Class = 0x26; -const TAG_GRAPH :Class = 0x27; -//... -const TAG_RECORD :Class = 0x3e; -const TAG_SCHEMA :Class = 0x3f; + /* Access */ + // pub fn with(&self, INDEX) -> Result + // pub fn size(&self, PTR) -> Result + // pub fn len(&self, PTR) -> Result + // pub fn into(&self, PTR, INDEX) -> Result -fn mask_tag (tag:Class) -> Handle { (tag as u64) << 56 } -fn unmask_tag (handle:Handle) -> Class { (handle >> 56) as Class } -fn handle_id (handle:Handle) -> usize { (handle & !mask_tag(0xff)) as usize } + /* Modifiers */ + // pub fn set(&mut self, dest:PTR, src:PTR) + // pub fn unset(&mut self, dest:PTR, src:PTR) + // pub fn insert(&mut self, dest:PTR, index:usize) + // pub fn remove(&mut self, dest:PTR, index:usize) -struct Container { - pub class:Vec, - pub data:T, + /* Translation */ + // pub fn encode(&self, PTR) -> Result,ERR> + // pub fn decode(&mut self) -> Result + + fn acquire_memory() + { + + } + + fn release_memory() + { + + } + + fn store_integer(&mut self, address:usize, value:i64) + { + + } } -pub struct Interface { - pool_boolean:stdu::Pool, - pool_natural:stdu::Pool, - pool_integer:stdu::Pool, - pool_block:stdu::Pool>, - pool_string:stdu::Pool, - pool_option:stdu::Pool>>, - pool_array:stdu::Pool>>, - pool_list:stdu::Pool>>, - pool_sparse:stdu::Pool>>, -} -impl Interface { - pub(crate) fn new() -> Self - { - Self { - pool_boolean:stdu::Pool::::new(), - pool_natural:stdu::Pool::::new(), - pool_integer:stdu::Pool::::new(), - pool_block:stdu::Pool::>::new(), - pool_string:stdu::Pool::::new(), - pool_option:stdu::Pool::>>::new(), - pool_array:stdu::Pool::>>::new(), - pool_list:stdu::Pool::>>::new(), - pool_sparse:stdu::Pool::>>::new(), - } - } - - - /* DATA CONSTRUCTORS */ - - pub fn boolean(&mut self, value:bool) -> Handle { - mask_tag(TAG_BOOLEAN) + self.pool_boolean.add(value) as Handle - } - - pub fn natural(&mut self, value:u64) -> Handle { - mask_tag(TAG_NATURAL) + self.pool_natural.add(value) as Handle - } - - pub fn integer(&mut self, value:i64) -> Handle { - mask_tag(TAG_INTEGER) + self.pool_integer.add(value) as Handle - } - - pub fn block(&mut self, value:&Vec) -> Handle { - mask_tag(TAG_BLOCK) + self.pool_block.add(value.clone()) as Handle - } - - pub fn string(&mut self, value:&str) -> Handle { - mask_tag(TAG_STRING) + self.pool_string.add(value.to_string()) as Handle - } - - - /* ENCODING/DECODING */ - - fn encode_tags(tags:Vec) -> Vec - { - let mut encoded = Vec::::with_capacity(16); - for tag in tags { - encoded.append(&mut util::pack_natural(tag as u64)); - } - return encoded; - } - - fn encode_parts(&self, handle:Handle) -> Result<(Vec, Vec), ()> - { - let mut tags = Vec::::with_capacity(3); - let mut encoded = Vec::::with_capacity(64); - - match unmask_tag(handle) { - TAG_NULL => { - tags.push(TAG_NULL); - } - TAG_BOOLEAN => match self.pool_boolean.get(handle_id(handle)) { - Some(value) => { - tags.push(TAG_BOOLEAN + *value as Class); - - } - None => { return Err(()); } - } - TAG_NATURAL => match self.pool_natural.get(handle_id(handle)) { - Some(value) => { - tags.push(TAG_NATURAL); - encoded.append(&mut util::pack_natural(*value)); - } - None => { return Err(()); } - } - TAG_INTEGER => match self.pool_integer.get(handle_id(handle)) { - Some(value) => { - tags.push(TAG_INTEGER); - encoded.append(&mut util::pack_integer(*value)); - } - None => { return Err(()); } - } - TAG_BLOCK => match self.pool_block.get(handle_id(handle)) { - Some(data) => { - tags.push(TAG_BLOCK); - for b in data { - encoded.push(*b); - } - } - None => { return Err(()); } - } - TAG_STRING => match self.pool_string.get(handle_id(handle)) { - Some(data) => { - tags.push(TAG_STRING); - let mut bytes = Vec::::from(data.as_bytes()); - encoded.append(&mut util::pack_natural(bytes.len() as u64)); - encoded.append(&mut bytes); - } - None => { return Err(()); } - } - TAG_ARRAY => match self.pool_array.get(handle_id(handle)) { - Some(object) => { - tags.push(TAG_ARRAY); - tags.append(&mut object.class.clone()); - - } - None => { return Err(()); } - } - TAG_LIST => match self.pool_list.get(handle_id(handle)) { - Some(object) => { - tags.push(TAG_LIST); - tags.append(&mut object.class.clone()); - - } - None => { return Err(()); } - } - TAG_SPARSE => match self.pool_sparse.get(handle_id(handle)) { - Some(object) => { - tags.push(TAG_SPARSE); - tags.append(&mut object.class.clone()); - - // lookup table - - - // data table - - } - None => { return Err(()); } - } - _ => { return Err(()); } - } - Err(()) - } - - pub fn encode_data(&self, handle:Handle) -> Result,()> - { - match self.encode_parts(handle) { - Ok((_, encoded)) => Ok(encoded), - Err(_) => Err(()) - } - } - - pub fn encode(&self, handle:Handle) -> Result,()> - { - match self.encode_parts(handle) { - Ok((tags, data)) => { - let prefix = Self::encode_tags(tags); - let mut encoded = Vec::::with_capacity(prefix.len() + data.len()); - for b in prefix { encoded.push(b); } - for b in data { encoded.push(b); } - - Ok(encoded) - } - Err(_) => Err(()) - } - } - - fn decode_tags(data:&Vec, index:&mut usize) -> Vec - { - let mut tags = Vec::::new(); - while *index < data.len() { - let tag = util::unpack_natural(data, index) as Class; - tags.push(tag); - match tag { - TAG_ARRAY | TAG_LIST | TAG_SPARSE |TAG_RECORD => { } - _ => { break; } - } - } - return tags; - } - - pub fn decode(&mut self, data:&Vec) -> Result - { - let mut index :usize = 0; - let tags = Self::decode_tags(data, &mut index); - - for tag in tags { - println!("{}", tag); - } - - Err(()) +pub fn init(size:usize) -> Instance +{ + Instance { + classes:util::TypeTree::new(), + schemas:stdu::Sparse::::new(), + memory:vec![0; size], } } diff --git a/src/runtime/lib.cc b/src/runtime/lib.cc new file mode 100644 index 0000000..9b20ca6 --- /dev/null +++ b/src/runtime/lib.cc @@ -0,0 +1,23 @@ +#include "lib.h" + +void init() +{ + +} + +void* acquire(uint16_t type) +{ + switch(type) { + case Type::Tag::Boolean: return malloc(1); + case Type::Tag::Natural: return malloc(8); + case Type::Tag::Integer: return malloc(8); + default: return nullptr; + } +} + +void release(void* address) +{ + if(address != nullptr) { + free(address); + } +} diff --git a/src/runtime/lib.h b/src/runtime/lib.h new file mode 100644 index 0000000..69cd7a4 --- /dev/null +++ b/src/runtime/lib.h @@ -0,0 +1,41 @@ +#include +#include +#include "type.h" +#include "typetree.h" +#include "nametree.h" + +extern TypeTree DB_TYPE; +extern NameTree DB_NAME; + +struct List { + uint64_t capacity; + uint64_t length; + void* data; + + void* allocate(size_t size); + + List(); + ~List(); +}; + +struct Schema { + struct Row { + uint16_t type; + uint16_t offset; + }; + struct Node { + uint16_t keyword; + uint16_t index; + }; + + uint16_t capacity; + uint16_t length; + + Node* nodes; + Row* members; + + Schema(); + ~Schema(); + + void* allocate(); +}; diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs new file mode 100644 index 0000000..8318307 --- /dev/null +++ b/src/runtime/mod.rs @@ -0,0 +1,3 @@ +extern "C" { + fn acquire() -> usize; +} diff --git a/src/runtime/nametree.h b/src/runtime/nametree.h new file mode 100644 index 0000000..10aa1a9 --- /dev/null +++ b/src/runtime/nametree.h @@ -0,0 +1,122 @@ +#ifndef H_NameTree +#define H_NameTree + +#include +#include +#include + +class NameTree { +public: + struct Node { + std::string prefix; + size_t parent; + std::vector children; + + Node(const std::string& prefix, size_t parent); + }; + + NameTree(); + ~NameTree(); + + size_t lookup(const std::string& value); + std::string get(size_t) const; + +private: + std::vector m_nodes; +}; + +NameTree::Node::Node(const std::string& prefix, size_t parent) + :prefix(prefix), parent(parent) { } + +NameTree::NameTree() +{ + m_nodes.push_back(Node("", 0)); +} + +NameTree::~NameTree() +{ } + +size_t NameTree::lookup(const std::string& value) +{ + size_t current = 0; + size_t index = 0; + + while(index < value.length()) { + Node& node = m_nodes[current]; + + size_t find = 0; + for(size_t ci = 0; ci < node.children.size(); ++ci) { + size_t child = node.children[ci]; + if(value[index] == m_nodes[child].prefix[0]) { + size_t prefix_index = 0; + for(; prefix_index < m_nodes[child].prefix.length() && index < value.length(); prefix_index++ && index++) { + if(m_nodes[child].prefix[prefix_index] != value[index]) { + break; + } + } + + if(prefix_index == m_nodes[child].prefix.length()) { + current = child; + break; + } + else { + find = child; + + // create intermediate node + m_nodes.push_back(Node(m_nodes[child].prefix.substr(0, prefix_index), child)); + m_nodes[current].children[ci] = m_nodes.size() - 1; + m_nodes[m_nodes.size() - 1].children.push_back(child); + + // update child node + m_nodes[child].parent = m_nodes.size() - 1; + + // create branching node if value is not prefix + if(index != value.length()) { + m_nodes.push_back(Node(value.substr(index), child)); + find = m_nodes.size() - 1; + } + + return find; + } + } + } + + if(find == 0) { + // add suffix to new node pointing to value + m_nodes.push_back(Node(value.substr(index), current)); + find = m_nodes.size() - 1; + node.children.push_back(find); + return find; + } + } + + return current; +} + +std::string NameTree::get(size_t id) const +{ + size_t length = 0; + std::string out; + + if(id < m_nodes.size()) { + for(size_t current = id; current != 0;) { + length += m_nodes[current].prefix.length(); + current = m_nodes[current].parent; + } + + out = std::string(length, '\0'); + size_t index = length - 1; + + for(size_t current = id; current != 0;) { + size_t prefix_length = m_nodes[current].prefix.length() - 1; + for(size_t i = 0; i < m_nodes[current].prefix.length(); ++i) { + out[index--] = m_nodes[current].prefix[prefix_length - i]; + } + current = m_nodes[current].parent; + } + } + + return out; +} + +#endif diff --git a/src/runtime/type.h b/src/runtime/type.h new file mode 100644 index 0000000..18e63f9 --- /dev/null +++ b/src/runtime/type.h @@ -0,0 +1,43 @@ +#include + +namespace Type { + +enum Tag { + Null = 0x01, + Boolean = 0x02, + Natural = 0x10, + Integer = 0x11, + Block = 0x1e, + String = 0x1f, + Set = 0x21, + Array = 0x22, + List = 0x23, + Trie = 0x27, + Map = 0x28, + Record = 0x4e, + Schema = 0x4f, +}; + +struct Info { + uint16_t Tag; + uint16_t Size; + + Info(uint16_t tag, uint16_t size) + :Tag(tag), Size(size) { } +}; + +const Info Null (Tag::Null, 0); +const Info Boolean (Tag::Boolean, 0); +const Info Natural (Tag::Natural, 8); +const Info Integer (Tag::Integer, 8); +const Info Block (Tag::Block, -1); +const Info String (Tag::String, -1); +const Info Set (Tag::Set, -1); +const Info Array (Tag::Array, -1); +const Info List (Tag::List, -1); +const Info Trie (Tag::Trie, -1); +const Info Map (Tag::Map, -1); +const Info Record (Tag::Record, -1); +const Info Schema (Tag::Schema, -1); + +} diff --git a/src/runtime/typetree.h b/src/runtime/typetree.h new file mode 100644 index 0000000..40da166 --- /dev/null +++ b/src/runtime/typetree.h @@ -0,0 +1,80 @@ +#ifndef H_TYPETREE +#define H_TYPETREE + +#include +#include + +class TypeTree { +public: + struct Node { + uint16_t type; + size_t parent; + std::vector children; + + Node(uint16_t type, size_t parent); + }; + + TypeTree(); + ~TypeTree(); + + size_t get(size_t id, uint16_t type); + uint16_t type(size_t id); + size_t parent(size_t id); + +private: + std::vector m_nodes; +}; + +TypeTree::Node::Node(uint16_t type, size_t parent) :type(type), parent(parent) { } + +TypeTree::TypeTree() +{ + m_nodes.push_back(Node(0, 0)); +} + +TypeTree::~TypeTree() +{ } + +size_t TypeTree::get(size_t id, uint16_t type) +{ + size_t find = 0; + + if(id < m_nodes.size()) + { + Node& node = m_nodes[id]; + + for(size_t child : node.children) { + if(m_nodes[child].type == type) { + find = child; + break; + } + } + + if(find == 0) { + m_nodes.push_back(Node(type, id)); + find = m_nodes.size() - 1; + + node.children.push_back(find); + } + } + + return find; +} + +uint16_t TypeTree::type(size_t id) +{ + if(id > 0 && id < m_nodes.size()) { + return m_nodes[id].type; + } + return 0; +} + +size_t TypeTree::parent(size_t id) +{ + if(id > 0 && id < m_nodes.size()) { + return m_nodes[id].parent; + } + return 0; +} + +#endif diff --git a/src/tag.rs b/src/tag.rs new file mode 100644 index 0000000..8a3563d --- /dev/null +++ b/src/tag.rs @@ -0,0 +1,29 @@ +pub type Class = u16; + +pub const VARYING :Class = 0x00; +pub const NULL :Class = 0x01; +pub const BOOLEAN :Class = 0x02; +//... +pub const NATURAL :Class = 0x10; +pub const INTEGER :Class = 0x11; +pub const DECIMAL :Class = 0x12; +pub const FLOAT :Class = 0x13; +pub const COMPLEX :Class = 0x14; +//... +pub const RANGE :Class = 0x1c; +pub const CHAR :Class = 0x1d; +pub const BLOCK :Class = 0x1e; +pub const STRING :Class = 0x1f; +pub const OPTION :Class = 0x20; +pub const SET :Class = 0x21; +pub const ARRAY :Class = 0x22; +pub const LIST :Class = 0x23; +pub const SPARSE :Class = 0x24; +pub const MAP :Class = 0x25; +pub const TRIE :Class = 0x26; +pub const TREE :Class = 0x27; +pub const GRAPH :Class = 0x28; +//... +pub const RECORD :Class = 0x3e; +pub const SCHEMA :Class = 0x3f; +pub const USER :Class = 0x40; diff --git a/src/util/memory.rs b/src/util/memory.rs new file mode 100644 index 0000000..b7f1a39 --- /dev/null +++ b/src/util/memory.rs @@ -0,0 +1,42 @@ +pub struct Memory { + data:Vec, +} +impl Memory { + pub fn new(size:usize) -> Self + { + Self { + data:vec![0; size], + } + } + + pub fn allocate(&mut self, size:usize) -> Result + { + if size < self.data.len() { + + } + + Err(()) + } + + pub fn free(&mut self, address:usize) + { + if address < self.data.len() { + + } + } + + pub fn size(&self) -> usize { self.data.len() } + + pub fn resize(&mut self, size:usize) -> Result<(),()> + // Modifies the size of memory available for allocation. + // Fails if memory could not be allocated or resize conflicts with allocated memory. + { + let new_data = vec![0; size]; + let mut index = 0; + + while index < self.data.len() && index < new_data.len() { + + } + + } +} diff --git a/src/util/mod.rs b/src/util/mod.rs index 132d82f..4eea320 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -1,3 +1,6 @@ +mod typetree; pub use typetree::TypeTree; +mod memory; pub use memory::Memory; + fn pack_count_leading_ones(data:u8) -> usize { (data == 0xff) as usize diff --git a/src/util/typetree.rs b/src/util/typetree.rs new file mode 100644 index 0000000..d89063c --- /dev/null +++ b/src/util/typetree.rs @@ -0,0 +1,96 @@ +struct Node { + pub class:u32, + pub parent:usize, + pub children:stdu::Sparse, +} +impl Node { + pub fn new(class:u32, parent:usize) -> Self + { + Self { + class:class, + parent:parent, + children:stdu::Sparse::::new(), + } + } +} + +pub struct TypeTree { + data:stdu::Pool, +} +impl TypeTree { + pub fn new() -> Self + { + Self { + data:stdu::Pool::::new(), + } + } + + pub fn add(&mut self, hierarchy:&Vec) -> usize + // add + // + { + let mut node = 0; + for class in hierarchy { + match self.data.get(node) { + Some(parent) => match parent.children.get(*class as usize) { + Some(child) => { + node = *child; + } + None => { + let new_node = self.data.add(Node::new(*class, node)); + self.data.get_mut(node).unwrap().children.set(*class as usize, new_node); + node = new_node; + } + } + None => { return 0; } + } + } + return node; + } + + pub fn insert(&mut self, id:usize, class:u32) -> Result + // wrap an existing type + // + { + let new_node = self.data.add(Node::new(class, id)); + return match self.data.get_mut(id) { + Some(node) => { + node.children.set(class as usize, new_node); + Ok(new_node) + } + None => Err(()), + } + } + + pub fn inner(&self, id:usize) -> Option + // returns an inner type if one exists + // + { + return match self.data.get(id) { + Some(node) => { + if node.parent == 0 { None } + else { Some(node.parent) } + } + None => None, + } + } + + fn lookup_node(&self, hierarchy:&Vec) -> (usize, usize) + // finds the last existing node in the hierarchy + { + let mut index :usize = 0; + let mut current :usize = 0; + for i in 0..hierarchy.len() { + match self.data.get(current).unwrap().children.get(hierarchy[i] as usize) { + Some(child) => { + current = *child; + index += 1; + } + None => { + return (index, current); + } + } + } + return (0, 0); + } +}