Starting on case-matching
This commit is contained in:
parent
77cdfc229f
commit
6162d05b60
@ -243,9 +243,8 @@ impl<'a> Reducer<'a> {
|
|||||||
item: else_clause,
|
item: else_clause,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
Expression::CaseMatch { cond, alternatives }
|
||||||
Expr::CaseMatch { cond, alternatives }
|
},
|
||||||
}
|
|
||||||
IfExpressionBody::CondList(ref condition_arms) => {
|
IfExpressionBody::CondList(ref condition_arms) => {
|
||||||
let mut alternatives = vec![];
|
let mut alternatives = vec![];
|
||||||
for arm in condition_arms {
|
for arm in condition_arms {
|
||||||
|
@ -148,12 +148,14 @@ impl<'a> Reducer<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_if_expression(&mut self, discriminator: Option<&ast::Expression>, body: &ast::IfExpressionBody) -> Expression {
|
fn reduce_if_expression(&mut self, discriminator: Option<&ast::Expression>, body: &ast::IfExpressionBody) -> Expression {
|
||||||
|
use ast::IfExpressionBody::*;
|
||||||
|
|
||||||
let cond = Box::new(match discriminator {
|
let cond = Box::new(match discriminator {
|
||||||
Some(expr) => self.expression(expr),
|
Some(expr) => self.expression(expr),
|
||||||
None => return Expression::ReductionError("blank cond if-expr not supported".to_string()),
|
None => return Expression::ReductionError("blank cond if-expr not supported".to_string()),
|
||||||
});
|
});
|
||||||
match body {
|
match body {
|
||||||
ast::IfExpressionBody::SimpleConditional {
|
SimpleConditional {
|
||||||
then_case,
|
then_case,
|
||||||
else_case,
|
else_case,
|
||||||
} => {
|
} => {
|
||||||
@ -168,7 +170,34 @@ impl<'a> Reducer<'a> {
|
|||||||
else_clause,
|
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)],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -66,6 +66,10 @@ pub enum Expression {
|
|||||||
then_clause: Vec<Statement>,
|
then_clause: Vec<Statement>,
|
||||||
else_clause: Vec<Statement>,
|
else_clause: Vec<Statement>,
|
||||||
},
|
},
|
||||||
|
CaseMatch {
|
||||||
|
cond: Box<Expression>,
|
||||||
|
alternatives: Vec<Alternative>,
|
||||||
|
},
|
||||||
ReductionError(String),
|
ReductionError(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,3 +115,17 @@ pub enum Literal {
|
|||||||
Bool(bool),
|
Bool(bool),
|
||||||
StringLit(Rc<String>),
|
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>,
|
||||||
|
}
|
||||||
|
@ -270,6 +270,9 @@ impl<'a> State<'a> {
|
|||||||
v => return Err(format!("Non-boolean value {:?} in if-statement", v).into())
|
v => return Err(format!("Non-boolean value {:?} in if-statement", v).into())
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
Expression::CaseMatch { cond, alternatives } => {
|
||||||
|
panic!()
|
||||||
|
},
|
||||||
Expression::ReductionError(e) => return Err(e.into()),
|
Expression::ReductionError(e) => return Err(e.into()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user