Literal patterns
This commit is contained in:
parent
284d7ce383
commit
899a4df55e
@ -289,8 +289,35 @@ impl<'a> Reducer<'a> {
|
||||
|
||||
impl ast::Pattern {
|
||||
fn reduce(&self, symbol_table: &SymbolTable) -> Result<Pattern, PatternError> {
|
||||
Ok(match self {
|
||||
ast::Pattern::Ignored => {
|
||||
unimplemented!()
|
||||
},
|
||||
ast::Pattern::TuplePattern(/*Vec<Pattern>*/..) => {
|
||||
unimplemented!()
|
||||
|
||||
Ok(Pattern::Ignored)
|
||||
},
|
||||
ast::Pattern::Literal(lit) => Pattern::Literal(match lit {
|
||||
ast::PatternLiteral::NumPattern { neg, num } => match (neg, num) {
|
||||
(false, ast::ExpressionKind::NatLiteral(n)) => Literal::Nat(*n),
|
||||
(false, ast::ExpressionKind::FloatLiteral(f)) => Literal::Float(*f),
|
||||
(true, ast::ExpressionKind::NatLiteral(n)) => Literal::Int(-(*n as i64)),
|
||||
(true, ast::ExpressionKind::FloatLiteral(f)) => Literal::Float(-f),
|
||||
(_, e) => return Err(format!("Internal error, unexpected pattern literal: {:?}", e).into())
|
||||
},
|
||||
ast::PatternLiteral::StringPattern(s) => Literal::StringLit(s.clone()),
|
||||
ast::PatternLiteral::BoolPattern(b) => Literal::Bool(*b),
|
||||
}),
|
||||
ast::Pattern::TupleStruct(_name, _subpatterns) => {
|
||||
unimplemented!()
|
||||
},
|
||||
ast::Pattern::Record(name, /*Vec<(Rc<String>, Pattern)>*/ _) => {
|
||||
unimplemented!()
|
||||
},
|
||||
ast::Pattern::VarOrName(_name) => {
|
||||
unimplemented!()
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,7 +108,7 @@ pub enum Lookup {
|
||||
Param(u8),
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[derive(Debug, Clone, PartialEq)]
|
||||
pub enum Literal {
|
||||
Nat(u64),
|
||||
Int(i64),
|
||||
@ -149,3 +149,9 @@ impl From<&str> for PatternError {
|
||||
Self { msg: s.to_string() }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for PatternError {
|
||||
fn from(msg: String) -> Self {
|
||||
Self { msg }
|
||||
}
|
||||
}
|
||||
|
@ -277,12 +277,17 @@ impl<'a> State<'a> {
|
||||
|
||||
fn case_match_expression(&mut self, cond: Expression, alternatives: Vec<Alternative>) -> EvalResult<Primitive> {
|
||||
|
||||
fn matches(cond: &Expression, matcher: &Pattern) -> bool {
|
||||
|
||||
|
||||
|
||||
false
|
||||
fn matches(scrut: &Primitive, pat: &Pattern) -> bool {
|
||||
match pat {
|
||||
Pattern::Ignored => true,
|
||||
Pattern::Literal(pat_literal) => if let Primitive::Literal(scrut_literal) = scrut {
|
||||
pat_literal == scrut_literal
|
||||
} else {
|
||||
false
|
||||
},
|
||||
}
|
||||
}
|
||||
let cond = self.expression(cond)?;
|
||||
|
||||
for alt in alternatives.into_iter() {
|
||||
if matches(&cond, &alt.pattern) {
|
||||
|
@ -85,6 +85,19 @@ fn basic_if_statement() {
|
||||
eval_assert(source, "69");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn basic_patterns() {
|
||||
let source =r#"
|
||||
let x = 10
|
||||
let a = if x is 10 then { 255 } else { 256 }
|
||||
let b = if 23 is 99 then { 255 } else { 256 }
|
||||
let c = if true is false then { 9 } else { 10 }
|
||||
let d = if "xxx" is "yyy" then { 20 } else { 30 }
|
||||
(a, b, c, d)
|
||||
"#;
|
||||
eval_assert(source, "(255, 256, 10, 30)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_is_patterns() {
|
||||
let source = r#"
|
||||
|
Loading…
Reference in New Issue
Block a user