diff options
Diffstat (limited to 'src/forth')
| -rw-r--r-- | src/forth/compiler.rs (renamed from src/forth/parser.rs) | 126 | ||||
| -rw-r--r--[-rwxr-xr-x] | src/forth/mod.rs | 24 | ||||
| -rw-r--r-- | src/forth/vm.rs (renamed from src/forth/interp.rs) | 356 |
3 files changed, 253 insertions, 253 deletions
diff --git a/src/forth/parser.rs b/src/forth/compiler.rs index c934c4a..9120506 100644 --- a/src/forth/parser.rs +++ b/src/forth/compiler.rs @@ -1,18 +1,18 @@ -use super::interp::{ByteCode, OpCode, WordList}; +use super::vm::{ByteCode, OpCode, WordList}; use std::collections::HashMap; use std::iter::{Enumerate, Iterator}; use std::str::Chars; #[derive(Debug)] -pub enum ParseError { +pub enum CompileError { EOF, DefStackEmpty, MissingIf, MissingQuote, UnknownWord(String), } -impl std::fmt::Display for ParseError { +impl std::fmt::Display for CompileError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::EOF => write!(f, "premature end-of-file"), @@ -23,9 +23,9 @@ impl std::fmt::Display for ParseError { } } } -impl std::error::Error for ParseError {} +impl std::error::Error for CompileError {} -type ParseResult<T> = Result<T, ParseError>; +type CompileResult<T> = Result<T, CompileError>; // todo: the annotations should be directly tied to the wordlist so // they can't get out of sync. @@ -45,7 +45,7 @@ pub enum IfClauses { } #[derive(Debug)] -pub struct Parser<'a> { +pub struct Compiler<'a> { text: &'a str, enumerator: Enumerate<Chars<'a>>, // list of all word definitions, in the order defined. the main @@ -64,7 +64,7 @@ pub struct Parser<'a> { if_stack: Vec<(IfClauses, Annotation)>, } -impl<'a> Parser<'a> { +impl<'a> Compiler<'a> { pub fn new(text: &'a str) -> Self { let mut wl = vec![]; // main routine is always the first entry. @@ -115,7 +115,7 @@ impl<'a> Parser<'a> { self.anno_mut().push(anno); } - pub fn parse(&mut self) -> ParseResult<()> { + pub fn compile(&mut self) -> CompileResult<()> { while let Some((word, start, end)) = self.next_word() { let anno = Annotation { loc: (start, end) }; if let Ok(i) = word.parse::<i32>() { @@ -128,11 +128,11 @@ impl<'a> Parser<'a> { let (s_end, _) = self.enumerator .find(|(_i, c)| return *c == '"') - .ok_or(ParseError::MissingQuote)?; + .ok_or(CompileError::MissingQuote)?; self.bc_push(OpCode::Str(end+1, s_end), anno); }, ":" => { - let (name, _, _) = self.next_word().ok_or(ParseError::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![])); @@ -155,7 +155,7 @@ impl<'a> Parser<'a> { }, _ => self.bc_push(OpCode::Ret, anno), } - self.defstack.pop().ok_or(ParseError::DefStackEmpty)?; + self.defstack.pop().ok_or(CompileError::DefStackEmpty)?; }, "if" => { let i = self.wordlist.0.len(); @@ -175,8 +175,8 @@ impl<'a> Parser<'a> { self.defstack.push(i); let (true_clause, anno) = match self.if_stack.pop() { - None => return Err(ParseError::MissingIf), - Some((IfClauses::TrueFalse(_, _), _)) => return Err(ParseError::MissingIf), + None => 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)); @@ -186,7 +186,7 @@ impl<'a> Parser<'a> { self.defstack.pop(); match self.if_stack.pop() { - None => return Err(ParseError::MissingIf), + None => return Err(CompileError::MissingIf), Some((IfClauses::True(true_clause), anno)) => { self.bc_push(OpCode::If(true_clause, None), anno); }, @@ -206,7 +206,7 @@ impl<'a> Parser<'a> { ">=" => self.bc_push(OpCode::GTE, anno), "<" => self.bc_push(OpCode::LT, anno), "<=" => self.bc_push(OpCode::LTE, anno), - other => return Err(ParseError::UnknownWord(String::from(other))), + other => return Err(CompileError::UnknownWord(String::from(other))), } } } @@ -217,11 +217,11 @@ impl<'a> Parser<'a> { #[cfg(test)] mod tests { use super::*; - use super::super::interp::OpCode; + use super::super::vm::OpCode; - fn parser_for(text: &str) -> Parser { - let mut p = Parser::new(text); - p.parse().expect("badparse"); + fn compiler_for(text: &str) -> Compiler { + let mut p = Compiler::new(text); + p.compile().expect("badparse"); p } @@ -233,42 +233,42 @@ mod tests { #[test] fn literal_num() { - let p = parser_for("1\n"); - let main = &p.wordlist.0[0]; + let comp = compiler_for("1\n"); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Num(1)); } #[test] fn literal_string() { - let p = parser_for(r#"s" hello there""#); - let main = &p.wordlist.0[0]; + let comp = compiler_for(r#"s" hello there""#); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Str(3, 14)); } #[test] fn add_opcode() { - let p = parser_for("+\n"); - let main = &p.wordlist.0[0]; + let comp = compiler_for("+\n"); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Add); } #[test] fn sub_opcode() { - let p = parser_for("-\n"); - let main = &p.wordlist.0[0]; + let comp = compiler_for("-\n"); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Sub); } #[test] fn def_word() { - let p = parser_for(": add2 2 + ; 3 add2\n"); - let main = &p.wordlist.0[0]; - let add2_index = p.wordalog.0.get("add2").expect("add2 has entry in wordlist"); - let add2 = &p.wordlist.0[*add2_index]; + 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 = &comp.wordlist.0[*add2_index]; assert_eq!(main.len(), 2); assert_eq!(main[0], OpCode::Num(3)); assert_eq!(main[1], OpCode::Call(*add2_index)); @@ -280,13 +280,13 @@ mod tests { #[test] fn if_then() { - let p = parser_for("if 1 2 + then\n"); - eprintwordlist(&p.wordlist); - assert_eq!(p.wordlist.0.len(), 2); - let main = &p.wordlist.0[0]; + let comp = compiler_for("if 1 2 + then\n"); + eprintwordlist(&comp.wordlist); + assert_eq!(comp.wordlist.0.len(), 2); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::If(1, None)); - let tr = &p.wordlist.0[1]; + let tr = &comp.wordlist.0[1]; assert_eq!(tr.len(), 4); assert_eq!(tr[0], OpCode::Num(1)); assert_eq!(tr[1], OpCode::Num(2)); @@ -296,19 +296,19 @@ mod tests { #[test] fn if_else_then() { - let p = parser_for("if 1 2 + else 1 2 - then\n"); - eprintwordlist(&p.wordlist); - assert_eq!(p.wordlist.0.len(), 3, "wordlist length"); - let main = &p.wordlist.0[0]; + let comp = compiler_for("if 1 2 + else 1 2 - then\n"); + eprintwordlist(&comp.wordlist); + assert_eq!(comp.wordlist.0.len(), 3, "wordlist length"); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::If(1, Some(2))); - let tr = &p.wordlist.0[1]; + let tr = &comp.wordlist.0[1]; assert_eq!(tr.len(), 4); assert_eq!(tr[0], OpCode::Num(1)); assert_eq!(tr[1], OpCode::Num(2)); assert_eq!(tr[2], OpCode::Add); assert_eq!(tr[3], OpCode::Ret); - let fl = &p.wordlist.0[2]; + let fl = &comp.wordlist.0[2]; assert_eq!(fl.len(), 4); assert_eq!(fl[0], OpCode::Num(1)); assert_eq!(fl[1], OpCode::Num(2)); @@ -318,24 +318,24 @@ mod tests { #[test] fn tail_call() { - let p = parser_for(": first + ; : second 3 first ; 1 second\n"); - assert_eq!(p.wordlist.0.len(), 3, "wordlist length"); - eprintwordlist(&p.wordlist); + let comp = compiler_for(": first + ; : second 3 first ; 1 second\n"); + assert_eq!(comp.wordlist.0.len(), 3, "wordlist length"); + eprintwordlist(&comp.wordlist); } #[test] fn tail_if() { - let p = parser_for(": t if 1 2 + then ; t\n"); - eprintwordlist(&p.wordlist); - assert_eq!(p.wordlist.0.len(), 3); - let main = &p.wordlist.0[0]; + let comp = compiler_for(": t if 1 2 + then ; t\n"); + eprintwordlist(&comp.wordlist); + assert_eq!(comp.wordlist.0.len(), 3); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Call(1)); - let t = &p.wordlist.0[1]; + let t = &comp.wordlist.0[1]; assert_eq!(t.len(), 2); assert_eq!(t[0], OpCode::TIf(2, None)); assert_eq!(t[1], OpCode::Ret); - let tr = &p.wordlist.0[2]; + let tr = &comp.wordlist.0[2]; assert_eq!(tr.len(), 4); assert_eq!(tr[0], OpCode::Num(1)); assert_eq!(tr[1], OpCode::Num(2)); @@ -345,23 +345,23 @@ mod tests { #[test] fn tail_if_else() { - let p = parser_for(": t if 1 2 + else 1 2 - then ; t\n"); - eprintwordlist(&p.wordlist); - assert_eq!(p.wordlist.0.len(), 4, "wordlist length"); - let main = &p.wordlist.0[0]; + let comp = compiler_for(": t if 1 2 + else 1 2 - then ; t\n"); + eprintwordlist(&comp.wordlist); + assert_eq!(comp.wordlist.0.len(), 4, "wordlist length"); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Call(1)); - let t = &p.wordlist.0[1]; + let t = &comp.wordlist.0[1]; assert_eq!(t.len(), 2); assert_eq!(t[0], OpCode::TIf(2, Some(3))); assert_eq!(t[1], OpCode::Ret); - let tr = &p.wordlist.0[2]; + let tr = &comp.wordlist.0[2]; assert_eq!(tr.len(), 4); assert_eq!(tr[0], OpCode::Num(1)); assert_eq!(tr[1], OpCode::Num(2)); assert_eq!(tr[2], OpCode::Add); assert_eq!(tr[3], OpCode::Ret); - let fl = &p.wordlist.0[3]; + let fl = &comp.wordlist.0[3]; assert_eq!(fl.len(), 4); assert_eq!(fl[0], OpCode::Num(1)); assert_eq!(fl[1], OpCode::Num(2)); @@ -371,13 +371,13 @@ mod tests { #[test] fn recursion() { - let p = parser_for(": foo foo ; foo\n"); - eprintwordlist(&p.wordlist); - assert_eq!(p.wordlist.0.len(), 2); - let main = &p.wordlist.0[0]; + let comp = compiler_for(": foo foo ; foo\n"); + eprintwordlist(&comp.wordlist); + assert_eq!(comp.wordlist.0.len(), 2); + let main = &comp.wordlist.0[0]; assert_eq!(main.len(), 1); assert_eq!(main[0], OpCode::Call(1)); - let foo = &p.wordlist.0[1]; + let foo = &comp.wordlist.0[1]; assert_eq!(foo.len(), 1); assert_eq!(foo[0], OpCode::TCall(1)); } diff --git a/src/forth/mod.rs b/src/forth/mod.rs index 063b40e..f244ef4 100755..100644 --- a/src/forth/mod.rs +++ b/src/forth/mod.rs @@ -1,16 +1,16 @@ -pub mod interp; -pub mod parser; +pub mod compiler; +pub mod vm; #[cfg(test)] mod tests { use super::{ - interp::{Interp, WordList}, - parser::Parser + vm::{VM, WordList}, + compiler::Compiler, }; - fn parser_for(text: &str) -> Parser { - let mut p = Parser::new(text); - p.parse().expect("badparse"); + fn parser_for(text: &str) -> Compiler { + let mut p = Compiler::new(text); + p.compile().expect("badparse"); p } @@ -26,10 +26,10 @@ mod tests { let prog = ": fac dup 1 > if dup 1 - fac * then ; 5 fac\n"; let p = parser_for(prog); eprintwordlist(&p.wordlist); - let mut interp = Interp::new(p.wordlist); - interp.run().expect("should run to completion"); - eprintln!("stack: {:?}", interp.stack); - assert_eq!(interp.stack.0.len(), 1, "factorial result stack len"); - assert_eq!(interp.stack.0[0], 120, "factorial result value"); + let mut vm = VM::new(p.wordlist); + vm.run().expect("should run to completion"); + eprintln!("stack: {:?}", vm.stack); + assert_eq!(vm.stack.0.len(), 1, "factorial result stack len"); + assert_eq!(vm.stack.0[0], 120, "factorial result value"); } } diff --git a/src/forth/interp.rs b/src/forth/vm.rs index 512c022..b4ce674 100644 --- a/src/forth/interp.rs +++ b/src/forth/vm.rs @@ -81,7 +81,7 @@ impl std::ops::Deref for WordList { } #[derive(Debug)] -pub struct Interp { +pub struct VM { // todo: don't be pub, probably pub stack: DataStack, pub callstack: CallStack, @@ -94,7 +94,7 @@ pub enum RuntimeError { StackUnderflow, } -impl Interp { +impl VM { pub fn new(wordlist: WordList) -> Self { Self { stack: DataStack(Vec::new()), @@ -232,22 +232,22 @@ mod tests { fn simple_ticks() -> Result<(), RuntimeError> { let mut wordlist = WordList(vec![]); wordlist.0.push(ByteCode(vec![OpCode::Num(2), OpCode::Num(3), OpCode::Add])); - let mut interp = Interp::new(wordlist); - assert_eq!(interp.tick()?, true, "first arg running"); - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 1); - assert_eq!(interp.stack.0.len(), 1); - assert_eq!(interp.stack.0[0], 2, "first argument"); - assert_eq!(interp.tick()?, true, "second arg running"); - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 2); - assert_eq!(interp.stack.0.len(), 2); - assert_eq!(interp.stack.0[1], 3, "second argument"); - assert_eq!(interp.tick()?, false, "stopped after addition"); - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 3); - assert_eq!(interp.stack.0.len(), 1); - assert_eq!(interp.stack.0[0], 5, "result of addition"); + let mut vm = VM::new(wordlist); + assert_eq!(vm.tick()?, true, "first arg running"); + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 1); + assert_eq!(vm.stack.0.len(), 1); + assert_eq!(vm.stack.0[0], 2, "first argument"); + assert_eq!(vm.tick()?, true, "second arg running"); + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 2); + assert_eq!(vm.stack.0.len(), 2); + assert_eq!(vm.stack.0[1], 3, "second argument"); + assert_eq!(vm.tick()?, false, "stopped after addition"); + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 3); + assert_eq!(vm.stack.0.len(), 1); + assert_eq!(vm.stack.0[0], 5, "result of addition"); Ok(()) } @@ -259,50 +259,50 @@ mod tests { OpCode::Num(2), OpCode::Num(3), OpCode::Call(1), OpCode::Num(-2), OpCode::Add, OpCode::Sub, OpCode::Ret, ])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); // "sub" definition - interp.wordlist.0.push(ByteCode(vec![ + vm.wordlist.0.push(ByteCode(vec![ OpCode::Sub, OpCode::Ret, ])); - interp.tick()?; - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 1); - assert_eq!(interp.stack.0.len(), 1); - assert_eq!(interp.stack.0[0], 2, "first argument"); - interp.tick()?; - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 2); - assert_eq!(interp.stack.0.len(), 2); - assert_eq!(interp.stack.0[1], 3, "second argument"); + vm.tick()?; + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 1); + assert_eq!(vm.stack.0.len(), 1); + assert_eq!(vm.stack.0[0], 2, "first argument"); + vm.tick()?; + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 2); + assert_eq!(vm.stack.0.len(), 2); + assert_eq!(vm.stack.0[1], 3, "second argument"); - interp.tick()?; // call sub - assert_eq!(interp.ip.word, 1); - assert_eq!(interp.ip.offset, 0); - assert_eq!(interp.stack.0.len(), 2); + vm.tick()?; // call sub + assert_eq!(vm.ip.word, 1); + assert_eq!(vm.ip.offset, 0); + assert_eq!(vm.stack.0.len(), 2); - interp.tick()?; // - - assert_eq!(interp.ip.word, 1); - assert_eq!(interp.ip.offset, 1); - assert_eq!(interp.stack.0.len(), 1); + vm.tick()?; // - + assert_eq!(vm.ip.word, 1); + assert_eq!(vm.ip.offset, 1); + assert_eq!(vm.stack.0.len(), 1); - interp.tick()?; // ret - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 3); - assert_eq!(interp.stack.0.len(), 1); - assert_eq!(interp.stack.0[0], -1, "result of sub word"); + vm.tick()?; // ret + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 3); + assert_eq!(vm.stack.0.len(), 1); + assert_eq!(vm.stack.0[0], -1, "result of sub word"); - interp.tick()?; // 2 - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 4); - assert_eq!(interp.stack.0.len(), 2); - assert_eq!(interp.stack.0[1], -2, "post sub arg"); + vm.tick()?; // 2 + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 4); + assert_eq!(vm.stack.0.len(), 2); + assert_eq!(vm.stack.0[1], -2, "post sub arg"); - interp.tick()?; // - - assert_eq!(interp.ip.word, 0); - assert_eq!(interp.ip.offset, 5); - assert_eq!(interp.stack.0.len(), 1); - assert_eq!(interp.stack.0[0], -3, "add opcode result"); + vm.tick()?; // - + assert_eq!(vm.ip.word, 0); + assert_eq!(vm.ip.offset, 5); + assert_eq!(vm.stack.0.len(), 1); + assert_eq!(vm.stack.0[0], -3, "add opcode result"); Ok(()) } @@ -313,14 +313,14 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Call(1)])); wordlist.0.push(ByteCode(vec![OpCode::TCall(2), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; // call - assert_eq!(interp.callstack.0.len(), 1, "callstack after call"); - interp.tick()?; // tcall - assert_eq!(interp.callstack.0.len(), 1, "callstack after tcall"); - interp.tick()?; // ret - assert_eq!(interp.callstack.0.len(), 0, "callstack after ret"); + vm.tick()?; // call + assert_eq!(vm.callstack.0.len(), 1, "callstack after call"); + vm.tick()?; // tcall + assert_eq!(vm.callstack.0.len(), 1, "callstack after tcall"); + vm.tick()?; // ret + assert_eq!(vm.callstack.0.len(), 0, "callstack after ret"); Ok(()) } @@ -329,22 +329,22 @@ mod tests { let mut wordlist = WordList(vec![]); wordlist.0.push(ByteCode(vec![OpCode::Num(-1), OpCode::If(1, None), OpCode::Num(0)])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push -1 stack len"); - assert_eq!(interp.stack.0[0], -1, "push -1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "if stack "); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 1 stack len"); - assert_eq!(interp.stack.0[0], 1, "push 1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "ret stack len"); - assert_eq!(interp.stack.0[0], 1, "ret stack val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 2, "push 0 stack len"); - assert_eq!(interp.stack.0[1], 0, "push 0 stack val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push -1 stack len"); + assert_eq!(vm.stack.0[0], -1, "push -1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "if stack "); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 1 stack len"); + assert_eq!(vm.stack.0[0], 1, "push 1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "ret stack len"); + assert_eq!(vm.stack.0[0], 1, "ret stack val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 2, "push 0 stack len"); + assert_eq!(vm.stack.0[1], 0, "push 0 stack val"); Ok(()) } @@ -354,16 +354,16 @@ mod tests { let mut wordlist = WordList(vec![]); wordlist.0.push(ByteCode(vec![OpCode::Num(0), OpCode::If(1, None), OpCode::Num(-1)])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 0 stack len"); - assert_eq!(interp.stack.0[0], 0, "push 0 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "if stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push -1 stack len"); - assert_eq!(interp.stack.0[0], -1, "push -1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 0 stack len"); + assert_eq!(vm.stack.0[0], 0, "push 0 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "if stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push -1 stack len"); + assert_eq!(vm.stack.0[0], -1, "push -1 val"); Ok(()) } @@ -374,22 +374,22 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Num(-1), OpCode::If(1, Some(2)), OpCode::Num(-2)])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(2), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push -1 stack len"); - assert_eq!(interp.stack.0[0], -1, "push -1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "if stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 1 stack len"); - assert_eq!(interp.stack.0[0], 1, "push 1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "ret stack len"); - assert_eq!(interp.stack.0[0], 1, "ret val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 2, "push -2 stack len"); - assert_eq!(interp.stack.0[1], -2, "push -2 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push -1 stack len"); + assert_eq!(vm.stack.0[0], -1, "push -1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "if stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 1 stack len"); + assert_eq!(vm.stack.0[0], 1, "push 1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "ret stack len"); + assert_eq!(vm.stack.0[0], 1, "ret val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 2, "push -2 stack len"); + assert_eq!(vm.stack.0[1], -2, "push -2 val"); Ok(()) } @@ -400,22 +400,22 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Num(0), OpCode::If(1, Some(2)), OpCode::Num(-2)])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(2), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 0 stack len"); - assert_eq!(interp.stack.0[0], 0, "push 0 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "if"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 2 stack len"); - assert_eq!(interp.stack.0[0], 2, "push 2 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "ret"); - assert_eq!(interp.stack.0[0], 2, "ret"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 2, "push -2 stack len"); - assert_eq!(interp.stack.0[1], -2, "push -2 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 0 stack len"); + assert_eq!(vm.stack.0[0], 0, "push 0 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "if"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 2 stack len"); + assert_eq!(vm.stack.0[0], 2, "push 2 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "ret"); + assert_eq!(vm.stack.0[0], 2, "ret"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 2, "push -2 stack len"); + assert_eq!(vm.stack.0[1], -2, "push -2 val"); Ok(()) } @@ -426,24 +426,24 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Call(1), OpCode::Num(0)])); wordlist.0.push(ByteCode(vec![OpCode::Num(-1), OpCode::TIf(2, None), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "call(1) stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push -1 stack len"); - assert_eq!(interp.stack.0[0], -1, "push -1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "tif stack "); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 1 stack len"); - assert_eq!(interp.stack.0[0], 1, "push 1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "ret stack len"); - assert_eq!(interp.stack.0[0], 1, "ret stack val"); - interp.tick()?; // no ret on wordlist[1] since it's ‘tif’ - assert_eq!(interp.stack.0.len(), 2, "push 0 stack len"); - assert_eq!(interp.stack.0[1], 0, "push 0 stack val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "call(1) stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push -1 stack len"); + assert_eq!(vm.stack.0[0], -1, "push -1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "tif stack "); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 1 stack len"); + assert_eq!(vm.stack.0[0], 1, "push 1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "ret stack len"); + assert_eq!(vm.stack.0[0], 1, "ret stack val"); + vm.tick()?; // no ret on wordlist[1] since it's ‘tif’ + assert_eq!(vm.stack.0.len(), 2, "push 0 stack len"); + assert_eq!(vm.stack.0[1], 0, "push 0 stack val"); Ok(()) } @@ -454,20 +454,20 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Call(1), OpCode::Num(0)])); wordlist.0.push(ByteCode(vec![OpCode::Num(0), OpCode::TIf(2, None), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "call(1) stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 0 stack len"); - assert_eq!(interp.stack.0[0], 0, "push 0 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "tif stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "ret stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 0 stack len"); - assert_eq!(interp.stack.0[0], 0, "push 0 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "call(1) stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 0 stack len"); + assert_eq!(vm.stack.0[0], 0, "push 0 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "tif stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "ret stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 0 stack len"); + assert_eq!(vm.stack.0[0], 0, "push 0 val"); Ok(()) } @@ -479,24 +479,24 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Num(-1), OpCode::TIf(2, Some(3)), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(2), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "call(1) stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push -1 stack len"); - assert_eq!(interp.stack.0[0], -1, "push -1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "tif stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 1 stack len"); - assert_eq!(interp.stack.0[0], 1, "push 1 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "ret stack len"); - assert_eq!(interp.stack.0[0], 1, "ret val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 2, "push -2 stack len"); - assert_eq!(interp.stack.0[1], -2, "push -2 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "call(1) stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push -1 stack len"); + assert_eq!(vm.stack.0[0], -1, "push -1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "tif stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 1 stack len"); + assert_eq!(vm.stack.0[0], 1, "push 1 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "ret stack len"); + assert_eq!(vm.stack.0[0], 1, "ret val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 2, "push -2 stack len"); + assert_eq!(vm.stack.0[1], -2, "push -2 val"); Ok(()) } @@ -508,24 +508,24 @@ mod tests { wordlist.0.push(ByteCode(vec![OpCode::Num(0), OpCode::TIf(2, Some(3)), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(1), OpCode::Ret])); wordlist.0.push(ByteCode(vec![OpCode::Num(2), OpCode::Ret])); - let mut interp = Interp::new(wordlist); + let mut vm = VM::new(wordlist); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "call(1) stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 0 stack len"); - assert_eq!(interp.stack.0[0], 0, "push 0 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 0, "tif stack len"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "push 2 stack len"); - assert_eq!(interp.stack.0[0], 2, "push 2 val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 1, "ret stack len"); - assert_eq!(interp.stack.0[0], 2, "ret val"); - interp.tick()?; - assert_eq!(interp.stack.0.len(), 2, "push -2 stack len"); - assert_eq!(interp.stack.0[1], -2, "push -2 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "call(1) stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 0 stack len"); + assert_eq!(vm.stack.0[0], 0, "push 0 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 0, "tif stack len"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "push 2 stack len"); + assert_eq!(vm.stack.0[0], 2, "push 2 val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 1, "ret stack len"); + assert_eq!(vm.stack.0[0], 2, "ret val"); + vm.tick()?; + assert_eq!(vm.stack.0.len(), 2, "push -2 stack len"); + assert_eq!(vm.stack.0[1], -2, "push -2 val"); Ok(()) } |
