aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGustav Sörnäs <gustav@sornas.net>2021-03-10 18:02:16 +0100
committerGustav Sörnäs <gustav@sornas.net>2021-03-10 18:02:16 +0100
commit62147f625e2a51a405c1c7ea5ca2ef4d96b8e7f6 (patch)
tree7098a1f54e44603705c376fd24ec5c186738c4fe /src
parentf671ecc40626e9fbac452981a87636b6f00d7e15 (diff)
downloadsylt-62147f625e2a51a405c1c7ea5ca2ef4d96b8e7f6.tar.gz
rework run_file
Diffstat (limited to 'src')
-rw-r--r--src/error.rs19
-rw-r--r--src/lib.rs78
-rw-r--r--src/main.rs24
-rw-r--r--src/vm.rs18
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")
+ }
}
}
}
diff --git a/src/lib.rs b/src/lib.rs
index e1c6ad5..e88941e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);
}
diff --git a/src/vm.rs b/src/vm.rs
index c5e2d68..792dc36 100644
--- a/src/vm.rs
+++ b/src/vm.rs
@@ -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()
}