Add tests, add interface methods, updated README.

This commit is contained in:
yukirij 2023-08-11 18:32:50 -07:00
parent 2d6f643373
commit 182bf00f71
12 changed files with 464 additions and 58 deletions

224
README.md
View File

@ -1,2 +1,226 @@
# Suzu Runtime and Notation
# Documentation
## Conventions
### Namespacing
Examples in this documentation will assume inclusion of the szun namespace.
In practice, this is not recommended outside of limited scopes.
```
fn procedure()
{
use szun::*;
/* ... */
}
```
## Type Building
Type building functions allow for the construction of identifiers representing complex data types. These identifiers are used to allocate typed
```
varying()
boolean()
natural()
integer()
block(size)
sequence()
array(size, type)
list(type)
schema()
record(schema)
```
### Example
This example produces an identifier representing a list of blocks of 4 bytes each.
```
let type_id = list(block(4));
```
## Global Functions
### allocate(type)
```
let ref = allocate(list(integer()));
```
### encode(ref:Reference) -> vec<u8>
### decode(data:Vec<u8>) -> Reference
## Language Compiler
## Common Methods
### new() -> Self
```
let value = Integer::new();
```
### from(ref:Reference) -> Result<Self,()>
```
match Integer::from(list.at(0)) {
Ok(data) => { println!("Integer: {}", data); }
Err(_) => { println!("Not Integer"); }
}
```
### with(value) -> Self
```
let b = Boolean::with(true);
```
### Dereference
```
let ref = *Integer::new();
```
## Varying
### set(ref:Reference)
```
let var = Varying::new();
var.set(*Sequence::with("Hello!"))
```
### get() -> Reference
```
let var = Varying::with(*Boolean::with(true));
let ref = var.get();
```
## Boolean
Stores the value true or false.
### get() -> bool
```
let value = Boolean::with(true);
if value.get() {
println!("True");
}
```
### set(value:bool)
```
let mut value = Boolean::new();
value.set(true);
```
## Natural
Stores a non-negative integer value.
### get() -> u64
```
let value = Integer::with(-1);
println!("{}", value.get());
```
### set(value:u64)
```
let mut value = Integer::new();
value.set(-273);
```
## Integer
Stores a signed integer value.
### get() -> i64
```
let value = Integer::with(-1);
println!("{}", value.get());
```
### set(value:i64)
```
let mut value = Integer::new();
value.set(-273);
```
## Block
Constant-sized series of bytes.
## Sequence
Variable-sized series of bytes.
### get() -> String
### get_raw() -> Vec<u8>
### set(data:&str)
### set_raw(data:Vec<u8>)
## Array
Constant-sized, ordered collection of items.
### new(size:usize, type_id:usize)
### length() -> usize
### at(index:usize) -> Reference
### set(index:usize, ref:Reference)
## List
Variable-sized, ordered collection of items.
### new(type_id:usize)
### length() -> usize
### capacity() -> usize
### at(index:usize) -> Reference
### set(index:usize, ref:Reference)
### insert(index:usize, ref:Reference)
### remove(index:usize)
### reserve(capacity:usize)
### clear()
## Schema
Definition of an abstract structure composed of named items.
### get(index:usize) -> usize
### add(type_id:usize) -> usize
### remove(index:usize)
### assign(key:&str, type_id:usize) -> usize
### map(key:&str, index:usize)
### unmap(key:&str)
### clear()
### bind(id:usize)
## Record
Instance of a schema.
### at(index:usize) -> Reference
### set(index:usize, source:Reference)
### keyof(index:usize) -> String
### indexof(key:&str) -> usize

View File

@ -1,4 +1,4 @@
fn main()
{
szun::test();
}

View File

