Add ffi calls and interfaces for runtime representation.

This commit is contained in:
yukirij 2023-08-02 17:15:24 -07:00
parent b4277d2c6f
commit f0304624c9
40 changed files with 886 additions and 1260 deletions

View File

@ -2,10 +2,12 @@
name = "szun"
version = "0.1.0"
repository = "https://git.yukiri.dev/Suzu/szun"
license-file = "LICENSE.md"
license-file = "LICENSE.txt"
edition = "2021"
publish = false
[dependencies]
stdu = { package = "util", git = "https://git.yukiri.dev/Yukiri/util.git" }
[build-dependencies]
cc = "1.0"
[dependencies]
yutil = { package = "util", git = "https://git.yukiri.dev/Yukiri/util.git" }

View File

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

View File

@ -1,6 +1,10 @@
extern crate cc;
fn main() {
println!("cargo:rerun-if-changed=src/runtime");
cc::Build::new()
.cpp(true)
.file("src/runtime/lib.cc")
.compile("lib_runtime.a");
.compile("runtime");
}

View File

@ -13,7 +13,8 @@
],
"rust-analyzer.showUnlinkedFileNotification": false,
"files.associations": {
"xstring": "cpp"
"xstring": "cpp",
"xmemory": "cpp"
}
}
}

View File

@ -1,6 +1,4 @@
fn main()
{
let sz = szun::init();
//let ptr = sz.boolean();
szun::test();
}

View File

@ -0,0 +1,5 @@
use crate::runtime;
pub fn new(t:u32) -> usize { unsafe { runtime::acquire(t) } }
pub fn address(id:usize) -> runtime::Variable { unsafe { runtime::address(id) } }
pub fn delete(id:usize) -> bool { unsafe { runtime::release(id) } }

38
src/interface/boolean.rs Normal file
View File

@ -0,0 +1,38 @@
use crate::runtime::{Variable, bool_get, bool_set};
use crate::interface::{ allocate::*, builder::* };
pub struct Boolean {
managed:bool,
addr:Variable,
}
impl Boolean {
pub fn new() -> Self
{
let t = boolean();
Self {
managed:true,
addr:Variable { class:t as usize, address: new(t) },
}
}
pub fn set(&mut self, value:bool)
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { bool_set(mem, value) };
}
pub fn get(&self) -> bool
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { bool_get(mem) }
}
}
impl Drop for Boolean {
fn drop(&mut self) {
if self.managed {
delete(self.addr.address);
}
}
}

13
src/interface/builder.rs Normal file
View File

@ -0,0 +1,13 @@
use crate::tag;
use crate::runtime;
pub fn varying() -> u32 { 0 }
pub fn null() -> u32 { unsafe { runtime::type_outer(0, tag::NULL) } }
pub fn boolean() -> u32 { unsafe { runtime::type_outer(0, tag::BOOLEAN) } }
pub fn natural() -> u32 { unsafe { runtime::type_outer(0, tag::NATURAL) } }
pub fn integer() -> u32 { unsafe { runtime::type_outer(0, tag::INTEGER) } }
pub fn array(s:u32, t:u32) -> u32 {
let size_node = unsafe { runtime::type_outer(t, s) };
unsafe { runtime::type_outer(size_node, tag::ARRAY) }
}
pub fn list(t:u32) -> u32 { unsafe { runtime::type_outer(t, tag::LIST) } }

38
src/interface/integer.rs Normal file
View File

@ -0,0 +1,38 @@
use crate::runtime::{Variable, integer_get, integer_set};
use crate::interface::{ allocate::*, builder::* };
pub struct Integer {
managed:bool,
addr:Variable,
}
impl Integer {
pub fn new() -> Self
{
let t = integer();
Self {
managed:true,
addr:Variable { class:t as usize, address: new(t) },
}
}
pub fn set(&mut self, value:i64)
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { integer_set(mem, value) };
}
pub fn get(&self) -> i64
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { integer_get(mem) }
}
}
impl Drop for Integer {
fn drop(&mut self) {
if self.managed {
delete(self.addr.address);
}
}
}

50
src/interface/list.rs Normal file
View File

@ -0,0 +1,50 @@
use crate::runtime::Variable;
use crate::interface::{ allocate::*, builder::* };
pub struct List {
managed:bool,
addr:Variable,
}
impl List {
pub fn new(t:u32) -> Self
{
let t = list(t);
Self {
managed:true,
addr:Variable { class:t as usize, address: new(t) },
}
}
pub fn capacity(&mut self) -> usize
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { list_capacity(mem) };
}
pub fn length(&mut self) -> usize
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { list_length(mem) };
}
pub fn at(&mut self, index:usize) -> Variable
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { list_at(mem, index) };
}
pub fn capacity(&mut self)
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { list_capacity(mem) };
}
}
impl Drop for List {
fn drop(&mut self) {
if self.managed {
delete(self.addr.address);
}
}
}

15
src/interface/mod.rs Normal file
View File

