Merge branch 'master' into bytecode

This commit is contained in:
Jeremy Wall 2019-11-09 19:42:34 -06:00
commit 7e3e598423
8 changed files with 64 additions and 77 deletions

View File

@ -575,22 +575,27 @@ impl ModuleDef {
} }
pub fn imports_to_absolute(&mut self, base: PathBuf) { pub fn imports_to_absolute(&mut self, base: PathBuf) {
&base;
let rewrite_import = |e: &mut Expression| { let rewrite_import = |e: &mut Expression| {
let main_separator = format!("{}", std::path::MAIN_SEPARATOR); let main_separator = format!("{}", std::path::MAIN_SEPARATOR);
if let Expression::Include(ref mut def) = e { if let Expression::Include(ref mut def) = e {
let path = PathBuf::from( let path = PathBuf::from(&def.path.fragment);
&def.path #[cfg(not(windows))]
.fragment {
.replace("/", &main_separator) if path.is_relative() {
.replace("\\", &main_separator), def.path.fragment = base
); .join(path)
if path.is_relative() { .canonicalize()
def.path.fragment = base .unwrap()
.join(path) .to_string_lossy()
.canonicalize() .to_string();
.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 { if let Expression::Import(ref mut def) = e {
@ -604,13 +609,22 @@ impl ModuleDef {
if path.starts_with(format!("std{}", main_separator)) { if path.starts_with(format!("std{}", main_separator)) {
return; return;
} }
if path.is_relative() { #[cfg(not(windows))]
def.path.fragment = base {
.join(path) if path.is_relative() {
.canonicalize() def.path.fragment = base
.unwrap() .join(path)
.to_string_lossy() .canonicalize()
.to_string(); .unwrap()
.to_string_lossy()
.to_string();
}
}
#[cfg(windows)]
{
if path.is_relative() {
def.path.fragment = base.join(path).to_string_lossy().to_string();
}
} }
} }
}; };

View File

@ -16,9 +16,6 @@ use std::io::Write;
use crate::ast::*; use crate::ast::*;
use crate::parse::CommentMap; 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> pub struct AstPrinter<'a, W>
where where
W: Write, W: Write,

View File

@ -17,6 +17,7 @@ use std::cell::RefCell;
use std::collections::HashMap; use std::collections::HashMap;
use std::convert::TryInto; use std::convert::TryInto;
use std::env; use std::env;
use std::process;
use std::error::Error; use std::error::Error;
use std::fs::File; use std::fs::File;
use std::io::Read; use std::io::Read;
@ -24,13 +25,13 @@ use std::path::PathBuf;
use std::rc::Rc; use std::rc::Rc;
use rustyline; use rustyline;
use rustyline::error::ReadlineError;
use simple_error; use simple_error;
use crate::ast::*; use crate::ast::*;
use crate::error; use crate::error;
use crate::iter::OffsetStrIter; use crate::iter::OffsetStrIter;
use crate::parse::parse; use crate::parse::parse;
use crate::build::opcode::pointer::OpPointer; use crate::build::opcode::pointer::OpPointer;
use crate::build::opcode::translate; use crate::build::opcode::translate;
use crate::build::opcode::translate::PositionMap; use crate::build::opcode::translate::PositionMap;
@ -214,7 +215,7 @@ where
pub fn repl(&mut self, mut editor: rustyline::Editor<()>, config_home: PathBuf) -> BuildResult { pub fn repl(&mut self, mut editor: rustyline::Editor<()>, config_home: PathBuf) -> BuildResult {
// loop // loop
let mut lines = crate::io::StatementAccumulator::new(); 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!("Type '#help' for help.");
println!(""); println!("");
// Initialize VM with an empty OpPointer // Initialize VM with an empty OpPointer
@ -226,7 +227,23 @@ where
); );
loop { loop {
// print prompt // 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; // repl commands are only valid while not accumulating a statement;
let trimmed = line.trim(); let trimmed = line.trim();
if trimmed.starts_with("#") { if trimmed.starts_with("#") {
@ -245,6 +262,8 @@ where
eprintln!("No such binding {}", key); eprintln!("No such binding {}", key);
} }
} }
} else if trimmed.starts_with("#exit") {
process::exit(0);
} else { } else {
eprintln!("Invalid repl command..."); eprintln!("Invalid repl command...");
eprintln!(""); eprintln!("");

View File

@ -16,3 +16,6 @@ Currently supported commands are:
* #del <name> * #del <name>
- deletes a previously created named binding - deletes a previously created named binding
* #exit
- Exits the repl.

View File

@ -24,6 +24,10 @@ impl StatementAccumulator {
Self { acc: Vec::new() } Self { acc: Vec::new() }
} }
pub fn reset(&mut self) {
self.acc = Vec::new();
}
pub fn next_line(&self) -> usize { pub fn next_line(&self) -> usize {
self.acc.len() + 1 self.acc.len() + 1
} }

View File

@ -471,53 +471,6 @@ make_fn!(
) )
); );
//fn select_expression(input: SliceIter<Token>) -> Result<SliceIter<Token>, 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!( make_fn!(
simple_format_args<SliceIter<Token>, FormatArgs>, simple_format_args<SliceIter<Token>, FormatArgs>,
do_each!( do_each!(

View File

@ -61,19 +61,16 @@ fn escapequoted<'a>(input: OffsetStrIter<'a>) -> Result<OffsetStrIter<'a>, Strin
if escape { if escape {
match c as char { match c as char {
'n' => { 'n' => {
eprintln!("Pushing new line onto string");
frag.push('\n'); frag.push('\n');
escape = false; escape = false;
continue; continue;
} }
'r' => { 'r' => {
eprintln!("Pushing carriage return onto string");
frag.push('\r'); frag.push('\r');
escape = false; escape = false;
continue; continue;
} }
't' => { 't' => {
eprintln!("Pushing tab onto string");
frag.push('\t'); frag.push('\t');
escape = false; escape = false;
continue; continue;