Add a hacky None literal

A more native `None` value might be nice,
but would be more effort than re-using
the match logic we already have for
Reflective(None<()>)
This commit is contained in:
Olivier 'reivilibre' 2025-05-14 21:39:26 +01:00
parent 845a05b720
commit dc8447f08e
6 changed files with 25 additions and 2 deletions

View File

@ -186,6 +186,7 @@ pub enum Expression {
IntLiteral {
val: i64,
},
NoneLiteral,
StringExpr(StringExpr),
// Relatives

View File

@ -197,11 +197,11 @@ MethodCall = { "." ~ ws* ~ Identifier ~ "(" ~ commaSeparatedExprs ~ ")" }
FieldLookup = { "." ~ ws* ~ Identifier }
Indexing = { "[" ~ ws* ~ Expr ~ ws* ~ "]" }
Term = _{ (IntLiteral | bracketedTerm | FunctionCall | ListLiteral | MapLiteral | String | Variable) }
Term = _{ (IntLiteral | bracketedTerm | FunctionCall | ListLiteral | MapLiteral | String | Variable | NoneLiteral) }
bracketedTerm = _{ "(" ~ Expr ~ ")" }
NoneLiteral = { "None" }
IntLiteral = @{ (ASCII_NONZERO_DIGIT ~ ASCII_DIGIT+ | ASCII_DIGIT) }
// `-` is important in identifiers for `kebab-case` HTML element attributes
// We could consider splitting this out into its own kind of identifier but let's not bother now.

View File

@ -360,6 +360,7 @@ impl HornbeamParser {
let node = Node::new_with_user_data(primary, ud.clone());
Ok(match node.as_rule() {
Rule::IntLiteral => Expression::IntLiteral { val: node.as_str().parse().map_err(|e| error(&format!("can't parse int: {e:?}"), node.as_span()))? },
Rule::NoneLiteral => Expression::NoneLiteral,
Rule::String => Expression::StringExpr(HornbeamParser::String(node)?),
Rule::Variable => HornbeamParser::Variable(node)?,
Rule::FunctionCall => HornbeamParser::FunctionCall(node)?,

View File

@ -692,6 +692,7 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
Ok(Value::List(result))
}
Expression::IntLiteral { val } => Ok(Value::Int(*val)),
Expression::NoneLiteral => Ok(Value::Reflective(Box::new(None::<()>))),
Expression::StringExpr(sexpr) => {
let mut output = String::new();
for piece in &sexpr.pieces {

View File

@ -97,3 +97,18 @@ for $part in $sts.carrot.split("A")
"#
))
}
#[test]
fn snapshot_005() {
assert_snapshot!(simple_render(
r#"
set $unused_var = None
match $unused_var
Some($nope) =>
"UNEXPECTED $nope"
None =>
"indeed, var not used"
"#
))
}

View File

@ -0,0 +1,5 @@
---
source: hornbeam_interpreter/tests/snapshots.rs
expression: "simple_render(r#\"\nset $unused_var = None\n\nmatch $unused_var\n Some($nope) =>\n \"UNEXPECTED $nope\"\n None =>\n \"indeed, var not used\"\n \"#)"
---
indeed, var not used