diff --git a/src/error.rs b/src/error.rs index 010d9dc..666a814 100644 --- a/src/error.rs +++ b/src/error.rs @@ -16,6 +16,7 @@ pub enum Error { expected: &'static str, actual: &'static str, location: tree_sitter::Point, + surrounding_text: String, }, ExpectedFieldName, @@ -530,9 +531,11 @@ impl fmt::Display for Error { expected, actual, location, + surrounding_text, } => write!( f, - "Unexpected syntax at {location}. Expected {expected}, but found {actual}." + "Unexpected syntax at {location}. Expected {expected}, but found {actual}. + >> {surrounding_text} <<" ), ExpectedFieldName => write!( f, diff --git a/src/interface.rs b/src/interface.rs index 2e1ea29..b030338 100644 --- a/src/interface.rs +++ b/src/interface.rs @@ -136,8 +136,6 @@ pub enum Item { impl EvaluatorTree for Item { fn from_syntax_node(node: Node, source: &str) -> Result { - debug_assert_eq!(node.kind(), "item"); - let child = node.child(0).unwrap(); if child.kind() == "comment" { @@ -152,6 +150,7 @@ impl EvaluatorTree for Item { expected: "comment or statement", actual: child.kind(), location: child.start_position(), + surrounding_text: source[node.byte_range()].to_string(), }) } } @@ -178,8 +177,6 @@ pub enum Statement { impl EvaluatorTree for Statement { fn from_syntax_node(node: Node, source: &str) -> Result { - debug_assert_eq!(node.kind(), "statement"); - let child = node.child(0).unwrap(); match child.kind() { @@ -196,6 +193,7 @@ impl EvaluatorTree for Statement { expected: "expression", actual: child.kind(), location: child.start_position(), + surrounding_text: source[node.byte_range()].to_string(), }), } } @@ -219,8 +217,6 @@ pub enum Expression { impl EvaluatorTree for Expression { fn from_syntax_node(node: Node, source: &str) -> Result { - debug_assert_eq!(node.kind(), "expression"); - let child = node.child(0).unwrap(); let expression = match child.kind() { @@ -235,6 +231,7 @@ impl EvaluatorTree for Expression { "identifier, operation, control_flow, assignment, math, function_call or value", actual: child.kind(), location: child.start_position(), + surrounding_text: source[node.byte_range()].to_string(), }), }; @@ -270,8 +267,6 @@ impl Identifier { impl EvaluatorTree for Identifier { fn from_syntax_node(node: Node, source: &str) -> Result { - assert_eq!(node.kind(), "identifier"); - let identifier = &source[node.byte_range()]; Ok(Identifier(identifier.to_string())) @@ -293,8 +288,6 @@ pub struct ControlFlow { impl EvaluatorTree for ControlFlow { fn from_syntax_node(node: Node, source: &str) -> Result { - assert_eq!(node.kind(), "control_flow"); - let if_node = node.child(1).unwrap(); let if_expression = Expression::from_syntax_node(if_node, source)?; @@ -336,8 +329,6 @@ pub struct Assignment { impl EvaluatorTree for Assignment { fn from_syntax_node(node: Node, source: &str) -> Result { - assert_eq!(node.kind(), "assignment"); - let identifier_node = node.child(0).unwrap(); let identifier = Identifier::from_syntax_node(identifier_node, source)?; @@ -369,8 +360,6 @@ pub struct Math { impl EvaluatorTree for Math { fn from_syntax_node(node: Node, source: &str) -> Result { - assert_eq!(node.kind(), "math"); - let left_node = node.child(0).unwrap(); let left = Expression::from_syntax_node(left_node, source)?; @@ -386,6 +375,7 @@ impl EvaluatorTree for Math { expected: "+, -, *, / or %", actual: operator_node.kind(), location: operator_node.start_position(), + surrounding_text: source[operator_node.byte_range()].to_string(), }) } }; @@ -432,8 +422,6 @@ pub struct FunctionCall { impl EvaluatorTree for FunctionCall { fn from_syntax_node(node: Node, source: &str) -> Result { - assert_eq!(node.kind(), "function_call"); - let identifier_node = node.child(0).unwrap(); let identifier = Identifier::from_syntax_node(identifier_node, source)?; @@ -585,6 +573,27 @@ mod tests { ); } + #[test] + fn evaluate_if_else_if_then_else() { + assert_eq!( + evaluate( + " + if false + then 'no' + else if 1 + 1 = 3 + then 'nope' + else + 'ok' + " + ), + vec![Ok(Value::String("ok".to_string()))] + ); + assert_eq!( + evaluate("if true then 1.0 else 42.0"), + vec![Ok(Value::Float(1.0))] + ); + } + #[test] fn evaluate_function() { let function = Function::new( diff --git a/src/value/mod.rs b/src/value/mod.rs index 0e028d9..4347bcb 100644 --- a/src/value/mod.rs +++ b/src/value/mod.rs @@ -49,8 +49,6 @@ pub enum Value { impl Value { pub fn from_syntax_node(node: Node, source: &str) -> Result { - debug_assert_eq!(node.kind(), "value"); - let child = node.child(0).unwrap(); match child.kind() { @@ -185,13 +183,12 @@ impl Value { expected: "string, integer, float, boolean, list, table, map, function or empty", actual: child.kind(), location: child.start_position(), + surrounding_text: source[child.byte_range()].to_string(), }), } } pub fn list_from_syntax_node(node: Node, source: &str) -> Result { - debug_assert_eq!(node.kind(), "list"); - let item_count = node.named_child_count(); let mut values = Vec::with_capacity(item_count); let mut current_node = node.child(1).unwrap();