@ -0,0 +1,15 @@
mod builder; pub use builder::*;
mod allocate; pub use allocate::*;
mod util; pub use util::*;
mod boolean; pub use boolean::Boolean;
mod natural; pub use natural::Natural;
mod integer; pub use integer::Integer;
enum Type {
Null,
Boolean(Boolean),
Natural(Natural),
Integer(Integer),
List,
}

38
src/interface/natural.rs Normal file
View File

@ -0,0 +1,38 @@
use crate::runtime::{Variable, natural_get, natural_set};
use crate::interface::{ allocate::*, builder::* };
pub struct Natural {
managed:bool,
addr:Variable,
}
impl Natural {
pub fn new() -> Self
{
let t = natural();
Self {
managed:true,
addr:Variable { class:t as usize, address: new(t) },
}
}
pub fn set(&mut self, value:u64)
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { natural_set(mem, value) };
}
pub fn get(&self) -> u64
{
let mem = if self.managed { address(self.addr.address) } else { self.addr };
unsafe { natural_get(mem) }
}
}
impl Drop for Natural {
fn drop(&mut self) {
if self.managed {
delete(self.addr.address);
}
}
}

4
src/interface/util.rs Normal file
View File

@ -0,0 +1,4 @@
use crate::runtime;
pub fn get_type(t:u32) -> u32 { unsafe { runtime::type_key(t)} }
pub fn get_inner(t:u32) -> u32 { unsafe { runtime::type_inner(t)} }

24
src/interface/varying.rs Normal file
View File

@ -0,0 +1,24 @@
struct Varying {
addr:usize,
}
impl Varying {
pub fn new() -> Self
{
}
pub fn set()
{
}
pub fn class()
{
}
pub fn get()
{
}
}

View File

@ -1,216 +0,0 @@
#![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,66 +1,11 @@
#![allow(dead_code)]
mod tag;
mod util;
mod representation;
mod runtime;
mod interface; pub use interface::*;
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>
/* 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()
{
}
fn release_memory()
{
}
fn store_integer(&mut self, address:usize, value:i64)
{
}
}
pub fn init(size:usize) -> Instance
pub fn test()
{
Instance {
classes:util::TypeTree::new(),
schemas:stdu::Sparse::<usize>::new(),
memory:vec![0; size],
}
}

View File

@ -1,16 +0,0 @@
use crate::{Instance, Handle};
#[derive(Clone)]
pub struct ArrayData {
pub class:u32,
pub data:Vec<Handle>,
}
pub struct Array<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Array<'a> {
pub fn tag() -> u32 { 0x21 }
}

View File

@ -1,66 +0,0 @@
use crate::{Instance, Szun};
pub struct Block<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Block<'a> {
pub fn tag() -> u32 { 0x1e }
fn acquire(&self) -> Option<&Vec<u8>>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Block(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut Vec<u8>>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Block(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> Vec<u8>
{
return match self.acquire() {
Some(data) => data.clone(),
None => vec![],
}
}
pub fn get_ref(&self) -> Option<&Vec<u8>>
{
return match self.acquire() {
Some(data) => Some(data),
None => None,
}
}
pub fn get_mut(&mut self) -> Option<&mut Vec<u8>>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self, value:Vec<u8>)
{
match self.acquire_mut() {
Some(data) => { *data = value; }
None => { }
}
}
}

View File

@ -1,74 +0,0 @@
use crate::{Instance, Szun};
pub struct Boolean<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Boolean<'a> {
pub fn tag() -> u32 { 0x02 }
fn acquire(&self) -> Option<&bool>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Boolean(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut bool>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Boolean(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> bool
{
return match self.acquire() {
Some(data) => *data,
None => false,
}
}
pub fn get_mut(&mut self) -> Option<&mut bool>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self)
{
match self.acquire_mut() {
Some(data) => { *data = true; }
None => { }
}
}
pub fn unset(&mut self)
{
match self.acquire_mut() {
Some(data) => { *data = false; }
None => { }
}
}
pub fn toggle(&mut self)
{
match self.acquire_mut() {
Some(data) => { *data = !*data; }
None => { }
}
}
}

View File

@ -1,58 +0,0 @@
use crate::{Instance, Szun};
pub struct Integer<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Integer<'a> {
pub fn tag() -> u32 { 0x11 }
fn acquire(&self) -> Option<&i64>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Integer(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut i64>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Integer(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> i64
{
return match self.acquire() {
Some(data) => *data,
None => 0,
}
}
pub fn get_mut(&mut self) -> Option<&mut i64>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self, value:i64)
{
match self.acquire_mut() {
Some(data) => { *data = value; }
None => { }
}
}
}

View File

@ -1,90 +0,0 @@
use crate::{Instance, Szun, Handle};
#[derive(Clone)]
pub struct ListData {
pub class:u32,
pub data:Vec<Handle>,
}
pub struct List<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> List<'a> {
pub fn tag() -> u32 { 0x22 }
fn acquire(&self) -> Option<&ListData>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::List(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut ListData>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::List(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> Vec<Handle>
{
return match self.acquire() {
Some(data) => data.data.clone(),
None => vec![],
}
}
pub fn get_ref(&self) -> Option<&Vec<Handle>>
{
return match self.acquire() {
Some(data) => Some(&data.data),
None => None,
}
}
pub fn get_mut(&mut self) -> Option<&mut Vec<Handle>>
{
return match self.acquire_mut() {
Some(data) => Some(&mut data.data),
None => None,
}
}
pub fn set(&mut self, data:Vec<Handle>) -> Result<(),()>
{
/* return match self.acquire_mut() {
Some(ld) => {
let mut is_valid = true;
for handle in data {
match self.instance.data.get(handle) {
Some(entry) => {
if entry.object.tag() != ld.class && ld.class != 0 { is_valid = false; break; }
}
None => { is_valid = false; break; }
}
}
if is_valid {
ld.data = data;
Ok(())
} else {
Err(())
}
}
None => Err(())
} */
Err(())
}
}

