Literal patterns
This commit is contained in:
parent
284d7ce383
commit
899a4df55e
@ -289,8 +289,35 @@ impl<'a> Reducer<'a> {
|
|||||||
|
|
||||||
impl ast::Pattern {
|
impl ast::Pattern {
|
||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Result<Pattern, PatternError> {
|
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),
|
Param(u8),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
Nat(u64),
|
Nat(u64),
|
||||||
Int(i64),
|
Int(i64),
|
||||||
@ -149,3 +149,9 @@ impl From<&str> for PatternError {
|
|||||||
Self { msg: s.to_string() }
|
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 case_match_expression(&mut self, cond: Expression, alternatives: Vec<Alternative>) -> EvalResult<Primitive> {
|
||||||
|
|
||||||
fn matches(cond: &Expression, matcher: &Pattern) -> bool {
|
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
|
false
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
let cond = self.expression(cond)?;
|
||||||
|
|
||||||
for alt in alternatives.into_iter() {
|
for alt in alternatives.into_iter() {
|
||||||
if matches(&cond, &alt.pattern) {
|
if matches(&cond, &alt.pattern) {
|
||||||
|
@ -85,6 +85,19 @@ fn basic_if_statement() {
|
|||||||
eval_assert(source, "69");
|
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]
|
#[test]
|
||||||
fn if_is_patterns() {
|
fn if_is_patterns() {
|
||||||
let source = r#"
|
let source = r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user