@ -34,7 +34,7 @@ impl Array {
{
let mut obj = Self::new(length, class);
for i in 0..usize::min(length, data.len()) {
obj.update(i, data[i]);
obj.set(i, data[i]);
}
return obj;
}
@ -44,7 +44,7 @@ impl Array {
unsafe {array_length(self.addr)}
}
pub fn update(&mut self, index:usize, source:Reference)
pub fn set(&mut self, index:usize, source:Reference)
{
unsafe { array_update(self.addr, index, source); }
}

View File

@ -2,7 +2,8 @@ use crate::runtime::{
Reference,
acquire, release,
type_inner, type_key,
block_set, block_get
block_length,
block_set, block_get,
};
use crate::tag;
use super::block;
@ -30,6 +31,11 @@ impl Block {
}
}
pub fn length(&self) -> usize
{
unsafe {block_length(self.addr)}
}
pub fn set(&mut self, data:Vec<u8>)
{
let length = unsafe {type_key(type_inner(self.addr.class))};

View File

@ -69,7 +69,7 @@ impl List {
unsafe{list_insert(self.addr, index, source)};
}
pub fn update(&mut self, index:usize, source:Reference)
pub fn set(&mut self, index:usize, source:Reference)
{
unsafe{list_update(self.addr, index, source)};
}

View File

@ -40,35 +40,48 @@ impl Sequence {
return obj;
}
pub fn set(&mut self, data:&str)
pub fn length(&self) -> usize
{
unsafe {sequence_length(self.addr)}
}
pub fn set_raw(&mut self, data:Vec<u8>)
{
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]); }
if data.len() > 0 {
unsafe { sequence_reserve(self.addr, data.len()); }
for i in 0..data.len() {
unsafe { sequence_insert(self.addr, i, data[i]); }
}
}
}
pub fn get(&self) -> String
pub fn set(&mut self, data:&str)
{
self.set_raw(Vec::from(data.as_bytes()));
}
pub fn get_raw(&self) -> Vec<u8>
{
let length = unsafe {sequence_length(self.addr)};
let mut result = Vec::<u8>::new();
if length > 0 {
let mut bytes = Vec::<u8>::with_capacity(length);
result.reserve_exact(length);
for i in 0..length {
bytes.push(unsafe {sequence_get(self.addr, i)});
result.push(unsafe {sequence_get(self.addr, i)});
}
return match String::from_utf8(bytes) {
Ok(data) => data,
}
return result;
}
pub fn get(&self) -> String
{
match String::from_utf8(self.get_raw()) {
Ok(s) => s,
Err(_) => String::new(),
}
}
else {
return String::new();
}
}
}
impl std::ops::Deref for Sequence {
type Target = Reference;

View File

@ -5,61 +5,61 @@ 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
fn check<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()
/*pub fn test()
{
{
println!("Boolean");
let mut dat = Boolean::new();
assert::<bool>(false, dat.get());
check(false, dat.get());
dat.set(true);
assert::<bool>(true, dat.get());
check(true, dat.get());
dat.set(false);
assert::<bool>(false, dat.get());
check(false, dat.get());
}
{
println!("Natural");
let mut dat = Natural::new();
assert::<u64>(0, dat.get());
check(0, dat.get());
dat.set(50);
assert::<u64>(50, dat.get());
check(50, dat.get());
dat.set(25000);
assert::<u64>(25000, dat.get());
check(25000, dat.get());
}
{
println!("Integer");
let mut dat = Integer::new();
assert::<i64>(0, dat.get());
check(0, dat.get());
dat.set(-12);
assert::<i64>(-12, dat.get());
check(-12, dat.get());
dat.set(38695);
assert::<i64>(38695, dat.get());
check(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]);
check(4, dat.get().len());
check(1, dat.get()[0]);
check(2, dat.get()[1]);
check(3, dat.get()[2]);
check(4, dat.get()[3]);
}
{
println!("Sequence");
let mut dat = Sequence::new();
assert::<String>(String::from(""), dat.get());
check(String::from(""), dat.get());
dat.set("hello");
assert::<String>(String::from("hello"), dat.get());
check(String::from("hello"), dat.get());
}
{
@ -69,14 +69,14 @@ pub fn test()
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());
check(4, dat.length());
check(250, Natural::from(dat.at(0)).unwrap().get());
check(500, Natural::from(dat.at(1)).unwrap().get());
check(750, Natural::from(dat.at(2)).unwrap().get());
check(1000,Natural::from(dat.at(3)).unwrap().get());
}
/* {
{
println!("List - Undefined");
println!("List - Variable");
@ -97,20 +97,127 @@ pub fn test()
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");
let mut sch = Schema::new();
sch.add(integer());
sch.map("abc", 0);
check(1, sch.length());
check(0, sch.index("abc"));
check(sch.length(), sch.index("def"));
}
}*/
/*{
{
println!("Record");
}*/
}
}*/
#[cfg(test)]
mod tests {
#[test]
fn boolean_initialize()
{
let value = crate::Boolean::new();
assert_eq!(false, value.get(), "Boolean::new() produces value of false.");
}
#[test]
fn boolean_with()
{
assert_eq!(false, crate::Boolean::with(false).get(), "Boolean::with(false) produces value of false.");
assert_eq!(true, crate::Boolean::with(true).get(), "Boolean::with(true) produces value of true.");
}
#[test]
fn boolean_set_get()
{
let mut value = crate::Boolean::new();
value.set(true);
assert_eq!(true, value.get(), "Boolean.set(true) produces value of true.");
value.set(false);
assert_eq!(false, value.get(), "Boolean.set(false) produces value of false.");
}
#[test]
fn natural_initialize()
{
let value = crate::Natural::new();
assert_eq!(0, value.get(), "Natural::new() produces value of 0.");
}
#[test]
fn natural_set_get()
{
let mut value = crate::Natural::new();
value.set(12);
assert_eq!(12, value.get(), "Natural.set(12) produces value of 12.");
value.set(38695);
assert_eq!(38695, value.get(), "Natural.set(38695) produces value of 38695.");
}
#[test]
fn integer_initialize()
{
let value = crate::Integer::new();
assert_eq!(0, value.get(), "Integer::new() produces value of 0.");
}
#[test]
fn integer_set_get()
{
let mut value = crate::Integer::new();
value.set(-273);
assert_eq!(-273, value.get(), "Integer.set(-273) produces value of -273.");
value.set(100);
assert_eq!(100, value.get(), "Integer.set(100) produces value of 100.");
}
#[test]
fn block_initialize()
{
let value = crate::Block::new(8);
assert_eq!(8, value.length(), "Block::new(8) has length of 8.");
assert_eq!(vec![0;8], value.get(), "Block::new(8) has value of 0.");
}
#[test]
fn block_set_get()
{
let mut value = crate::Block::new(4);
value.set(vec![1, 2, 3, 4]);
assert_eq!(vec![1, 2, 3, 4], value.get(), "Block::set([1,2,3,4]) has value of [1,2,3,4].");
}
#[test]
fn sequence_initialize()
{
let value = crate::Sequence::new();
assert_eq!(0, value.length(), "Sequence::new() has length 0.");
}
#[test]
fn sequence_set_get_raw()
{
let mut value = crate::Sequence::new();
value.set_raw(vec![0, 1, 2, 3, 2, 1]);
assert_eq!(6, value.length(), "Sequence.set_raw([0,1,2,3,2,1]) has length 6.");
assert_eq!(vec![0,1,2,3,2,1], value.get_raw(), "Sequence.set_raw([0,1,2,3,2,1]) produces value [0,1,2,3,2,1].");
}
#[test]
fn sequence_set_get_str()
{
let mut value = crate::Sequence::new();
value.set("hello");
assert_eq!(5, value.length(), "Sequence.set(hello) has length 5.");
assert_eq!(String::from("hello"), value.get(), "Sequence.set(hello) produces value hello.");
}
}

