Implement array interface, add interface operations.

This commit is contained in:
yukirij 2023-08-06 03:31:40 -07:00
parent f0304624c9
commit afd3e23e04
18 changed files with 733 additions and 337 deletions

View File

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

View File

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

47
src/interface/array.rs Normal file
View File

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

49
src/interface/block.rs Normal file
View File

@ -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<u8>)
{
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<u8>
{
let mut result = Vec::<u8>::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)}; } }
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -4,25 +4,25 @@ TypeTree DB_TYPE;
NameTree DB_NAME;
Pool<Variable> 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<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)));
size_t length = DB_TYPE.inner(type_id);
size_t inner = DB_TYPE.inner(length);
return static_cast<size_t>(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<Variable*>(addr.address);
if(var.address != nullptr) {
drop(var);
}
var.type = 0;
var.address = nullptr;
} break;
case Type::Tag::List: {
//Type::List& list = *reinterpret_cast<Type::List*>(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<Type::List*>(source.address);
auto& dst_list = *reinterpret_cast<Type::List*>(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<Variable*>(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<Variable*>(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<Variable*>(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<Type::Boolean*>(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<Type::Boolean*>(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<Type::Natural*>(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<Type::Natural*>(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<Type::Integer*>(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<Type::Integer*>(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<uint8_t*>(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<uint8_t*>(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<void*>(reinterpret_cast<size_t>(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<Type::List*>(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<Type::List*>(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<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);
//if(type_key(addr.type) == Type::Tag::List) {
Type::List& list = *reinterpret_cast<Type::List*>(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<void*>(reinterpret_cast<size_t>(addr.address) + (offset * index));
result.type = inner;
result.address = reinterpret_cast<void*>(reinterpret_cast<size_t>(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<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);
//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<Variable*>(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<Type::List*>(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<Type::List*>(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<Type::List*>(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<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);
list_reserve(addr, list.capacity * 2);
}
// 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)
/*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));
Type::List& list = *reinterpret_cast<Type::List*>(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<Type::List*>(addr.address));
//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)
extern "C" void list_update(Variable addr, size_t index, Variable source)
{
if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
//if(type_key(addr.type) == Type::Tag::List) {
//auto& list = (*reinterpret_cast<Type::List*>(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<Type::List*>(addr.address));
//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));
//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) {
//if(type_key(addr.type) == Type::Tag::List) {
auto& list = (*reinterpret_cast<Type::List*>(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<Type::List*>(addr.address));
//auto& list = (*reinterpret_cast<Type::List*>(addr.address));
}
}
}*/

View File

@ -12,22 +12,26 @@ extern TypeTree DB_TYPE;
extern NameTree DB_NAME;
extern Pool<Variable> 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 //

View File

@ -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<u8>);
// fn block_get(id:u64) -> Vec<u8>
// 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<u8>);
// fn string_get(id:u64) -> Vec<u8>;
// fn string_at(id:u64, index:u64) -> u32;
//pub fn string_set(id:u64, data:Vec<u8>);
//pub fn string_get(id:u64) -> Vec<u8>;
//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;
}

View File

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

View File

@ -7,11 +7,11 @@
class TypeTree {
public:
struct Node {
uint32_t value;
size_t parent;
size_t key;
size_t parent;
std::vector<size_t> 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<Node> 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;
}

View File

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