Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'lemu/src/instructions/io.rs')
| -rw-r--r-- | lemu/src/instructions/io.rs | 90 |
1 files changed, 90 insertions, 0 deletions
diff --git a/lemu/src/instructions/io.rs b/lemu/src/instructions/io.rs new file mode 100644 index 0000000..22d1b52 --- /dev/null +++ b/lemu/src/instructions/io.rs @@ -0,0 +1,90 @@ +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<W: Wr>(&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<W: Wr>(&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<W: Wr>(&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]) + } +} |