Added runtime definitions, reorganized code structure.

This commit is contained in:
yukirij 2023-06-21 12:04:41 -07:00
parent 4a7700b6ee
commit b4277d2c6f
19 changed files with 813 additions and 230 deletions

7
Cargo.lock generated
View File

@ -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",
]

View File

@ -8,3 +8,4 @@ publish = false
[dependencies]
stdu = { package = "util", git = "https://git.yukiri.dev/Yukiri/util.git" }
cc = "1.0"

View File

@ -1 +1,2 @@
Project: Kirisame
https://ykr.info/license/

33
README.md Normal file
View File

@ -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| |

6
build.rs Normal file
View File

@ -0,0 +1,6 @@
fn main() {
cc::Build::new()
.cpp(true)
.file("src/runtime/lib.cc")
.compile("lib_runtime.a");
}

View File

@ -6,7 +6,14 @@
],
"settings": {
"rust-analyzer.linkedProjects": [
".\\Cargo.toml",
".\\Cargo.toml",
".\\Cargo.toml",
".\\Cargo.toml"
]
],
"rust-analyzer.showUnlinkedFileNotification": false,
"files.associations": {
"xstring": "cpp"
}
}
}

View File

@ -1,9 +1,6 @@
fn main()
{
/* let mut sz = szun::init();
let sz = szun::init();
//let ptr = sz.boolean();
let ob = sz.string("false");
let enc = sz.encode(ob).unwrap();
for b in enc { print!("{:02x}", b); } print!("\n"); */
}

216
src/lib-old.rs Normal file
View File

