Check scalars in lamda were defined in script (#218)

This commit is contained in:
Mike Voronov 2022-02-17 23:39:01 +03:00 committed by GitHub
parent 1ca121cf93
commit f994ce73c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 49 additions and 6 deletions

View File

@ -120,7 +120,7 @@ impl<'i> VariableWithLambda<'i> {
} }
} }
pub fn lambda(&self) -> &Option<LambdaAST> { pub fn lambda(&self) -> &Option<LambdaAST<'i>> {
match self { match self {
VariableWithLambda::Scalar(scalar) => &scalar.lambda, VariableWithLambda::Scalar(scalar) => &scalar.lambda,
VariableWithLambda::Stream(stream) => &stream.lambda, VariableWithLambda::Stream(stream) => &stream.lambda,

View File

@ -559,3 +559,33 @@ fn no_output() {
); );
assert_eq!(actual, expected); assert_eq!(actual, expected);
} }
#[test]
fn not_defined_scalar_in_lambda() {
let source_code = r#"
(seq
(call "" ("" "") [] value)
(call "" ("" "") [value.$.[not_defined_scalar]])
)
"#;
let lexer = crate::AIRLexer::new(source_code);
let parser = crate::AIRParser::new();
let mut errors = Vec::new();
let mut validator = crate::parser::VariableValidator::new();
parser
.parse(source_code, &mut errors, &mut validator, lexer)
.expect("parser shouldn't fail");
let errors = validator.finalize();
assert_eq!(errors.len(), 1);
let error = &errors[0].error;
let parser_error = match error {
ParseError::User { error } => error,
_ => panic!("unexpected error type"),
};
assert!(matches!(parser_error, ParserError::UndefinedVariable(..)));
}

View File

@ -35,11 +35,8 @@ fn parse(source_code: &str) -> Instruction {
let mut errors = Vec::new(); let mut errors = Vec::new();
let lexer = crate::parser::AIRLexer::new(source_code); let lexer = crate::parser::AIRLexer::new(source_code);
let mut validator = crate::parser::VariableValidator::new(); let mut validator = crate::parser::VariableValidator::new();
let res = parser parser
.parse(source_code, &mut errors, &mut validator, lexer) .parse(source_code, &mut errors, &mut validator, lexer)
.expect("parsing should be successful"); .expect("parsing should be successful")
println!("{:?}", errors);
res
}) })
} }

View File

@ -20,6 +20,7 @@ use crate::parser::lexer::Token;
use crate::parser::ParserError; use crate::parser::ParserError;
use crate::parser::Span; use crate::parser::Span;
use air_lambda_ast::ValueAccessor;
use lalrpop_util::ErrorRecovery; use lalrpop_util::ErrorRecovery;
use lalrpop_util::ParseError; use lalrpop_util::ParseError;
@ -184,6 +185,21 @@ impl<'i> VariableValidator<'i> {
fn met_variable_wl(&mut self, variable: &VariableWithLambda<'i>, span: Span) { fn met_variable_wl(&mut self, variable: &VariableWithLambda<'i>, span: Span) {
self.met_variable_name(variable.name(), span); self.met_variable_name(variable.name(), span);
let lambda = match variable.lambda() {
Some(lambda) => lambda,
None => return,
};
for accessor in lambda.iter() {
match accessor {
&ValueAccessor::FieldAccessByScalar { scalar_name } => {
self.met_variable_name(scalar_name, span)
}
ValueAccessor::ArrayAccess { .. }
| ValueAccessor::FieldAccessByName { .. }
| ValueAccessor::Error => {}
}
}
} }
fn met_variable_name(&mut self, name: &'i str, span: Span) { fn met_variable_name(&mut self, name: &'i str, span: Span) {