View File

@ -1,9 +0,0 @@
mod null; pub use null::*;
mod boolean; pub use boolean::*;
mod natural; pub use natural::*;
mod integer; pub use integer::*;
mod block; pub use block::*;
mod string; pub use string::*;
mod array; pub use array::*;
mod list; pub use list::*;
mod sparse; pub use sparse::*;

View File

@ -1,58 +0,0 @@
use crate::{Instance, Szun};
pub struct Natural<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Natural<'a> {
pub fn tag() -> u32 { 0x10 }
fn acquire(&self) -> Option<&u64>
{
return match self.instance.data.get(self.target) {
Some(entry) => {
match &entry.object { Szun::Natural(data) => Some(data),
_ => None
}
}
None => None
};
}
fn acquire_mut(&mut self) -> Option<&mut u64>
{
return match self.instance.data.get_mut(self.target) {
Some(entry) => {
match &mut entry.object {
Szun::Natural(data) => Some(data),
_ => None
}
}
None => None
};
}
pub fn get(&self) -> u64
{
return match self.acquire() {
Some(data) => *data,
None => 0,
}
}
pub fn get_mut(&mut self) -> Option<&mut u64>
{
return match self.acquire_mut() {
Some(data) => Some(data),
None => None,
}
}
pub fn set(&mut self, value:u64)
{
match self.acquire_mut() {
Some(data) => { *data = value; }
None => { }
}
}
}

View File

@ -1,10 +0,0 @@
use crate::{Instance};
pub struct Null<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Null<'a> {
pub fn tag() -> u32 { 0x00 }
}

View File

@ -1,16 +0,0 @@
use crate::{Instance, Szun};
#[derive(Clone)]
pub struct SparseData {
pub class:u32,
pub data:stdu::Sparse<Szun>,
}
pub struct Sparse<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> Sparse<'a> {
pub fn tag() -> u32 { 0x23 }
}

View File

@ -1,10 +0,0 @@
use crate::{Instance};
pub struct String<'a> {
pub(crate) instance:&'a mut Instance,
pub(crate) target:usize,
}
impl<'a> String<'a> {
pub fn tag() -> u32 { 0x1f }
}

View File

