More work on subpattern matching
This commit is contained in:
parent
e71d404071
commit
bada386979
@ -372,6 +372,7 @@ impl<'a> State<'a> {
|
|||||||
fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>) -> EvalResult<Node> {
|
fn case_match_expression(&mut self, cond: Expr, alternatives: Vec<Alternative>) -> EvalResult<Node> {
|
||||||
let cond = self.expression(Node::Expr(cond))?;
|
let cond = self.expression(Node::Expr(cond))?;
|
||||||
for alt in alternatives {
|
for alt in alternatives {
|
||||||
|
println!("ALT: {:?}", alt);
|
||||||
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
// no matter what type of condition we have, ignore alternative if the guard evaluates false
|
||||||
if let Some(ref guard_expr) = alt.guard {
|
if let Some(ref guard_expr) = alt.guard {
|
||||||
let guard_expr = match &cond {
|
let guard_expr = match &cond {
|
||||||
@ -406,7 +407,7 @@ impl<'a> State<'a> {
|
|||||||
return inner_state.block(alt.item)
|
return inner_state.block(alt.item)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Node::PrimTuple { .. } => {
|
Node::PrimTuple { ref items } => {
|
||||||
return Err(format!("Prim tuple not done"))
|
return Err(format!("Prim tuple not done"))
|
||||||
},
|
},
|
||||||
Node::Expr(ref _e) => {
|
Node::Expr(ref _e) => {
|
||||||
|
@ -65,12 +65,6 @@ pub struct Alternative {
|
|||||||
pub item: Vec<Stmt>,
|
pub item: Vec<Stmt>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Alternative {
|
|
||||||
fn default(item: Vec<Stmt>) -> Alternative {
|
|
||||||
Alternative { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![], item }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct Subpattern {
|
pub struct Subpattern {
|
||||||
pub tag: Option<usize>,
|
pub tag: Option<usize>,
|
||||||
@ -172,7 +166,13 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
|||||||
|
|
||||||
let alternatives = vec![
|
let alternatives = vec![
|
||||||
pat.to_alternative(then_clause, symbol_table),
|
pat.to_alternative(then_clause, symbol_table),
|
||||||
Alternative::default(else_clause),
|
Alternative {
|
||||||
|
tag: None,
|
||||||
|
subpatterns: vec![],
|
||||||
|
bound_vars: vec![],
|
||||||
|
guard: None,
|
||||||
|
item: else_clause
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
Expr::CaseMatch {
|
Expr::CaseMatch {
|
||||||
@ -202,17 +202,27 @@ fn reduce_if_expression(discriminator: &Discriminator, body: &IfExpressionBody,
|
|||||||
* x is SomeBigOldEnum(_, x, Some(t))
|
* x is SomeBigOldEnum(_, x, Some(t))
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fn handle_symbol(symbol: Option<&Symbol>, subpatterns: &Vec<Pattern>) -> Subpattern {
|
fn handle_symbol(symbol: Option<&Symbol>, inner_patterns: &Vec<Pattern>, symbol_table: &SymbolTable) -> Subpattern {
|
||||||
use self::Pattern::*;
|
use self::Pattern::*;
|
||||||
let tag = symbol.map(|symbol| match symbol.spec {
|
let tag = symbol.map(|symbol| match symbol.spec {
|
||||||
SymbolSpec::DataConstructor { index, .. } => index.clone(),
|
SymbolSpec::DataConstructor { index, .. } => index.clone(),
|
||||||
_ => panic!("Symbol is not a data constructor - this should've been caught in type-checking"),
|
_ => panic!("Symbol is not a data constructor - this should've been caught in type-checking"),
|
||||||
});
|
});
|
||||||
let bound_vars = subpatterns.iter().map(|p| match p {
|
let bound_vars = inner_patterns.iter().map(|p| match p {
|
||||||
Literal(PatternLiteral::VarPattern(var)) => Some(var.clone()),
|
Literal(PatternLiteral::VarPattern(var)) => Some(var.clone()),
|
||||||
_ => None,
|
_ => None,
|
||||||
}).collect();
|
}).collect();
|
||||||
|
|
||||||
|
let subpatterns = inner_patterns.iter().map(|p| match p {
|
||||||
|
Ignored => None,
|
||||||
|
Literal(PatternLiteral::VarPattern(_)) => None,
|
||||||
|
Literal(other) => Some(other.to_subpattern(symbol_table)),
|
||||||
|
tp @ TuplePattern(_) => Some(tp.to_subpattern(symbol_table)),
|
||||||
|
ts @ TupleStruct(_, _) => Some(ts.to_subpattern(symbol_table)),
|
||||||
|
Record(..) => unimplemented!(),
|
||||||
|
}).collect();
|
||||||
|
|
||||||
|
let guard = None;
|
||||||
/*
|
/*
|
||||||
let guard_equality_exprs: Vec<Expr> = subpatterns.iter().map(|p| match p {
|
let guard_equality_exprs: Vec<Expr> = subpatterns.iter().map(|p| match p {
|
||||||
Literal(lit) => match lit {
|
Literal(lit) => match lit {
|
||||||
@ -222,9 +232,6 @@ fn handle_symbol(symbol: Option<&Symbol>, subpatterns: &Vec<Pattern>) -> Subpatt
|
|||||||
}).collect();
|
}).collect();
|
||||||
*/
|
*/
|
||||||
|
|
||||||
let guard = None;
|
|
||||||
let subpatterns = vec![];
|
|
||||||
|
|
||||||
Subpattern {
|
Subpattern {
|
||||||
tag,
|
tag,
|
||||||
subpatterns,
|
subpatterns,
|
||||||
@ -235,43 +242,30 @@ fn handle_symbol(symbol: Option<&Symbol>, subpatterns: &Vec<Pattern>) -> Subpatt
|
|||||||
|
|
||||||
impl Pattern {
|
impl Pattern {
|
||||||
fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
|
fn to_alternative(&self, item: Vec<Stmt>, symbol_table: &SymbolTable) -> Alternative {
|
||||||
|
use self::Pattern::*;
|
||||||
|
let s = self.to_subpattern(symbol_table);
|
||||||
|
Alternative {
|
||||||
|
tag: s.tag,
|
||||||
|
subpatterns: s.subpatterns,
|
||||||
|
bound_vars: s.bound_vars,
|
||||||
|
guard: s.guard,
|
||||||
|
item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn to_subpattern(&self, symbol_table: &SymbolTable) -> Subpattern {
|
||||||
use self::Pattern::*;
|
use self::Pattern::*;
|
||||||
match self {
|
match self {
|
||||||
TupleStruct(name, subpatterns) => {
|
TupleStruct(name, inner_patterns) => {
|
||||||
let symbol = symbol_table.lookup_by_name(name).expect(&format!("Symbol {} not found", name));
|
let symbol = symbol_table.lookup_by_name(name).expect(&format!("Symbol {} not found", name));
|
||||||
let s = handle_symbol(Some(symbol), subpatterns);
|
handle_symbol(Some(symbol), inner_patterns, symbol_table)
|
||||||
Alternative {
|
|
||||||
tag: s.tag,
|
|
||||||
subpatterns: s.subpatterns,
|
|
||||||
guard: s.guard,
|
|
||||||
bound_vars: s.bound_vars,
|
|
||||||
item
|
|
||||||
}
|
|
||||||
},
|
|
||||||
TuplePattern(subpatterns) => {
|
|
||||||
let s = handle_symbol(None, subpatterns);
|
|
||||||
Alternative {
|
|
||||||
tag: s.tag,
|
|
||||||
subpatterns: s.subpatterns,
|
|
||||||
guard: s.guard,
|
|
||||||
bound_vars: s.bound_vars,
|
|
||||||
item
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
TuplePattern(inner_patterns) => handle_symbol(None, inner_patterns, symbol_table),
|
||||||
Record(_name, _pairs) => {
|
Record(_name, _pairs) => {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
},
|
},
|
||||||
Ignored => Alternative::default(item),
|
Ignored => Subpattern { tag: None, subpatterns: vec![], guard: None, bound_vars: vec![] },
|
||||||
Literal(lit) => {
|
Literal(lit) => lit.to_subpattern(symbol_table),
|
||||||
let s = lit.to_subpattern(symbol_table);
|
|
||||||
Alternative {
|
|
||||||
tag: s.tag,
|
|
||||||
subpatterns: s.subpatterns,
|
|
||||||
bound_vars: s.bound_vars,
|
|
||||||
guard: s.guard,
|
|
||||||
item
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -329,7 +323,7 @@ impl PatternLiteral {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
VarPattern(var) => match symbol_table.lookup_by_name(var) {
|
VarPattern(var) => match symbol_table.lookup_by_name(var) {
|
||||||
Some(symbol) => handle_symbol(Some(symbol), &vec![]),
|
Some(symbol) => handle_symbol(Some(symbol), &vec![], symbol_table),
|
||||||
None => Subpattern {
|
None => Subpattern {
|
||||||
tag: None,
|
tag: None,
|
||||||
subpatterns: vec![],
|
subpatterns: vec![],
|
||||||
|
Loading…
Reference in New Issue
Block a user