diff options
| author | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-14 20:18:23 +0100 |
|---|---|---|
| committer | Edvard Thörnros <edvard.thornros@gmail.com> | 2021-01-14 20:18:23 +0100 |
| commit | 4e6071aee97a26610aeee423d830a695b8c4d563 (patch) | |
| tree | 0ec3ab88f6ca93e473ee48e7b0c2d5330162e021 | |
| parent | de04d2f40c4bcfdbb041551ca7bc1f87e81eefbf (diff) | |
| download | sylt-4e6071aee97a26610aeee423d830a695b8c4d563.tar.gz | |
Pass printing as an argument
| -rw-r--r-- | src/lib.rs | 19 | ||||
| -rw-r--r-- | src/main.rs | 29 | ||||
| -rw-r--r-- | src/vm.rs | 48 |
3 files changed, 65 insertions, 31 deletions
@@ -10,17 +10,20 @@ mod error; use error::Error; use tokenizer::TokenStream; -pub fn run_file(path: &Path) -> Result<(), Vec<Error>> { - run(tokenizer::file_to_tokens(path), path) +pub fn run_file(path: &Path, print: bool) -> Result<(), Vec<Error>> { + run(tokenizer::file_to_tokens(path), path, print) } -pub fn run_string(s: &str) -> Result<(), Vec<Error>> { - run(tokenizer::string_to_tokens(s), Path::new("builtin")) +pub fn run_string(s: &str, print: bool) -> Result<(), Vec<Error>> { + run(tokenizer::string_to_tokens(s), Path::new("builtin"), print) } -pub fn run(tokens: TokenStream, path: &Path) -> Result<(), Vec<Error>> { +pub fn run(tokens: TokenStream, path: &Path, print: bool) -> Result<(), Vec<Error>> { match compiler::compile("main", path, tokens) { - Ok(block) => vm::run_block(Rc::new(block)).or_else(|e| Err(vec![e])), + Ok(block) => + vm::VM::new().print_blocks(print) + .print_ops(print) + .run(Rc::new(block)).or_else(|e| Err(vec![e])), Err(errors) => Err(errors), } } @@ -49,7 +52,7 @@ mod tests { #[test] fn unreachable_token() { - assert_errs!(run_string("<!>\n"), [ErrorKind::Unreachable]); + assert_errs!(run_string("<!>\n", true), [ErrorKind::Unreachable]); } macro_rules! test_file { @@ -57,7 +60,7 @@ mod tests { #[test] fn $fn() { let file = Path::new($path); - assert!(run_file(&file).is_ok()); + assert!(run_file(&file, true).is_ok()); } }; } diff --git a/src/main.rs b/src/main.rs index ab5f4a0..d5cb465 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,15 @@ use std::path::{Path, PathBuf}; use tihdy::run_file; +struct Args { + file: Option<PathBuf>, + print: bool, +} + fn main() { - let file = file_from_args().unwrap_or_else(|| Path::new("tests/simple.tdy").to_owned()); - if let Err(errs) = run_file(&file) { + let args = parse_args(); + let file = args.file.unwrap_or_else(|| Path::new("tests/simple.tdy").to_owned()); + if let Err(errs) = run_file(&file, args.print) { for err in errs.iter() { println!("{}", err); } @@ -12,6 +18,21 @@ fn main() { } } -fn file_from_args() -> Option<PathBuf> { - std::env::args().skip(1).map(|s| Path::new(&s).to_owned()).find(|p| p.is_file()) +fn parse_args() -> Args { + let mut args = Args { + file: None, + print: false, + }; + + for s in std::env::args().skip(1) { + let path = Path::new(&s).to_owned(); + if path.is_file() { + args.file = Some(path); + } else if "-p" == s { + args.print = true; + } else { + eprintln!("Invalid argument {}.", s); + } + }; + args } @@ -155,22 +155,30 @@ struct Frame { pub struct VM { stack: Vec<Value>, frames: Vec<Frame>, + print_blocks: bool, + print_ops: bool, } -pub fn run_block(block: Rc<Block>) -> Result<(), Error> { - let mut vm = VM { - stack: Vec::new(), - frames: vec![Frame { - stack_offset: 0, - block, - ip: 0 - }], - }; +impl VM { + pub fn new() -> Self { + Self { + stack: Vec::new(), + frames: Vec::new(), + print_blocks: false, + print_ops: false, + } + } - vm.run() -} + pub fn print_blocks(mut self, b: bool) -> Self { + self.print_blocks = b; + self + } + + pub fn print_ops(mut self, b: bool) -> Self { + self.print_ops = b; + self + } -impl VM { fn pop_twice(&mut self) -> (Value, Value) { let len = self.stack.len(); let res = (self.stack[len-2].clone(), self.stack[len-1].clone()); @@ -202,17 +210,19 @@ impl VM { } } - pub fn run(&mut self) -> Result<(), Error>{ - //TODO better system so tests dont print - const PRINT_WHILE_RUNNING: bool = true; - const PRINT_BLOCK: bool = true; + pub fn run(&mut self, block: Rc<Block>) -> Result<(), Error>{ + self.frames.push(Frame { + stack_offset: 0, + block, + ip: 0 + }); - if PRINT_BLOCK { + if self.print_blocks { self.frame().block.debug_print(); } loop { - if PRINT_WHILE_RUNNING { + if self.print_ops { let start = self.frame().stack_offset; print!(" {:3} [", start); for (i, s) in self.stack.iter().skip(start).enumerate() { @@ -380,7 +390,7 @@ impl VM { format!("Invalid number of arguments, got {} expected {}.", num_args, arity)); } - if PRINT_BLOCK { + if self.print_blocks { block.debug_print(); } self.frames.push(Frame { |