@ -1,309 +0,0 @@
#![allow(dead_code)]
mod util;
mod template; pub use template::Type;
mod interface; pub use interface::*;
pub type Class = u32;
pub type Handle = usize;
#[derive(Clone)]
pub enum Szun {
/*00*/ Null,
/*02*/ Boolean(bool),
/*10*/ Natural(u64),
/*11*/ Integer(i64),
/*12*/ //Decimal(f64),
/*20*/ Block(Vec<u8>),
/*21*/ String(std::string::String),
/*30*/ //Set(Set),
/*31*/ Array(ArrayData),
/*32*/ List(ListData),
/*33*/ Sparse(SparseData),
/*34*/ //Map(Map),
/*35*/ //Tree(Tree),
/*36*/ //Graph(Graph),
/*40*/ //Enum(Enum),
/*41*/ //Selection(Selection),
/*4e*/ //Record(Record),
/*4f*/ //Schema(Schema),
}
impl Szun {
pub fn tag(&self) -> Class
{
match self {
Self::Null => Null::tag(),
Self::Boolean(_) => Boolean::tag(),
Self::Natural(_) => Natural::tag(),
Self::Integer(_) => Integer::tag(),
Self::Block(_) => Block::tag(),
Self::String(_) => String::tag(),
Self::Array(_) => Array::tag(),
Self::List(_) => List::tag(),
Self::Sparse(_) => Sparse::tag(),
}
}
}
macro_rules! szun_as {
($name:ident, $class:pat, $impl:ident) => {
pub fn $name(&mut self, handle:usize) -> Option<$impl>
{
match self.data.get(handle) {
Some(object) => {
match object.object {
$class => { return Some($impl { instance: self, target: handle }); }
_ => { }
}
}
None => { }
}
return None;
}
};
}
pub fn init() -> Instance { Instance::new() }
struct Entry {
owner:Handle,
class:Class,
object:Szun,
}
impl Entry {
pub fn new(object:Szun) -> Self
{
Self {
owner:0,
class:0,
object:object,
}
}
pub fn new_classed(class:Class, object:Szun) -> Self
{
Self {
owner:0,
class:class,
object:object,
}
}
}
pub struct Instance {
pub(crate) schemas:stdu::Sparse<Szun>,
pub(crate) data:stdu::Pool<Entry>,
}
impl Instance {
pub(crate) fn new() -> Self
{
Self {
schemas:stdu::Sparse::<Szun>::new(),
data:stdu::Pool::<Entry>::new(),
}
}
pub fn null(&mut self) -> Handle { self.data.add(Entry::new(Szun::Null)) }
pub fn boolean(&mut self, data:bool) -> Handle { self.data.add(Entry::new(Szun::Boolean(data))) }
pub fn natural(&mut self, data:u64) -> Handle { self.data.add(Entry::new(Szun::Natural(data))) }
pub fn integer(&mut self, data:i64) -> Handle { self.data.add(Entry::new(Szun::Integer(data))) }
pub fn block(&mut self, data:Vec<u8>) -> Handle { self.data.add(Entry::new(Szun::Block(data))) }
pub fn string(&mut self, data:&str) -> Handle { self.data.add(Entry::new(Szun::String(data.to_string()))) }
//pub fn array(&mut self, data:Vec<Handle>) -> Handle { self.data.add(Szun::Array(data)) }
pub fn list(&mut self, class:Class, data:&Vec<Handle>) -> Option<Handle> {
for handle in data {
match self.data.get(*handle) {
Some(object) => {
if object.object.tag() != class && class != 0 { return None; }
}
None => { return None; }
}
}
let obj = Szun::List(ListData { class:class, data:data.clone() });
return Some(self.data.add(Entry::new(obj)));
}
//pub fn sparse(&mut self, data:stdu::Sparse<Handle>) -> Handle { self.data.add(Szun::Sparse(data)) }
szun_as!(as_null, Szun::Null, Null);
szun_as!(as_boolean, Szun::Boolean(_), Boolean);
szun_as!(as_natural, Szun::Natural(_), Natural);
szun_as!(as_integer, Szun::Integer(_), Integer);
szun_as!(as_block, Szun::Block(_), Block);
szun_as!(as_string, Szun::String(_), String);
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, object:&Szun) -> Result<(Vec<Class>, Vec<u8>), ()>
{
let mut tags = Vec::<Class>::with_capacity(1);
let mut encoded = Vec::<u8>::with_capacity(64);
match object {
Szun::Null => {
tags.push(Null::tag());
}
Szun::Boolean(data) => {
tags.push(if *data { Boolean::tag() + 1 } else { Boolean::tag() });
}
Szun::Natural(data) => {
tags.push(Natural::tag());
encoded.append(&mut util::pack_natural(*data));
}
Szun::Integer(data) => {
tags.push(Integer::tag());
encoded.append(&mut &mut util::pack_integer(*data));
}
//Szun::Decimal(_data) => {
// tag = Decimal::tag();
//}
Szun::Block(data) => {
tags.push(Block::tag());
tags.push(data.len() as Class);
for b in data {
encoded.push(*b);
}
}
Szun::String(data) => {
tags.push(String::tag());
let mut bytes = Vec::<u8>::from(data.as_bytes());
let mut size = util::pack_natural(bytes.len() as u64);
encoded.append(&mut size);
encoded.append(&mut bytes);
}
//Szun::Set(_data) => {
// tag = Set::tag();
//}
Szun::Array(data) => {
tags.push(Array::tag());
tags.push(data.data.len() as Class);
tags.push(data.class);
for item in &data.data {
match self.data.get(*item) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((s_tags, mut s_data)) => {
if data.class == 0 {
encoded.append(&mut Self::encode_tags(s_tags));
}
encoded.append(&mut s_data);
}
Err(_) => { return Err(()); }
}
}
None => { return Err(()); }
}
}
}
Szun::List(data) => {
tags.push(List::tag());
tags.push(data.class);
encoded.append(&mut util::pack_natural(data.data.len() as u64));
for item in &data.data {
match self.data.get(*item) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((s_tags, mut s_data)) => {
if data.class == 0 {
encoded.append(&mut Self::encode_tags(s_tags));
}
encoded.append(&mut s_data);
}
Err(_) => { return Err(()); }
}
}
None => { return Err(()); }
}
}
}
Szun::Sparse(data) => {
tags.push(Sparse::tag());
tags.push(data.class);
encoded.append(&mut util::pack_natural(data.data.len() as u64));
//for item in &data {
// let (s_tags, mut s_data) = item.encode_parts();
// if data.class == 0 {
// encoded.append(&mut Szun::encode_tags(s_tags));
// }
// encoded.append(&mut s_data);
//}
}
/*Szun::Map(_data) => {
tag = Map::tag();
}
Szun::Enum(_data) => {
tag = Enum::tag();
}
Szun::Selection(_data) => {
tag = Selection::tag();
}
Szun::Record(_data) => {
tag = Record::tag();
}
Szun::Schema(_data) => {
tag = Schema::tag();
}*/
}
return Ok((tags, encoded));
}
pub fn encode_data(&self, handle:Handle) -> Result<Vec<u8>,()>
{
return match self.data.get(handle) {
Some(entry) => {
match self.encode_parts(&entry.object) {
Ok((_, encoded)) => Ok(encoded),
Err(_) => Err(())
}
}
None => Err(())
};
}
pub fn encode(&self, handle:Handle) -> Result<Vec<u8>,()>
{
return match self.data.get(handle) {
Some(entry) => {
match self.encode_parts(&entry.object) {
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(())
}
}
None => Err(())
};
}
}

