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, 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 {

View File

@ -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)],
}
}
}
}
}
*/
}
}

View File

@ -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>,
}

View File

@ -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()),
}) })
} }