diff --git a/Cargo.toml b/Cargo.toml index bbe1508..6efe945 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,3 +11,9 @@ cc = "1.0" [dependencies] yutil = { package = "util", git = "https://git.yukiri.dev/Yukiri/util.git" } + +[profile.dev] +opt-level = 0 + +[profile.release] +opt-level = 3 diff --git a/src/interface/allocate.rs b/src/interface/allocate.rs deleted file mode 100644 index 9036f50..0000000 --- a/src/interface/allocate.rs +++ /dev/null @@ -1,5 +0,0 @@ -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) } } diff --git a/src/interface/array.rs b/src/interface/array.rs new file mode 100644 index 0000000..687f80d --- /dev/null +++ b/src/interface/array.rs @@ -0,0 +1,47 @@ +use crate::runtime::{ + Variable, + acquire, release, + array_length, array_get, array_set +}; +use super::{Type, array}; + +pub struct Array { + managed:bool, + addr:Variable, +} +impl Array { + pub fn new(size:usize, class:usize) -> Self + { + Self { + managed:true, + addr:unsafe {acquire(array(size, class))}, + } + } + + pub fn from(addr:Variable) -> Self + { + Self { managed:false, addr:addr } + } + + pub fn length(&self) -> usize + { + unsafe {array_length(self.addr)} + } + + pub fn set(&mut self, index:usize, source:Variable) + { + unsafe { array_set(self.addr, index, source); } + } + + pub fn get(&self, index:usize) -> Type + { + Type::from(unsafe {array_get(self.addr, index)}) + } +} +impl std::ops::Deref for Array { + type Target = Variable; + fn deref(&self) -> &Self::Target { return &self.addr; } +} +impl Drop for Array { + fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } +} diff --git a/src/interface/block.rs b/src/interface/block.rs new file mode 100644 index 0000000..255fbe9 --- /dev/null +++ b/src/interface/block.rs @@ -0,0 +1,49 @@ +use crate::runtime::{Variable, acquire, release, type_inner, type_key, block_set, block_get}; +use super::block; + +pub struct Block { + managed:bool, + addr:Variable, +} +impl Block { + pub fn new(size:usize) -> Self + { + Self { + managed:true, + addr:unsafe {acquire(block(size))}, + } + } + + pub fn from(addr:Variable) -> Self + { + Self { managed:false, addr:addr } + } + + pub fn set(&mut self, data:Vec) + { + let length = unsafe {type_key(type_inner(self.addr.class))}; + for index in 0..usize::min(data.len(), length) { + unsafe {block_set(self.addr, index, data[index])}; + } + } + + pub fn get(&self) -> Vec + { + let mut result = Vec::::new(); + let length = unsafe {type_key(type_inner(self.addr.class))}; + if length > 0 { + result.resize(length, 0); + for index in 0..length { + result[index] = unsafe {block_get(self.addr, index)}; + } + } + return result; + } +} +impl std::ops::Deref for Block { + type Target = Variable; + fn deref(&self) -> &Self::Target { return &self.addr; } +} +impl Drop for Block { + fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } +} diff --git a/src/interface/boolean.rs b/src/interface/boolean.rs index ea20865..18e1040 100644 --- a/src/interface/boolean.rs +++ b/src/interface/boolean.rs @@ -1,5 +1,5 @@ -use crate::runtime::{Variable, bool_get, bool_set}; -use crate::interface::{ allocate::*, builder::* }; +use crate::runtime::{Variable, acquire, release, bool_get, bool_set}; +use super::boolean; pub struct Boolean { managed:bool, @@ -9,30 +9,38 @@ pub struct Boolean { impl Boolean { pub fn new() -> Self { - let t = boolean(); Self { managed:true, - addr:Variable { class:t as usize, address: new(t) }, + addr:unsafe {acquire(boolean())}, } } + pub fn from(addr:Variable) -> Self + { + Self { managed:false, addr:addr } + } + + pub fn with(value:bool) -> Self + { + let mut obj = Self::new(); + obj.set(value); + return obj; + } + pub fn set(&mut self, value:bool) { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { bool_set(mem, value) }; + unsafe { bool_set(self.addr, value) }; } pub fn get(&self) -> bool { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { bool_get(mem) } + unsafe { bool_get(self.addr) } } } - +impl std::ops::Deref for Boolean { + type Target = Variable; + fn deref(&self) -> &Self::Target { return &self.addr; } +} impl Drop for Boolean { - fn drop(&mut self) { - if self.managed { - delete(self.addr.address); - } - } + fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } } diff --git a/src/interface/builder.rs b/src/interface/builder.rs index 2846324..f94a674 100644 --- a/src/interface/builder.rs +++ b/src/interface/builder.rs @@ -1,13 +1,24 @@ 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 varying() -> usize { 0 } +pub fn null() -> usize { unsafe { runtime::type_outer(0, tag::NULL) } } +pub fn boolean() -> usize { unsafe { runtime::type_outer(0, tag::BOOLEAN) } } +pub fn natural() -> usize { unsafe { runtime::type_outer(0, tag::NATURAL) } } +pub fn integer() -> usize { unsafe { runtime::type_outer(0, tag::INTEGER) } } + +pub fn block(size:usize) -> usize { + unsafe { + let inner_node = runtime::type_outer(0, size); + runtime::type_outer(inner_node, tag::BLOCK) + } } -pub fn list(t:u32) -> u32 { unsafe { runtime::type_outer(t, tag::LIST) } } + +pub fn array(size:usize, type_id:usize) -> usize { + unsafe { + let inner_node = runtime::type_outer(type_id, size); + runtime::type_outer(inner_node, tag::ARRAY) + } +} + +pub fn list(type_id:usize) -> usize { unsafe { runtime::type_outer(type_id, tag::LIST) } } diff --git a/src/interface/integer.rs b/src/interface/integer.rs index d02abf3..f517400 100644 --- a/src/interface/integer.rs +++ b/src/interface/integer.rs @@ -1,38 +1,45 @@ -use crate::runtime::{Variable, integer_get, integer_set}; -use crate::interface::{ allocate::*, builder::* }; +use crate::runtime::{Variable, acquire, release, integer_get, integer_set}; +use super::integer; 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) }, + addr:unsafe {acquire(integer())}, } } + pub fn from(addr:Variable) -> Self + { + Self { managed:false, addr:addr } + } + + pub fn with(value:i64) -> Self + { + let mut obj = Self::new(); + obj.set(value); + return obj; + } + pub fn set(&mut self, value:i64) { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { integer_set(mem, value) }; + unsafe { integer_set(self.addr, value) }; } pub fn get(&self) -> i64 { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { integer_get(mem) } + unsafe { integer_get(self.addr) } } } - +impl std::ops::Deref for Integer { + type Target = Variable; + fn deref(&self) -> &Self::Target { return &self.addr; } +} impl Drop for Integer { - fn drop(&mut self) { - if self.managed { - delete(self.addr.address); - } - } + fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } } diff --git a/src/interface/list.rs b/src/interface/list.rs index bc84205..6ad1ac3 100644 --- a/src/interface/list.rs +++ b/src/interface/list.rs @@ -1,50 +1,86 @@ -use crate::runtime::Variable; -use crate::interface::{ allocate::*, builder::* }; +use crate::runtime::{ + Variable, + acquire, release, + list_capacity, list_length, + list_at, + list_clear, + list_insert, list_update, + list_remove, + list_reserve, +}; +use super::{varying, list}; pub struct List { managed:bool, addr:Variable, } - impl List { - pub fn new(t:u32) -> Self + pub fn new(class:usize) -> Self { - let t = list(t); Self { managed:true, - addr:Variable { class:t as usize, address: new(t) }, + addr:unsafe {acquire(list(class))}, } } - pub fn capacity(&mut self) -> usize + pub fn from(addr:Variable) -> Self { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { list_capacity(mem) }; + Self { managed:false, addr:addr } } - pub fn length(&mut self) -> usize + pub fn with(data:Vec) -> Self { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { list_length(mem) }; + let mut obj = Self::new(varying()); + for item in data { + obj.insert(obj.length(), item); + } + return obj; } - pub fn at(&mut self, index:usize) -> Variable + pub fn capacity(&self) -> usize { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { list_at(mem, index) }; + unsafe {list_capacity(self.addr)} } - pub fn capacity(&mut self) + pub fn length(&self) -> usize { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { list_capacity(mem) }; + unsafe {list_length(self.addr)} + } + + pub fn at(&self, index:usize) -> Variable + { + unsafe {list_at(self.addr, index)} + } + + pub fn clear(&mut self) + { + unsafe{list_clear(self.addr)}; + } + + pub fn insert(&mut self, index:usize, source:Variable) + { + unsafe{list_insert(self.addr, index, source)}; + } + + pub fn update(&mut self, index:usize, source:Variable) + { + unsafe{list_update(self.addr, index, source)}; + } + + pub fn remove(&mut self, index:usize, maximum:usize) + { + unsafe{list_remove(self.addr, index, maximum)}; + } + + pub fn reserve(&mut self, length:usize) + { + unsafe{list_reserve(self.addr, length)}; } } - +impl std::ops::Deref for List { + type Target = Variable; + fn deref(&self) -> &Self::Target { return &self.addr; } +} impl Drop for List { - fn drop(&mut self) { - if self.managed { - delete(self.addr.address); - } - } + fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } } diff --git a/src/interface/mod.rs b/src/interface/mod.rs index e5d76ba..98d59e1 100644 --- a/src/interface/mod.rs +++ b/src/interface/mod.rs @@ -1,15 +1,37 @@ +use crate::runtime::{Variable, type_key}; +use crate::tag; + 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; +mod block; pub use block::Block; +mod array; pub use array::Array; +mod list; pub use list::List; -enum Type { +pub enum Type { + Varying, Null, Boolean(Boolean), Natural(Natural), Integer(Integer), - List, + Block(Block), + Array(Array), + List(List), +} +impl Type { + pub fn from(addr:Variable) -> Self + { + match unsafe {type_key(addr.class)} { + tag::VARYING => Type::Varying, + tag::NULL => Type::Null, + tag::BOOLEAN => Type::Boolean(Boolean::from(addr)), + tag::NATURAL => Type::Natural(Natural::from(addr)), + tag::INTEGER => Type::Integer(Integer::from(addr)), + tag::ARRAY => Type::Array(Array::from(addr)), + //tag::LIST => Type::List(List::from(addr)), + _ => Type::Null, + } + } } diff --git a/src/interface/natural.rs b/src/interface/natural.rs index 1415b37..4e85cc1 100644 --- a/src/interface/natural.rs +++ b/src/interface/natural.rs @@ -1,38 +1,45 @@ -use crate::runtime::{Variable, natural_get, natural_set}; -use crate::interface::{ allocate::*, builder::* }; +use crate::runtime::{Variable, acquire, release, natural_get, natural_set}; +use super::natural; 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) }, + addr:unsafe {acquire(natural())}, } } + pub fn from(addr:Variable) -> Self + { + Self { managed:false, addr:addr } + } + + pub fn with(value:u64) -> Self + { + let mut obj = Self::new(); + obj.set(value); + return obj; + } + pub fn set(&mut self, value:u64) { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { natural_set(mem, value) }; + unsafe { natural_set(self.addr, value) }; } pub fn get(&self) -> u64 { - let mem = if self.managed { address(self.addr.address) } else { self.addr }; - unsafe { natural_get(mem) } + unsafe { natural_get(self.addr) } } } - +impl std::ops::Deref for Natural { + type Target = Variable; + fn deref(&self) -> &Self::Target { return &self.addr; } +} impl Drop for Natural { - fn drop(&mut self) { - if self.managed { - delete(self.addr.address); - } - } + fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } } } diff --git a/src/interface/util.rs b/src/interface/util.rs deleted file mode 100644 index ceb44f8..0000000 --- a/src/interface/util.rs +++ /dev/null @@ -1,4 +0,0 @@ -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)} } diff --git a/src/interface/varying.rs b/src/interface/varying.rs index 19fc618..4c5f3a0 100644 --- a/src/interface/varying.rs +++ b/src/interface/varying.rs @@ -1,24 +1,35 @@ -struct Varying { - addr:usize, +use crate::runtime::{Variable, acquire, release, bool_get, bool_set}; +use super::varying; + +pub struct Boolean { + managed:bool, + addr:Variable, } + impl Varying { pub fn new() -> Self + { + Self { + managed:true, + addr:unsafe {acquire(varying())}, + } + } + + pub fn set(&mut self, value:bool) { } - - pub fn set() + + pub fn get(&self) -> Variable { - - } - - pub fn class() - { - - } - - pub fn get() - { - + false + } +} + +impl Drop for Varying { + fn drop(&mut self) { + if self.managed { + unsafe {release(self.addr)}; + } } } diff --git a/src/runtime/lib.cc b/src/runtime/lib.cc index fed8ecd..5f61825 100644 --- a/src/runtime/lib.cc +++ b/src/runtime/lib.cc @@ -4,25 +4,25 @@ TypeTree DB_TYPE; NameTree DB_NAME; Pool DB_DATA; -extern "C" uint32_t type_outer(uint32_t id, uint32_t key) +extern "C" size_t type_outer(size_t type_id, size_t key) { - return DB_TYPE.outer(id, key); + return DB_TYPE.outer(type_id, key); } -extern "C" uint32_t type_inner(uint32_t id) +extern "C" size_t type_inner(size_t type_id) { - return DB_TYPE.inner(id); + return DB_TYPE.inner(type_id); } -extern "C" uint32_t type_key(uint32_t id) +extern "C" size_t type_key(size_t type_id) { - return DB_TYPE.value(id); + return DB_TYPE.key(type_id); } -extern "C" size_t type_size(uint32_t type_id) +extern "C" size_t type_size(size_t type_id) { if(DB_TYPE.has(type_id)) { - uint32_t type = DB_TYPE.value(type_id); + size_t type = DB_TYPE.key(type_id); switch(type) { case Type::Tag::Varying: return sizeof(Variable); @@ -30,11 +30,12 @@ extern "C" size_t type_size(uint32_t type_id) case Type::Tag::Boolean: return sizeof(Type::Boolean); case Type::Tag::Natural: return sizeof(Type::Natural); case Type::Tag::Integer: return sizeof(Type::Integer); - case Type::Tag::Block: return DB_TYPE.value(DB_TYPE.inner(type_id)); + case Type::Tag::Block: return DB_TYPE.key(DB_TYPE.inner(type_id)); case Type::Tag::String: return sizeof(Type::List); case Type::Tag::Array: { - uint32_t inner = static_cast(DB_TYPE.inner(type_id)); - return static_cast(DB_TYPE.value(inner)) * type_size(static_cast(DB_TYPE.inner(inner))); + size_t length = DB_TYPE.inner(type_id); + size_t inner = DB_TYPE.inner(length); + return static_cast(DB_TYPE.key(length)) * type_size(inner); }; case Type::Tag::List: return sizeof(Type::List); default: return 0; @@ -43,7 +44,7 @@ extern "C" size_t type_size(uint32_t type_id) return 0; } -void* allocate(uint32_t type_id, size_t count) +void* allocate(size_t type_id, size_t count) { void* mem = nullptr; size_t size = type_size(type_id) * count; @@ -57,40 +58,55 @@ void* allocate(uint32_t type_id, size_t count) return nullptr; } -extern "C" size_t acquire(uint32_t type_id) +extern "C" Variable acquire(size_t type_id) { - void* mem = allocate(type_id, 1); Variable addr {0}; - if(mem != nullptr) { + addr.address = allocate(type_id, 1); + if(addr.address != 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; + } + +void drop(Variable addr) +{ + if(addr.address != nullptr) { + switch(addr.type) { + case Type::Tag::Boolean: + case Type::Tag::Natural: + case Type::Tag::Integer: + case Type::Tag::Block: + break; + + case Type::Tag::Varying: { + Variable& var = *reinterpret_cast(addr.address); + if(var.address != nullptr) { + drop(var); + } + var.type = 0; + var.address = nullptr; + } break; + + case Type::Tag::List: { + //Type::List& list = *reinterpret_cast(addr.address); + //if(list.data != nullptr) { + // for(size_t i = 0; i < list.length; ++i) { + // drop(list_cell(addr, i)); + // } + // free(list.data); + //} + } break; + } + memset(addr.address, 0, type_size(addr.type)); + } +} + +extern "C" void release(Variable addr) +{ + if(addr.address != nullptr) { + drop(addr); + free(addr.address); + } } bool copy(Variable src, Variable dst) @@ -114,8 +130,7 @@ bool copy(Variable src, Variable dst) dest_ref.type = Type::Tag::Null; dest_ref.address = nullptr; } - dest_ref.type = source.type; - dest_ref.address = allocate(dest_ref.type, 1); + dest_ref = acquire(source.type); } } @@ -132,7 +147,7 @@ bool copy(Variable src, Variable dst) memcpy(destination.address, source.address, type_size(source.type)); } break; - case Type::Tag::List: { + /*case Type::Tag::List: { auto& src_list = *reinterpret_cast(source.address); auto& dst_list = *reinterpret_cast(destination.address); @@ -143,7 +158,7 @@ bool copy(Variable src, Variable dst) for(size_t i = 0; i < src_list.length; ++i) { copy(list_at(source, i), list_at(destination, i)); } - } break; + } break;*/ } return true; @@ -153,21 +168,68 @@ bool copy(Variable src, Variable dst) } +// Varying // + +extern "C" Variable varying_get(Variable addr) +{ + Variable result {0}; + //if(type_key(addr.type) == Type::Tag::Varying) { + result = *reinterpret_cast(addr.address); + //} + return result; +} + +extern "C" void varying_set(Variable addr, Variable source) +{ + //if(type_key(addr.type) == Type::Tag::Varying) { + Variable& var = *reinterpret_cast(addr.address); + + if(var.address != nullptr) { + drop(var); + } + + if(var.type != source.type || var.address == nullptr) { + if(var.address != nullptr) { + free(var.address); + } + var.type = source.type; + var.address = allocate(source.type, 1); + } + + copy(source, var); + //} +} + +extern "C" void varying_clear(Variable addr) +{ + //if(type_key(addr.type) == Type::Tag::Varying) { + Variable& var = *reinterpret_cast(addr.address); + + if(var.address != nullptr) { + drop(var); + free(var.address); + var.type = 0; + var.address = nullptr; + } + //} +} + + // Boolean // extern "C" void bool_set(Variable addr, Type::Boolean value) { - if(type_key(addr.type) == Type::Tag::Boolean) { + //if(type_key(addr.type) == Type::Tag::Boolean) { *(reinterpret_cast(addr.address)) = value; - } + //} } extern "C" Type::Boolean bool_get(Variable addr) { - if(type_key(addr.type) == Type::Tag::Boolean) { + //if(type_key(addr.type) == Type::Tag::Boolean) { return *(reinterpret_cast(addr.address)); - } - return false; + //} + //return false; } @@ -175,17 +237,17 @@ extern "C" Type::Boolean bool_get(Variable addr) extern "C" void natural_set(Variable addr, Type::Natural value) { - if(type_key(addr.type) == Type::Tag::Natural) { + //if(type_key(addr.type) == Type::Tag::Natural) { *(reinterpret_cast(addr.address)) = value; - } + //} } extern "C" Type::Natural natural_get(Variable addr) { - if(type_key(addr.type) == Type::Tag::Natural) { + //if(type_key(addr.type) == Type::Tag::Natural) { return *(reinterpret_cast(addr.address)); - } - return false; + //} + //return false; } @@ -193,192 +255,293 @@ extern "C" Type::Natural natural_get(Variable addr) extern "C" void integer_set(Variable addr, Type::Integer value) { - if(type_key(addr.type) == Type::Tag::Integer) { + //if(type_key(addr.type) == Type::Tag::Integer) { *(reinterpret_cast(addr.address)) = value; - } + //} } extern "C" Type::Integer integer_get(Variable addr) { - if(type_key(addr.type) == Type::Tag::Integer) { + //if(type_key(addr.type) == Type::Tag::Integer) { return *(reinterpret_cast(addr.address)); - } - return false; + //} + //return false; } -// List +// Block // + +extern "C" uint8_t block_get(Variable addr, size_t index) +{ + //if(type_key(addr.type) == Type::Tag::Block) { + size_t length = type_key(type_inner(addr.type)); + if(index < length) { + return reinterpret_cast(addr.address)[index]; + } + //} + return 0; +} + +extern "C" void block_set(Variable addr, size_t index, uint8_t value) +{ + //if(type_key(addr.type) == Type::Tag::Block) { + size_t length = type_key(type_inner(addr.type)); + if(index < length) { + reinterpret_cast(addr.address)[index] = value; + } + //} +} + + +// String // + + +// Array // + +extern "C" size_t array_length(Variable addr) +{ + //if(type_key(addr.type) == Type::Tag::Array) { + return type_key(type_inner(addr.type)); + //} + //return 0; +} + +Variable array_cell(Variable addr, size_t index) +{ + Variable result {0}; + //if(type_key(addr.type) == Type::Tag::Array) { + size_t length_n = type_inner(addr.type); + size_t length = type_key(length_n); + size_t type = type_inner(length_n); + size_t offset = type_size(type); + + // validate for overflow + if(addr.address != nullptr && offset > 0 && index < length) { + result.type = type; + result.address = reinterpret_cast(reinterpret_cast(addr.address) + (offset * index)); + } + //} + return result; +} + +extern "C" Variable array_get(Variable addr, size_t index) +{ + Variable result {0}; + //if(type_key(addr.type) == Type::Tag::Array) { + Variable cell = array_cell(addr, index); + if(cell.address != nullptr) { + if(cell.type == Type::Tag::Varying) { + result = varying_get(cell); + } + else { + result = cell; + } + } + //} + return result; +} + +extern "C" void array_set(Variable addr, size_t index, Variable source) +{ + //if(type_key(addr.type) == Type::Tag::Array) { + Variable cell = array_cell(addr, index); + if(cell.type == Type::Tag::Varying) { + varying_set(cell, source); + } + else { + copy(source, cell); + } + //} +} + + +// List // extern "C" size_t list_capacity(Variable addr) { - if(type_key(addr.type) == Type::Tag::List) { + //if(type_key(addr.type) == Type::Tag::List) { return (*reinterpret_cast(addr.address)).capacity; - } - return 0; + //} + //return 0; } extern "C" size_t list_length(Variable addr) { - if(type_key(addr.type) == Type::Tag::List) { + //if(type_key(addr.type) == Type::Tag::List) { return (*reinterpret_cast(addr.address)).length; - } - return 0; + //} + //return 0; } -extern "C" Variable list_first(Variable addr) +Variable list_cell(Variable addr, size_t index) { Variable result {0}; - if(type_key(addr.type) == Type::Tag::List) { - auto& list = (*reinterpret_cast(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(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); + //if(type_key(addr.type) == Type::Tag::List) { Type::List& list = *reinterpret_cast(addr.address); + size_t inner = type_inner(addr.type); + size_t offset = type_size(inner); // validate for overflow - size_t offset = type_size(inner); if(list.data != nullptr && offset > 0 && index < list.length) { - return reinterpret_cast(reinterpret_cast(addr.address) + (offset * index)); + result.type = inner; + result.address = reinterpret_cast(reinterpret_cast(list.data) + (offset * index)); } - } - return nullptr; + //} + return result; } 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(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(cell); + //if(type_key(addr.type) == Type::Tag::List) { + Variable cell = list_cell(addr, index); + if(cell.address != nullptr) { + if(cell.type == Type::Tag::Varying) { + result = *reinterpret_cast(cell.address); } else { - result.type = inner; - result.address = cell; + result = cell; } } - } + //} return result; } -extern "C" void list_clear(Variable addr) +/*extern "C" Variable list_first(Variable addr) { + Variable result {0}; if(type_key(addr.type) == Type::Tag::List) { auto& list = (*reinterpret_cast(addr.address)); - list.length = 0; - memset(list.data, 0, list.offset * list.capacity); + if(list.length > 0) { + result = list_at(addr, 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(addr.address)); + if(list.length > 0) { + result = list_at(addr, list.length - 1); + } + } + return result; +}*/ + +extern "C" void list_clear(Variable addr) +{ + //if(type_key(addr.type) == Type::Tag::List) { + size_t offset = type_size(type_inner(addr.type)); + auto& list = (*reinterpret_cast(addr.address)); + for(size_t i = 0; i < list.length; ++i) { + drop(list_cell(addr, i)); + } + list.length = 0; + memset(list.data, 0, offset * list.capacity); + //} } -extern "C" void list_prepend(Variable addr, Variable source) +/*extern "C" void list_prepend(Variable addr, Variable source) { if(type_key(addr.type) == Type::Tag::List) { - uint32_t inner = type_inner(addr.type); + size_t inner = type_inner(addr.type); + //size_t offset = type_size(inner); // validate list can store value if(type_key(inner) == Type::Tag::Varying || source.type == inner) { auto& list = (*reinterpret_cast(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); + list_reserve(addr, list.capacity * 2); } // copy source to cell - Variable dst {0}; - dst.type = inner; - dst.address = reinterpret_cast(reinterpret_cast(addr.address) + (list.offset * list.length)); - copy(source, dst); list.length++; } } -} +}*/ -extern "C" void list_append(Variable addr, Variable source) +/*extern "C" void list_append(Variable addr, Variable source) { if(type_key(addr.type) == Type::Tag::List) { - auto& list = (*reinterpret_cast(addr.address)); - + Type::List& list = *reinterpret_cast(addr.address); + size_t inner = type_inner(addr.type); + //size_t offset = type_size(inner); + + // validate list can store value + if(type_key(inner) == Type::Tag::Varying || source.type == inner) { + if(list.length == list.capacity) { + list_reserve(addr, list.capacity * 2); + } + + // copy source to cell + + list.length++; + } } -} +}*/ extern "C" void list_insert(Variable addr, size_t index, Variable source) { - if(type_key(addr.type) == Type::Tag::List) { - auto& list = (*reinterpret_cast(addr.address)); + //if(type_key(addr.type) == Type::Tag::List) { + //auto& list = (*reinterpret_cast(addr.address)); - } + //} } -extern "C" void list_truncate(Variable addr, size_t maximum) +extern "C" void list_update(Variable addr, size_t index, Variable source) { - if(type_key(addr.type) == Type::Tag::List) { - auto& list = (*reinterpret_cast(addr.address)); + //if(type_key(addr.type) == Type::Tag::List) { + //auto& list = (*reinterpret_cast(addr.address)); - } + //} } -extern "C" void list_shift(Variable addr) +/*extern "C" void list_truncate(Variable addr, size_t maximum) { if(type_key(addr.type) == Type::Tag::List) { - auto& list = (*reinterpret_cast(addr.address)); + //auto& list = (*reinterpret_cast(addr.address)); } -} +}*/ + +/*extern "C" void list_shift(Variable addr) +{ + if(type_key(addr.type) == Type::Tag::List) { + //auto& list = (*reinterpret_cast(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(addr.address)); + //if(type_key(addr.type) == Type::Tag::List) { + //auto& list = (*reinterpret_cast(addr.address)); - } + //} } extern "C" void list_reserve(Variable addr, size_t capacity) { - if(type_key(addr.type) == Type::Tag::List) { + //if(type_key(addr.type) == Type::Tag::List) { auto& list = (*reinterpret_cast(addr.address)); + size_t inner = type_inner(addr.type); + size_t offset = type_size(inner); 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); + void* new_data = allocate(inner, capacity); + memcpy(new_data, list.data, offset * list.capacity); } - } + //} } -extern "C" void list_resize(Variable addr, size_t length) +/*extern "C" void list_resize(Variable addr, size_t length) { if(type_key(addr.type) == Type::Tag::List) { - auto& list = (*reinterpret_cast(addr.address)); + //auto& list = (*reinterpret_cast(addr.address)); } -} - +}*/ diff --git a/src/runtime/lib.h b/src/runtime/lib.h index a405c99..0910860 100644 --- a/src/runtime/lib.h +++ b/src/runtime/lib.h @@ -12,22 +12,26 @@ extern TypeTree DB_TYPE; extern NameTree DB_NAME; extern Pool DB_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); +extern "C" size_t type_outer(size_t id, size_t key); +extern "C" size_t type_inner(size_t id); +extern "C" size_t type_key(size_t id); +extern "C" size_t type_size(size_t type_id); -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); +void* allocate(size_t type_id, size_t count); +extern "C" Variable acquire(size_t type_id); +extern "C" void release(Variable id); extern "C" bool copy(Variable src, Variable dst); +// Varying // +extern "C" Variable varying_get(Variable addr); +extern "C" void varying_set(Variable addr, Variable source); +extern "C" void varying_clear(Variable addr); + // Boolean // extern "C" void bool_set(Variable addr, Type::Boolean value); extern "C" Type::Boolean bool_get(Variable addr); -// Natural // +// Natural //p extern "C" void natural_set(Variable addr, Type::Natural value); extern "C" Type::Natural natural_get(Variable addr); @@ -35,19 +39,46 @@ extern "C" Type::Natural natural_get(Variable addr); extern "C" void integer_set(Variable addr, Type::Integer value); extern "C" Type::Integer integer_get(Variable addr); +// Block // +extern "C" uint8_t block_get(Variable addr, size_t index); +extern "C" void block_set(Variable addr, size_t index, uint8_t value); + +// String // +//extern "C" size_t string_length(Variable addr); +//extern "C" Variable string_get(Variable addr, size_t index); +//extern "C" void string_clear(Variable addr); +//extern "C" void string_prepend(Variable addr, Variable source); +//extern "C" void string_append(Variable addr, Variable source); +//extern "C" void string_insert(Variable addr, size_t index, Variable source); +//extern "C" void string_set(Variable addr, size_t index, Variable source); +//extern "C" void string_truncate(Variable addr, size_t maximum); +//extern "C" void string_remove(Variable addr, size_t index, size_t maximum); + +// Array // +extern "C" size_t array_length(Variable addr); +Variable array_cell(Variable addr, size_t index); +extern "C" Variable array_get(Variable addr, size_t index); +extern "C" void array_set(Variable addr, size_t index, Variable source); + // 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); +Variable list_cell(Variable addr, size_t index); extern "C" Variable list_at(Variable addr, size_t index); +//extern "C" Variable list_first(Variable addr); +//extern "C" Variable list_last(Variable addr); 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_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_update(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); +//extern "C" void list_resize(Variable addr, size_t length); + +// Record // + +// Schema // diff --git a/src/runtime/mod.rs b/src/runtime/mod.rs index c29a395..ea78573 100644 --- a/src/runtime/mod.rs +++ b/src/runtime/mod.rs @@ -6,15 +6,14 @@ pub struct Variable { } extern "C" { - pub fn acquire(type_id:u32) -> usize; - pub fn release(id:usize) -> bool; - pub fn address(id:usize) -> Variable; + pub fn acquire(type_id:usize) -> Variable; + pub fn release(addr: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_outer(type_id:usize, key:usize) -> usize; + pub fn type_inner(type_id:usize) -> usize; + pub fn type_key(type_id:usize) -> usize; - pub fn type_size(type_id:u32) -> usize; + pub fn type_size(type_id:usize) -> usize; pub fn bool_set(addr:Variable, data:bool); pub fn bool_get(addr:Variable) -> bool; @@ -25,33 +24,37 @@ extern "C" { pub fn integer_set(addr:Variable, data:i64); pub fn integer_get(addr:Variable) -> i64; - // fn block_set(id:u64, data:Vec); - // fn block_get(id:u64) -> Vec - // fn block_at(id:u64, index:u64) -> u8; + pub fn block_set(addr:Variable, index:usize, data:u8); + pub fn block_get(addr:Variable, index:usize) -> u8; - // fn string_set(id:u64, data:Vec); - // fn string_get(id:u64) -> Vec; - // fn string_at(id:u64, index:u64) -> u32; + //pub fn string_set(id:u64, data:Vec); + //pub fn string_get(id:u64) -> Vec; + //pub fn string_at(id:u64, index:u64) -> u32; - // fn array_at(id:u64, index:u64) -> [u64;2]; + pub fn array_length(addr:Variable) -> usize; + pub fn array_get(addr:Variable, index:usize) -> Variable; + pub fn array_set(addr:Variable, index:usize, source:Variable); 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_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_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_update(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_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; } + + diff --git a/src/runtime/type.h b/src/runtime/type.h index 5115388..d53270f 100644 --- a/src/runtime/type.h +++ b/src/runtime/type.h @@ -1,6 +1,6 @@ #include -struct Variable { +extern "C" struct Variable { size_t type; void* address; }; @@ -33,10 +33,15 @@ typedef uint64_t Natural; typedef int64_t Integer; struct List { - size_t offset; size_t capacity; size_t length; - void* data; + void* data; +}; + +struct Schema { + size_t capacity; + size_t length; + void* data; }; } diff --git a/src/runtime/typetree.h b/src/runtime/typetree.h index 73fdfe8..bf3d547 100644 --- a/src/runtime/typetree.h +++ b/src/runtime/typetree.h @@ -7,11 +7,11 @@ class TypeTree { public: struct Node { - uint32_t value; - size_t parent; + size_t key; + size_t parent; std::vector children; - Node(uint32_t value, size_t parent); + Node(size_t key, size_t parent); }; TypeTree(); @@ -19,15 +19,15 @@ public: bool has(size_t id); - size_t outer(size_t id, uint32_t type); - uint32_t value(size_t id); + size_t outer(size_t id, size_t type); + size_t key(size_t id); size_t inner(size_t id); private: std::vector m_nodes; }; -TypeTree::Node::Node(uint32_t value, size_t parent) :value(value), parent(parent) { } +TypeTree::Node::Node(size_t key, size_t parent) :key(key), parent(parent) { } TypeTree::TypeTree() { @@ -42,36 +42,35 @@ bool TypeTree::has(size_t id) return id < m_nodes.size(); } -size_t TypeTree::outer(size_t id, uint32_t value) +size_t TypeTree::outer(size_t id, size_t key) { size_t find = 0; + //for(size_t i = 0; i < m_nodes.size(); ++i) { + // printf(" - [%u] : %u -> %u [%u]\n", i, m_nodes[i].parent, m_nodes[i].key, m_nodes[i].children.size()); + //} - if(id < m_nodes.size()) - { + if(key != 0 && id < m_nodes.size()) { Node& node = m_nodes[id]; - for(size_t child : node.children) { - if(m_nodes[child].value == value) { + if(m_nodes[child].key == key) { find = child; break; } } if(find == 0) { - m_nodes.push_back(Node(value, id)); + m_nodes.push_back(Node(key, id)); find = m_nodes.size() - 1; - - node.children.push_back(find); + m_nodes[id].children.push_back(find); } } - return find; } -uint32_t TypeTree::value(size_t id) +size_t TypeTree::key(size_t id) { if(id > 0 && id < m_nodes.size()) { - return m_nodes[id].value; + return m_nodes[id].key; } return 0; } diff --git a/src/tag.rs b/src/tag.rs index 529899d..e77080a 100644 --- a/src/tag.rs +++ b/src/tag.rs @@ -1,28 +1,28 @@ -//pub type Class = u32; +//pub type Class = usize; -pub const VARYING :u32 = 0x00; -pub const NULL :u32 = 0x01; -pub const BOOLEAN :u32 = 0x02; +pub const VARYING :usize = 0x00; +pub const NULL :usize = 0x01; +pub const BOOLEAN :usize = 0x02; //... -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 NATURAL :usize = 0x10; +pub const INTEGER :usize = 0x11; +//pub const DECIMAL :usize = 0x12; +//pub const FLOAT :usize = 0x13; +//pub const COMPLEX :usize = 0x14; //... -//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 RANGE :usize = 0x1c; +//pub const CHAR :usize = 0x1d; +pub const BLOCK :usize = 0x1e; +pub const STRING :usize = 0x1f; +//pub const OPTIONAL :usize = 0x20; +//pub const SET :usize = 0x21; +pub const ARRAY :usize = 0x22; +pub const LIST :usize = 0x23; +pub const SPARSE :usize = 0x24; +//pub const MAP :usize = 0x25; +//pub const TRIE :usize = 0x26; +//pub const TREE :usize = 0x27; +//pub const GRAPH :usize = 0x28; //... -pub const RECORD :u32 = 0x7e; -pub const SCHEMA :u32 = 0x7f; +pub const RECORD :usize = 0x7e; +pub const SCHEMA :usize = 0x7f;