Skip to content

Commit 9f0018d

Browse files
committed
Partial reimplementation
1 parent 2b76e80 commit 9f0018d

File tree

1 file changed

+89
-56
lines changed

1 file changed

+89
-56
lines changed

forth/src/lib.rs

Lines changed: 89 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#![feature(try_trait)]
2+
#![allow(dead_code)]
23
use std::{collections::HashMap, option::NoneError};
34
use Command::*;
45
use Operator::*;
@@ -39,6 +40,7 @@ impl From<NoneError> for Error {
3940

4041
#[derive(Default, Debug)]
4142
pub struct Forth {
43+
text: String,
4244
stack: Vec<i32>,
4345
words: HashMap<String, String>,
4446
}
@@ -51,38 +53,38 @@ impl Forth {
5153
self.stack.clone()
5254
}
5355

54-
fn filter_words(input: &str) -> String {
55-
input.chars().fold(String::new(), |acc, chr| {
56+
fn filter_words(&mut self) {
57+
let filtered = self.text.chars().fold(String::new(), |acc, chr| {
5658
if chr.is_whitespace() || chr.is_control() {
5759
acc + &' '.to_string()
5860
} else {
5961
acc + &chr.to_string()
6062
}
61-
})
63+
});
64+
self.text = filtered;
6265
}
6366

64-
pub fn eval<'a>(&'a mut self, input: &'a str) -> ForthResult {
65-
let mut input = Self::filter_words(input);
66-
while !input.is_empty() {
67-
input = self.eval_digits(&input);
68-
input = self.eval_operators(&input)?.to_string();
69-
input = self.eval_word_declarations(input)?;
70-
input = self.eval_word(&input)?;
71-
input = self.eval_commands(input)?;
67+
pub fn eval(&mut self, input: &str) -> ForthResult {
68+
self.text = input.to_string();
69+
self.filter_words();
70+
while !self.text.is_empty() {
71+
self.eval_digits();
72+
self.eval_operators()?;
73+
// input = self.eval_word_declarations(input)?;
74+
// input = self.eval_word(&input)?;
75+
self.eval_commands()?;
7276
}
7377
Ok(())
7478
}
7579

76-
fn eval_digits(&mut self, mut input: &str) -> String {
77-
while let (Some(head), tail) = Self::parse_digit(&input) {
78-
self.stack.push(head);
79-
input = tail;
80+
fn eval_digits(&mut self) {
81+
while let Some(digit) = self.parse_digit() {
82+
self.stack.push(digit);
8083
}
81-
input.to_string()
8284
}
8385

84-
fn eval_operators<'a>(&'a mut self, mut input: &'a str) -> Result<&'a str, Error> {
85-
while let (Some(operator), tail) = Self::parse_operator(&input) {
86+
fn eval_operators<'b>(&'b mut self) -> Result<(), Error> {
87+
while let Some(operator) = self.parse_operator() {
8688
let value2 = self.stack.pop()?;
8789
let value1 = self.stack.pop()?;
8890
match operator {
@@ -96,9 +98,8 @@ impl Forth {
9698
}
9799
Multiply => self.stack.push(value1 * value2),
98100
}
99-
input = tail;
100101
}
101-
Ok(input)
102+
Ok(())
102103
}
103104

104105
fn eval_word_declarations(&mut self, mut input: String) -> Result<String, Error> {
@@ -116,8 +117,8 @@ impl Forth {
116117
Ok(input.to_string())
117118
}
118119

119-
fn eval_commands(&mut self, mut input: String) -> Result<String, Error> {
120-
while let (Some(command), tail) = Self::parse_command(&input)? {
120+
fn eval_commands(&mut self) -> Result<(), Error> {
121+
while let Some(command) = self.parse_command()? {
121122
match command {
122123
Swap => {
123124
let value2 = self.stack.pop()?;
@@ -143,62 +144,94 @@ impl Forth {
143144
self.words.insert(key, value);
144145
}
145146
}
146-
input = tail.to_string();
147147
}
148-
Ok(input)
148+
Ok(())
149149
}
150150

151-
fn parse_digit(input: &str) -> (Option<Value>, &str) {
152-
match input.chars().position(|chr| chr.is_whitespace()) {
151+
fn parse_digit(&mut self) -> Option<Value> {
152+
match self.text.chars().position(|chr| chr.is_whitespace()) {
153153
Some(position) => {
154-
let head = &input[..position];
155-
let tail = &input[position..];
154+
let head = &self.text.clone()[..position];
155+
let tail = &self.text.clone()[position..];
156156
if let Ok(value) = head.parse::<Value>() {
157-
(Some(value), tail.trim_left())
157+
self.text = tail.trim_left().to_string();
158+
Some(value)
158159
} else {
159-
(None, input.trim())
160+
self.text = self.text.trim().to_string();
161+
None
160162
}
161163
}
162-
_ => match input.parse::<Value>() {
163-
Ok(value) => (Some(value), ""),
164-
_ => (None, input),
164+
_ => match self.text.parse::<Value>() {
165+
Ok(value) => {
166+
self.text = "".to_string();
167+
Some(value)
168+
}
169+
_ => None,
165170
},
166171
}
167172
}
168173

169-
fn parse_operator(input: &str) -> (Option<Operator>, &str) {
170-
if input.is_empty() {
171-
return (None, "");
174+
fn parse_operator(&mut self) -> Option<Operator> {
175+
if self.text.is_empty() {
176+
self.text = "".to_string();
177+
return None;
172178
}
173-
let head = &input[..1];
174-
let tail = &input[1..].trim_left();
179+
let text = self.text.clone();
180+
let head = &text[..1];
181+
let tail = &text[1..].trim_left();
175182
match head {
176-
"+" => (Some(Plus), tail),
177-
"-" => (Some(Minus), tail),
178-
"/" => (Some(Divide), tail),
179-
"*" => (Some(Multiply), tail),
180-
_ => (None, input),
183+
"+" => {
184+
self.text = tail.to_string();
185+
Some(Plus)
186+
}
187+
"-" => {
188+
self.text = tail.to_string();
189+
Some(Minus)
190+
}
191+
"/" => {
192+
self.text = tail.to_string();
193+
Some(Divide)
194+
}
195+
"*" => {
196+
self.text = tail.to_string();
197+
Some(Multiply)
198+
}
199+
_ => None,
181200
}
182201
}
183202

184-
fn parse_command(input: &str) -> Result<(Option<Command>, String), Error> {
185-
if input.is_empty() {
186-
return Ok((None, "".to_string()));
203+
fn parse_command(&mut self) -> Result<Option<Command>, Error> {
204+
if self.text.is_empty() {
205+
self.text = "".to_string();
206+
return Ok(None);
187207
}
188-
let (head, tail) = match input.chars().position(|chr| chr.is_whitespace()) {
208+
let text = self.text.clone();
209+
let (head, tail) = match self.text.chars().position(|chr| chr.is_whitespace()) {
189210
Some(position) => {
190-
let head = input[..position].to_lowercase();
191-
let tail = input[position..].trim_left();
211+
let head = text[..position].to_lowercase();
212+
let tail = text[position..].trim_left().to_string();
192213
(head, tail)
193214
}
194-
None => (input.to_string().to_lowercase(), ""),
215+
None => (self.text.to_string().to_lowercase(), "".to_string()),
195216
};
196217
match head.as_str() {
197-
"drop" => Ok((Some(Dropp), tail.to_string())),
198-
"dup" => Ok((Some(Dup), tail.to_string())),
199-
"swap" => Ok((Some(Swap), tail.to_string())),
200-
"over" => Ok((Some(Over), tail.to_string())),
201-
digits if digits.parse::<u32>().is_ok() => Ok((None, "".to_string())),
218+
"drop" => {
219+
self.text = tail;
220+
Ok(Some(Dropp))
221+
}
222+
"dup" => {
223+
self.text = tail;
224+
Ok(Some(Dup))
225+
}
226+
"swap" => {
227+
self.text = tail;
228+
Ok(Some(Swap))
229+
}
230+
"over" => {
231+
self.text = tail;
232+
Ok(Some(Over))
233+
}
234+
digits if digits.parse::<u32>().is_ok() => Ok(None),
202235
_ => Err(Error::UnknownWord),
203236
}
204237
}
@@ -241,7 +274,7 @@ impl Forth {
241274
))
242275
}
243276

244-
fn parse_word<'a>(&self, input: &'a str) -> (Option<String>, &'a str) {
277+
fn parse_word<'b>(&self, input: &'b str) -> (Option<String>, &'b str) {
245278
let (head, tail) = match input.chars().position(|chr| chr.is_whitespace()) {
246279
Some(position) => {
247280
let head = &input[..position];

0 commit comments

Comments
 (0)