Add !
unwrap operator
This commit is contained in:
parent
9098d72217
commit
2281a9bb50
@ -225,4 +225,9 @@ pub enum Expression {
|
||||
args: Vec<Expression>,
|
||||
loc: Locator,
|
||||
},
|
||||
|
||||
Unwrap {
|
||||
obj: Box<Expression>,
|
||||
loc: Locator,
|
||||
},
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ bnot = { "not" ~ ws+ }
|
||||
|
||||
// POSTFIX
|
||||
postfix = _{ unwrap | MethodCall | FieldLookup | Indexing }
|
||||
unwrap = { "?" } // Not sure I'm convinced about this one, but we can think about it.
|
||||
unwrap = { "!" } // Not sure I'm convinced about this one, but we can think about it.
|
||||
// Note that functions aren't first-class; we don't allow you to 'call' an arbitrary term.
|
||||
// This is probably for the best since we might have multiple backends for the templating.
|
||||
MethodCall = { "." ~ ws* ~ Identifier ~ "(" ~ commaSeparatedExprs ~ ")" }
|
||||
|
@ -432,7 +432,9 @@ impl HornbeamParser {
|
||||
let node = Node::new_with_user_data(op, ud.clone());
|
||||
let loc = nodeloc(&node);
|
||||
Ok(match node.as_rule() {
|
||||
Rule::unwrap => unimplemented!("unimp unwrap"),
|
||||
Rule::unwrap => {
|
||||
Expression::Unwrap { obj: Box::new(lhs?), loc }
|
||||
},
|
||||
Rule::FieldLookup => {
|
||||
let ident = intern(node.into_children().single()?.as_str());
|
||||
Expression::FieldLookup { obj: Box::new(lhs?), ident, loc }
|
||||
|
@ -855,6 +855,54 @@ impl<'a, O: OutputSystem + Send, LS: LocalisationSystem + Sync + Send> Interpret
|
||||
Expression::FunctionCall { .. } => {
|
||||
unimplemented!()
|
||||
}
|
||||
Expression::Unwrap { obj, loc } => {
|
||||
let obj_value = self.evaluate_expression(scope_idx, obj, loc)?;
|
||||
|
||||
match &obj_value {
|
||||
Value::Reflective(reflective) => match reflective.reflect_ref() {
|
||||
ReflectRef::Enum(reflenum) => match reflenum.variant_name() {
|
||||
"Some" => {
|
||||
if reflenum.field_len() != 1 {
|
||||
return Err(InterpreterError::TypeError {
|
||||
context: "unwrap".to_owned(),
|
||||
conflict: "wrong number of fields in Some".to_owned(),
|
||||
location: loc.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
if reflenum.variant_type() != VariantType::Tuple {
|
||||
return Err(InterpreterError::TypeError {
|
||||
context: "unwrap".to_owned(),
|
||||
conflict: "Some is not a tuple variant".to_owned(),
|
||||
location: loc.clone(),
|
||||
});
|
||||
}
|
||||
|
||||
Ok(Value::from_reflect(
|
||||
reflenum.field_at(0).unwrap().clone_value(),
|
||||
))
|
||||
}
|
||||
"None" => Err(InterpreterError::TypeError {
|
||||
context: "unwrap".to_owned(),
|
||||
conflict: "tried to unwrap None".to_owned(),
|
||||
location: loc.clone(),
|
||||
}),
|
||||
_other => {
|
||||
warn!("unnecessary unwrap (!) at {loc}");
|
||||
Ok(obj_value)
|
||||
}
|
||||
},
|
||||
_other => {
|
||||
warn!("unnecessary unwrap (!) at {loc}");
|
||||
Ok(obj_value)
|
||||
}
|
||||
},
|
||||
_other => {
|
||||
warn!("unnecessary unwrap (!) at {loc}");
|
||||
Ok(obj_value)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user