View File

@ -293,6 +293,11 @@ extern "C" Type::Integer integer_get(Reference addr)
// Block //
extern "C" size_t block_length(Reference addr)
{
return type_key(type_inner(addr.type));
}
extern "C" uint8_t block_get(Reference addr, size_t index)
{
size_t length = type_key(type_inner(addr.type));
@ -681,7 +686,7 @@ extern "C" void schema_unmap(Reference addr, size_t key)
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++) {
for(size_t i = 0; 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) {
@ -700,11 +705,15 @@ extern "C" size_t schema_bind(Reference addr, size_t id)
// 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);
for(size_t i = 0; i < object.data.length; ++i) {
size_t type_id = *reinterpret_cast<size_t*>(rawlist_cell(object.data, sizeof(size_t), i));
size_t size = type_size(type_id);
size_t alignment = size;
binding.alignment = std::max(alignment, binding.alignment);
size_t position = ((binding.size + (alignment - 1)) & ~(alignment - 1));
binding.size = size + position;
}
binding.size = ((binding.size + (binding.alignment - 1)) & ~(binding.alignment - 1));
// add binding to pool
//DB_SCHEMA.add(id, binding);

View File

@ -5,6 +5,7 @@
#include "type.h"
#include "typetree.h"
#include "nametree.h"
//#include "sparselist.h"
#include "rawlist.h"
#include "pool.h"
@ -23,6 +24,8 @@ 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 schema_bind(Reference addr, size_t 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);
@ -50,6 +53,7 @@ extern "C" void integer_set(Reference addr, Type::Integer value);
extern "C" Type::Integer integer_get(Reference addr);
// Block //
extern "C" size_t block_length(Reference addr);
extern "C" uint8_t block_get(Reference addr, size_t index);
extern "C" void block_set(Reference addr, size_t index, uint8_t value);

View File

@ -43,6 +43,7 @@ extern "C" {
pub fn integer_set(addr:Reference, data:i64);
pub fn integer_get(addr:Reference) -> i64;
pub fn block_length(addr:Reference) -> usize;
pub fn block_set(addr:Reference, index:usize, data:u8);
pub fn block_get(addr:Reference, index:usize) -> u8;

41
src/runtime/sparselist.h Normal file
View File

@ -0,0 +1,41 @@
#ifndef H_SPARSELIST
#define H_SPARSELIST
#include <vector>
template <typename T>
class SparseList {
public:
SparseList()
{ }
~SparseList()
{ }
void set(size_t index, const T& value)
{
}
void unset(size_t index)
{
}
T& get(size_t index)
{
}
private:
struct Header {
size_t start;
size_t length;
size_t index;
};
std::vector<Header> headers;
std::vector<T> data;
};
#endif

View File

@ -67,6 +67,7 @@ struct Schema {
struct SchemaBinding {
size_t binding;
size_t alignment;
size_t size;
Schema schema;
};