View File

@ -1,3 +0,0 @@
pub trait Type {
fn tag() -> u32;
}

View File

@ -1,23 +1,384 @@
#include "lib.h"
void init()
{
TypeTree DB_TYPE;
NameTree DB_NAME;
Pool<Variable> DB_DATA;
extern "C" uint32_t type_outer(uint32_t id, uint32_t key)
{
return DB_TYPE.outer(id, key);
}
void* acquire(uint16_t type)
extern "C" uint32_t type_inner(uint32_t id)
{
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;
return DB_TYPE.inner(id);
}
extern "C" uint32_t type_key(uint32_t id)
{
return DB_TYPE.value(id);
}
extern "C" size_t type_size(uint32_t type_id)
{
if(DB_TYPE.has(type_id)) {
uint32_t type = DB_TYPE.value(type_id);
switch(type) {
case Type::Tag::Varying: return sizeof(Variable);
case Type::Tag::Null: return 0;
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::Block: return DB_TYPE.value(DB_TYPE.inner(type_id));
case Type::Tag::String: return sizeof(Type::List);
case Type::Tag::Array: {
uint32_t inner = static_cast<uint32_t>(DB_TYPE.inner(type_id));
return static_cast<size_t>(DB_TYPE.value(inner)) * type_size(static_cast<uint32_t>(DB_TYPE.inner(inner)));
};
case Type::Tag::List: return sizeof(Type::List);
default: return 0;
}
}
return 0;
}
void* allocate(uint32_t type_id, size_t count)
{
void* mem = nullptr;
size_t size = type_size(type_id) * count;
if(size > 0) {
mem = malloc(size);
if(mem != nullptr) {
memset(mem, 0, size);
}
return mem;
}
return nullptr;
}
extern "C" size_t acquire(uint32_t type_id)
{
void* mem = allocate(type_id, 1);
Variable addr {0};
if(mem != nullptr) {
addr.type = type_id;
addr.address = mem;
return DB_DATA.add(addr);
}
return 0;
}
extern "C" bool release(size_t id)
{
if(DB_DATA.has(id)) {
Variable addr;
if(DB_DATA.get(id, addr)) {
if(addr.address != nullptr) {
free(addr.address);
}
DB_DATA.remove(id);
return true;
}
}
return false;
}
extern "C" Variable address(size_t id)
{
Variable addr {0};
if(DB_DATA.has(id)) {
DB_DATA.get(id, addr);
}
return addr;
}
bool copy(Variable src, Variable dst)
{
Variable source = src;
Variable destination = dst;
// dereference varying data
if(type_key(src.type) == Type::Tag::Varying) {
source = *reinterpret_cast<Variable*>(src.address);
}
// prepare destination for varying data
if(type_key(dst.type) == Type::Tag::Varying) {
auto& dest_ref = *reinterpret_cast<Variable*>(dst.address);
// determine if memory can be reused, otherwise free and reallocate
if(source.type != dest_ref.type) {
if(dest_ref.address != nullptr) {
free(dest_ref.address);
dest_ref.type = Type::Tag::Null;
dest_ref.address = nullptr;
}
dest_ref.type = source.type;
dest_ref.address = allocate(dest_ref.type, 1);
}
}
// copy data into destination
if(source.type == destination.type) {
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::List: {
auto& src_list = *reinterpret_cast<Type::List*>(source.address);
auto& dst_list = *reinterpret_cast<Type::List*>(destination.address);
dst_list.capacity = src_list.capacity;
dst_list.length = src_list.length;
dst_list.data = allocate(type_inner(source.type), src_list.capacity);
for(size_t i = 0; i < src_list.length; ++i) {
copy(list_at(source, i), list_at(destination, i));
}
} break;
}
return true;
}
return false;
}
// Boolean //
extern "C" void bool_set(Variable addr, Type::Boolean value)
{
if(type_key(addr.type) == Type::Tag::Boolean) {
*(reinterpret_cast<Type::Boolean*>(addr.address)) = value;
}
}
void release(void* address)
extern "C" Type::Boolean bool_get(Variable addr)
{
if(address != nullptr) {
free(address);
if(type_key(addr.type) == Type::Tag::Boolean) {
return *(reinterpret_cast<Type::Boolean*>(addr.address));
}
return false;
}
// Natural //
extern "C" void natural_set(Variable addr, Type::Natural value)
{
if(type_key(addr.type) == Type::Tag::Natural) {
*(reinterpret_cast<Type::Natural*>(addr.address)) = value;
}
}
extern "C" Type::Natural natural_get(Variable addr)
{
if(type_key(addr.type) == Type::Tag::Natural) {
return *(reinterpret_cast<Type::Natural*>(addr.address));
}
return false;
}
// Integer //
extern "C" void integer_set(Variable addr, Type::Integer value)
{
if(type_key(addr.type) == Type::Tag::Integer) {
*(reinterpret_cast<Type::Integer*>(addr.address)) = value;
}
}
extern "C" Type::Integer integer_get(Variable addr)
{
if(type_key(addr.type) == Type::Tag::Integer) {
return *(reinterpret_cast<Type::Integer*>(addr.address));
}
return false;
}
// List
extern "C" size_t list_capacity(Variable addr)
{
if(type_key(addr.type) == Type::Tag::List) {
return (*reinterpret_cast<Type::List*>(addr.address)).capacity;
}
return 0;
}
extern "C" size_t list_length(Variable addr)
{
if(type_key(addr.type) == Type::Tag::List) {
return (*reinterpret_cast<Type::List*>(addr.address)).length;
}
return 0;
}
extern "C" Variable list_first(Variable addr)
{
Variable result {0};
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
if(list.length > 0) {
}
}
return result;
}
extern "C" Variable list_last(Variable addr)
{
Variable result {0};
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
if(list.length > 0) {
}
}
return result;
}
void* list_cell(Variable addr, size_t index)
{
if(type_key(addr.type) == Type::Tag::List) {
uint32_t inner = type_inner(addr.type);
Type::List& list = *reinterpret_cast<Type::List*>(addr.address);
// validate for overflow
size_t offset = type_size(inner);
if(list.data != nullptr && offset > 0 && index < list.length) {
return reinterpret_cast<void*>(reinterpret_cast<size_t>(addr.address) + (offset * index));
}
}
return nullptr;
}
extern "C" Variable list_at(Variable addr, size_t index)
{
Variable result {0};
if(type_key(addr.type) == Type::Tag::List) {
uint32_t inner = type_inner(addr.type);
Type::List& list = *reinterpret_cast<Type::List*>(addr.address);
void* cell = list_cell(addr, index);
if(cell != nullptr) {
// handle varying inner type
if(type_key(inner) == Type::Tag::Varying) {
result = *reinterpret_cast<Variable*>(cell);
} else {
result.type = inner;
result.address = cell;
}
}
}
return result;
}
extern "C" void list_clear(Variable addr)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
list.length = 0;
memset(list.data, 0, list.offset * list.capacity);
}
}
extern "C" void list_prepend(Variable addr, Variable source)
{
if(type_key(addr.type) == Type::Tag::List) {
uint32_t inner = type_inner(addr.type);
// validate list can store value
if(type_key(inner) == Type::Tag::Varying || source.type == inner) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
if(list.length == list.capacity) {
size_t new_capacity = (list.capacity < 16)? 16 : list.capacity * 2;
void* new_data = malloc(list.offset * new_capacity);
memset(new_data, 0, list.offset * new_capacity);
memcpy(new_data, list.data, list.offset * list.capacity);
}
// copy source to cell
Variable dst {0};
dst.type = inner;
dst.address = reinterpret_cast<void*>(reinterpret_cast<size_t>(addr.address) + (list.offset * list.length));
copy(source, dst);
list.length++;
}
}
}
extern "C" void list_append(Variable addr, Variable source)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}
extern "C" void list_insert(Variable addr, size_t index, Variable source)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}
extern "C" void list_truncate(Variable addr, size_t maximum)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}
extern "C" void list_shift(Variable addr)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}
extern "C" void list_remove(Variable addr, size_t index, size_t maximum)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}
extern "C" void list_reserve(Variable addr, size_t capacity)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
if(list.capacity < capacity) {
void* new_data = allocate(type_inner(addr.type), capacity); //malloc(list.offset * capacity);
//memset(new_data, 0, list.offset * capacity);
memcpy(new_data, list.data, list.offset * list.capacity);
}
}
}
extern "C" void list_resize(Variable addr, size_t length)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}

