Add ffi calls and interfaces for runtime representation.
This commit is contained in:
parent
b4277d2c6f
commit
f0304624c9
@ -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" }
|
||||
|
@ -1,2 +1,2 @@
|
||||
Project: Kirisame
|
||||
Project: Suzu
|
||||
https://ykr.info/license/
|
6
build.rs
6
build.rs
@ -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");
|
||||
}
|
||||
|
@ -13,7 +13,8 @@
|
||||
],
|
||||
"rust-analyzer.showUnlinkedFileNotification": false,
|
||||
"files.associations": {
|
||||
"xstring": "cpp"
|
||||
"xstring": "cpp",
|
||||
"xmemory": "cpp"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
fn main()
|
||||
{
|
||||
let sz = szun::init();
|
||||
//let ptr = sz.boolean();
|
||||
|
||||
szun::test();
|
||||
}
|
||||
|
5
src/interface/allocate.rs
Normal file
5
src/interface/allocate.rs
Normal 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
38
src/interface/boolean.rs
Normal 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
13
src/interface/builder.rs
Normal 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
38
src/interface/integer.rs
Normal 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
50
src/interface/list.rs
Normal 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
15
src/interface/mod.rs
Normal 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
38
src/interface/natural.rs
Normal 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
4
src/interface/util.rs
Normal 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
24
src/interface/varying.rs
Normal file
@ -0,0 +1,24 @@
|
||||
struct Varying {
|
||||
addr:usize,
|
||||
}
|
||||
impl Varying {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pub fn set()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pub fn class()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pub fn get()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
216
src/lib-old.rs
216
src/lib-old.rs
@ -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(())
|
||||
}
|
||||
}
|
69
src/lib.rs
69
src/lib.rs
@ -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],
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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 }
|
||||
|
||||
}
|
@ -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 => { }
|
||||
}
|
||||
}
|
||||
}
|
@ -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 => { }
|
||||
}
|
||||
}
|
||||
}
|
@ -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 => { }
|
||||
}
|
||||
}
|
||||
}
|
@ -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(())
|
||||
}
|
||||
}
|
@ -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::*;
|
@ -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 => { }
|
||||
}
|
||||
}
|
||||
}
|
@ -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 }
|
||||
|
||||
}
|
@ -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 }
|
||||
|
||||
}
|
@ -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 }
|
||||
|
||||
}
|
309
src/old/lib.rs
309
src/old/lib.rs
@ -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(())
|
||||
};
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
pub trait Type {
|
||||
fn tag() -> u32;
|
||||
}
|
@ -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));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
81
src/runtime/pool.h
Normal 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
11
src/runtime/schema.h
Normal 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
|
@ -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);
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
|
49
src/tag.rs
49
src/tag.rs
@ -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;
|
||||
|
@ -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() {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user