summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorIrene Knapp <ireneista@irenes.space>2024-04-07 00:52:49 -0700
committerIrene Knapp <ireneista@irenes.space>2024-04-07 00:52:49 -0700
commit87848a0958a6f625fad9c2821515cc55ce02ea61 (patch)
treee4cc4a6e9cc5509d62d8924f8dc0cb7056394aa3 /src
parent134d8584c1cc5b77f73723912c8423798dac8ddd (diff)
move register-character into a readtable
Change-Id: I41714996c00e960a8137dfe66853547157017138
Diffstat (limited to 'src')
-rw-r--r--src/main.rs59
1 files changed, 33 insertions, 26 deletions
diff --git a/src/main.rs b/src/main.rs
index 0b41389..494a2de 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -118,6 +118,7 @@ fn main() {
       (Mode::Decimal, make_decimal_readtable()),
       (Mode::Str, make_string_readtable()),
       (Mode::CommandNamed, make_command_string_readtable()),
+      (Mode::RegisterChar, make_register_character_readtable()),
     ]),
     wip_str: String::from(""),
     // TODO: I don't think we need a return stack
@@ -540,35 +541,42 @@ fn register_str(c: char, state: &mut RPState) -> Result<(), Exit> {
 }
 
 
-fn register_char(c: char, state: &mut RPState) -> Result<(), Exit> {
-  match (state.reg_command.as_str(), c) {
-    (_, '[') => {
-      state.mode = Mode::RegisterStr;
-      Ok(())
-    }
-    ("s", c) => {
-      if state.stack.is_empty() {
-          return Err(err_msg(format!(
-              "Data underflow attempting to store to register {}", c)));
+fn make_register_character_readtable() -> ReadTable {
+  let mut result = ReadTable::new(move |c, state| {
+    state.mode = Mode::CommandChar;
+
+    match state.reg_command.as_str() {
+      "s" => {
+        if state.stack.is_empty() {
+            return Err(err_msg(format!(
+                "Data underflow attempting to store to register {}", c)));
+        }
+        state.registers.insert(String::from(c), state.stack.pop().unwrap());
+
+        Ok(())
       }
-      state.registers.insert(String::from(c),
-                             state.stack.pop().unwrap());
-      state.mode = Mode::CommandChar;
-      Ok(())
-    }
-    ("l", c) => {
-      if state.registers.contains_key(&String::from(c)) {
+
+      "l" => {
+        if state.registers.contains_key(&String::from(c)) {
           state.stack.push(state.registers[&String::from(c)].clone());
+        }
+
+        Ok(())
+      }
+
+      _ => {
+        Err(err_msg(format!(
+            "Unsupported register command {}", state.reg_command)))
       }
-      state.mode = Mode::CommandChar;
-      Ok(())
-    }
-    _ => {
-      state.mode = Mode::CommandChar;
-      return Err(err_msg(format!(
-          "Unsupported register command {}", state.reg_command)));
     }
-  }
+  });
+
+  result.set_action('[', move |_, state| {
+    state.mode = Mode::RegisterStr;
+    Ok(())
+  });
+
+  result
 }
 
 
@@ -593,7 +601,6 @@ fn eval(input: &str, state: &mut RPState) -> Result<(), Exit> {
     } else {
       match state.mode {
         Mode::CommandChar => command_char(c, state),
-        Mode::RegisterChar => register_char(c, state),
         Mode::RegisterStr => register_str(c, state),
         _ => return Err(err_msg(
             "Mode has neither readtable nor hardcoded case".to_string())),