View File

@ -1,41 +1,53 @@
#include <cstdint>
#include <cstdlib>
#include "type.h"
#include "typetree.h"
#include "nametree.h"
#include "pool.h"
#include "schema.h"
extern TypeTree DB_TYPE;
extern NameTree DB_NAME;
extern Pool<Variable> DB_DATA;
struct List {
uint64_t capacity;
uint64_t length;
void* data;
extern "C" uint32_t type_outer(uint32_t id, uint32_t key);
extern "C" uint32_t type_inner(uint32_t id);
extern "C" uint32_t type_key(uint32_t id);
extern "C" size_t type_size(uint32_t type_id);
void* allocate(size_t size);
void* allocate(uint32_t type_id, size_t count);
extern "C" size_t acquire(uint32_t type_id);
extern "C" bool release(size_t id);
extern "C" Variable address(size_t id);
extern "C" bool copy(Variable src, Variable dst);
List();
~List();
};
// Boolean //
extern "C" void bool_set(Variable addr, Type::Boolean value);
extern "C" Type::Boolean bool_get(Variable addr);
struct Schema {
struct Row {
uint16_t type;
uint16_t offset;
};
struct Node {
uint16_t keyword;
uint16_t index;
};
// Natural //
extern "C" void natural_set(Variable addr, Type::Natural value);
extern "C" Type::Natural natural_get(Variable addr);
uint16_t capacity;
uint16_t length;
// Integer //
extern "C" void integer_set(Variable addr, Type::Integer value);
extern "C" Type::Integer integer_get(Variable addr);
Node* nodes;
Row* members;
Schema();
~Schema();
void* allocate();
};
// List //
extern "C" size_t list_capacity(Variable addr);
extern "C" size_t list_length(Variable addr);
extern "C" Variable list_first(Variable addr);
extern "C" Variable list_last(Variable addr);
void* list_cell(Variable addr, size_t index);
extern "C" Variable list_at(Variable addr, size_t index);
extern "C" void list_clear(Variable addr);
extern "C" void list_prepend(Variable addr, Variable source);
extern "C" void list_append(Variable addr, Variable source);
extern "C" void list_insert(Variable addr, size_t index, Variable source);
extern "C" void list_truncate(Variable addr, size_t maximum);
extern "C" void list_shift(Variable addr);
extern "C" void list_remove(Variable addr, size_t index, size_t maximum);
extern "C" void list_reserve(Variable addr, size_t capacity);
extern "C" void list_resize(Variable addr, size_t length);

