Show location of error in parse error
This commit is contained in:
parent
a0f4abb9a3
commit
fa295aab28
@ -90,7 +90,8 @@ impl Schala {
|
||||
}
|
||||
|
||||
//TODO rejigger the signature of these methods so you don't awkwardly have the input in the middle
|
||||
fn load_source<'a>(_handle: &mut Schala, input: &'a str, comp: Option<&mut UnfinishedComputation>) -> Result<&'a str, String> {
|
||||
fn load_source<'a>(handle: &mut Schala, input: &'a str, _comp: Option<&mut UnfinishedComputation>) -> Result<&'a str, String> {
|
||||
handle.source_reference.load_new_source(input);
|
||||
Ok(input)
|
||||
}
|
||||
|
||||
@ -131,13 +132,25 @@ fn parsing(handle: &mut Schala, input: Vec<tokenizing::Token>, comp: Option<&mut
|
||||
Some(ref x) => println!("Bad parsing debug option: {}", x),
|
||||
};
|
||||
});
|
||||
ast.map_err(|error: parsing::ParseError| {
|
||||
let location_frag = match error.token {
|
||||
Some(tok) => format!(" at line: {} column: {}", tok.offset.0, tok.offset.1),
|
||||
None => "".into()
|
||||
};
|
||||
format!("'{}'{}", error.msg, location_frag)
|
||||
})
|
||||
ast.map_err(|err| format_parse_error(err, handle))
|
||||
}
|
||||
|
||||
fn format_parse_error(error: parsing::ParseError, handle: &mut Schala) -> String {
|
||||
//TODO make token no longer be Optoinal
|
||||
if let Some(tok) = error.token {
|
||||
let line = tok.offset.0;
|
||||
let ch = tok.offset.1;
|
||||
let line_from_program = handle.source_reference.get_line(line);
|
||||
let location_pointer = format!("{}^", " ".repeat(ch));
|
||||
format!(r#"
|
||||
{}
|
||||
|
|
||||
| {}
|
||||
| {}
|
||||
"#, error.msg, line_from_program, location_pointer)
|
||||
} else {
|
||||
format!("{}", error.msg)
|
||||
}
|
||||
}
|
||||
|
||||
fn symbol_table(handle: &mut Schala, input: ast::AST, comp: Option<&mut UnfinishedComputation>) -> Result<ast::AST, String> {
|
||||
@ -183,15 +196,20 @@ fn eval(handle: &mut Schala, input: reduced_ast::ReducedAST, comp: Option<&mut U
|
||||
}
|
||||
|
||||
struct SourceReference {
|
||||
|
||||
lines: Option<Vec<String>>
|
||||
}
|
||||
|
||||
impl SourceReference {
|
||||
fn new() -> SourceReference {
|
||||
SourceReference { }
|
||||
SourceReference { lines: None }
|
||||
}
|
||||
|
||||
fn load_new_source(&mut self, source: String) {
|
||||
fn load_new_source(&mut self, source: &str) {
|
||||
//TODO this is a lot of heap allocations - maybe there's a way to make it more efficient?
|
||||
self.lines = Some(source.lines().map(|s| s.to_string()).collect());
|
||||
}
|
||||
|
||||
fn get_line(&self, line: usize) -> String {
|
||||
self.lines.as_ref().and_then(|x| x.get(line).map(|s| s.to_string())).unwrap_or(format!("NO LINE FOUND"))
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user