Skip to content

Commit

Permalink
feat: Datatypes
Browse files Browse the repository at this point in the history
  • Loading branch information
can-keklik committed Dec 29, 2024
1 parent bd4d5ec commit 77f23b8
Show file tree
Hide file tree
Showing 7 changed files with 235 additions and 5 deletions.
3 changes: 2 additions & 1 deletion lykiadb-server/src/comm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,9 @@ impl ServerSession {
Message::Request(req) => match req {
Request::Run(command) => {
let execution = self.runtime.interpret(command);

let response = if execution.is_ok() {
Response::Value(execution.ok().or_else(|| Some(RV::Undefined)).unwrap())
Response::Value(execution.ok().unwrap())

Check warning on line 76 in lykiadb-server/src/comm/mod.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-server/src/comm/mod.rs#L76

Added line #L76 was not covered by tests
} else {
Response::Error(execution.err().unwrap())
};
Expand Down
18 changes: 18 additions & 0 deletions lykiadb-server/src/engine/stdlib/dtype.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
use crate::{
engine::interpreter::{HaltReason, InterpretError, Interpreter},
value::{datatype::Datatype, RV},
};

pub fn nt_of(_interpreter: &mut Interpreter, args: &[RV]) -> Result<RV, HaltReason> {
Ok(RV::Datatype(args[0].get_type()))
}

pub fn nt_array_of(_interpreter: &mut Interpreter, args: &[RV]) -> Result<RV, HaltReason> {
match &args[0] {
RV::Datatype(inner) => Ok(RV::Datatype(Datatype::Array(Box::new(inner.clone())))),
_ => Err(HaltReason::Error(InterpretError::Other {
message: format!("array_of: Unexpected argument '{:?}'", args[0]),
}
.into())),

Check warning on line 16 in lykiadb-server/src/engine/stdlib/dtype.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-server/src/engine/stdlib/dtype.rs#L13-L16

Added lines #L13 - L16 were not covered by tests
}
}
61 changes: 59 additions & 2 deletions lykiadb-server/src/engine/stdlib/mod.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use dtype::nt_array_of;
use rustc_hash::FxHashMap;

use crate::{
util::{alloc_shared, Shared},
value::{
callable::{Callable, CallableKind, Function},
RV,
callable::{Callable, CallableKind, Function}, datatype::Datatype, RV
},
};

Expand All @@ -13,6 +13,7 @@ use self::{
json::{nt_json_decode, nt_json_encode},
out::nt_print,
time::nt_clock,
dtype::nt_of,
};

use super::interpreter::Output;
Expand All @@ -21,6 +22,7 @@ pub mod fib;
pub mod json;
pub mod out;
pub mod time;
pub mod dtype;

pub fn stdlib(out: Option<Shared<Output>>) -> FxHashMap<String, RV> {
let mut std = FxHashMap::default();
Expand All @@ -29,6 +31,7 @@ pub fn stdlib(out: Option<Shared<Output>>) -> FxHashMap<String, RV> {
let mut json_namespace = FxHashMap::default();
let mut time_namespace = FxHashMap::default();
let mut io_namespace = FxHashMap::default();
let mut dtype_namespace = FxHashMap::default();

benchmark_namespace.insert(
"fib".to_owned(),
Expand Down Expand Up @@ -79,6 +82,59 @@ pub fn stdlib(out: Option<Shared<Output>>) -> FxHashMap<String, RV> {
)),
);

dtype_namespace.insert(
"of_".to_owned(),
RV::Callable(Callable::new(
Some(1),
CallableKind::Generic,
Function::Lambda { function: nt_of },
)),
);

dtype_namespace.insert(
"str".to_owned(),
RV::Datatype(Datatype::Str),
);

dtype_namespace.insert(
"num".to_owned(),
RV::Datatype(Datatype::Num),
);

dtype_namespace.insert(
"bool".to_owned(),
RV::Datatype(Datatype::Bool),
);

dtype_namespace.insert(
"array".to_owned(),
RV::Callable(Callable::new(
Some(1),
CallableKind::Generic,
Function::Lambda { function: nt_array_of },
)),
);

dtype_namespace.insert(
"document".to_owned(),
RV::Datatype(Datatype::Document(FxHashMap::default())),
);

dtype_namespace.insert(
"callable".to_owned(),
RV::Datatype(Datatype::Callable),
);

dtype_namespace.insert(
"dtype".to_owned(),
RV::Datatype(Datatype::Datatype),
);

dtype_namespace.insert(
"none".to_owned(),
RV::Datatype(Datatype::None),
);

if out.is_some() {
let mut test_namespace = FxHashMap::default();

Expand All @@ -104,6 +160,7 @@ pub fn stdlib(out: Option<Shared<Output>>) -> FxHashMap<String, RV> {
std.insert("json".to_owned(), RV::Object(alloc_shared(json_namespace)));
std.insert("time".to_owned(), RV::Object(alloc_shared(time_namespace)));
std.insert("io".to_owned(), RV::Object(alloc_shared(io_namespace)));
std.insert("dtype".to_owned(), RV::Object(alloc_shared(dtype_namespace)));

std
}
28 changes: 26 additions & 2 deletions lykiadb-server/src/value/datatype.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,35 @@
use rustc_hash::FxHashMap;
use std::fmt::Display;

#[derive(Debug, Clone, PartialEq)]
pub enum Datatype {
Str,
Num,
Bool,
Composite(FxHashMap<String, Datatype>),
Document(FxHashMap<String, Datatype>),
Array(Box<Datatype>),
Callable,
Undefined
Datatype,
None
}

impl Display for Datatype {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Datatype::Str => write!(f, "dtype::str"),
Datatype::Num => write!(f, "dtype::num"),
Datatype::Bool => write!(f, "dtype::bool"),
Datatype::Document(map) => {
write!(f, "dtype::document({{")?;
for (key, value) in map.iter() {
writeln!(f, "{}: {}, ", key, value)?;

Check warning on line 25 in lykiadb-server/src/value/datatype.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-server/src/value/datatype.rs#L22-L25

Added lines #L22 - L25 were not covered by tests
}
write!(f, "}})")

Check warning on line 27 in lykiadb-server/src/value/datatype.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-server/src/value/datatype.rs#L27

Added line #L27 was not covered by tests
},
Datatype::Array(inner) => write!(f, "dtype::array({})", inner),
Datatype::Callable => write!(f, "dtype::callable"),
Datatype::Datatype => write!(f, "dtype::dtype"),
Datatype::None => write!(f, "dtype::none")
}
}
}
2 changes: 2 additions & 0 deletions lykiadb-server/src/value/eval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ impl PartialEq for RV {
(RV::Num(_), RV::Bool(b)) => self.eq_any_bool(*b),
(RV::Bool(a), RV::Num(_)) => other.eq_any_bool(*a),
//
(RV::Datatype(a), RV::Datatype(b)) => a == b,
//
_ => false,
}
}
Expand Down
33 changes: 33 additions & 0 deletions lykiadb-server/src/value/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use datatype::Datatype;
use rustc_hash::FxHashMap;
use serde::ser::{SerializeMap, SerializeSeq};
use serde::{Deserialize, Serialize};
Expand All @@ -21,10 +22,41 @@ pub enum RV {
Object(Shared<FxHashMap<String, RV>>),
Array(Shared<Vec<RV>>),
Callable(Callable),
Datatype(Datatype),
Undefined
}

impl RV {
pub fn get_type(&self) -> Datatype {
match &self {
RV::Str(_) => Datatype::Str,
RV::Num(_) => Datatype::Num,
RV::Bool(_) => Datatype::Bool,
RV::Object(obj) => {
let obj: &FxHashMap<String, RV> = &obj.read().unwrap();
if obj.is_empty() {
return Datatype::None;
}
let mut document = FxHashMap::default();
for key in obj.keys() {
let datatype = obj.get(key).unwrap().get_type();
document.insert(key.to_string(), datatype);
}
Datatype::Document(document)

Check warning on line 45 in lykiadb-server/src/value/mod.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-server/src/value/mod.rs#L35-L45

Added lines #L35 - L45 were not covered by tests
},
RV::Array(arr) => {
let arr: &[RV] = &arr.read().unwrap();
if arr.is_empty() {
return Datatype::Array(Box::from(Datatype::None));

Check warning on line 50 in lykiadb-server/src/value/mod.rs

View check run for this annotation

Codecov / codecov/patch

lykiadb-server/src/value/mod.rs#L50

Added line #L50 was not covered by tests
}
Datatype::Array(Box::from(arr[0].get_type()))
},
RV::Callable(_) => Datatype::Callable,
RV::Datatype(_) => Datatype::Datatype,
RV::Undefined => Datatype::None,
}
}

pub fn as_bool(&self) -> bool {
match &self {
RV::Num(value) => !value.is_nan() && value.abs() > 0.0,
Expand Down Expand Up @@ -117,6 +149,7 @@ impl Display for RV {
write!(f, "}}")
}
RV::Callable(_) => write!(f, "<Callable>"),
RV::Datatype(dtype) => write!(f, "<Datatype, {}>", dtype),
}
}
}
Expand Down
95 changes: 95 additions & 0 deletions lykiadb-server/tests/interpreter/types/primitives
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#[name=numerical, run=interpreter]>

test_utils::out(dtype::of_(1) == dtype::num);
test_utils::out(dtype::of_(1.12) == dtype::num);
test_utils::out(dtype::of_(1) == dtype::str);
test_utils::out(dtype::of_(1));
test_utils::out(dtype::of_(1.12));
---

true
true
false
<Datatype, dtype::num>
<Datatype, dtype::num>


#[name=string, run=interpreter]>

test_utils::out(dtype::of_("1") == dtype::str);
test_utils::out(dtype::of_("1") == dtype::num);
test_utils::out(dtype::of_("1"));

---

true
false
<Datatype, dtype::str>


#[name=boolean, run=interpreter]>

test_utils::out(dtype::of_(true) == dtype::bool);
test_utils::out(dtype::of_(false) == dtype::bool);
test_utils::out(dtype::of_(true) == dtype::str);
test_utils::out(dtype::of_(true));
test_utils::out(dtype::of_(false));

---

true
true
false
<Datatype, dtype::bool>
<Datatype, dtype::bool>


#[name=array, run=interpreter]>
test_utils::out(dtype::of_([1, 2, 3]) == dtype::array(dtype::num));
test_utils::out(dtype::of_([1, 2, 3]) == dtype::array(dtype::str));
test_utils::out(dtype::of_([1, 2, 3]));

---

true
false
<Datatype, dtype::array(dtype::num)>


#[name=callable, run=interpreter]>

test_utils::out(dtype::of_(io::print) == dtype::callable);
test_utils::out(dtype::of_(io::print) == dtype::str);
test_utils::out(dtype::of_(io::print));

---

true
false
<Datatype, dtype::callable>


#[name=datatype, run=interpreter]>

test_utils::out(dtype::of_(dtype::num) == dtype::dtype);
test_utils::out(dtype::of_(dtype::num) == dtype::str);
test_utils::out(dtype::of_(dtype::num));

---

true
false
<Datatype, dtype::dtype>


#[name=none, run=interpreter]>

test_utils::out(dtype::of_(undefined) == dtype::none);
test_utils::out(dtype::of_(undefined) == dtype::str);
test_utils::out(dtype::of_(undefined));

---

true
false
<Datatype, dtype::none>

0 comments on commit 77f23b8

Please sign in to comment.