Add tests, type implementation, modify constants and conventions.
This commit is contained in:
parent
afd3e23e04
commit
2d6f643373
64
.vscode/launch.json
vendored
Normal file
64
.vscode/launch.json
vendored
Normal file
@ -0,0 +1,64 @@
|
||||
{
|
||||
// Use IntelliSense to learn about possible attributes.
|
||||
// Hover to view descriptions of existing attributes.
|
||||
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in library 'szun'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--lib",
|
||||
"--package=szun"
|
||||
],
|
||||
"filter": {
|
||||
"name": "szun",
|
||||
"kind": "lib"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug executable 'main'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"build",
|
||||
"--bin=main",
|
||||
"--package=szun"
|
||||
],
|
||||
"filter": {
|
||||
"name": "main",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
},
|
||||
{
|
||||
"type": "lldb",
|
||||
"request": "launch",
|
||||
"name": "Debug unit tests in executable 'main'",
|
||||
"cargo": {
|
||||
"args": [
|
||||
"test",
|
||||
"--no-run",
|
||||
"--bin=main",
|
||||
"--package=szun"
|
||||
],
|
||||
"filter": {
|
||||
"name": "main",
|
||||
"kind": "bin"
|
||||
}
|
||||
},
|
||||
"args": [],
|
||||
"cwd": "${workspaceFolder}"
|
||||
}
|
||||
]
|
||||
}
|
33
README.md
33
README.md
@ -1,33 +1,2 @@
|
||||
# Suzu Data Notation
|
||||
# Suzu Runtime and Notation
|
||||
|
||||
## Types
|
||||
|
||||
|Tag|Type|Data|
|
||||
|---|---|
|
||||
|**Tags**| | |
|
||||
|01|Null|No data|
|
||||
|02|Boolean|True (02) or False (03)|
|
||||
|**Primitives**| | |
|
||||
|10|Natural|Integer on [0, inf)|
|
||||
|11|Integer|Integer on (-inf, inf)|
|
||||
|12|Decimal|Floating-point number|
|
||||
|13|Complex|Floating-point number with imaginary component|
|
||||
|**Compounds**| | |
|
||||
|1c|Range| |
|
||||
|1d|Char|Natural representing character code|
|
||||
|1e|Block|Fixed-length series of bytes|
|
||||
|1f|String|Variable-length series of bytes|
|
||||
|**Containers**| | |
|
||||
|20|Option| |
|
||||
|21|Set|Unordered, unique collection of elements|
|
||||
|22|Array|Fixed-length, ordered collection of elements|
|
||||
|23|List|Variable-length, ordered collection of elements|
|
||||
|24|Sparse|Discontinuous, ordered collection of elements|
|
||||
|25|Map|Mapping of elements onto elements|
|
||||
|26|Trie|Mapping of string onto elements|
|
||||
|27|Tree| |
|
||||
|28|Graph| |
|
||||
|**Objects**| | |
|
||||
|3e|Record| |
|
||||
|3f|Schema| |
|
||||
|40+|User-defined| |
|
||||
|
9
build.rs
9
build.rs
@ -1,10 +1,19 @@
|
||||
extern crate cc;
|
||||
|
||||
fn main() {
|
||||
let debug = match std::env::var("PROFILE") {
|
||||
Ok(s) => match s.as_str() {
|
||||
"debug" => true,
|
||||
_ => false,
|
||||
},
|
||||
_ => false,
|
||||
};
|
||||
|
||||
println!("cargo:rerun-if-changed=src/runtime");
|
||||
|
||||
cc::Build::new()
|
||||
.cpp(true)
|
||||
.file("src/runtime/lib.cc")
|
||||
.debug(debug)
|
||||
.compile("runtime");
|
||||
}
|
||||
|
@ -14,7 +14,8 @@
|
||||
"rust-analyzer.showUnlinkedFileNotification": false,
|
||||
"files.associations": {
|
||||
"xstring": "cpp",
|
||||
"xmemory": "cpp"
|
||||
"xmemory": "cpp",
|
||||
"vector": "cpp"
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,42 @@
|
||||
use crate::runtime::{
|
||||
Variable,
|
||||
Reference,
|
||||
type_key,
|
||||
acquire, release,
|
||||
array_length, array_get, array_set
|
||||
array_length, array_at, array_update
|
||||
};
|
||||
use super::{Type, array};
|
||||
use crate::tag;
|
||||
use super::array;
|
||||
|
||||
pub struct Array {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Array {
|
||||
pub fn new(size:usize, class:usize) -> Self
|
||||
pub fn new(length:usize, class:usize) -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(array(size, class))},
|
||||
addr:unsafe {acquire(array(length, class))},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
Self { managed:false, addr:addr }
|
||||
return if(unsafe {type_key(addr.class)} == tag::ARRAY) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(length:usize, class:usize, data:Vec<Reference>) -> Self
|
||||
{
|
||||
let mut obj = Self::new(length, class);
|
||||
for i in 0..usize::min(length, data.len()) {
|
||||
obj.update(i, data[i]);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
@ -28,18 +44,18 @@ impl Array {
|
||||
unsafe {array_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, index:usize, source:Variable)
|
||||
pub fn update(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe { array_set(self.addr, index, source); }
|
||||
unsafe { array_update(self.addr, index, source); }
|
||||
}
|
||||
|
||||
pub fn get(&self, index:usize) -> Type
|
||||
pub fn at(&self, index:usize) -> Reference
|
||||
{
|
||||
Type::from(unsafe {array_get(self.addr, index)})
|
||||
unsafe {array_at(self.addr, index)}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Array {
|
||||
type Target = Variable;
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Array {
|
||||
|
@ -1,9 +1,15 @@
|
||||
use crate::runtime::{Variable, acquire, release, type_inner, type_key, block_set, block_get};
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_inner, type_key,
|
||||
block_set, block_get
|
||||
};
|
||||
use crate::tag;
|
||||
use super::block;
|
||||
|
||||
pub struct Block {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Block {
|
||||
pub fn new(size:usize) -> Self
|
||||
@ -14,9 +20,14 @@ impl Block {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
Self { managed:false, addr:addr }
|
||||
return if(unsafe {type_key(addr.class)} == tag::BLOCK) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data:Vec<u8>)
|
||||
@ -41,7 +52,7 @@ impl Block {
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Block {
|
||||
type Target = Variable;
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Block {
|
||||
|
@ -1,11 +1,16 @@
|
||||
use crate::runtime::{Variable, acquire, release, bool_get, bool_set};
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
bool_get, bool_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::boolean;
|
||||
|
||||
pub struct Boolean {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
|
||||
impl Boolean {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
@ -15,9 +20,14 @@ impl Boolean {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
Self { managed:false, addr:addr }
|
||||
return if(unsafe {type_key(addr.class)} == tag::BOOLEAN) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:bool) -> Self
|
||||
@ -38,7 +48,7 @@ impl Boolean {
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Boolean {
|
||||
type Target = Variable;
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Boolean {
|
||||
|
@ -14,6 +14,8 @@ pub fn block(size:usize) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sequence() -> usize { unsafe { runtime::type_outer(0, tag::SEQUENCE) } }
|
||||
|
||||
pub fn array(size:usize, type_id:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(type_id, size);
|
||||
@ -22,3 +24,12 @@ pub fn array(size:usize, type_id:usize) -> usize {
|
||||
}
|
||||
|
||||
pub fn list(type_id:usize) -> usize { unsafe { runtime::type_outer(type_id, tag::LIST) } }
|
||||
|
||||
pub fn record(schema_id:usize) -> usize {
|
||||
unsafe {
|
||||
let inner_node = runtime::type_outer(0, schema_id);
|
||||
runtime::type_outer(inner_node, tag::RECORD)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn schema() -> usize { unsafe { runtime::type_outer(0, tag::SCHEMA) } }
|
@ -1,9 +1,15 @@
|
||||
use crate::runtime::{Variable, acquire, release, integer_get, integer_set};
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
integer_get, integer_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::integer;
|
||||
|
||||
pub struct Integer {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Integer {
|
||||
pub fn new() -> Self
|
||||
@ -14,9 +20,14 @@ impl Integer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
Self { managed:false, addr:addr }
|
||||
return if(unsafe {type_key(addr.class)} == tag::INTEGER) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:i64) -> Self
|
||||
@ -37,7 +48,7 @@ impl Integer {
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Integer {
|
||||
type Target = Variable;
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Integer {
|
||||
|
@ -1,6 +1,7 @@
|
||||
use crate::runtime::{
|
||||
Variable,
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
list_capacity, list_length,
|
||||
list_at,
|
||||
list_clear,
|
||||
@ -8,11 +9,12 @@ use crate::runtime::{
|
||||
list_remove,
|
||||
list_reserve,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::{varying, list};
|
||||
|
||||
pub struct List {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
impl List {
|
||||
pub fn new(class:usize) -> Self
|
||||
@ -23,12 +25,17 @@ impl List {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
Self { managed:false, addr:addr }
|
||||
return if(unsafe {type_key(addr.class)} == tag::LIST) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(data:Vec<Variable>) -> Self
|
||||
pub fn with(data:Vec<Reference>) -> Self
|
||||
{
|
||||
let mut obj = Self::new(varying());
|
||||
for item in data {
|
||||
@ -47,7 +54,7 @@ impl List {
|
||||
unsafe {list_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn at(&self, index:usize) -> Variable
|
||||
pub fn at(&self, index:usize) -> Reference
|
||||
{
|
||||
unsafe {list_at(self.addr, index)}
|
||||
}
|
||||
@ -57,19 +64,19 @@ impl List {
|
||||
unsafe{list_clear(self.addr)};
|
||||
}
|
||||
|
||||
pub fn insert(&mut self, index:usize, source:Variable)
|
||||
pub fn insert(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe{list_insert(self.addr, index, source)};
|
||||
}
|
||||
|
||||
pub fn update(&mut self, index:usize, source:Variable)
|
||||
pub fn update(&mut self, index:usize, source:Reference)
|
||||
{
|
||||
unsafe{list_update(self.addr, index, source)};
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index:usize, maximum:usize)
|
||||
pub fn remove(&mut self, index:usize, count:usize)
|
||||
{
|
||||
unsafe{list_remove(self.addr, index, maximum)};
|
||||
unsafe{list_remove(self.addr, index, count)};
|
||||
}
|
||||
|
||||
pub fn reserve(&mut self, length:usize)
|
||||
@ -78,7 +85,7 @@ impl List {
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for List {
|
||||
type Target = Variable;
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for List {
|
||||
|
@ -1,17 +1,20 @@
|
||||
use crate::runtime::{Variable, type_key};
|
||||
use crate::runtime::{Reference, type_key};
|
||||
use crate::tag;
|
||||
|
||||
mod builder; pub use builder::*;
|
||||
|
||||
mod varying; pub use varying::Varying;
|
||||
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 sequence; pub use sequence::Sequence;
|
||||
mod array; pub use array::Array;
|
||||
mod list; pub use list::List;
|
||||
mod schema; pub use schema::Schema;
|
||||
|
||||
pub enum Type {
|
||||
Varying,
|
||||
Varying(Varying),
|
||||
Null,
|
||||
Boolean(Boolean),
|
||||
Natural(Natural),
|
||||
@ -21,16 +24,16 @@ pub enum Type {
|
||||
List(List),
|
||||
}
|
||||
impl Type {
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Self
|
||||
{
|
||||
match unsafe {type_key(addr.class)} {
|
||||
tag::VARYING => Type::Varying,
|
||||
tag::VARYING => Type::Varying(Varying::from(addr).unwrap()),
|
||||
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)),
|
||||
tag::BOOLEAN => Type::Boolean(Boolean::from(addr).unwrap()),
|
||||
tag::NATURAL => Type::Natural(Natural::from(addr).unwrap()),
|
||||
tag::INTEGER => Type::Integer(Integer::from(addr).unwrap()),
|
||||
tag::ARRAY => Type::Array(Array::from(addr).unwrap()),
|
||||
tag::LIST => Type::List(List::from(addr).unwrap()),
|
||||
_ => Type::Null,
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
use crate::runtime::{Variable, acquire, release, natural_get, natural_set};
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
natural_get, natural_set
|
||||
};
|
||||
use crate::tag;
|
||||
use super::natural;
|
||||
|
||||
pub struct Natural {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Natural {
|
||||
pub fn new() -> Self
|
||||
@ -14,9 +20,14 @@ impl Natural {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Variable) -> Self
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
Self { managed:false, addr:addr }
|
||||
return if(unsafe {type_key(addr.class)} == tag::NATURAL) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(value:u64) -> Self
|
||||
@ -37,7 +48,7 @@ impl Natural {
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Natural {
|
||||
type Target = Variable;
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Natural {
|
||||
|
44
src/interface/record.rs
Normal file
44
src/interface/record.rs
Normal file
@ -0,0 +1,44 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::record;
|
||||
|
||||
pub struct Record {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Record {
|
||||
pub fn new(schema:usize) -> Result<Self,()>
|
||||
{
|
||||
//if get_schema(schema) {
|
||||
Ok(Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(record())},
|
||||
})
|
||||
//} else {
|
||||
// Err(())
|
||||
//}
|
||||
}
|
||||
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
return if(unsafe {type_key(addr.class)} == tag::Record) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
//pub fn set(key, Reference)
|
||||
//pub fn get(key) -> Reference
|
||||
}
|
||||
impl std::ops::Deref for Record {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Record {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
135
src/interface/schema.rs
Normal file
135
src/interface/schema.rs
Normal file
@ -0,0 +1,135 @@
|
||||
use crate::runtime::{
|
||||
//util::{name_indexof, name_keyof},
|
||||
util::name_indexof,
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
schema_length,
|
||||
schema_add,
|
||||
schema_remove,
|
||||
schema_reorder,
|
||||
schema_map, schema_unmap, schema_index,
|
||||
schema_bind,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::schema;
|
||||
|
||||
//pub struct Builder {
|
||||
// data:Schema,
|
||||
//}
|
||||
//impl Builder {
|
||||
// pub fn add() { }
|
||||
// pub fn map() { }
|
||||
// pub fn bind() { }
|
||||
//}
|
||||
|
||||
pub struct Schema {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Schema {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(schema())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
return if(unsafe {type_key(addr.class)} == tag::SCHEMA) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(data:Vec<(&str, usize)>) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
for binding in data {
|
||||
let (key, type_id) = binding;
|
||||
obj.assign(key, type_id);
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
//pub fn build() -> Builder
|
||||
//{
|
||||
// Builder { }
|
||||
//}
|
||||
|
||||
pub fn length(&self) -> usize
|
||||
{
|
||||
unsafe {schema_length(self.addr)}
|
||||
}
|
||||
|
||||
pub fn add(&mut self, type_id:usize) -> usize
|
||||
{
|
||||
unsafe {schema_add(self.addr, type_id)}
|
||||
}
|
||||
|
||||
pub fn assign(&mut self, key:&str, type_id:usize)
|
||||
{
|
||||
if key.len() > 0 {
|
||||
let key_index = name_indexof(key);
|
||||
unsafe {
|
||||
schema_map(
|
||||
self.addr,
|
||||
key_index,
|
||||
schema_add(self.addr, type_id)
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
self.add(type_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn remove(&mut self, index:usize)
|
||||
{
|
||||
unsafe { schema_remove(self.addr, index); }
|
||||
}
|
||||
|
||||
pub fn reorder(&mut self, from:usize, to:usize)
|
||||
{
|
||||
unsafe { schema_reorder(self.addr, from, to); }
|
||||
}
|
||||
|
||||
pub fn map(&mut self, key:&str, index:usize)
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
unsafe { schema_map(self.addr, key_index, index); }
|
||||
}
|
||||
|
||||
pub fn unmap(&mut self, key:&str)
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
unsafe { schema_unmap(self.addr, key_index); }
|
||||
}
|
||||
|
||||
pub fn index(&mut self, key:&str) -> usize
|
||||
{
|
||||
let key_index = name_indexof(key);
|
||||
unsafe {schema_index(self.addr, key_index)}
|
||||
}
|
||||
|
||||
//pub fn key(&mut self, index:usize) -> String
|
||||
//{
|
||||
// name_keyof(unsafe {schema_key(self.addr, index)})
|
||||
//}
|
||||
|
||||
pub fn bind(&mut self, id:usize) -> usize
|
||||
{
|
||||
unsafe {schema_bind(self.addr, id)}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Schema {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Schema {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
79
src/interface/sequence.rs
Normal file
79
src/interface/sequence.rs
Normal file
@ -0,0 +1,79 @@
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
sequence_length,
|
||||
sequence_clear, sequence_reserve,
|
||||
sequence_get,
|
||||
sequence_insert,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::sequence;
|
||||
|
||||
pub struct Sequence {
|
||||
managed:bool,
|
||||
addr:Reference,
|
||||
}
|
||||
impl Sequence {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
Self {
|
||||
managed:true,
|
||||
addr:unsafe {acquire(sequence())},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
return if(unsafe {type_key(addr.class)} == tag::SEQUENCE) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with(data:&str) -> Self
|
||||
{
|
||||
let mut obj = Self::new();
|
||||
obj.set(data);
|
||||
return obj;
|
||||
}
|
||||
|
||||
pub fn set(&mut self, data:&str)
|
||||
{
|
||||
unsafe { sequence_clear(self.addr); }
|
||||
let bytes = Vec::from(data.as_bytes());
|
||||
if bytes.len() > 0 {
|
||||
unsafe { sequence_reserve(self.addr, bytes.len()); }
|
||||
for i in 0..bytes.len() {
|
||||
unsafe { sequence_insert(self.addr, i, bytes[i]); }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get(&self) -> String
|
||||
{
|
||||
let length = unsafe {sequence_length(self.addr)};
|
||||
if length > 0 {
|
||||
let mut bytes = Vec::<u8>::with_capacity(length);
|
||||
for i in 0..length {
|
||||
bytes.push(unsafe {sequence_get(self.addr, i)});
|
||||
}
|
||||
return match String::from_utf8(bytes) {
|
||||
Ok(data) => data,
|
||||
Err(_) => String::new(),
|
||||
}
|
||||
}
|
||||
else {
|
||||
return String::new();
|
||||
}
|
||||
}
|
||||
}
|
||||
impl std::ops::Deref for Sequence {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Sequence {
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
@ -1,11 +1,15 @@
|
||||
use crate::runtime::{Variable, acquire, release, bool_get, bool_set};
|
||||
use crate::runtime::{
|
||||
Reference,
|
||||
acquire, release,
|
||||
type_key,
|
||||
};
|
||||
use crate::tag;
|
||||
use super::varying;
|
||||
|
||||
pub struct Boolean {
|
||||
pub struct Varying {
|
||||
managed:bool,
|
||||
addr:Variable,
|
||||
addr:Reference,
|
||||
}
|
||||
|
||||
impl Varying {
|
||||
pub fn new() -> Self
|
||||
{
|
||||
@ -15,21 +19,30 @@ impl Varying {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, value:bool)
|
||||
pub fn from(addr:Reference) -> Result<Self,()>
|
||||
{
|
||||
return if(unsafe {type_key(addr.class)} == tag::VARYING) {
|
||||
Ok(Self { managed:false, addr:addr })
|
||||
}
|
||||
else {
|
||||
Err(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, _addr:Reference)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
pub fn get(&self) -> Variable
|
||||
pub fn get(&self) -> Reference
|
||||
{
|
||||
false
|
||||
self.addr
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Varying {
|
||||
type Target = Reference;
|
||||
fn deref(&self) -> &Self::Target { return &self.addr; }
|
||||
}
|
||||
impl Drop for Varying {
|
||||
fn drop(&mut self) {
|
||||
if self.managed {
|
||||
unsafe {release(self.addr)};
|
||||
}
|
||||
}
|
||||
fn drop(&mut self) { if self.managed { unsafe {release(self.addr)}; } }
|
||||
}
|
||||
|
8
src/language/mod.rs
Normal file
8
src/language/mod.rs
Normal file
@ -0,0 +1,8 @@
|
||||
struct Parser {
|
||||
|
||||
}
|
||||
|
||||
pub fn compile() -> Result<(),()>
|
||||
{
|
||||
Err(())
|
||||
}
|
107
src/lib.rs
107
src/lib.rs
@ -5,7 +5,112 @@ mod util;
|
||||
mod runtime;
|
||||
mod interface; pub use interface::*;
|
||||
|
||||
fn assert<T>(expected:T, actual:T) where T:std::fmt::Display, T:std::cmp::PartialEq
|
||||
{
|
||||
print!(" ({}) ", if expected == actual { " " } else { "!" });
|
||||
println!("'{}' = '{}'", expected, actual);
|
||||
}
|
||||
|
||||
pub fn test()
|
||||
{
|
||||
|
||||
{
|
||||
println!("Boolean");
|
||||
let mut dat = Boolean::new();
|
||||
assert::<bool>(false, dat.get());
|
||||
dat.set(true);
|
||||
assert::<bool>(true, dat.get());
|
||||
dat.set(false);
|
||||
assert::<bool>(false, dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Natural");
|
||||
let mut dat = Natural::new();
|
||||
assert::<u64>(0, dat.get());
|
||||
dat.set(50);
|
||||
assert::<u64>(50, dat.get());
|
||||
dat.set(25000);
|
||||
assert::<u64>(25000, dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Integer");
|
||||
let mut dat = Integer::new();
|
||||
assert::<i64>(0, dat.get());
|
||||
dat.set(-12);
|
||||
assert::<i64>(-12, dat.get());
|
||||
dat.set(38695);
|
||||
assert::<i64>(38695, dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Block");
|
||||
let mut dat = Block::new(4);
|
||||
dat.set(vec![1, 2, 3, 4]);
|
||||
assert::<usize>(4, dat.get().len());
|
||||
assert::<u8>(1, dat.get()[0]);
|
||||
assert::<u8>(2, dat.get()[1]);
|
||||
assert::<u8>(3, dat.get()[2]);
|
||||
assert::<u8>(4, dat.get()[3]);
|
||||
}
|
||||
|
||||
{
|
||||
println!("Sequence");
|
||||
let mut dat = Sequence::new();
|
||||
assert::<String>(String::from(""), dat.get());
|
||||
dat.set("hello");
|
||||
assert::<String>(String::from("hello"), dat.get());
|
||||
}
|
||||
|
||||
{
|
||||
println!("Array<Natural>");
|
||||
let dat = Array::new(4, natural());
|
||||
Natural::from(dat.at(0)).unwrap().set(250);
|
||||
Natural::from(dat.at(1)).unwrap().set(500);
|
||||
Natural::from(dat.at(2)).unwrap().set(750);
|
||||
Natural::from(dat.at(3)).unwrap().set(1000);
|
||||
assert::<usize>(4, dat.length());
|
||||
assert::<u64>(250, Natural::from(dat.at(0)).unwrap().get());
|
||||
assert::<u64>(500, Natural::from(dat.at(1)).unwrap().get());
|
||||
assert::<u64>(750, Natural::from(dat.at(2)).unwrap().get());
|
||||
assert::<u64>(1000,Natural::from(dat.at(3)).unwrap().get());
|
||||
}
|
||||
|
||||
/* {
|
||||
println!("List - Undefined");
|
||||
|
||||
println!("List - Variable");
|
||||
let mut dat = List::new(varying());
|
||||
dat.insert(usize::MAX, *Integer::with(15));
|
||||
match Type::from(dat.at(0)) {
|
||||
Type::Integer(value) => {
|
||||
println!(" = {}", value.get());
|
||||
}
|
||||
_ => { println!(" - Not Integer"); }
|
||||
}
|
||||
|
||||
println!("List<Sequence>");
|
||||
let mut dat = List::new(sequence());
|
||||
dat.insert(usize::MAX, *Sequence::with("hello"));
|
||||
dat.insert(usize::MAX, *Sequence::with("world"));
|
||||
dat.insert(usize::MAX, *Sequence::with("konnichiwa"));
|
||||
dat.insert(usize::MAX, *Sequence::with("konbanwa"));
|
||||
dat.insert(usize::MAX, *Sequence::with("tasogare"));
|
||||
println!(" = {}", Integer::from(dat.at(0)).unwrap().get());
|
||||
} */
|
||||
|
||||
/*{
|
||||
println!("Sparse");
|
||||
|
||||
}*/
|
||||
|
||||
/*{
|
||||
println!("Schema");
|
||||
|
||||
}*/
|
||||
|
||||
/*{
|
||||
println!("Record");
|
||||
|
||||
}*/
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
#include "lib.h"
|
||||
#include "rawlist.cc"
|
||||
|
||||
TypeTree DB_TYPE;
|
||||
NameTree DB_NAME;
|
||||
Pool<Variable> DB_DATA;
|
||||
//Pool<Type::Schema> DB_SCHEMA;
|
||||
Pool<Reference> DB_DATA;
|
||||
|
||||
extern "C" size_t type_outer(size_t type_id, size_t key)
|
||||
{
|
||||
@ -25,25 +27,64 @@ extern "C" size_t type_size(size_t type_id)
|
||||
size_t type = DB_TYPE.key(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.key(DB_TYPE.inner(type_id));
|
||||
case Type::Tag::String: return sizeof(Type::List);
|
||||
case Type::Tag::Null: return 0;
|
||||
case Type::Tag::Varying: return sizeof(Reference);
|
||||
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.key(DB_TYPE.inner(type_id));
|
||||
case Type::Tag::Sequence: return sizeof(Type::Sequence);
|
||||
case Type::Tag::Array: {
|
||||
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);
|
||||
case Type::Tag::List: return sizeof(Type::List);
|
||||
case Type::Tag::Record: {
|
||||
//if(DB_SCHEMA.has(type_key(type_inner(type_id)))) {
|
||||
// return DB_SCHEMA.get().size;
|
||||
//}
|
||||
return 0;
|
||||
}
|
||||
case Type::Tag::Schema: return sizeof(Type::Schema);
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length)
|
||||
{
|
||||
std::string str(reinterpret_cast<const char*>(bytes), length);
|
||||
return DB_NAME.indexof(str);
|
||||
}
|
||||
|
||||
extern "C" Str name_keyof(size_t index)
|
||||
{
|
||||
Str result {0};
|
||||
std::string str = DB_NAME.keyof(index);
|
||||
if(str.length() > 0) {
|
||||
result.bytes = new uint8_t[str.length()];
|
||||
}
|
||||
for(size_t i = 0; i < str.length(); ++i) {
|
||||
result.bytes[i] = str[i];
|
||||
}
|
||||
result.length = str.length();
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string name_keyof_internal(size_t index)
|
||||
{
|
||||
return DB_NAME.keyof(index);
|
||||
}
|
||||
|
||||
extern "C" void name_release(Str data)
|
||||
{
|
||||
if(data.bytes != nullptr) {
|
||||
delete[] data.bytes;
|
||||
}
|
||||
}
|
||||
|
||||
void* allocate(size_t type_id, size_t count)
|
||||
{
|
||||
void* mem = nullptr;
|
||||
@ -58,9 +99,9 @@ void* allocate(size_t type_id, size_t count)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
extern "C" Variable acquire(size_t type_id)
|
||||
extern "C" Reference acquire(size_t type_id)
|
||||
{
|
||||
Variable addr {0};
|
||||
Reference addr {0};
|
||||
addr.address = allocate(type_id, 1);
|
||||
if(addr.address != nullptr) {
|
||||
addr.type = type_id;
|
||||
@ -68,10 +109,10 @@ extern "C" Variable acquire(size_t type_id)
|
||||
return addr;
|
||||
}
|
||||
|
||||
void drop(Variable addr)
|
||||
void drop(Reference addr)
|
||||
{
|
||||
if(addr.address != nullptr) {
|
||||
switch(addr.type) {
|
||||
switch(type_key(addr.type)) {
|
||||
case Type::Tag::Boolean:
|
||||
case Type::Tag::Natural:
|
||||
case Type::Tag::Integer:
|
||||
@ -79,7 +120,7 @@ void drop(Variable addr)
|
||||
break;
|
||||
|
||||
case Type::Tag::Varying: {
|
||||
Variable& var = *reinterpret_cast<Variable*>(addr.address);
|
||||
auto& var = *reinterpret_cast<Reference*>(addr.address);
|
||||
if(var.address != nullptr) {
|
||||
drop(var);
|
||||
}
|
||||
@ -87,21 +128,24 @@ void drop(Variable addr)
|
||||
var.address = nullptr;
|
||||
} break;
|
||||
|
||||
case Type::Tag::Sequence: {
|
||||
auto& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
rawlist_clear(seq.data);
|
||||
} 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);
|
||||
//}
|
||||
Type::List& list = *reinterpret_cast<Type::List*>(addr.address);
|
||||
for(size_t i = 0; i < list.data.length; ++i) {
|
||||
drop(list_cell(addr, i));
|
||||
}
|
||||
rawlist_clear(list.data);
|
||||
} break;
|
||||
}
|
||||
memset(addr.address, 0, type_size(addr.type));
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void release(Variable addr)
|
||||
extern "C" void release(Reference addr)
|
||||
{
|
||||
if(addr.address != nullptr) {
|
||||
drop(addr);
|
||||
@ -109,19 +153,19 @@ extern "C" void release(Variable addr)
|
||||
}
|
||||
}
|
||||
|
||||
bool copy(Variable src, Variable dst)
|
||||
bool copy(Reference src, Reference dst)
|
||||
{
|
||||
Variable source = src;
|
||||
Variable destination = dst;
|
||||
Reference source = src;
|
||||
Reference destination = dst;
|
||||
|
||||
// dereference varying data
|
||||
if(type_key(src.type) == Type::Tag::Varying) {
|
||||
source = *reinterpret_cast<Variable*>(src.address);
|
||||
source = *reinterpret_cast<Reference*>(src.address);
|
||||
}
|
||||
|
||||
// prepare destination for varying data
|
||||
if(type_key(dst.type) == Type::Tag::Varying) {
|
||||
auto& dest_ref = *reinterpret_cast<Variable*>(dst.address);
|
||||
auto& dest_ref = *reinterpret_cast<Reference*>(dst.address);
|
||||
|
||||
// determine if memory can be reused, otherwise free and reallocate
|
||||
if(source.type != dest_ref.type) {
|
||||
@ -147,268 +191,270 @@ 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);
|
||||
|
||||
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) {
|
||||
rawlist_reserve(dst_list.data, type_size(type_inner(source.type)), src_list.data.capacity);
|
||||
dst_list.data.length = src_list.data.length;
|
||||
//dst_list.data = allocate(type_inner(source.type), src_list.capacity);
|
||||
|
||||
for(size_t i = 0; i < src_list.data.length; ++i) {
|
||||
copy(list_at(source, i), list_at(destination, i));
|
||||
}
|
||||
} break;*/
|
||||
} break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Varying //
|
||||
|
||||
extern "C" Variable varying_get(Variable addr)
|
||||
extern "C" Reference varying_get(Reference addr)
|
||||
{
|
||||
Variable result {0};
|
||||
//if(type_key(addr.type) == Type::Tag::Varying) {
|
||||
result = *reinterpret_cast<Variable*>(addr.address);
|
||||
//}
|
||||
Reference result {0};
|
||||
result = *reinterpret_cast<Reference*>(addr.address);
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" void varying_set(Variable addr, Variable source)
|
||||
extern "C" void varying_set(Reference addr, Reference source)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Varying) {
|
||||
Variable& var = *reinterpret_cast<Variable*>(addr.address);
|
||||
|
||||
if(var.address != nullptr) {
|
||||
drop(var);
|
||||
}
|
||||
Reference& var = *reinterpret_cast<Reference*>(addr.address);
|
||||
|
||||
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);
|
||||
}
|
||||
if(var.address != nullptr) {
|
||||
drop(var);
|
||||
}
|
||||
|
||||
copy(source, 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)
|
||||
extern "C" void varying_clear(Reference 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;
|
||||
}
|
||||
//}
|
||||
Reference& var = *reinterpret_cast<Reference*>(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)
|
||||
extern "C" void bool_set(Reference addr, Type::Boolean value)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Boolean) {
|
||||
*(reinterpret_cast<Type::Boolean*>(addr.address)) = value;
|
||||
//}
|
||||
*(reinterpret_cast<Type::Boolean*>(addr.address)) = value;
|
||||
}
|
||||
|
||||
extern "C" Type::Boolean bool_get(Variable addr)
|
||||
extern "C" Type::Boolean bool_get(Reference addr)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Boolean) {
|
||||
return *(reinterpret_cast<Type::Boolean*>(addr.address));
|
||||
//}
|
||||
//return false;
|
||||
return *(reinterpret_cast<Type::Boolean*>(addr.address));
|
||||
}
|
||||
|
||||
|
||||
// Natural //
|
||||
|
||||
extern "C" void natural_set(Variable addr, Type::Natural value)
|
||||
extern "C" void natural_set(Reference addr, Type::Natural value)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Natural) {
|
||||
*(reinterpret_cast<Type::Natural*>(addr.address)) = value;
|
||||
//}
|
||||
*(reinterpret_cast<Type::Natural*>(addr.address)) = value;
|
||||
}
|
||||
|
||||
extern "C" Type::Natural natural_get(Variable addr)
|
||||
extern "C" Type::Natural natural_get(Reference addr)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Natural) {
|
||||
return *(reinterpret_cast<Type::Natural*>(addr.address));
|
||||
//}
|
||||
//return false;
|
||||
return *(reinterpret_cast<Type::Natural*>(addr.address));
|
||||
}
|
||||
|
||||
|
||||
// Integer //
|
||||
|
||||
extern "C" void integer_set(Variable addr, Type::Integer value)
|
||||
extern "C" void integer_set(Reference addr, Type::Integer value)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Integer) {
|
||||
*(reinterpret_cast<Type::Integer*>(addr.address)) = value;
|
||||
//}
|
||||
*(reinterpret_cast<Type::Integer*>(addr.address)) = value;
|
||||
}
|
||||
|
||||
extern "C" Type::Integer integer_get(Variable addr)
|
||||
extern "C" Type::Integer integer_get(Reference addr)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Integer) {
|
||||
return *(reinterpret_cast<Type::Integer*>(addr.address));
|
||||
//}
|
||||
//return false;
|
||||
return *(reinterpret_cast<Type::Integer*>(addr.address));
|
||||
}
|
||||
|
||||
|
||||
// Block //
|
||||
|
||||
extern "C" uint8_t block_get(Variable addr, size_t index)
|
||||
extern "C" uint8_t block_get(Reference 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];
|
||||
}
|
||||
//}
|
||||
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)
|
||||
extern "C" void block_set(Reference 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;
|
||||
}
|
||||
//}
|
||||
size_t length = type_key(type_inner(addr.type));
|
||||
if(index < length) {
|
||||
reinterpret_cast<uint8_t*>(addr.address)[index] = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// String //
|
||||
// Sequence //
|
||||
|
||||
extern "C" size_t sequence_length(Reference addr)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
return seq.data.length;
|
||||
}
|
||||
|
||||
extern "C" uint8_t sequence_get(Reference addr, size_t index)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
if(index < seq.data.length) {
|
||||
return *reinterpret_cast<uint8_t*>(rawlist_cell(seq.data, 1, index));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern "C" void sequence_clear(Reference addr)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
rawlist_clear(seq.data);
|
||||
}
|
||||
|
||||
extern "C" void sequence_set(Reference addr, size_t index, uint8_t value)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
auto cell = reinterpret_cast<uint8_t*>(rawlist_cell(seq.data, 1, index));
|
||||
if(cell != nullptr) {
|
||||
*cell = value;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void sequence_insert(Reference addr, size_t index, uint8_t value)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
auto cell = reinterpret_cast<uint8_t*>(rawlist_insert(seq.data, 1, index));
|
||||
if(cell != nullptr) {
|
||||
*cell = value;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void sequence_reserve(Reference addr, size_t capacity)
|
||||
{
|
||||
Type::Sequence& seq = *reinterpret_cast<Type::Sequence*>(addr.address);
|
||||
rawlist_reserve(seq.data, 1, capacity);
|
||||
}
|
||||
|
||||
|
||||
// Array //
|
||||
|
||||
extern "C" size_t array_length(Variable addr)
|
||||
extern "C" size_t array_length(Reference addr)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::Array) {
|
||||
return type_key(type_inner(addr.type));
|
||||
//}
|
||||
//return 0;
|
||||
return type_key(type_inner(addr.type));
|
||||
}
|
||||
|
||||
Variable array_cell(Variable addr, size_t index)
|
||||
Reference array_cell(Reference 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);
|
||||
Reference result {0};
|
||||
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));
|
||||
}
|
||||
//}
|
||||
// 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)
|
||||
extern "C" Reference array_at(Reference 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);
|
||||
Reference result {0};
|
||||
Reference cell = array_cell(addr, index);
|
||||
if(cell.address != nullptr) {
|
||||
if(type_key(cell.type) == Type::Tag::Varying) {
|
||||
result = varying_get(cell);
|
||||
}
|
||||
else {
|
||||
copy(source, cell);
|
||||
result = cell;
|
||||
}
|
||||
//}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" void array_update(Reference addr, size_t index, Reference source)
|
||||
{
|
||||
Reference cell = array_cell(addr, index);
|
||||
if(type_key(cell.type) == Type::Tag::Varying) {
|
||||
varying_set(cell, source);
|
||||
}
|
||||
else {
|
||||
copy(source, cell);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// List //
|
||||
|
||||
extern "C" size_t list_capacity(Variable addr)
|
||||
extern "C" size_t list_capacity(Reference addr)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::List) {
|
||||
return (*reinterpret_cast<Type::List*>(addr.address)).capacity;
|
||||
//}
|
||||
//return 0;
|
||||
return (*reinterpret_cast<Type::List*>(addr.address)).data.capacity;
|
||||
}
|
||||
|
||||
extern "C" size_t list_length(Variable addr)
|
||||
extern "C" size_t list_length(Reference addr)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::List) {
|
||||
return (*reinterpret_cast<Type::List*>(addr.address)).length;
|
||||
//}
|
||||
//return 0;
|
||||
return (*reinterpret_cast<Type::List*>(addr.address)).data.length;
|
||||
}
|
||||
|
||||
Variable list_cell(Variable addr, size_t index)
|
||||
Reference list_cell(Reference addr, size_t index)
|
||||
{
|
||||
Variable result {0};
|
||||
//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);
|
||||
Reference result {0};
|
||||
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
|
||||
if(list.data.data != nullptr && offset > 0 && index < list.data.capacity) {
|
||||
result.type = inner;
|
||||
result.address = rawlist_cell(list.data, offset, index);
|
||||
}
|
||||
|
||||
// validate for overflow
|
||||
if(list.data != nullptr && offset > 0 && index < list.length) {
|
||||
result.type = inner;
|
||||
result.address = reinterpret_cast<void*>(reinterpret_cast<size_t>(list.data) + (offset * index));
|
||||
}
|
||||
//}
|
||||
return result;
|
||||
}
|
||||
|
||||
extern "C" Variable list_at(Variable addr, size_t index)
|
||||
extern "C" Reference list_at(Reference addr, size_t index)
|
||||
{
|
||||
Variable result {0};
|
||||
//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 = cell;
|
||||
}
|
||||
Reference result {0};
|
||||
Reference cell = list_cell(addr, index);
|
||||
|
||||
if(cell.address != nullptr) {
|
||||
if(type_key(cell.type) == Type::Tag::Varying) {
|
||||
result = *reinterpret_cast<Reference*>(cell.address);
|
||||
} else {
|
||||
result = cell;
|
||||
}
|
||||
//}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*extern "C" Variable list_first(Variable addr)
|
||||
/*extern "C" Reference list_first(Reference addr)
|
||||
{
|
||||
Variable result {0};
|
||||
Reference result {0};
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
if(list.length > 0) {
|
||||
@ -418,9 +464,9 @@ extern "C" Variable list_at(Variable addr, size_t index)
|
||||
return result;
|
||||
}*/
|
||||
|
||||
/*extern "C" Variable list_last(Variable addr)
|
||||
/*extern "C" Reference list_last(Reference addr)
|
||||
{
|
||||
Variable result {0};
|
||||
Reference result {0};
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
if(list.length > 0) {
|
||||
@ -430,20 +476,12 @@ extern "C" Variable list_at(Variable addr, size_t index)
|
||||
return result;
|
||||
}*/
|
||||
|
||||
extern "C" void list_clear(Variable addr)
|
||||
extern "C" void list_clear(Reference 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);
|
||||
//}
|
||||
drop(addr);
|
||||
}
|
||||
|
||||
/*extern "C" void list_prepend(Variable addr, Variable source)
|
||||
/*extern "C" void list_prepend(Reference addr, Reference source)
|
||||
{
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
size_t inner = type_inner(addr.type);
|
||||
@ -464,7 +502,7 @@ extern "C" void list_clear(Variable addr)
|
||||
}
|
||||
}*/
|
||||
|
||||
/*extern "C" void list_append(Variable addr, Variable source)
|
||||
/*extern "C" void list_append(Reference addr, Reference source)
|
||||
{
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
Type::List& list = *reinterpret_cast<Type::List*>(addr.address);
|
||||
@ -484,64 +522,192 @@ extern "C" void list_clear(Variable addr)
|
||||
}
|
||||
}*/
|
||||
|
||||
extern "C" void list_insert(Variable addr, size_t index, Variable source)
|
||||
extern "C" void list_insert(Reference addr, size_t index, Reference source)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::List) {
|
||||
//auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
|
||||
//}
|
||||
}
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
size_t inner = type_inner(addr.type);
|
||||
size_t offset = type_size(inner);
|
||||
|
||||
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(index > list.data.length) { index = list.data.length; }
|
||||
|
||||
/*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));
|
||||
|
||||
void* cell = rawlist_insert(list.data, offset, index);
|
||||
|
||||
if(type_key(inner) == Type::Tag::Varying) {
|
||||
varying_set(list_cell(addr, index), source);
|
||||
}
|
||||
}*/
|
||||
|
||||
/*extern "C" void list_shift(Variable addr)
|
||||
{
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
//auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
|
||||
else {
|
||||
copy(source, list_cell(addr, index));
|
||||
}
|
||||
}*/
|
||||
|
||||
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)
|
||||
extern "C" void list_update(Reference addr, size_t index, Reference source)
|
||||
{
|
||||
//if(type_key(addr.type) == Type::Tag::List) {
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
if(index < list.data.length) {
|
||||
size_t inner = type_inner(addr.type);
|
||||
size_t offset = type_size(inner);
|
||||
|
||||
if(list.capacity < capacity) {
|
||||
void* new_data = allocate(inner, capacity);
|
||||
memcpy(new_data, list.data, offset * list.capacity);
|
||||
if(type_key(inner) == Type::Tag::Varying) {
|
||||
varying_set(list_cell(addr, index), source);
|
||||
}
|
||||
//}
|
||||
else {
|
||||
copy(source, list_cell(addr, index));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*extern "C" void list_resize(Variable addr, size_t length)
|
||||
/*extern "C" void list_truncate(Reference 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(Reference addr)
|
||||
{
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
//auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
extern "C" void list_remove(Reference addr, size_t index)
|
||||
{
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
size_t inner = type_inner(addr.type);
|
||||
size_t offset = type_size(inner);
|
||||
|
||||
|
||||
drop(list_at(addr, index));
|
||||
rawlist_remove(list.data, offset, index);
|
||||
}
|
||||
|
||||
extern "C" void list_reserve(Reference addr, size_t capacity)
|
||||
{
|
||||
auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
size_t inner = type_inner(addr.type);
|
||||
size_t offset = type_size(inner);
|
||||
|
||||
rawlist_reserve(list.data, offset, capacity);
|
||||
}
|
||||
|
||||
/*extern "C" void list_resize(Reference addr, size_t length)
|
||||
{
|
||||
if(type_key(addr.type) == Type::Tag::List) {
|
||||
//auto& list = (*reinterpret_cast<Type::List*>(addr.address));
|
||||
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
// Schema //
|
||||
|
||||
extern "C" size_t schema_length(Reference addr)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
return object.data.length;
|
||||
}
|
||||
|
||||
extern "C" size_t schema_add(Reference addr, size_t type_id)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
void* cell = rawlist_insert(object.data, sizeof(size_t), object.data.length);
|
||||
*reinterpret_cast<size_t*>(cell) = type_id;
|
||||
return object.data.length - 1;
|
||||
}
|
||||
|
||||
extern "C" void schema_remove(Reference addr, size_t index)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
if(index < object.data.length) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
if(index_from < object.data.length && index_to <= object.data.length) {
|
||||
if(index_from > index_to) {
|
||||
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void schema_map(Reference addr, size_t key, size_t index)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
if(index < object.data.length) {
|
||||
size_t find_index = 0;
|
||||
for(; find_index < object.map.length; find_index++) {
|
||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), find_index));
|
||||
if(cell != nullptr) {
|
||||
if(cell->key == key) { break; }
|
||||
}
|
||||
}
|
||||
|
||||
// if key is not found, add new mapping
|
||||
if(find_index == object.map.length) {
|
||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_insert(object.map, sizeof(Type::Schema::Mapping), object.map.length));
|
||||
cell->key = key;
|
||||
cell->index = index;
|
||||
}
|
||||
// otherwise, update existing key
|
||||
else {
|
||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), find_index));
|
||||
cell->index = index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void schema_unmap(Reference addr, size_t key)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
for(size_t i; i < object.map.length; i++) {
|
||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
|
||||
if(cell != nullptr) {
|
||||
if(cell->key == key) {
|
||||
rawlist_remove(object.map, sizeof(Type::Schema::Mapping), i);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" size_t schema_index(Reference addr, size_t key)
|
||||
{
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
for(size_t i; i < object.map.length; i++) {
|
||||
auto cell = reinterpret_cast<Type::Schema::Mapping*>(rawlist_cell(object.map, sizeof(Type::Schema::Mapping), i));
|
||||
if(cell != nullptr) {
|
||||
if(cell->key == key) {
|
||||
return cell->index;
|
||||
}
|
||||
}
|
||||
}
|
||||
return object.data.length;
|
||||
}
|
||||
|
||||
extern "C" size_t schema_bind(Reference addr, size_t id)
|
||||
{
|
||||
Type::SchemaBinding binding {0};
|
||||
auto& object = (*reinterpret_cast<Type::Schema*>(addr.address));
|
||||
|
||||
// prepare binding
|
||||
binding.schema = object;
|
||||
binding.binding = id;
|
||||
//for(size_t type_id : object.data) {
|
||||
// binding.size += type_size(type_id);
|
||||
//}
|
||||
|
||||
printf("bind: (%zu) %zu\n", binding.binding, binding.size);
|
||||
|
||||
// add binding to pool
|
||||
//DB_SCHEMA.add(id, binding);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
@ -1,84 +1,108 @@
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include "type.h"
|
||||
#include "typetree.h"
|
||||
#include "nametree.h"
|
||||
#include "rawlist.h"
|
||||
#include "pool.h"
|
||||
|
||||
#include "schema.h"
|
||||
extern "C" struct Str {
|
||||
uint8_t* bytes;
|
||||
size_t length;
|
||||
};
|
||||
|
||||
extern TypeTree DB_TYPE;
|
||||
extern NameTree DB_NAME;
|
||||
extern Pool<Variable> DB_DATA;
|
||||
//extern Pool<Type::Schema> DB_SCHEMA;
|
||||
extern Pool<Reference> DB_DATA;
|
||||
|
||||
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);
|
||||
|
||||
extern "C" size_t name_indexof(const uint8_t* bytes, size_t length);
|
||||
std::string name_keyof_internal(size_t index);
|
||||
extern "C" Str name_keyof(size_t index);
|
||||
|
||||
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);
|
||||
extern "C" Reference acquire(size_t type_id);
|
||||
extern "C" void release(Reference id);
|
||||
extern "C" bool copy(Reference src, Reference 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);
|
||||
extern "C" Reference varying_get(Reference addr);
|
||||
extern "C" void varying_set(Reference addr, Reference source);
|
||||
extern "C" void varying_clear(Reference addr);
|
||||
|
||||
// Boolean //
|
||||
extern "C" void bool_set(Variable addr, Type::Boolean value);
|
||||
extern "C" Type::Boolean bool_get(Variable addr);
|
||||
extern "C" void bool_set(Reference addr, Type::Boolean value);
|
||||
extern "C" Type::Boolean bool_get(Reference addr);
|
||||
|
||||
// Natural //p
|
||||
extern "C" void natural_set(Variable addr, Type::Natural value);
|
||||
extern "C" Type::Natural natural_get(Variable addr);
|
||||
extern "C" void natural_set(Reference addr, Type::Natural value);
|
||||
extern "C" Type::Natural natural_get(Reference addr);
|
||||
|
||||
// Integer //
|
||||
extern "C" void integer_set(Variable addr, Type::Integer value);
|
||||
extern "C" Type::Integer integer_get(Variable addr);
|
||||
extern "C" void integer_set(Reference addr, Type::Integer value);
|
||||
extern "C" Type::Integer integer_get(Reference 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);
|
||||
extern "C" uint8_t block_get(Reference addr, size_t index);
|
||||
extern "C" void block_set(Reference 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);
|
||||
extern "C" size_t sequence_length(Reference addr);
|
||||
extern "C" uint8_t sequence_get(Reference addr, size_t index);
|
||||
extern "C" void sequence_clear(Reference addr);
|
||||
extern "C" void sequence_set(Reference addr, size_t index, uint8_t value);
|
||||
extern "C" void sequence_insert(Reference addr, size_t index, uint8_t value);
|
||||
extern "C" void sequence_reserve(Reference addr, size_t capacity);
|
||||
|
||||
// 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);
|
||||
extern "C" size_t array_length(Reference addr);
|
||||
Reference array_cell(Reference addr, size_t index);
|
||||
extern "C" Reference array_at(Reference addr, size_t index);
|
||||
extern "C" void array_update(Reference addr, size_t index, Reference source);
|
||||
|
||||
// List //
|
||||
|
||||
extern "C" size_t list_capacity(Variable addr);
|
||||
extern "C" size_t list_length(Variable addr);
|
||||
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_insert(Variable addr, size_t index, Variable source);
|
||||
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" size_t list_capacity(Reference addr);
|
||||
extern "C" size_t list_length(Reference addr);
|
||||
Reference list_cell(Reference addr, size_t index);
|
||||
extern "C" Reference list_at(Reference addr, size_t index);
|
||||
//extern "C" Reference list_first(Reference addr);
|
||||
//extern "C" Reference list_last(Reference addr);
|
||||
extern "C" void list_clear(Reference addr);
|
||||
//extern "C" void list_prepend(Reference addr, Reference source);
|
||||
//extern "C" void list_append(Reference addr, Reference source);
|
||||
extern "C" void list_insert(Reference addr, size_t index, Reference source);
|
||||
extern "C" void list_update(Reference addr, size_t index, Reference source);
|
||||
//extern "C" void list_truncate(Reference addr, size_t maximum);
|
||||
//extern "C" void list_shift(Reference addr);
|
||||
extern "C" void list_remove(Reference addr, size_t index);
|
||||
extern "C" void list_reserve(Reference addr, size_t capacity);
|
||||
//extern "C" void list_resize(Reference addr, size_t length);
|
||||
|
||||
// Record //
|
||||
|
||||
/*
|
||||
- set_at(index, value)
|
||||
- set(key, value)
|
||||
- get_at(index) value
|
||||
- get(key) value
|
||||
- key(index) key
|
||||
- index(key) index
|
||||
*/
|
||||
|
||||
// Schema //
|
||||
extern "C" size_t schema_length(Reference addr);
|
||||
extern "C" size_t schema_add(Reference addr, size_t type_id);
|
||||
extern "C" void schema_remove(Reference addr, size_t index);
|
||||
extern "C" void schema_reorder(Reference addr, size_t index_from, size_t index_to);
|
||||
extern "C" void schema_map(Reference addr, size_t key, size_t index);
|
||||
extern "C" void schema_unmap(Reference addr, size_t key);
|
||||
extern "C" size_t schema_index(Reference addr, size_t key);
|
||||
extern "C" size_t schema_bind(Reference addr, size_t key);
|
||||
|
@ -1,13 +1,28 @@
|
||||
pub mod util;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Variable {
|
||||
pub class:usize,
|
||||
pub address:usize,
|
||||
pub struct Reference {
|
||||
pub(crate) class:usize,
|
||||
pub(crate) address:usize,
|
||||
}
|
||||
impl Reference {
|
||||
pub fn is_null(&self) -> bool
|
||||
{
|
||||
self.address != 0
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct Str {
|
||||
pub bytes:*mut u8,
|
||||
pub length:usize,
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
pub fn acquire(type_id:usize) -> Variable;
|
||||
pub fn release(addr:Variable);
|
||||
pub fn acquire(type_id:usize) -> Reference;
|
||||
pub fn release(addr:Reference);
|
||||
|
||||
pub fn type_outer(type_id:usize, key:usize) -> usize;
|
||||
pub fn type_inner(type_id:usize) -> usize;
|
||||
@ -15,46 +30,60 @@ extern "C" {
|
||||
|
||||
pub fn type_size(type_id:usize) -> usize;
|
||||
|
||||
pub fn bool_set(addr:Variable, data:bool);
|
||||
pub fn bool_get(addr:Variable) -> bool;
|
||||
pub fn name_indexof(data:*const u8, length:usize) -> usize;
|
||||
pub fn name_keyof(index:usize) -> Str;
|
||||
pub fn name_release(data:Str);
|
||||
|
||||
pub fn bool_set(addr:Reference, data:bool);
|
||||
pub fn bool_get(addr:Reference) -> bool;
|
||||
|
||||
pub fn natural_set(addr:Variable, data:u64);
|
||||
pub fn natural_get(addr:Variable) -> u64;
|
||||
pub fn natural_set(addr:Reference, data:u64);
|
||||
pub fn natural_get(addr:Reference) -> u64;
|
||||
|
||||
pub fn integer_set(addr:Variable, data:i64);
|
||||
pub fn integer_get(addr:Variable) -> i64;
|
||||
pub fn integer_set(addr:Reference, data:i64);
|
||||
pub fn integer_get(addr:Reference) -> i64;
|
||||
|
||||
pub fn block_set(addr:Variable, index:usize, data:u8);
|
||||
pub fn block_get(addr:Variable, index:usize) -> u8;
|
||||
pub fn block_set(addr:Reference, index:usize, data:u8);
|
||||
pub fn block_get(addr:Reference, index:usize) -> u8;
|
||||
|
||||
//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;
|
||||
pub fn sequence_length(addr:Reference) -> usize;
|
||||
pub fn sequence_get(addr:Reference, index:usize) -> u8;
|
||||
pub fn sequence_clear(addr:Reference);
|
||||
pub fn sequence_set(addr:Reference, index:usize, value:u8);
|
||||
pub fn sequence_insert(addr:Reference, index:usize, value:u8);
|
||||
pub fn sequence_reserve(addr:Reference, capacity:usize);
|
||||
|
||||
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 array_length(addr:Reference) -> usize;
|
||||
pub fn array_at(addr:Reference, index:usize) -> Reference;
|
||||
pub fn array_update(addr:Reference, index:usize, source:Reference);
|
||||
|
||||
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_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_capacity(addr:Reference) -> usize;
|
||||
pub fn list_length(addr:Reference) -> usize;
|
||||
//pub fn list_first(addr:Reference) -> Reference;
|
||||
//pub fn list_last(addr:Reference) -> Reference;
|
||||
pub fn list_at(addr:Reference, index:usize) -> Reference;
|
||||
pub fn list_clear(addr:Reference);
|
||||
//pub fn list_prepend(addr:Reference, src:Reference);
|
||||
//pub fn list_append(addr:Reference, src:Reference);
|
||||
pub fn list_insert(addr:Reference, index:usize, src:Reference);
|
||||
pub fn list_update(addr:Reference, index:usize, src:Reference);
|
||||
//pub fn list_truncate(addr:Reference, maximum:usize);
|
||||
//pub fn list_shift(addr:Reference, maximum:usize);
|
||||
pub fn list_remove(addr:Reference, index:usize, count:usize);
|
||||
pub fn list_reserve(addr:Reference, capacity:usize);
|
||||
//pub fn list_resize(addr:Reference, length:usize);
|
||||
|
||||
//pub fn list_cut(addr:Variable, index:usize, length:usize) -> Variable;
|
||||
//pub fn list_cut(addr:Reference, index:usize, length:usize) -> Reference;
|
||||
|
||||
//pub fn list_find(addr:Variable, target:Variable, start:usize) -> usize;
|
||||
//pub fn list_count(addr:Variable, target:Variable, start:usize) -> usize;
|
||||
//pub fn list_find(addr:Reference, target:Reference, start:usize) -> usize;
|
||||
//pub fn list_count(addr:Reference, target:Reference, start:usize) -> usize;
|
||||
|
||||
pub fn schema_length(addr:Reference) -> usize;
|
||||
pub fn schema_add(addr:Reference, type_id:usize) -> usize;
|
||||
pub fn schema_remove(addr:Reference, index:usize);
|
||||
pub fn schema_reorder(addr:Reference, from:usize, to:usize);
|
||||
pub fn schema_map(addr:Reference, key:usize, index:usize);
|
||||
pub fn schema_unmap(addr:Reference, key:usize);
|
||||
pub fn schema_index(addr:Reference, key:usize) -> usize;
|
||||
pub fn schema_bind(addr:Reference, id:usize) -> usize;
|
||||
}
|
||||
|
||||
|
||||
|
@ -18,8 +18,8 @@ public:
|
||||
NameTree();
|
||||
~NameTree();
|
||||
|
||||
size_t lookup(const std::string& value);
|
||||
std::string get(size_t) const;
|
||||
size_t indexof(const std::string& value);
|
||||
std::string keyof(size_t) const;
|
||||
|
||||
private:
|
||||
std::vector<Node> m_nodes;
|
||||
@ -36,64 +36,72 @@ NameTree::NameTree()
|
||||
NameTree::~NameTree()
|
||||
{ }
|
||||
|
||||
size_t NameTree::lookup(const std::string& value)
|
||||
size_t NameTree::indexof(const std::string& key)
|
||||
{
|
||||
size_t current = 0;
|
||||
size_t index = 0;
|
||||
|
||||
while(index < value.length()) {
|
||||
// descend node tree until key is found
|
||||
while(index < key.length()) {
|
||||
Node& node = m_nodes[current];
|
||||
|
||||
size_t find = 0;
|
||||
for(size_t ci = 0; ci < node.children.size(); ++ci) {
|
||||
size_t child = node.children[ci];
|
||||
if(value[index] == m_nodes[child].prefix[0]) {
|
||||
size_t prefix_index = 0;
|
||||
for(; prefix_index < m_nodes[child].prefix.length() && index < value.length(); prefix_index++ && index++) {
|
||||
if(m_nodes[child].prefix[prefix_index] != value[index]) {
|
||||
break;
|
||||
}
|
||||
// search child nodes for first character match
|
||||
bool find = false;
|
||||
for(size_t list_index = 0; list_index < node.children.size(); ++list_index) {
|
||||
size_t child_index = node.children[list_index];
|
||||
Node& child = m_nodes[child_index];
|
||||
|
||||
// match extent of key to child prefix
|
||||
if(child.prefix[0] == key[index]) {
|
||||
index++;
|
||||
find = true;
|
||||
|
||||
size_t prefix_index = 1;
|
||||
for(; prefix_index < child.prefix.length() && index < key.length(); prefix_index++ && index++) {
|
||||
// check whether prefixes are equal
|
||||
if(child.prefix[prefix_index] != key[index]) { break; }
|
||||
}
|
||||
|
||||
if(prefix_index == m_nodes[child].prefix.length()) {
|
||||
current = child;
|
||||
// if prefix matches, continue to child node
|
||||
if(prefix_index == child.prefix.length()) {
|
||||
current = child_index;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
find = child;
|
||||
|
||||
// create intermediate node
|
||||
m_nodes.push_back(Node(m_nodes[child].prefix.substr(0, prefix_index), child));
|
||||
m_nodes[current].children[ci] = m_nodes.size() - 1;
|
||||
m_nodes[m_nodes.size() - 1].children.push_back(child);
|
||||
// otherwise, branch prefix and create node for key
|
||||
else {
|
||||
// create intermediate node, retaining node index of original
|
||||
m_nodes.push_back(Node(m_nodes[child_index].prefix.substr(0, prefix_index), current));
|
||||
size_t intermediate_index = m_nodes.size() - 1;
|
||||
m_nodes[current].children[list_index] = intermediate_index;
|
||||
m_nodes[intermediate_index].children.push_back(child_index);
|
||||
|
||||
// update child node
|
||||
m_nodes[child].parent = m_nodes.size() - 1;
|
||||
m_nodes[child_index].prefix = m_nodes[child_index].prefix.substr(prefix_index);
|
||||
m_nodes[child_index].parent = intermediate_index;
|
||||
|
||||
// create branching node if value is not prefix
|
||||
if(index != value.length()) {
|
||||
m_nodes.push_back(Node(value.substr(index), child));
|
||||
find = m_nodes.size() - 1;
|
||||
if(index != key.length()) {
|
||||
m_nodes.push_back(Node(key.substr(index), intermediate_index));
|
||||
}
|
||||
|
||||
return find;
|
||||
|
||||
return m_nodes.size() - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(find == 0) {
|
||||
// add suffix to new node pointing to value
|
||||
m_nodes.push_back(Node(value.substr(index), current));
|
||||
find = m_nodes.size() - 1;
|
||||
node.children.push_back(find);
|
||||
return find;
|
||||
|
||||
// if first character is not found, create new child
|
||||
if(!find) {
|
||||
m_nodes.push_back(Node(key.substr(index), current));
|
||||
m_nodes[current].children.push_back(m_nodes.size() - 1);
|
||||
return m_nodes.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
std::string NameTree::get(size_t id) const
|
||||
std::string NameTree::keyof(size_t id) const
|
||||
{
|
||||
size_t length = 0;
|
||||
std::string out;
|
||||
@ -104,7 +112,7 @@ std::string NameTree::get(size_t id) const
|
||||
current = m_nodes[current].parent;
|
||||
}
|
||||
|
||||
out = std::string(length, '\0');
|
||||
out = std::string(length, 0);
|
||||
size_t index = length - 1;
|
||||
|
||||
for(size_t current = id; current != 0;) {
|
||||
|
93
src/runtime/rawlist.cc
Normal file
93
src/runtime/rawlist.cc
Normal file
@ -0,0 +1,93 @@
|
||||
#include "rawlist.h"
|
||||
|
||||
void* rawlist_insert(RawList& list, size_t offset, size_t index)
|
||||
{
|
||||
if(list.length == list.capacity) { rawlist_reserve(list, offset, (list.capacity == 0) + list.capacity * 2); }
|
||||
if(index > list.length) { index = list.length; }
|
||||
|
||||
// shift elements back until index is reached
|
||||
for(size_t i = list.length; i > index; --i) {
|
||||
memcpy(rawlist_cell(list, offset, i), rawlist_cell(list, offset, i - 1), offset);
|
||||
}
|
||||
|
||||
list.length++;
|
||||
return rawlist_cell(list, offset, index);
|
||||
}
|
||||
|
||||
void rawlist_remove(RawList& list, size_t offset, size_t index)
|
||||
{
|
||||
if(index > list.length) { index = list.length - 1; }
|
||||
|
||||
// shift elements back until index is reached
|
||||
for(size_t i = index; i < list.length - 1; ++i) {
|
||||
memcpy(rawlist_cell(list, offset, i), rawlist_cell(list, offset, i + 1), offset);
|
||||
}
|
||||
|
||||
list.length--;
|
||||
memset(rawlist_cell(list, offset, list.length), 0, offset);
|
||||
}
|
||||
|
||||
void rawlist_reorder(RawList& list, size_t offset, size_t from, size_t to)
|
||||
{
|
||||
// ensure there is a trailing cell in which to swap moving data
|
||||
if(list.length == list.capacity) { rawlist_reserve(list, offset, list.capacity * 2); }
|
||||
|
||||
if(from > list.length) { from = list.length - 1; }
|
||||
if(to > list.length) { to = list.length - 1; }
|
||||
if(from != to) {
|
||||
// move data to unused cell
|
||||
memcpy(rawlist_cell(list, offset, from), rawlist_cell(list, offset, list.length), offset);
|
||||
|
||||
if(from < to) {
|
||||
for(size_t i = from; i < to; ++i) {
|
||||
memcpy(rawlist_cell(list, offset, i), rawlist_cell(list, offset, i + 1), offset);
|
||||
}
|
||||
}
|
||||
else if(from > to) {
|
||||
for(size_t i = from; i > to; --i) {
|
||||
memcpy(rawlist_cell(list, offset, i), rawlist_cell(list, offset, i - 1), offset);
|
||||
}
|
||||
}
|
||||
|
||||
// move data to target cell and clear swap cell
|
||||
memcpy(rawlist_cell(list, offset, from), rawlist_cell(list, offset, list.length), offset);
|
||||
memset(rawlist_cell(list, offset, list.length), 0, offset);
|
||||
}
|
||||
}
|
||||
|
||||
inline void* rawlist_cell(RawList& list, size_t offset, size_t index)
|
||||
{
|
||||
if(index < list.capacity) {
|
||||
return reinterpret_cast<void*>(reinterpret_cast<size_t>(list.data) + (offset * index));
|
||||
}
|
||||
else {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void rawlist_reserve(RawList& list, size_t offset, size_t capacity)
|
||||
{
|
||||
if(capacity > list.capacity) {
|
||||
size_t block_size = offset * capacity;
|
||||
void* old_data = list.data;
|
||||
|
||||
list.data = malloc(block_size);
|
||||
memset(list.data, 0, block_size);
|
||||
if(old_data != nullptr) {
|
||||
memcpy(list.data, old_data, offset * list.length);
|
||||
free(old_data);
|
||||
}
|
||||
|
||||
list.capacity = capacity;
|
||||
}
|
||||
}
|
||||
|
||||
void rawlist_clear(RawList& list)
|
||||
{
|
||||
if(list.data != nullptr) {
|
||||
free(list.data);
|
||||
}
|
||||
list.capacity = 0;
|
||||
list.length = 0;
|
||||
list.data = nullptr;
|
||||
}
|
20
src/runtime/rawlist.h
Normal file
20
src/runtime/rawlist.h
Normal file
@ -0,0 +1,20 @@
|
||||
#ifndef RAWLIST_H
|
||||
#define RAWLIST_H
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
struct RawList {
|
||||
size_t offset;
|
||||
size_t capacity;
|
||||
size_t length;
|
||||
void* data;
|
||||
};
|
||||
|
||||
void* rawlist_insert(RawList& list, size_t offset, size_t index);
|
||||
void rawlist_remove(RawList& list, size_t offset, size_t index);
|
||||
inline void* rawlist_cell(RawList& list, size_t offset, size_t index);
|
||||
void rawlist_reserve(RawList& list, size_t offset, size_t capacity);
|
||||
void rawlist_clear(RawList& list);
|
||||
|
||||
#endif
|
@ -1,11 +0,0 @@
|
||||
#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,6 +1,7 @@
|
||||
#include <cstdint>
|
||||
#include "rawlist.h"
|
||||
|
||||
extern "C" struct Variable {
|
||||
extern "C" struct Reference {
|
||||
size_t type;
|
||||
void* address;
|
||||
};
|
||||
@ -9,22 +10,19 @@ namespace Type {
|
||||
|
||||
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,
|
||||
Null = 0x00,
|
||||
Varying = 0x01,
|
||||
Boolean = 0x02,
|
||||
Natural = 0x10,
|
||||
Integer = 0x11,
|
||||
Decimal = 0x12,
|
||||
Block = 0x1e,
|
||||
Sequence = 0x1f,
|
||||
Array = 0x22,
|
||||
List = 0x23,
|
||||
Sparse = 0x24,
|
||||
Record = 0x7e,
|
||||
Schema = 0x7f,
|
||||
};
|
||||
}
|
||||
|
||||
@ -32,16 +30,45 @@ typedef bool Boolean;
|
||||
typedef uint64_t Natural;
|
||||
typedef int64_t Integer;
|
||||
|
||||
struct Sequence {
|
||||
RawList data;
|
||||
};
|
||||
|
||||
struct List {
|
||||
size_t capacity;
|
||||
size_t length;
|
||||
void* data;
|
||||
RawList data;
|
||||
};
|
||||
|
||||
struct Sparse {
|
||||
struct Header {
|
||||
size_t start;
|
||||
size_t length;
|
||||
size_t index;
|
||||
|
||||
Header() {
|
||||
start = 0;
|
||||
length = 0;
|
||||
index = 0;
|
||||
}
|
||||
};
|
||||
|
||||
RawList data;
|
||||
RawList header;
|
||||
};
|
||||
|
||||
struct Schema {
|
||||
size_t capacity;
|
||||
size_t length;
|
||||
void* data;
|
||||
struct Mapping {
|
||||
size_t key;
|
||||
size_t index;
|
||||
};
|
||||
|
||||
RawList data;
|
||||
RawList map;
|
||||
};
|
||||
|
||||
struct SchemaBinding {
|
||||
size_t binding;
|
||||
size_t size;
|
||||
Schema schema;
|
||||
};
|
||||
|
||||
}
|
||||
|
16
src/runtime/util.rs
Normal file
16
src/runtime/util.rs
Normal file
@ -0,0 +1,16 @@
|
||||
pub fn name_indexof(key:&str) -> usize
|
||||
{
|
||||
unsafe {super::name_indexof(key.as_ptr(), key.len())}
|
||||
}
|
||||
|
||||
pub fn name_keyof(index:usize) -> String
|
||||
{
|
||||
let str = unsafe {super::name_keyof(index)};
|
||||
let bytes = Vec::<u8>::from(unsafe {std::slice::from_raw_parts(str.bytes, str.length)});
|
||||
let result = match String::from_utf8(bytes) {
|
||||
Ok(str) => str,
|
||||
Err(_) => String::new()
|
||||
};
|
||||
unsafe { super::name_release(str); }
|
||||
return result;
|
||||
}
|
47
src/tag.rs
47
src/tag.rs
@ -1,28 +1,25 @@
|
||||
//pub type Class = usize;
|
||||
|
||||
pub const VARYING :usize = 0x00;
|
||||
pub const NULL :usize = 0x01;
|
||||
pub const BOOLEAN :usize = 0x02;
|
||||
//...
|
||||
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 :usize = 0x1c;
|
||||
//pub const CHAR :usize = 0x1d;
|
||||
pub const BLOCK :usize = 0x1e;
|
||||
pub const STRING :usize = 0x1f;
|
||||
pub const NULL :usize = 0x00;
|
||||
pub const VARYING :usize = 0x01;
|
||||
pub const BOOLEAN :usize = 0x02;
|
||||
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 :usize = 0x1c;
|
||||
//pub const CHAR :usize = 0x1d;
|
||||
pub const BLOCK :usize = 0x1e;
|
||||
pub const SEQUENCE :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 :usize = 0x7e;
|
||||
pub const SCHEMA :usize = 0x7f;
|
||||
//pub const SET :usize = 0x21;
|
||||
pub const ARRAY :usize = 0x22;
|
||||
pub const LIST :usize = 0x23;
|
||||
pub const SPARSE :usize = 0x24;
|
||||
//pub const TRIE :usize = 0x25;
|
||||
//pub const MAP :usize = 0x26;
|
||||
//pub const TREE :usize = 0x27;
|
||||
//pub const GRAPH :usize = 0x28;
|
||||
pub const RECORD :usize = 0x7e;
|
||||
pub const SCHEMA :usize = 0x7f;
|
||||
|
Reference in New Issue
Block a user