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
|
//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)
|
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),
|
Some(ref x) => println!("Bad parsing debug option: {}", x),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
ast.map_err(|error: parsing::ParseError| {
|
ast.map_err(|err| format_parse_error(err, handle))
|
||||||
let location_frag = match error.token {
|
}
|
||||||
Some(tok) => format!(" at line: {} column: {}", tok.offset.0, tok.offset.1),
|
|
||||||
None => "".into()
|
fn format_parse_error(error: parsing::ParseError, handle: &mut Schala) -> String {
|
||||||
};
|
//TODO make token no longer be Optoinal
|
||||||
format!("'{}'{}", error.msg, location_frag)
|
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> {
|
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 {
|
struct SourceReference {
|
||||||
|
lines: Option<Vec<String>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SourceReference {
|
impl SourceReference {
|
||||||
fn new() -> 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