Make multi-armed patterns work
This commit is contained in:
parent
899a4df55e
commit
e40b8ece3b
4
TODO.md
4
TODO.md
@ -1,5 +1,9 @@
|
|||||||
# Immediate TODOs / General Code Cleanup
|
# Immediate TODOs / General Code Cleanup
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
* Get a test library for running many unit tests working
|
||||||
|
|
||||||
## Symbols
|
## Symbols
|
||||||
|
|
||||||
* Add some good printf-debugging impls for SymbolTable-related items
|
* Add some good printf-debugging impls for SymbolTable-related items
|
||||||
|
@ -195,7 +195,25 @@ impl<'a> Reducer<'a> {
|
|||||||
Expression::CaseMatch { cond, alternatives }
|
Expression::CaseMatch { cond, alternatives }
|
||||||
},
|
},
|
||||||
CondList(ref condition_arms) => {
|
CondList(ref condition_arms) => {
|
||||||
Expression::ReductionError("if expr".to_string())
|
let mut alternatives = vec![];
|
||||||
|
for arm in condition_arms {
|
||||||
|
match arm.condition {
|
||||||
|
ast::Condition::Expression(ref _expr) => return Expression::ReductionError("case-expression".to_string()),
|
||||||
|
ast::Condition::Pattern(ref pat) => {
|
||||||
|
let alt = Alternative {
|
||||||
|
pattern: match pat.reduce(self.symbol_table) {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(e) => return Expression::ReductionError(format!("Bad pattern: {:?}", e)),
|
||||||
|
},
|
||||||
|
item: self.function_internal_block(&arm.body),
|
||||||
|
};
|
||||||
|
alternatives.push(alt);
|
||||||
|
},
|
||||||
|
ast::Condition::TruncatedOp(_, _) => return Expression::ReductionError("case-expression-trunc-op".to_string()),
|
||||||
|
ast::Condition::Else => return Expression::ReductionError("case-expression-else".to_string()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Expression::CaseMatch { cond, alternatives }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -291,11 +309,10 @@ impl ast::Pattern {
|
|||||||
fn reduce(&self, symbol_table: &SymbolTable) -> Result<Pattern, PatternError> {
|
fn reduce(&self, symbol_table: &SymbolTable) -> Result<Pattern, PatternError> {
|
||||||
Ok(match self {
|
Ok(match self {
|
||||||
ast::Pattern::Ignored => {
|
ast::Pattern::Ignored => {
|
||||||
unimplemented!()
|
Pattern::Ignored
|
||||||
},
|
},
|
||||||
ast::Pattern::TuplePattern(/*Vec<Pattern>*/..) => {
|
ast::Pattern::TuplePattern(/*Vec<Pattern>*/..) => {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
|
||||||
},
|
},
|
||||||
ast::Pattern::Literal(lit) => Pattern::Literal(match lit {
|
ast::Pattern::Literal(lit) => Pattern::Literal(match lit {
|
||||||
ast::PatternLiteral::NumPattern { neg, num } => match (neg, num) {
|
ast::PatternLiteral::NumPattern { neg, num } => match (neg, num) {
|
||||||
|
@ -276,7 +276,6 @@ 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(scrut: &Primitive, pat: &Pattern) -> bool {
|
fn matches(scrut: &Primitive, pat: &Pattern) -> bool {
|
||||||
match pat {
|
match pat {
|
||||||
Pattern::Ignored => true,
|
Pattern::Ignored => true,
|
||||||
|
@ -86,7 +86,7 @@ fn basic_if_statement() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic_patterns() {
|
fn basic_patterns_1() {
|
||||||
let source =r#"
|
let source =r#"
|
||||||
let x = 10
|
let x = 10
|
||||||
let a = if x is 10 then { 255 } else { 256 }
|
let a = if x is 10 then { 255 } else { 256 }
|
||||||
@ -98,6 +98,20 @@ let d = if "xxx" is "yyy" then { 20 } else { 30 }
|
|||||||
eval_assert(source, "(255, 256, 10, 30)");
|
eval_assert(source, "(255, 256, 10, 30)");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn basic_patterns_2() {
|
||||||
|
let source = r#"
|
||||||
|
let x = "hella"
|
||||||
|
if x {
|
||||||
|
is "sanchez" then 23
|
||||||
|
is "mouri" then 99
|
||||||
|
is "hella" then 2
|
||||||
|
is _ then 94
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
eval_assert(source, "2");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn if_is_patterns() {
|
fn if_is_patterns() {
|
||||||
let source = r#"
|
let source = r#"
|
||||||
|
Loading…
Reference in New Issue
Block a user