mirror of
https://github.com/fluencelabs/interface-types
synced 2025-04-25 15:52:13 +00:00
84 lines
2.6 KiB
Rust
84 lines
2.6 KiB
Rust
|
use crate::instructions::{stack::Stack, Instruction};
|
||
|
use std::convert::TryFrom;
|
||
|
|
||
|
type ExecutableInstruction = dyn Fn(&mut Stack);
|
||
|
//trait ExecutableInstruction: Fn(&mut Stack) {}
|
||
|
|
||
|
pub(crate) struct Interpreter {
|
||
|
stack: Stack,
|
||
|
instructions: Vec<Box<dyn Fn(&mut Stack) + 'static>>,
|
||
|
}
|
||
|
|
||
|
impl Interpreter {
|
||
|
pub(crate) fn is_eos(&self) -> bool {
|
||
|
self.stack.is_empty()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
impl<'binary_input> TryFrom<&Vec<Instruction<'binary_input>>> for Interpreter {
|
||
|
type Error = &'static str;
|
||
|
|
||
|
fn try_from(instructions: &Vec<Instruction>) -> Result<Self, Self::Error> {
|
||
|
let executable_instructions = instructions
|
||
|
.iter()
|
||
|
.map(|instruction| -> Box<dyn Fn(&mut Stack) + 'static> {
|
||
|
match instruction {
|
||
|
Instruction::ArgumentGet(index) => {
|
||
|
let index = index.to_owned();
|
||
|
|
||
|
Box::new(move |stack: &mut Stack| {
|
||
|
println!("argument get {}", index);
|
||
|
})
|
||
|
}
|
||
|
Instruction::CallExport(export_name) => {
|
||
|
let export_name = (*export_name).to_owned();
|
||
|
|
||
|
Box::new(move |stack: &mut Stack| {
|
||
|
println!("call export {}", export_name);
|
||
|
})
|
||
|
}
|
||
|
Instruction::ReadUtf8 => Box::new(|stack: &mut Stack| {
|
||
|
println!("read utf8");
|
||
|
}),
|
||
|
Instruction::Call(index) => {
|
||
|
let index = index.to_owned();
|
||
|
|
||
|
Box::new(move |stack: &mut Stack| {
|
||
|
println!("call {}", index);
|
||
|
})
|
||
|
}
|
||
|
_ => unimplemented!(),
|
||
|
}
|
||
|
})
|
||
|
.collect::<Vec<_>>();
|
||
|
|
||
|
Ok(Interpreter {
|
||
|
stack: Stack::new(),
|
||
|
instructions: executable_instructions,
|
||
|
})
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[cfg(test)]
|
||
|
mod tests {
|
||
|
use super::Interpreter;
|
||
|
use crate::instructions::Instruction;
|
||
|
use std::convert::TryInto;
|
||
|
|
||
|
#[test]
|
||
|
fn test_interpreter_from_instructions() {
|
||
|
let instructions = vec![
|
||
|
Instruction::ArgumentGet(0),
|
||
|
Instruction::ArgumentGet(0),
|
||
|
Instruction::CallExport("strlen"),
|
||
|
Instruction::ReadUtf8,
|
||
|
Instruction::Call(7),
|
||
|
];
|
||
|
let interpreter: Result<Interpreter, _> = (&instructions).try_into();
|
||
|
assert!(interpreter.is_ok());
|
||
|
|
||
|
let interpreter = interpreter.unwrap();
|
||
|
assert_eq!(interpreter.is_eos(), true);
|
||
|
}
|
||
|
}
|