summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/main.rs76
1 files changed, 50 insertions, 26 deletions
diff --git a/src/main.rs b/src/main.rs
index 494a2de..2e6e9ea 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -119,6 +119,7 @@ fn main() {
       (Mode::Str, make_string_readtable()),
       (Mode::CommandNamed, make_command_string_readtable()),
       (Mode::RegisterChar, make_register_character_readtable()),
+      (Mode::RegisterStr, make_register_string_readtable()),
     ]),
     wip_str: String::from(""),
     // TODO: I don't think we need a return stack
@@ -508,36 +509,60 @@ fn make_string_readtable() -> ReadTable {
 }
 
 
-fn register_str(c: char, state: &mut RPState) -> Result<(), Exit> {
-  match (c, state.reg_command.as_str()) {
-    (']', "l")  => {
-      if state.registers.contains_key(&state.wip_str) {
-        state.stack.push(state.registers[&state.wip_str].clone());
+fn make_register_string_readtable() -> ReadTable {
+  let mut result = ReadTable::new(move |c, state| {
+    match state.reg_command.as_str() {
+      "l" | "s" => {
+        state.wip_str.push(c);
+
+        Ok(())
       }
-      state.wip_str.clear();
-      state.mode = Mode::CommandChar;
-    }
-    (']', "s")  => {
-      if state.stack.is_empty() {
-        return Err(err_msg(format!(
-            "Data underflow attempting to store to register {}", c)));
+
+      _ => {
+        state.mode = Mode::CommandChar;
+
+        Err(err_msg(format!(
+            "Unsupported register command {}", state.reg_command)))
       }
-      state.registers.insert(state.wip_str.clone(),
-                             state.stack.pop().unwrap());
-      state.wip_str.clear();
-      state.mode = Mode::CommandChar;
-    }
-    (_, "l"|"s") => {
-      state.wip_str.push(c)
     }
-    _ => {
-      state.mode = Mode::CommandChar;
-      return Err(err_msg(format!(
-          "Unsupported register command {}", state.reg_command)));
+  });
+
+  result.set_action(']', move |c, state| {
+    state.mode = Mode::CommandChar;
+
+    match state.reg_command.as_str() {
+      "l"  => {
+        if state.registers.contains_key(&state.wip_str) {
+          state.stack.push(state.registers[&state.wip_str].clone());
+        }
+
+        state.wip_str.clear();
+
+        Ok(())
+      }
+
+      "s"  => {
+        if state.stack.is_empty() {
+          return Err(err_msg(format!(
+              "Data underflow attempting to store to register {}", c)));
+        }
+        state.registers.insert(state.wip_str.clone(),
+                               state.stack.pop().unwrap());
+
+        state.wip_str.clear();
+
+        Ok(())
+      }
+
+      _ => {
+
+        Err(err_msg(format!(
+            "Unsupported register command {}", state.reg_command)))
+      }
     }
-  }
+  });
 
-  Ok(())
+  result
 }
 
 
@@ -601,7 +626,6 @@ fn eval(input: &str, state: &mut RPState) -> Result<(), Exit> {
     } else {
       match state.mode {
         Mode::CommandChar => command_char(c, state),
-        Mode::RegisterStr => register_str(c, state),
         _ => return Err(err_msg(
             "Mode has neither readtable nor hardcoded case".to_string())),
       }?;