Starting on case-matching

This commit is contained in:
Greg Shuflin 2021-10-25 21:19:26 -07:00
parent 77cdfc229f
commit 6162d05b60
4 changed files with 108 additions and 5 deletions

View File

@ -243,9 +243,8 @@ impl<'a> Reducer<'a> {
item: else_clause,
},
];
Expr::CaseMatch { cond, alternatives }
}
Expression::CaseMatch { cond, alternatives }
},
IfExpressionBody::CondList(ref condition_arms) => {
let mut alternatives = vec![];
for arm in condition_arms {

View File

@ -148,12 +148,14 @@ impl<'a> Reducer<'a> {
}
fn reduce_if_expression(&mut self, discriminator: Option<&ast::Expression>, body: &ast::IfExpressionBody) -> Expression {
use ast::IfExpressionBody::*;
let cond = Box::new(match discriminator {
Some(expr) => self.expression(expr),
None => return Expression::ReductionError("blank cond if-expr not supported".to_string()),
});
match body {
ast::IfExpressionBody::SimpleConditional {
SimpleConditional {
then_case,
else_case,
} => {
@ -168,7 +170,34 @@ impl<'a> Reducer<'a> {
else_clause,
}
},
_ => Expression::ReductionError("if expr".to_string())
SimplePatternMatch {
pattern,
then_case,
else_case,
} => {
let alternatives = vec![
Alternative {
matchable: pattern.to_subpattern(self.symbol_table),
item: self.function_internal_block(then_case),
},
Alternative {
matchable: Subpattern {
tag: None,
subpatterns: vec![],
guard: None,
},
item: match else_case.as_ref() {
Some(else_case) => self.function_internal_block(else_case),
None => vec![],
},
},
];
Expression::CaseMatch { cond, alternatives }
},
CondList(ref condition_arms) => {
Expression::ReductionError("if expr".to_string())
}
}
}
@ -258,3 +287,57 @@ impl<'a> Reducer<'a> {
}
}
}
impl ast::Pattern {
fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern {
Subpattern {
tag: None,
subpatterns: vec![],
guard: None,
}
/*
use self::Pattern::*;
match self {
TupleStruct(QualifiedName { components, id }, inner_patterns) => {
match symbol_table.lookup_symbol(id) {
Some(symbol) => handle_symbol(Some(symbol), inner_patterns, symbol_table),
None => panic!("Symbol {:?} not found", components),
}
}
TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table),
Record(_name, _pairs) => {
unimplemented!()
}
Ignored => Subpattern {
tag: None,
subpatterns: vec![],
guard: None,
bound_vars: vec![],
},
Literal(lit) => lit.to_subpattern(symbol_table),
VarOrName(QualifiedName { components, id }) => {
// if symbol is Some, treat this as a symbol pattern. If it's None, treat it
// as a variable.
match symbol_table.lookup_symbol(id) {
Some(symbol) => handle_symbol(Some(symbol), &[], symbol_table),
None => {
println!("Components: {:?}", components);
let name = if components.len() == 1 {
components[0].clone()
} else {
panic!("check this line of code yo");
};
Subpattern {
tag: None,
subpatterns: vec![],
guard: None,
bound_vars: vec![Some(name)],
}
}
}
}
}
*/
}
}

View File

@ -66,6 +66,10 @@ pub enum Expression {
then_clause: Vec<Statement>,
else_clause: Vec<Statement>,
},
CaseMatch {
cond: Box<Expression>,
alternatives: Vec<Alternative>,
},
ReductionError(String),
}
@ -111,3 +115,17 @@ pub enum Literal {
Bool(bool),
StringLit(Rc<String>),
}
#[derive(Debug, Clone)]
pub struct Alternative {
pub matchable: Subpattern,
pub item: Vec<Statement>,
}
#[derive(Debug, Clone)]
pub struct Subpattern {
pub tag: Option<usize>,
pub subpatterns: Vec<Option<Subpattern>>,
//pub bound_vars: BoundVars,
pub guard: Option<Expression>,
}

View File

@ -270,6 +270,9 @@ impl<'a> State<'a> {
v => return Err(format!("Non-boolean value {:?} in if-statement", v).into())
}
},
Expression::CaseMatch { cond, alternatives } => {
panic!()
},
Expression::ReductionError(e) => return Err(e.into()),
})
}