mirror of
https://github.com/zaphar/ucg.git
synced 2025-07-22 18:19:54 -04:00
Merge branch 'master' into bytecode
This commit is contained in:
commit
7e3e598423
@ -575,15 +575,13 @@ 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)
|
|
||||||
.replace("\\", &main_separator),
|
|
||||||
);
|
|
||||||
if path.is_relative() {
|
if path.is_relative() {
|
||||||
def.path.fragment = base
|
def.path.fragment = base
|
||||||
.join(path)
|
.join(path)
|
||||||
@ -593,6 +591,13 @@ impl ModuleDef {
|
|||||||
.to_string();
|
.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 {
|
||||||
let path = PathBuf::from(
|
let path = PathBuf::from(
|
||||||
&def.path
|
&def.path
|
||||||
@ -604,6 +609,8 @@ impl ModuleDef {
|
|||||||
if path.starts_with(format!("std{}", main_separator)) {
|
if path.starts_with(format!("std{}", main_separator)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
#[cfg(not(windows))]
|
||||||
|
{
|
||||||
if path.is_relative() {
|
if path.is_relative() {
|
||||||
def.path.fragment = base
|
def.path.fragment = base
|
||||||
.join(path)
|
.join(path)
|
||||||
@ -613,6 +620,13 @@ impl ModuleDef {
|
|||||||
.to_string();
|
.to_string();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[cfg(windows)]
|
||||||
|
{
|
||||||
|
if path.is_relative() {
|
||||||
|
def.path.fragment = base.join(path).to_string_lossy().to_string();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
let mut walker = walk::AstWalker::new().with_expr_handler(&rewrite_import);
|
let mut walker = walk::AstWalker::new().with_expr_handler(&rewrite_import);
|
||||||
for stmt in self.statements.iter_mut() {
|
for stmt in self.statements.iter_mut() {
|
||||||
|
@ -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,
|
||||||
|
@ -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!("");
|
||||||
|
@ -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.
|
||||||
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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!(
|
||||||
|
@ -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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user