use super::{get_num, Flow, LInstruction}; use crate::{ debug::{info::DebugInfo, printable::Printable}, executor::{ExecutorContext, Memory}, memory::{LAddress, LVar}, }; use std::{fmt, io::Write as Wr}; #[derive(Debug, Copy, Clone)] pub struct Read { pub(crate) index: LAddress, pub(crate) output: LAddress, pub(crate) container: Memory, } impl LInstruction for Read { fn run(&self, exec: &mut ExecutorContext<'_, W>) -> Flow { let i = get_num!(exec.get(self.index)).round() as usize; if let Some(&n) = exec.mem(self.container).get(i) { *exec.get_mut(self.output) = LVar::from(n); }; Flow::Continue } } impl Printable for Read { fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { write!( f, "read {} {} {}", info[self.output], self.container, info[self.index] ) } } #[derive(Debug, Copy, Clone)] pub struct Write { pub(crate) index: LAddress, pub(crate) set: LAddress, pub(crate) container: Memory, } impl LInstruction for Write { fn run(&self, exec: &mut ExecutorContext<'_, W>) -> Flow { let i = get_num!(exec.get(self.index)).round() as usize; if let &LVar::Num(b) = exec.get(self.set) { if let Some(a) = exec.mem(self.container).get_mut(i) { *a = b; } } Flow::Continue } } impl Printable for Write { fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { write!( f, "write {} {} {}", info[self.set], self.container, info[self.index] ) } } #[derive(Debug, Copy, Clone)] pub struct Print { pub(crate) val: LAddress, } impl LInstruction for Print { fn run(&self, exec: &mut ExecutorContext<'_, W>) -> Flow { let v = exec.get(self.val).clone(); if let Some(o) = &mut exec.output { match v { LVar::Num(n) => write!(o, "{n}"), LVar::String(s) => write!(o, r#"{s}"#), } .unwrap(); } Flow::Continue } } // haha impl Printable for Print { fn print(&self, info: &DebugInfo<'_>, f: &mut impl fmt::Write) -> fmt::Result { write!(f, "print {}", info[self.val]) } }