diff options
| -rw-r--r-- | Cargo.lock | 64 | ||||
| -rw-r--r-- | Cargo.toml | 1 | ||||
| -rw-r--r-- | src/compiler.rs | 5 | ||||
| -rw-r--r-- | src/error.rs | 19 | ||||
| -rw-r--r-- | src/lib.rs | 91 | ||||
| -rw-r--r-- | src/main.rs | 24 | ||||
| -rw-r--r-- | src/vm.rs | 25 |
7 files changed, 86 insertions, 143 deletions
@@ -195,17 +195,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] -name = "getrandom" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9495705279e7140bf035dde1f6e750c162df8b625267cd52cc44e0b156732c8" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] name = "half" version = "1.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -372,12 +361,6 @@ dependencies = [ ] [[package]] -name = "ppv-lite86" -version = "0.2.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" - -[[package]] name = "proc-macro2" version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -396,46 +379,6 @@ dependencies = [ ] [[package]] -name = "rand" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", - "rand_hc", -] - -[[package]] -name = "rand_chacha" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7" -dependencies = [ - "getrandom", -] - -[[package]] -name = "rand_hc" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73" -dependencies = [ - "rand_core", -] - -[[package]] name = "rayon" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -574,7 +517,6 @@ dependencies = [ "criterion", "logos", "owo-colors", - "rand", "sylt_macro", ] @@ -647,12 +589,6 @@ dependencies = [ ] [[package]] -name = "wasi" -version = "0.10.2+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" - -[[package]] name = "wasm-bindgen" version = "0.2.71" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -12,7 +12,6 @@ name = "sylt" [dependencies] logos = "~0.11.4" owo-colors = { git="https://github.com/FredTheDino/owo-colors.git" } -rand = "0.8" sylt_macro = { path = "sylt_macro" } criterion = { version = "0.3", optional = true } diff --git a/src/compiler.rs b/src/compiler.rs index 9ab868f..0754a1e 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -596,8 +596,7 @@ impl Compiler { /// The line of the current token. fn line(&self) -> usize { if self.section().tokens.len() == 0 { - // unreachable!("An error occured without a section."); - 666666 + 0 } else { self.section().tokens[std::cmp::min(self.current_token, self.section().tokens.len() - 1)].1 } @@ -1782,7 +1781,7 @@ impl Compiler { } pub(crate) fn compile(&mut self, name: &str, file: &Path, functions: &[(String, RustFunction)]) -> Result<Prog, Vec<Error>> { - let main = Variable::new("/main/", false, Type::Void); + let main = Variable::new("/preamble", false, Type::Void); let slot = self.define(main).unwrap(); self.frame_mut().stack[slot].read = true; 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,48 +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) } -pub fn run_string(source: &str, print: bool, functions: Vec<(String, RustFunction)>) -> Result<(), Vec<Error>> { - let mut path = std::env::temp_dir(); - path.push(format!("test_{}.sy", rand::random::<u32>())); - std::fs::write(path.clone(), source).expect("Failed to write source to temporary file"); - run(&path, print, 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() { @@ -73,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>; @@ -884,11 +883,11 @@ impl Block { for (i, s) in self.ops.iter().enumerate() { println!("{}{}", if self.line_offsets.contains_key(&i) { - format!("{:5} ", self.line_offsets[&i].red()) + format!("{:5} ", self.line_offsets[&i].blue()) } else { - format!(" {} ", "|".red()) + format!(" {} ", "|".blue()) }, - format!("{:05} {:?}", i.blue(), s) + format!("{:05} {:?}", i.red(), s) ); } println!(); @@ -1001,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..23ababa 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_bytecode = true; + } else if s == "-vv" { + args.print_bytecode = true; + args.print_exec = 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,8 @@ impl VM { error!(self, ErrorKind::ArgumentCount(args.len(), num_args)); } - if self.print_blocks { + #[cfg(debug_assertions)] + if self.print_bytecode { inner.debug_print(); } self.frames.push(Frame { @@ -498,8 +499,8 @@ impl VM { println!("]"); println!("{:5} {:05} {:?}", - self.frame().block.borrow().line(self.frame().ip).red(), - self.frame().ip.blue(), + self.frame().block.borrow().line(self.frame().ip).blue(), + self.frame().ip.red(), self.frame().block.borrow().ops[self.frame().ip]); } @@ -525,13 +526,14 @@ 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 { + #[cfg(debug_assertions)] + if self.print_exec { self.print_stack() } @@ -835,7 +837,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 +849,8 @@ impl VM { break; } - if self.print_ops { + #[cfg(debug_assertions)] + if self.print_exec { self.print_stack() } |
