Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions fix/evaluator/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "test-evaluator"
version = "0.1.0"
edition = "2024"

[lib]
path = "src/lib.rs"

[dependencies]
5 changes: 5 additions & 0 deletions fix/evaluator/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#![no_std]
#![allow(dead_code)]

pub mod mockruntime;
pub mod testevaluator;
17 changes: 17 additions & 0 deletions fix/evaluator/src/mockruntime.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use core::clone::Clone;
use core::result::Result;

pub trait MockRuntime {
type BlobData: Clone + core::fmt::Debug;
type TreeData: Clone + core::fmt::Debug;
type Handle: Clone + core::fmt::Debug;
type Error;

fn create_blob(&mut self, data: Self::BlobData) -> Self::Handle;
fn create_tree(&mut self, data: Self::TreeData) -> Self::Handle;

fn get_blob(&self, handle: &Self::Handle) -> Result<Self::BlobData, Self::Error>;
fn get_tree(&self, handle: &Self::Handle) -> Result<Self::TreeData, Self::Error>;

fn apply(&mut self, combination: &Self::Handle) -> Result<Self::Handle, Self::Error>;
}
108 changes: 108 additions & 0 deletions fix/evaluator/src/testevaluator.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
extern crate alloc;
use crate::mockruntime::MockRuntime;
use alloc::{boxed::Box, vec::Vec};

#[derive(Debug)]
pub enum Error {
OOB,
TypeMismatch,
UnexpectedFunction,
}

enum Object {
Blob(Box<[u8]>),
Tree(Box<[usize]>),
}

pub struct FakeRuntime {
store: Vec<Object>,
}

impl FakeRuntime {
fn new() -> Self {
Self { store: Vec::new() }
}

fn create_blob_i64(&mut self, data: i64) -> <FakeRuntime as MockRuntime>::Handle {
self.create_blob(Box::from(data.to_le_bytes()))
}
}

impl MockRuntime for FakeRuntime {
type Handle = usize;
type BlobData = Box<[u8]>;
type TreeData = Box<[usize]>;
type Error = Error;

fn create_blob(&mut self, data: Self::BlobData) -> Self::Handle {
let index = self.store.len();
self.store.push(Object::Blob(data));
index
}

fn create_tree(&mut self, data: Self::TreeData) -> Self::Handle {
let index = self.store.len();
self.store.push(Object::Tree(data));
index
}

fn get_blob(&self, handle: &Self::Handle) -> Result<Self::BlobData, Self::Error> {
match self.store.get(*handle) {
Some(Object::Blob(data)) => Ok(data.clone()),
Some(Object::Tree(_)) => Err(Error::TypeMismatch),
None => Err(Error::OOB),
}
}

fn get_tree(&self, handle: &Self::Handle) -> Result<Self::TreeData, Self::Error> {
match self.store.get(*handle) {
Some(Object::Tree(data)) => Ok(data.clone()),
Some(Object::Blob(_)) => Err(Error::TypeMismatch),
None => Err(Error::OOB),
}
}

fn apply(&mut self, combination: &Self::Handle) -> Result<Self::Handle, Self::Error> {
let span = self.get_tree(combination)?;
if span.len() < 2 {
return Err(Error::OOB);
}

let function = self.get_blob(&span[0])?;
if function.as_ref() != b"+" {
return Err(Error::UnexpectedFunction);
}

let left_bytes: [u8; 8] = (*self.get_blob(&span[1])?)
.try_into()
.map_err(|_| Error::OOB)?;
let left = i64::from_le_bytes(left_bytes);
let right_bytes: [u8; 8] = (*self.get_blob(&span[2])?)
.try_into()
.map_err(|_| Error::OOB)?;
let right = i64::from_le_bytes(right_bytes);

Ok(self.create_blob_i64(left + right))
}
}

#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_add() {
let mut fake_runtime = FakeRuntime::new();

let one_literal = fake_runtime.create_blob_i64(1);
let two_literal = fake_runtime.create_blob_i64(2);
let plus_literal = fake_runtime.create_blob(Box::from(*b"+"));

let tree = fake_runtime.create_tree(Box::from([plus_literal, one_literal, two_literal]));
let result = fake_runtime.apply(&tree).expect("valid apply addition");

assert_eq!(
fake_runtime.get_blob(&result).expect("valid result blob"),
Box::from(3_i64.to_le_bytes())
);
}
}
Loading