From f3bef425631d998e5dc0eef164b545b6f6269f3e Mon Sep 17 00:00:00 2001 From: Jeff Date: Mon, 12 Aug 2024 19:39:26 -0400 Subject: [PATCH] Write some failing analyzer tests --- dust-lang/src/analyzer.rs | 61 ++++++++++++++++++++++++++++++++++++++- 1 file changed, 60 insertions(+), 1 deletion(-) diff --git a/dust-lang/src/analyzer.rs b/dust-lang/src/analyzer.rs index 1023132..f065385 100644 --- a/dust-lang/src/analyzer.rs +++ b/dust-lang/src/analyzer.rs @@ -445,6 +445,12 @@ pub enum AnalyzerError { actual: usize, position: Span, }, + IndexOutOfBounds { + list: Node, + index: Node, + index_value: usize, + length: usize, + }, TypeConflict { actual_statement: Node, actual_type: Type, @@ -472,6 +478,9 @@ impl AnalyzerError { AnalyzerError::ExpectedMap { actual } => actual.position, AnalyzerError::ExpectedValue { actual } => actual.position, AnalyzerError::ExpectedValueArgumentCount { position, .. } => *position, + AnalyzerError::IndexOutOfBounds { list, index, .. } => { + (list.position.0, index.position.1) + } AnalyzerError::TypeConflict { actual_statement, .. } => actual_statement.position, @@ -507,6 +516,16 @@ impl Display for AnalyzerError { AnalyzerError::ExpectedValueArgumentCount { expected, actual, .. } => write!(f, "Expected {} value arguments, found {}", expected, actual), + AnalyzerError::IndexOutOfBounds { + list, + index, + index_value, + length, + } => write!( + f, + "Index {} out of bounds for list {} with length {}", + index_value, list, length + ), AnalyzerError::TypeConflict { actual_statement, actual_type, @@ -537,6 +556,46 @@ mod tests { use super::*; + #[test] + fn constant_list_index_out_of_bounds() { + let source = "[1, 2, 3][3]"; + + assert_eq!( + analyze(source), + Err(DustError::AnalyzerError { + analyzer_error: AnalyzerError::IndexOutOfBounds { + list: Node::new( + Statement::List(vec![ + Node::new(Statement::Constant(Value::integer(1)), (1, 2)), + Node::new(Statement::Constant(Value::integer(2)), (4, 5)), + Node::new(Statement::Constant(Value::integer(3)), (7, 8)), + ]), + (0, 9) + ), + index: Node::new(Statement::Constant(Value::integer(3)), (10, 11)), + index_value: 3, + length: 3 + }, + source + }) + ); + } + + #[test] + fn nonexistant_field() { + let source = "{ x = 1 }.y"; + + assert_eq!( + analyze(source), + Err(DustError::AnalyzerError { + analyzer_error: AnalyzerError::UndefinedVariable { + identifier: Node::new(Statement::Identifier(Identifier::new("y")), (10, 11)), + }, + source + }) + ); + } + #[test] fn malformed_list_index() { let source = "[1, 2, 3]['foo']"; @@ -553,7 +612,7 @@ mod tests { } #[test] - fn malformed_property_access() { + fn malformed_field_access() { let source = "{ x = 1 }.0"; assert_eq!(