Skip to content

Commit

Permalink
Output multiple errors & change diamond operator (#8)
Browse files Browse the repository at this point in the history
Signed-off-by: Andrew Helwer <2n8rn1w1f@mozmail.com>
  • Loading branch information
ahelwer authored Nov 11, 2023
1 parent d73115e commit c6c9170
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 25 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "tlauc"
description = "Rewrites TLA⁺ specs to use Unicode symbols instead of ASCII, and vice-versa"
version = "0.1.5"
version = "0.2.0"
authors = ["Andrew Helwer <2n8rn1w1f@mozmail.com>"]
repository = "https://github.com/tlaplus-community/tlauc"
license = "MIT"
Expand All @@ -17,7 +17,7 @@ clap = { version = "4.0.32", features = ["derive"] }
csv = "1.3.0"
serde = { version = "1.0.192", features = ["derive"] }
tree-sitter = "0.20.10"
tree-sitter-tlaplus = "1.0.4"
tree-sitter-tlaplus = "1.0.6"

[dev-dependencies]
glob = "0.3.0"
Expand Down
2 changes: 1 addition & 1 deletion resources/tla-unicode.csv
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ case_arrow,->,→,U+2192
label_as,::,∷,U+2237
lnot,~;\lnot;\neg,¬,U+00AC
always,[],□,U+25A1
eventually,<>,,U+22C4
eventually,<>,,U+25C7
implies,=>,⇒,U+21D2
plus_arrow,-+->,⇸,U+21F8
equiv,\equiv,≡,U+2261
Expand Down
34 changes: 16 additions & 18 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub enum Mode {
pub enum TlaError {
InputFileParseError {
parse_tree: Tree,
first_error_line: Option<usize>,
error_lines: Vec<usize>,
},
OutputFileParseError {
output_tree: Tree,
Expand All @@ -38,11 +38,10 @@ pub fn rewrite(input: &str, mode: &Mode, force: bool) -> Result<String, TlaError
// Parse input TLA⁺ file and construct data structures to hold information about it
let input_tree = parser.parse(input, None).unwrap();
if !force && input_tree.root_node().has_error() {
let first_error_line =
find_first_error_line(&input_tree).map_or_else(|e| Some(e), |_| None);
let error_lines = find_error_lines(&input_tree);
return Err(TlaError::InputFileParseError {
parse_tree: input_tree,
first_error_line,
error_lines,
});
}

Expand Down Expand Up @@ -81,21 +80,24 @@ pub fn rewrite(input: &str, mode: &Mode, force: bool) -> Result<String, TlaError
Ok(output)
}

fn find_first_error_line(tree: &Tree) -> Result<(), usize> {
fn find_error_lines(tree: &Tree) -> Vec<usize> {
let mut error_lines: Vec<usize> = vec![];
traverse_parse_tree(tree, |n| {
if n.is_error() || n.is_missing() {
Err(n.start_position().row + 1)
} else {
Ok(())
error_lines.push(n.start_position().row + 1);
}
})
});
error_lines
}

fn traverse_parse_tree<T>(tree: &Tree, m: fn(Node) -> Result<(), T>) -> Result<(), T> {
fn traverse_parse_tree<F>(tree: &Tree, mut visit: F)
where
F: FnMut(Node),
{
let mut cursor: TreeCursor = tree.walk();
loop {
// Every time a new node is found the control flow passes here
m(cursor.node())?;
visit(cursor.node());
// Descend as far as possible
if !cursor.goto_first_child() {
loop {
Expand All @@ -108,7 +110,7 @@ fn traverse_parse_tree<T>(tree: &Tree, m: fn(Node) -> Result<(), T>) -> Result<(
// parent's sibling in next loop iteration
if !cursor.goto_parent() {
// If parent does not exist, we are done
return Ok(());
return;
}
}
}
Expand Down Expand Up @@ -555,13 +557,9 @@ mod tests {
Ok(converted) => converted,
Err(TlaError::InputFileParseError {
parse_tree,
first_error_line,
error_lines,
}) => {
panic!(
"{}\n{}",
first_error_line.unwrap_or(0),
parse_tree.root_node().to_sexp()
)
panic!("{:?}\n{}", error_lines, parse_tree.root_node().to_sexp())
}
Err(TlaError::OutputFileParseError {
output_tree,
Expand Down
9 changes: 5 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,11 @@ fn convert(config: &Config, mode: Mode) -> Result<()> {
output_file.write_all(output.as_bytes()).context(format!("Failed to write to output file [{}]", &config.output))?;
Ok(())
},
Err(TlaError::InputFileParseError { first_error_line, .. }) => {
let line_msg = first_error_line.map_or(
"Could not identify line of first syntax error.".to_string(),
|line| format!("First syntax error might occur on line {}.", line));
Err(TlaError::InputFileParseError { error_lines, .. }) => {
let line_msg = match error_lines.as_slice() {
[] => "Could not identify line of first syntax error.".to_string(),
[..] => format!("Syntax errors might occur on or near the following lines: {:?}.", error_lines)
};
Err(anyhow!("Failed to correctly parse input TLA⁺ file; use --force flag to bypass this check.\n".to_string() + &line_msg))
}
Err(TlaError::OutputFileParseError{..}) => Err(anyhow!("Failed to correctly parse converted TLA⁺ output; this is a bug, please report it to the maintainer! Use --force to bypass this check (not recommended).")),
Expand Down

0 comments on commit c6c9170

Please sign in to comment.