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.rs90
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])
+ }
+}