View File

@ -1,3 +1,57 @@
extern "C" {
fn acquire() -> usize;
#[repr(C)]
#[derive(Clone, Copy)]
pub struct Variable {
pub class:usize,
pub address:usize,
}
extern "C" {
pub fn acquire(type_id:u32) -> usize;
pub fn release(id:usize) -> bool;
pub fn address(id:usize) -> Variable;
pub fn type_outer(type_id:u32, key:u32) -> u32;
pub fn type_inner(type_id:u32) -> u32;
pub fn type_key(type_id:u32) -> u32;
pub fn type_size(type_id:u32) -> usize;
pub fn bool_set(addr:Variable, data:bool);
pub fn bool_get(addr:Variable) -> bool;
pub fn natural_set(addr:Variable, data:u64);
pub fn natural_get(addr:Variable) -> u64;
pub fn integer_set(addr:Variable, data:i64);
pub fn integer_get(addr:Variable) -> i64;
// fn block_set(id:u64, data:Vec<u8>);
// fn block_get(id:u64) -> Vec<u8>
// fn block_at(id:u64, index:u64) -> u8;
// fn string_set(id:u64, data:Vec<u8>);
// fn string_get(id:u64) -> Vec<u8>;
// fn string_at(id:u64, index:u64) -> u32;
// fn array_at(id:u64, index:u64) -> [u64;2];
pub fn list_capacity(addr:Variable) -> usize;
pub fn list_length(addr:Variable) -> usize;
pub fn list_first(addr:Variable) -> Variable;
pub fn list_last(addr:Variable) -> Variable;
pub fn list_at(addr:Variable, index:usize) -> Variable;
pub fn list_clear(addr:Variable);
pub fn list_prepend(addr:Variable, src:Variable);
pub fn list_append(addr:Variable, src:Variable);
pub fn list_insert(addr:Variable, index:usize, src:Variable);
pub fn list_truncate(addr:Variable, maximum:usize);
pub fn list_shift(addr:Variable, maximum:usize);
pub fn list_remove(addr:Variable, index:usize, maximum:usize);
pub fn list_reserve(addr:Variable, capacity:usize);
pub fn list_resize(addr:Variable, length:usize);
//pub fn list_cut(addr:Variable, index:usize, length:usize) -> Variable;
//pub fn list_find(addr:Variable, target:Variable, start:usize) -> usize;
//pub fn list_count(addr:Variable, target:Variable, start:usize) -> usize;
}

View File

@ -41,7 +41,7 @@ size_t NameTree::lookup(const std::string& value)
size_t current = 0;
size_t index = 0;
while(index < value.length()) {
while(index < value.length()) {
Node& node = m_nodes[current];
size_t find = 0;

81
src/runtime/pool.h Normal file
View File

@ -0,0 +1,81 @@
#ifndef H_POOL
#define H_POOL
template <typename T>
class Pool {
public:
Pool()
{
m_next = 0;
}
~Pool()
{ }
size_t add(const T& data)
{
size_t location = m_next;
if(m_next == m_nodes.size()) {
m_nodes.push_back(Node());
m_next++;
m_nodes[location].active = true;
m_nodes[location].data.value = data;
}
else {
m_nodes[location].active = true;
m_next = m_nodes[location].data.addr;
m_nodes[location].data.value = data;
}
return location + 1;
}
void remove(size_t id)
{
if(has(id)) {
size_t index = id - 1;
m_nodes[index].active = false;
m_nodes[index].data.addr = m_next;
m_next = index;
}
}
bool has(size_t id)
{
if(id > 0 && id <= m_nodes.size()) {
if(m_nodes[id - 1].active) {
return true;
}
}
return false;
}
bool get(size_t id, T& data)
{
if(has(id)) {
data = m_nodes[id - 1].data.value;
return true;
}
return false;
}
private:
struct Node {
bool active;
union {
T value;
size_t addr;
} data;
Node() {
active = false;
data.addr = 0;
}
};
std::vector<Node> m_nodes;
size_t m_next;
};
#endif

11
src/runtime/schema.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef H_SCHEMA
#define H_SCHEMA
#include <cstdint>
struct Schema {
std::vector<uint32_t> types;
std::vector<std::pair<uint32_t, uint16_t>> names;
};
#endif

View File

@ -1,43 +1,42 @@
#include <cstdint>
struct Variable {
size_t type;
void* address;
};
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,
namespace Tag {
enum {
Varying = 0x00,
Null = 0x01,
Boolean = 0x02,
Natural = 0x10,
Integer = 0x11,
Block = 0x1e,
String = 0x1f,
//Optional = 0x20,
//Set = 0x21,
Array = 0x22,
List = 0x23,
Sparse = 0x24,
//Trie = 0x27,
//Map = 0x28,
Record = 0x4e,
Schema = 0x4f,
};
}
typedef bool Boolean;
typedef uint64_t Natural;
typedef int64_t Integer;
struct List {
size_t offset;
size_t capacity;
size_t length;
void* data;
};
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);
}

View File

@ -7,25 +7,27 @@
class TypeTree {
public:
struct Node {
uint16_t type;
uint32_t value;
size_t parent;
std::vector<size_t> children;
Node(uint16_t type, size_t parent);
Node(uint32_t value, 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);
bool has(size_t id);
size_t outer(size_t id, uint32_t type);
uint32_t value(size_t id);
size_t inner(size_t id);
private:
std::vector<Node> m_nodes;
};
TypeTree::Node::Node(uint16_t type, size_t parent) :type(type), parent(parent) { }
TypeTree::Node::Node(uint32_t value, size_t parent) :value(value), parent(parent) { }
TypeTree::TypeTree()
{
@ -35,7 +37,12 @@ TypeTree::TypeTree()
TypeTree::~TypeTree()
{ }
size_t TypeTree::get(size_t id, uint16_t type)
bool TypeTree::has(size_t id)
{
return id < m_nodes.size();
}
size_t TypeTree::outer(size_t id, uint32_t value)
{
size_t find = 0;
@ -44,14 +51,14 @@ size_t TypeTree::get(size_t id, uint16_t type)
Node& node = m_nodes[id];
for(size_t child : node.children) {
if(m_nodes[child].type == type) {
if(m_nodes[child].value == value) {
find = child;
break;
}
}
if(find == 0) {
m_nodes.push_back(Node(type, id));
m_nodes.push_back(Node(value, id));
find = m_nodes.size() - 1;
node.children.push_back(find);
@ -61,15 +68,15 @@ size_t TypeTree::get(size_t id, uint16_t type)
return find;
}
uint16_t TypeTree::type(size_t id)
uint32_t TypeTree::value(size_t id)
{
if(id > 0 && id < m_nodes.size()) {
return m_nodes[id].type;
return m_nodes[id].value;
}
return 0;
}
size_t TypeTree::parent(size_t id)
size_t TypeTree::inner(size_t id)
{
if(id > 0 && id < m_nodes.size()) {
return m_nodes[id].parent;

View File

@ -1,29 +1,28 @@
pub type Class = u16;
//pub type Class = u32;
pub const VARYING :Class = 0x00;
pub const NULL :Class = 0x01;
pub const BOOLEAN :Class = 0x02;
pub const VARYING :u32 = 0x00;
pub const NULL :u32 = 0x01;
pub const BOOLEAN :u32 = 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 NATURAL :u32 = 0x10;
pub const INTEGER :u32 = 0x11;
//pub const DECIMAL :u32 = 0x12;
//pub const FLOAT :u32 = 0x13;
//pub const COMPLEX :u32 = 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 RANGE :u32 = 0x1c;
//pub const CHAR :u32 = 0x1d;
pub const BLOCK :u32 = 0x1e;
pub const STRING :u32 = 0x1f;
//pub const OPTIONAL :u32 = 0x20;
//pub const SET :u32 = 0x21;
pub const ARRAY :u32 = 0x22;
pub const LIST :u32 = 0x23;
pub const SPARSE :u32 = 0x24;
//pub const MAP :u32 = 0x25;
//pub const TRIE :u32 = 0x26;
//pub const TREE :u32 = 0x27;
//pub const GRAPH :u32 = 0x28;
//...
pub const RECORD :Class = 0x3e;
pub const SCHEMA :Class = 0x3f;
pub const USER :Class = 0x40;
pub const RECORD :u32 = 0x7e;
pub const SCHEMA :u32 = 0x7f;

View File

@ -1,42 +0,0 @@
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,5 +1,5 @@
mod typetree; pub use typetree::TypeTree;
mod memory; pub use memory::Memory;
//mod typetree; pub use typetree::TypeTree;
//mod memory; pub use memory::Memory;
fn pack_count_leading_ones(data:u8) -> usize
{

View File

@ -1,96 +0,0 @@
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);
}
}