Added `null` as a first class token (#29)

An expression may evaluate to Null but an equality test evaluates to UndefinedIdentifier
This commit is contained in:
jhugman 2023-05-25 16:11:03 +01:00 коммит произвёл GitHub
Родитель ee044f7abb b28fe78294
Коммит 2dff4e7444
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 1279 добавлений и 1079 удалений

Просмотреть файл

@ -160,6 +160,7 @@ impl<'a> Evaluator<'a> {
Expression::Boolean(b) => Ok(value!(b)),
Expression::String(s) => Ok(value!(s)),
Expression::Array(xs) => xs.into_iter().map(|x| self.eval_ast(*x, context)).collect(),
Expression::Null => Ok(Value::Null),
Expression::Object(items) => {
let mut map = serde_json::Map::with_capacity(items.len());
@ -834,6 +835,7 @@ mod tests {
test("BOOLEAN", "true", true);
test("OBJECT", "OBJECT", true);
test("ARRAY", "[ 'string' ]", true);
test("NULL", "null", true);
test("OBJECT", "{ 'x': 1, 'y': 2 }", false);

Просмотреть файл

@ -10,6 +10,7 @@ pub enum Expression {
Array(Vec<Box<Expression>>),
Object(Vec<(String, Box<Expression>)>),
Identifier(String),
Null,
BinaryOperation {
operation: OpCode,

Просмотреть файл

@ -136,6 +136,23 @@ mod tests {
);
}
#[test]
fn test_dot_op_equality_with_null() {
let exp = "foo.bar == null";
let parsed = Parser::parse(exp).unwrap();
assert_eq!(
parsed,
Expression::BinaryOperation {
operation: OpCode::Equal,
left: Box::new(Expression::DotOperation {
subject: Box::new(Expression::Identifier("foo".to_string())),
ident: "bar".to_string()
}),
right: Box::new(Expression::Null),
}
);
}
#[test]
fn test_dot_op_object_literal() {
let exp = "{'foo': 1}.foo";
@ -151,4 +168,9 @@ mod tests {
}
);
}
#[test]
fn test_parsing_null() {
assert_eq!(Parser::parse("null"), Ok(Expression::Null));
}
}

Просмотреть файл

@ -76,6 +76,7 @@ Expr80: Box<Expression> = {
String => Box::new(Expression::String(<>)),
Array => Box::new(Expression::Array(<>)),
Object => Box::new(Expression::Object(<>)),
Null => Box::new(Expression::Null),
Identifier => Box::new(Expression::Identifier(<>)),
"(" <Expression> ")",
};
@ -126,6 +127,9 @@ String: String = {
<s: r#"'([^'\\]*(\\')?)*'"#> => s[1..s.len() - 1].to_string().replace("\\'", "'"),
};
Null: Option<Box<Expression>> = {
"null" => None,
}
Identifier: String = {
r#"[a-zA-Z_][a-zA-Z0-9_]*"# => <>.to_string()

Разница между файлами не показана из-за своего большого размера Загрузить разницу