summaryrefslogtreecommitdiffstats
path: root/src/forth/compiler.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/forth/compiler.rs')
-rw-r--r--src/forth/compiler.rs88
1 files changed, 56 insertions, 32 deletions
diff --git a/src/forth/compiler.rs b/src/forth/compiler.rs
index e8aaa7f..b518b7e 100644
--- a/src/forth/compiler.rs
+++ b/src/forth/compiler.rs
@@ -82,12 +82,11 @@ impl<'a> Compiler<'a> {
// pull the next, whitespace-delimited word off the input stream.
fn next_word(&mut self) -> Option<(&'a str, usize, usize)> {
- let (start, _c) =
- self.enumerator.by_ref()
- .find(|(_i, c)| !c.is_whitespace())?;
- let (end, _c) =
- self.enumerator.by_ref()
- .find(|(_i, c)| c.is_whitespace())?;
+ let (start, _c) = self
+ .enumerator
+ .by_ref()
+ .find(|(_i, c)| !c.is_whitespace())?;
+ let (end, _c) = self.enumerator.by_ref().find(|(_i, c)| c.is_whitespace())?;
let word = &self.text[start..end];
Some((word, start, end))
}
@@ -126,7 +125,7 @@ impl<'a> Compiler<'a> {
let k = *i;
self.bc_mut().0.pop();
self.bc_mut().0.push(OpCode::TCall(k));
- },
+ }
Some(OpCode::If(t, f)) => {
let t = *t;
let f = *f;
@@ -134,7 +133,7 @@ impl<'a> Compiler<'a> {
self.bc_mut().0.push(OpCode::TIf(t, f));
// technically only needed if ‘f’ is None, but whatever.
//self.bc_push(OpCode::Ret, anno);
- },
+ }
_ => self.bc_push(OpCode::Ret, anno),
}
}
@@ -149,33 +148,33 @@ impl<'a> Compiler<'a> {
} else {
match word {
r#"s""# => {
- let (s_end, _) =
- self.enumerator
- .find(|(_i, c)| *c == '"')
- .ok_or(CompileError::MissingQuote)?;
- self.bc_push(OpCode::Str(end+1, s_end), anno);
- },
+ let (s_end, _) = self
+ .enumerator
+ .find(|(_i, c)| *c == '"')
+ .ok_or(CompileError::MissingQuote)?;
+ self.bc_push(OpCode::Str(end + 1, s_end), anno);
+ }
"(" => {
self.enumerator
.find(|(_i, c)| *c == ')')
.ok_or(CompileError::MissingParen)?;
- },
+ }
"\\" => {
self.enumerator
.find(|(_i, c)| *c == '\n')
.ok_or(CompileError::EOF)?;
- },
+ }
":" => {
let (name, _, _) = self.next_word().ok_or(CompileError::EOF)?;
self.wordalog.0.insert(name, self.wordlist.0.len());
self.defstack.push(self.wordlist.0.len());
self.wordlist.0.push(ByteCode(vec![]));
self.annotations.push(vec![]);
- },
+ }
";" => {
self.sub_tcall(anno);
self.defstack.pop().ok_or(CompileError::DefStackEmpty)?;
- },
+ }
"if" => {
let i = self.wordlist.0.len();
self.wordlist.0.push(ByteCode(vec![]));
@@ -183,7 +182,7 @@ impl<'a> Compiler<'a> {
self.defstack.push(i);
self.if_stack.push((IfClauses::True(i), anno));
- },
+ }
"else" => {
self.sub_tcall(anno);
self.defstack.pop();
@@ -195,11 +194,14 @@ impl<'a> Compiler<'a> {
let (true_clause, anno) = match self.if_stack.pop() {
None => return Err(CompileError::MissingIf),
- Some((IfClauses::TrueFalse(_, _), _)) => return Err(CompileError::MissingIf),
+ Some((IfClauses::TrueFalse(_, _), _)) => {
+ return Err(CompileError::MissingIf);
+ }
Some((IfClauses::True(cl), anno)) => (cl, anno),
};
- self.if_stack.push((IfClauses::TrueFalse(true_clause, i), anno));
- },
+ self.if_stack
+ .push((IfClauses::TrueFalse(true_clause, i), anno));
+ }
"then" => {
self.sub_tcall(anno);
self.defstack.pop();
@@ -208,12 +210,12 @@ impl<'a> Compiler<'a> {
None => return Err(CompileError::MissingIf),
Some((IfClauses::True(true_clause), anno)) => {
self.bc_push(OpCode::If(true_clause, None), anno);
- },
+ }
Some((IfClauses::TrueFalse(true_clause, false_clause), anno)) => {
self.bc_push(OpCode::If(true_clause, Some(false_clause)), anno);
}
}
- },
+ }
"+" => self.bc_push(OpCode::Add, anno),
"-" => self.bc_push(OpCode::Sub, anno),
"*" => self.bc_push(OpCode::Mul, anno),
@@ -237,8 +239,8 @@ impl<'a> Compiler<'a> {
#[cfg(test)]
mod tests {
- use super::*;
use super::super::vm::OpCode;
+ use super::*;
fn compiler_for(text: &str) -> Compiler {
let mut p = Compiler::new(text);
@@ -298,7 +300,11 @@ mod tests {
fn def_word() {
let comp = compiler_for(": add2 2 + ; 3 add2\n");
let main = &comp.wordlist.0[0];
- let add2_index = comp.wordalog.0.get("add2").expect("add2 has entry in wordlist");
+ let add2_index = comp
+ .wordalog
+ .0
+ .get("add2")
+ .expect("add2 has entry in wordlist");
assert_eq!(main, vec![OpCode::Num(3), OpCode::Call(*add2_index)]);
let add2 = &comp.wordlist.0[*add2_index];
@@ -313,7 +319,10 @@ mod tests {
let main = &comp.wordlist.0[0];
assert_eq!(main, vec![OpCode::If(1, None)]);
let tr = &comp.wordlist.0[1];
- assert_eq!(tr, vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]);
+ assert_eq!(
+ tr,
+ vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]
+ );
}
#[test]
@@ -326,9 +335,15 @@ mod tests {
assert_eq!(main[0], OpCode::If(1, Some(2)));
assert_eq!(main, vec![OpCode::If(1, Some(2))]);
let tr = &comp.wordlist.0[1];
- assert_eq!(tr, vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]);
+ assert_eq!(
+ tr,
+ vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]
+ );
let fl = &comp.wordlist.0[2];
- assert_eq!(fl, vec![OpCode::Num(1), OpCode::Num(2), OpCode::Sub, OpCode::Ret]);
+ assert_eq!(
+ fl,
+ vec![OpCode::Num(1), OpCode::Num(2), OpCode::Sub, OpCode::Ret]
+ );
}
#[test]
@@ -354,7 +369,10 @@ mod tests {
let t = &comp.wordlist.0[1];
assert_eq!(t, vec![OpCode::TIf(2, None)]);
let tr = &comp.wordlist.0[2];
- assert_eq!(tr, vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]);
+ assert_eq!(
+ tr,
+ vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]
+ );
}
#[test]
@@ -367,9 +385,15 @@ mod tests {
let t = &comp.wordlist.0[1];
assert_eq!(t, vec![OpCode::TIf(2, Some(3))]);
let tr = &comp.wordlist.0[2];
- assert_eq!(tr, vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]);
+ assert_eq!(
+ tr,
+ vec![OpCode::Num(1), OpCode::Num(2), OpCode::Add, OpCode::Ret]
+ );
let fl = &comp.wordlist.0[3];
- assert_eq!(fl, vec![OpCode::Num(1), OpCode::Num(2), OpCode::Sub, OpCode::Ret]);
+ assert_eq!(
+ fl,
+ vec![OpCode::Num(1), OpCode::Num(2), OpCode::Sub, OpCode::Ret]
+ );
}
#[test]