diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 1ffd725..32a2483 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -575,22 +575,27 @@ impl ModuleDef { } pub fn imports_to_absolute(&mut self, base: PathBuf) { + &base; let rewrite_import = |e: &mut Expression| { let main_separator = format!("{}", std::path::MAIN_SEPARATOR); if let Expression::Include(ref mut def) = e { - let path = PathBuf::from( - &def.path - .fragment - .replace("/", &main_separator) - .replace("\\", &main_separator), - ); - if path.is_relative() { - def.path.fragment = base - .join(path) - .canonicalize() - .unwrap() - .to_string_lossy() - .to_string(); + let path = PathBuf::from(&def.path.fragment); + #[cfg(not(windows))] + { + if path.is_relative() { + def.path.fragment = base + .join(path) + .canonicalize() + .unwrap() + .to_string_lossy() + .to_string(); + } + } + #[cfg(windows)] + { + if path.is_relative() { + def.path.fragment = base.join(path).to_string_lossy().to_string(); + } } } if let Expression::Import(ref mut def) = e { @@ -604,13 +609,22 @@ impl ModuleDef { if path.starts_with(format!("std{}", main_separator)) { return; } - if path.is_relative() { - def.path.fragment = base - .join(path) - .canonicalize() - .unwrap() - .to_string_lossy() - .to_string(); + #[cfg(not(windows))] + { + if path.is_relative() { + def.path.fragment = base + .join(path) + .canonicalize() + .unwrap() + .to_string_lossy() + .to_string(); + } + } + #[cfg(windows)] + { + if path.is_relative() { + def.path.fragment = base.join(path).to_string_lossy().to_string(); + } } } }; diff --git a/src/ast/printer/mod.rs b/src/ast/printer/mod.rs index 03aba29..ccac6be 100644 --- a/src/ast/printer/mod.rs +++ b/src/ast/printer/mod.rs @@ -16,9 +16,6 @@ use std::io::Write; use crate::ast::*; use crate::parse::CommentMap; -// TODO(jwall): We really need a way to preserve comments for these. -// Perhaps for code formatting we actually want to work on the token stream instead? - pub struct AstPrinter<'a, W> where W: Write, diff --git a/src/build/compile_test.rs b/src/build/compile_test.rs index c71d09d..2cbfc25 100644 --- a/src/build/compile_test.rs +++ b/src/build/compile_test.rs @@ -575,4 +575,4 @@ fn test_bad_import_path_compile_failure() { Regex::new(r"line: 1 column: 18").unwrap(), ], ) -} +} \ No newline at end of file diff --git a/src/build/mod.rs b/src/build/mod.rs index ac522b7..f71f3c4 100644 --- a/src/build/mod.rs +++ b/src/build/mod.rs @@ -17,6 +17,7 @@ use std::cell::RefCell; use std::collections::HashMap; use std::convert::TryInto; use std::env; +use std::process; use std::error::Error; use std::fs::File; use std::io::Read; @@ -24,13 +25,13 @@ use std::path::PathBuf; use std::rc::Rc; use rustyline; +use rustyline::error::ReadlineError; use simple_error; use crate::ast::*; use crate::error; use crate::iter::OffsetStrIter; use crate::parse::parse; - use crate::build::opcode::pointer::OpPointer; use crate::build::opcode::translate; use crate::build::opcode::translate::PositionMap; @@ -214,7 +215,7 @@ where pub fn repl(&mut self, mut editor: rustyline::Editor<()>, config_home: PathBuf) -> BuildResult { // loop let mut lines = crate::io::StatementAccumulator::new(); - println!("Welcome to the UCG repl. Ctrl-D to exit"); + println!("Welcome to the UCG repl. Ctrl-D to exit, Ctrl-C to abort expression."); println!("Type '#help' for help."); println!(""); // Initialize VM with an empty OpPointer @@ -226,7 +227,23 @@ where ); loop { // print prompt - let line = editor.readline(&format!("{}> ", lines.next_line()))?; + let line = match editor.readline(&format!("{}> ", lines.next_line())) { + Ok(l) => l, + Err(e) => { + if let ReadlineError::Eof = e { + eprintln!("Recieved EOF Exiting..."); + process::exit(0); + } + if let ReadlineError::Interrupted = e { + // Reset our lines and start over again + eprintln!("Interrupted!"); + lines.reset(); + continue; + } + eprintln!("Error: {}", e); + process::exit(1); + } + }; // repl commands are only valid while not accumulating a statement; let trimmed = line.trim(); if trimmed.starts_with("#") { @@ -245,6 +262,8 @@ where eprintln!("No such binding {}", key); } } + } else if trimmed.starts_with("#exit") { + process::exit(0); } else { eprintln!("Invalid repl command..."); eprintln!(""); diff --git a/src/help/repl.txt b/src/help/repl.txt index da4ac5f..68ffb67 100644 --- a/src/help/repl.txt +++ b/src/help/repl.txt @@ -15,4 +15,7 @@ Currently supported commands are: * #del - deletes a previously created named binding + +* #exit + - Exits the repl. \ No newline at end of file diff --git a/src/io/mod.rs b/src/io/mod.rs index df38f55..045a6a8 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -24,6 +24,10 @@ impl StatementAccumulator { Self { acc: Vec::new() } } + pub fn reset(&mut self) { + self.acc = Vec::new(); + } + pub fn next_line(&self) -> usize { self.acc.len() + 1 } diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 6fc8585..662fec6 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -471,53 +471,6 @@ make_fn!( ) ); -//fn select_expression(input: SliceIter) -> Result, Expression> { -//let parsed = do_each!(input, -//_ => word!("select"), -//val => do_each!( -//expr => wrap_err!( -//trace_parse!(must!(expression)), -//"Did you forget a comma after your selector value?"), -//_ => must!(punct!(",")), -//(expr) -//), -//default_and_map => either!( -//do_each!( -//default => do_each!( -//expr => trace_parse!(expression), -//_ => punct!(","), -//(expr) -//), -//map => trace_parse!(must!(tuple)), -//(Some(default), map) -//), -//do_each!( -//map => wrap_err!( -//trace_parse!(must!(tuple)), -//"Did you forget a comma after your default value?" -//), -//(None, map) -//) -//), -//(val, default_and_map.0, default_and_map.1) -//); -//match parsed { -//Result::Abort(e) => Result::Abort(e), -//Result::Fail(e) => Result::Fail(e), -//Result::Incomplete(offset) => Result::Incomplete(offset), -//Result::Complete(rest, (val, default, map)) => { -//match tuple_to_select(input.clone(), val, default, map) { -//Ok(expr) => Result::Complete(rest, expr), -//Err(e) => Result::Fail(Error::caused_by( -//"Invalid Select Expression", -//Box::new(e), -//Box::new(rest.clone()), -//)), -//} -//} -//} -//} - make_fn!( simple_format_args, FormatArgs>, do_each!( diff --git a/src/tokenizer/mod.rs b/src/tokenizer/mod.rs index f3c178a..0b5fc5b 100644 --- a/src/tokenizer/mod.rs +++ b/src/tokenizer/mod.rs @@ -61,19 +61,16 @@ fn escapequoted<'a>(input: OffsetStrIter<'a>) -> Result, Strin if escape { match c as char { 'n' => { - eprintln!("Pushing new line onto string"); frag.push('\n'); escape = false; continue; } 'r' => { - eprintln!("Pushing carriage return onto string"); frag.push('\r'); escape = false; continue; } 't' => { - eprintln!("Pushing tab onto string"); frag.push('\t'); escape = false; continue;