use crate::{heap, HeapMap, Runner};
use gluescript::GlueNode;
use std::{fs, sync::Arc};
pub struct Stack {
runners: Vec<Runner>,
heap: HeapMap,
current: usize,
}
impl Stack {
pub fn new() -> Self {
Stack {
runners: vec![],
heap: heap(),
current: 0,
}
}
pub fn from_root_node(root: GlueNode, log_info: bool) -> Self {
let mut stack = Stack::new();
let runner = Runner::from_root_node(root, Arc::clone(&stack.heap), log_info);
stack.push_runner(runner);
stack
}
pub fn push_from_file(self: &mut Self, path: String, log_info: bool) -> Result<(), String> {
let content = match fs::read_to_string(path) {
Err(x) => return Err(x.to_string()),
Ok(x) => x,
};
for command in content.split(';') {
self.push_runner_from_string(&command.to_owned(), log_info)?;
}
Ok(())
}
pub fn push_runner_from_string(
self: &mut Self,
command: &String,
log_info: bool,
) -> Result<(), String> {
let runner = Runner::from_string(command, Arc::clone(&self.heap), log_info)?;
self.runners.push(runner);
Ok(())
}
pub fn push_runner(self: &mut Self, mut runner: Runner) -> () {
runner.heap = Arc::clone(&self.heap);
self.runners.push(runner);
}
pub async fn execute_next(self: &mut Self) -> Result<(), String> {
let runner = &mut self.runners[self.current];
self.current += 1;
runner.execute().await?;
Ok(())
}
pub async fn execute_all(self: &mut Self) -> Result<(), String> {
loop {
if self.current > self.runners.len() - 1 {
break;
}
self.execute_next().await?;
println!("{}", self.current().unwrap().result.clone().unwrap());
}
Ok(())
}
pub fn current(self: &Self) -> Option<&Runner> {
match self.current {
x if x > 0 => Some(&self.runners[x - 1]),
_ => None,
}
}
pub fn heap(self: &Self) -> &HeapMap {
&self.heap
}
}