@ -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<T> {
pub class:usize,
pub data:T,
}
pub struct Instance {
scope:stdu::Trie<Handle>,
type_tree:util::TypeTree,
pool_boolean:stdu::Pool<bool>,
pool_natural:stdu::Pool<u64>,
pool_integer:stdu::Pool<i64>,
pool_block:stdu::Pool<Vec<u8>>,
pool_string:stdu::Pool<String>,
pool_option:stdu::Pool<Container<Option<Handle>>>,
pool_array:stdu::Pool<Container<Vec<Handle>>>,
pool_list:stdu::Pool<Container<Vec<Handle>>>,
pool_sparse:stdu::Pool<Container<stdu::Sparse<Handle>>>,
}
impl Instance {
pub(crate) fn new() -> Self
{
Self {
scope:stdu::Trie::<Handle>::new(),
type_tree:util::TypeTree::new(),
pool_boolean:stdu::Pool::<bool>::new(),
pool_natural:stdu::Pool::<u64>::new(),
pool_integer:stdu::Pool::<i64>::new(),
pool_block:stdu::Pool::<Vec<u8>>::new(),
pool_string:stdu::Pool::<String>::new(),
pool_option:stdu::Pool::<Container<Option<Handle>>>::new(),
pool_array:stdu::Pool::<Container<Vec<Handle>>>::new(),
pool_list:stdu::Pool::<Container<Vec<Handle>>>::new(),
pool_sparse:stdu::Pool::<Container<stdu::Sparse<Handle>>>::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<u8>) -> 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<Class>) -> Vec<u8>
{
let mut encoded = Vec::<u8>::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<Class>, Vec<u8>), ()>
{
let mut tags = Vec::<Class>::with_capacity(3);
let mut encoded = Vec::<u8>::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::<u8>::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<Vec<u8>,()>
{
match self.encode_parts(handle) {
Ok((_, encoded)) => Ok(encoded),
Err(_) => Err(())
}
}
pub fn encode(&self, handle:Handle) -> Result<Vec<u8>,()>
{
match self.encode_parts(handle) {
Ok((tags, data)) => {
let prefix = Self::encode_tags(tags);
let mut encoded = Vec::<u8>::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<u8>, index:&mut usize) -> Vec<Class>
{
let mut tags = Vec::<Class>::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<u8>) -> Result<Handle,()>
{
let mut index :usize = 0;
let tags = Self::decode_tags(data, &mut index);
for tag in tags {
println!("{}", tag);
}
Err(())
}
}

View File

@ -1,233 +1,66 @@
#![allow(dead_code)]
mod util;
mod representation;
pub fn init() -> Interface { Interface::new() }
type Class = u8;
type Handle = u64;
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;
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<T> {
pub class:Vec<Class>,
pub data:T,
pub struct Instance {
classes:util::TypeTree,
schemas:stdu::Sparse<usize>,
memory:Vec<u8>,
}
impl Instance {
/* Constructors */
// pub fn boolean(&mut self, data:bool) -> Result<PTR,ERR>
// pub fn natural(&mut self, data:u64) -> Result<PTR,ERR>
// pub fn integer(&mut self, data:i64) -> Result<PTR,ERR>
// pub fn float(&mut self, data:f64) -> Result<PTR,ERR>
// pub fn block(&mut self, size:usize, data:Vec<u8>) -> Result<PTR,ERR>
// pub fn string(&mut self, data:String) -> Result<PTR,ERR>
pub struct Interface {
pool_boolean:stdu::Pool<bool>,
pool_natural:stdu::Pool<u64>,
pool_integer:stdu::Pool<i64>,
pool_block:stdu::Pool<Vec<u8>>,
pool_string:stdu::Pool<String>,
pool_option:stdu::Pool<Container<Option<Handle>>>,
pool_array:stdu::Pool<Container<Vec<Handle>>>,
pool_list:stdu::Pool<Container<Vec<Handle>>>,
pool_sparse:stdu::Pool<Container<stdu::Sparse<Handle>>>,
}
impl Interface {
pub(crate) fn new() -> Self
/* Casters */
// pub fn as_bool(&self, PTR) -> Result<bool,ERR>
// pub fn as_uint(&self, PTR) -> Result<u64,ERR>
// pub fn as_int(&self, PTR) -> Result<i64,ERR>
// pub fn as_float(&self, PTR) -> Result<f64,ERR>
// pub fn as_bytes(&self, PTR) -> Result<Vec<u8>,ERR>
// pub fn as_string(&self, PTR) -> Result<String,ERR>
// pub fn as_list(&self, PTR) -> Result<Vec<PTR>,ERR>
/* Access */
// pub fn with(&self, INDEX) -> Result<CONTEXT,ERR>
// pub fn size(&self, PTR) -> Result<usize,ERR>
// pub fn len(&self, PTR) -> Result<usize,ERR>
// pub fn into(&self, PTR, INDEX) -> Result<PTR,ERR>
/* 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)
/* Translation */
// pub fn encode(&self, PTR) -> Result<Vec<u8>,ERR>
// pub fn decode(&mut self) -> Result<PTR,ERR>
fn acquire_memory()
{
Self {
pool_boolean:stdu::Pool::<bool>::new(),
pool_natural:stdu::Pool::<u64>::new(),
pool_integer:stdu::Pool::<i64>::new(),
pool_block:stdu::Pool::<Vec<u8>>::new(),
pool_string:stdu::Pool::<String>::new(),
pool_option:stdu::Pool::<Container<Option<Handle>>>::new(),
pool_array:stdu::Pool::<Container<Vec<Handle>>>::new(),
pool_list:stdu::Pool::<Container<Vec<Handle>>>::new(),
pool_sparse:stdu::Pool::<Container<stdu::Sparse<Handle>>>::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<u8>) -> 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<Class>) -> Vec<u8>
fn release_memory()
{
let mut encoded = Vec::<u8>::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<Class>, Vec<u8>), ()>
fn store_integer(&mut self, address:usize, value:i64)
{
let mut tags = Vec::<Class>::with_capacity(3);
let mut encoded = Vec::<u8>::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::<u8>::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<Vec<u8>,()>
pub fn init(size:usize) -> Instance
{
match self.encode_parts(handle) {
Ok((_, encoded)) => Ok(encoded),
Err(_) => Err(())
}
}
pub fn encode(&self, handle:Handle) -> Result<Vec<u8>,()>
{
match self.encode_parts(handle) {
Ok((tags, data)) => {
let prefix = Self::encode_tags(tags);
let mut encoded = Vec::<u8>::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<u8>, index:&mut usize) -> Vec<Class>
{
let mut tags = Vec::<Class>::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<u8>) -> Result<Handle,()>
{
let mut index :usize = 0;
let tags = Self::decode_tags(data, &mut index);
for tag in tags {
println!("{}", tag);
}
Err(())
Instance {
classes:util::TypeTree::new(),
schemas:stdu::Sparse::<usize>::new(),
memory:vec![0; size],
}
}

23
src/runtime/lib.cc Normal file
View File

@ -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);
}
}

41
src/runtime/lib.h Normal file
View File

@ -0,0 +1,41 @@
#include <cstdint>
#include <cstdlib>
#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();
};

3
src/runtime/mod.rs Normal file
View File

@ -0,0 +1,3 @@
extern "C" {
fn acquire() -> usize;
}

122
src/runtime/nametree.h Normal file
View File

@ -0,0 +1,122 @@
#ifndef H_NameTree
#define H_NameTree
#include <cstdint>
#include <vector>
#include <string>
class NameTree {
public:
struct Node {
std::string prefix;
size_t parent;
std::vector<size_t> 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<Node> 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

43
src/runtime/type.h Normal file
View File

@ -0,0 +1,43 @@
#include <cstdint>
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);
}

80
src/runtime/typetree.h Normal file
View File

@ -0,0 +1,80 @@
#ifndef H_TYPETREE
#define H_TYPETREE
#include <cstdint>
#include <vector>
class TypeTree {
public:
struct Node {
uint16_t type;
size_t parent;
std::vector<size_t> 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<Node> 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

29
src/tag.rs Normal file
View File

@ -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;

42
src/util/memory.rs Normal file
View File

@ -0,0 +1,42 @@
pub struct Memory {
data:Vec<u8>,
}
impl Memory {
pub fn new(size:usize) -> Self
{
Self {
data:vec![0; size],
}
}
pub fn allocate(&mut self, size:usize) -> Result<usize,()>
{
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() {
}
}
}

View File

@ -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

96
src/util/typetree.rs Normal file
View File

@ -0,0 +1,96 @@
struct Node {
pub class:u32,
pub parent:usize,
pub children:stdu::Sparse<usize>,
}
impl Node {
pub fn new(class:u32, parent:usize) -> Self
{
Self {
class:class,
parent:parent,
children:stdu::Sparse::<usize>::new(),
}
}
}
pub struct TypeTree {
data:stdu::Pool<Node>,
}
impl TypeTree {
pub fn new() -> Self
{
Self {
data:stdu::Pool::<Node>::new(),
}
}
pub fn add(&mut self, hierarchy:&Vec<u32>) -> 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<usize,()>
// 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<usize>
// 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<u32>) -> (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);
}
}