diff options
| author | Gustav Sörnäs <gustav@sornas.net> | 2021-03-10 18:02:16 +0100 |
|---|---|---|
| committer | Gustav Sörnäs <gustav@sornas.net> | 2021-03-10 18:02:16 +0100 |
| commit | 62147f625e2a51a405c1c7ea5ca2ef4d96b8e7f6 (patch) | |
| tree | 7098a1f54e44603705c376fd24ec5c186738c4fe | |
| parent | f671ecc40626e9fbac452981a87636b6f00d7e15 (diff) | |
| download | sylt-62147f625e2a51a405c1c7ea5ca2ef4d96b8e7f6.tar.gz | |
rework run_file
| -rw-r--r-- | src/error.rs | 19 | ||||
| -rw-r--r-- | src/lib.rs | 78 | ||||
| -rw-r--r-- | src/main.rs | 24 | ||||
| -rw-r--r-- | src/vm.rs | 18 |
4 files changed, 76 insertions, 63 deletions
diff --git a/src/error.rs b/src/error.rs index 9aca985..f967685 100644 --- a/src/error.rs +++ b/src/error.rs @@ -34,6 +34,9 @@ pub enum ErrorKind { SyntaxError(usize, Token), /// (start, end) GitConflictError(usize, usize), + + FileNotFound(PathBuf), + NoFileGiven, } #[derive(Debug, Clone)] @@ -54,10 +57,10 @@ impl fmt::Display for ErrorKind { write!(f, "Cannot apply {:?} to types {}", op, types) } ErrorKind::TypeMismatch(a, b) => { - write!(f, "Expected '{:?}' and got '{:?}'.", a, b) + write!(f, "Expected '{:?}' and got '{:?}'", a, b) } ErrorKind::CannotInfer(a, b) => { - write!(f, "Failed to infer type '{:?}' from '{:?}'.", a, b) + write!(f, "Failed to infer type '{:?}' from '{:?}'", a, b) } ErrorKind::ArgumentType(a, b) => { let expected = a @@ -70,7 +73,7 @@ impl fmt::Display for ErrorKind { expected, given) } ErrorKind::IndexError(value, slot) => { - write!(f, "Cannot index value '{:?}' with type '{:?}'.", value, slot) + write!(f, "Cannot index value '{:?}' with type '{:?}'", value, slot) } ErrorKind::ExternTypeMismatch(name, types) => { write!(f, "Extern function '{}' doesn't accept argument(s) with type(s) {:?}", @@ -86,7 +89,7 @@ impl fmt::Display for ErrorKind { write!(f, "Cannot find field '{}' on {:?}", field, obj) } ErrorKind::ArgumentCount(expected, given) => { - write!(f, "Incorrect argument count, expected {} but got {}.", + write!(f, "Incorrect argument count, expected {} but got {}", expected, given) } ErrorKind::IndexOutOfBounds(value, len, slot) => { @@ -100,7 +103,7 @@ impl fmt::Display for ErrorKind { write!(f, "{}", "[!!] Invalid program [!!]".bold()) } ErrorKind::Unreachable => { - write!(f, "Reached unreachable code.") + write!(f, "Reached unreachable code") } ErrorKind::SyntaxError(line, token) => { write!(f, "Syntax Error on line {} at token {:?}", line, token) @@ -109,6 +112,12 @@ impl fmt::Display for ErrorKind { write!(f, "Git conflict markers found between lines {} and {}", start_line, end_line) } + ErrorKind::FileNotFound(path) => { + write!(f, "File '{}' not found", path.display()) + } + ErrorKind::NoFileGiven => { + write!(f, "No file to run") + } } } } @@ -19,41 +19,31 @@ mod compiler; mod sectionizer; mod tokenizer; -/// Compiles a file and links the supplied functions as callable external -/// functions. Use this if you want your programs to be able to yield. -pub fn compile_file( - path: &Path, - print: bool, - functions: Vec<(String, RustFunction)> -) -> Result<vm::VM, Vec<Error>> { - let sections = sectionizer::sectionize(path); - match compiler::Compiler::new(sections).compile("main", path, &functions) { - Ok(prog) => { - let mut vm = vm::VM::new(); - vm.print_blocks = print; - vm.print_ops = print; - vm.typecheck(&prog)?; - vm.init(&prog); - Ok(vm) - } - Err(errors) => Err(errors), - } -} - /// Compiles, links and runs the given file. Supplied functions are callable /// external functions. If you want your program to be able to yield, use /// [compile_file]. -pub fn run_file(path: &Path, print: bool, functions: Vec<(String, RustFunction)>) -> Result<(), Vec<Error>> { - run(path, print, functions) +pub fn run_file(args: Args, functions: Vec<(String, RustFunction)>) -> Result<(), Vec<Error>> { + run(args, functions) } -fn run(path: &Path, print: bool, functions: Vec<(String, RustFunction)>) -> Result<(), Vec<Error>> { - let sections = sectionizer::sectionize(path); - match compiler::Compiler::new(sections).compile("main", path, &functions) { +fn run(args: Args, functions: Vec<(String, RustFunction)>) -> Result<(), Vec<Error>> { + let path = match args.file { + Some(file) => file, + None => { + return Err(vec![Error { + kind: ErrorKind::NoFileGiven, + file: PathBuf::from(""), + line: 0, + message: None, + }]); + } + }; + let sections = sectionizer::sectionize(&path); + match compiler::Compiler::new(sections).compile("/preamble", &path, &functions) { Ok(prog) => { let mut vm = vm::VM::new(); - vm.print_blocks = print; - vm.print_ops = print; + vm.print_bytecode = args.print_bytecode; + vm.print_exec = args.print_exec; vm.typecheck(&prog)?; vm.init(&prog); if let Err(e) = vm.run() { @@ -66,6 +56,22 @@ fn run(path: &Path, print: bool, functions: Vec<(String, RustFunction)>) -> Resu } } +pub struct Args { + pub file: Option<PathBuf>, + pub print_exec: bool, + pub print_bytecode: bool, +} + +impl Default for Args { + fn default() -> Self { + Self { + file: None, + print_exec: false, + print_bytecode: false, + } + } +} + /// A linkable external function. Created either manually or using /// [sylt_macro::extern_function]. pub type RustFunction = fn(&[Value], bool) -> Result<Value, ErrorKind>; @@ -994,19 +1000,23 @@ mod tests { ($fn:ident, $path:literal, $print:expr) => { #[test] fn $fn() { - let file = std::path::Path::new($path); - crate::run_file(&file, $print, Vec::new()).unwrap(); + let mut args = $crate::Args::default(); + args.file = Some(std::path::PathBuf::from($path)); + args.print_bytecode = $print; + $crate::run_file(args, Vec::new()).unwrap(); } }; ($fn:ident, $path:literal, $print:expr, $errs:tt) => { #[test] fn $fn() { - use crate::error::ErrorKind; + use $crate::error::ErrorKind; #[allow(unused_imports)] - use crate::Type; + use $crate::Type; - let file = std::path::Path::new($path); - let res = crate::run_file(&file, $print, Vec::new()); + let mut args = $crate::Args::default(); + args.file = Some(std::path::PathBuf::from($path)); + args.print_bytecode = $print; + let res = $crate::run_file(args, Vec::new()); $crate::assert_errs!(res, $errs); } }; diff --git a/src/main.rs b/src/main.rs index 28e4e79..1489fda 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,16 +1,10 @@ -use std::path::{Path, PathBuf}; +use std::path::Path; -use sylt::run_file; - -struct Args { - file: Option<PathBuf>, - print: bool, -} +use sylt::{run_file, Args}; fn main() { let args = parse_args(); - let file = args.file.unwrap_or_else(|| Path::new("progs/tests/simple.sy").to_owned()); - let errs = match run_file(&file, args.print, sylt_macro::link!(extern_test as test)) { + let errs = match run_file(args, sylt_macro::link!(extern_test as test)) { Err(it) => it, _ => return, }; @@ -21,17 +15,17 @@ fn main() { } fn parse_args() -> Args { - let mut args = Args { - file: None, - print: false, - }; + let mut args = Args::default(); 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 if s == "-v" { + args.print_exec = true; + } else if s == "-vv" { + args.print_exec = true; + args.print_bytecode = true; } else { eprintln!("Invalid argument {}.", s); } @@ -60,8 +60,8 @@ pub struct VM { constants: Vec<Value>, strings: Vec<String>, - pub print_blocks: bool, - pub print_ops: bool, + pub print_bytecode: bool, + pub print_exec: bool, runtime: bool, @@ -89,8 +89,8 @@ impl VM { constants: Vec::new(), strings: Vec::new(), - print_blocks: false, - print_ops: false, + print_bytecode: false, + print_exec: false, runtime: false, extern_functions: Vec::new() @@ -437,7 +437,7 @@ impl VM { error!(self, ErrorKind::ArgumentCount(args.len(), num_args)); } - if self.print_blocks { + if self.print_bytecode { inner.debug_print(); } self.frames.push(Frame { @@ -525,13 +525,13 @@ impl VM { /// Simulates the program. pub fn run(&mut self) -> Result<OpResult, Error> { - if self.print_blocks { + if self.print_bytecode { println!("\n [[{}]]\n", "RUNNING".red()); self.frame().block.borrow().debug_print(); } loop { - if self.print_ops { + if self.print_exec { self.print_stack() } @@ -835,7 +835,7 @@ impl VM { ip: 0 }); - if self.print_blocks { + if self.print_bytecode { println!("\n [[{} - {}]]\n", "TYPECHECKING".purple(), self.frame().block.borrow().name); self.frame().block.borrow().debug_print(); } @@ -847,7 +847,7 @@ impl VM { break; } - if self.print_ops { + if self.print_exec { self.print_stack() } |
