More work on pattern-matching
This commit is contained in:
parent
e52d0bf515
commit
9e799c23ba
3
TODO.md
3
TODO.md
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
* Get a test library for running many unit tests working
|
* Get a test library for running many unit tests working
|
||||||
* Write a human-readable display of the AST
|
* Write a human-readable display of the AST
|
||||||
|
* Make an automatic (macro-based?) system for numbering compiler errors, this should be every type of error
|
||||||
|
|
||||||
## Symbols
|
## Symbols
|
||||||
|
|
||||||
@ -13,6 +14,8 @@
|
|||||||
* dealing with variable lookup w/in functions/closures should probably happen in AST -> ReducedAST
|
* dealing with variable lookup w/in functions/closures should probably happen in AST -> ReducedAST
|
||||||
* b/c that's where we go from a string name to a canonical ID (for e.g. 2nd param in 3rd enclosing scope)
|
* b/c that's where we go from a string name to a canonical ID (for e.g. 2nd param in 3rd enclosing scope)
|
||||||
|
|
||||||
|
* In fact to prove this works, the symbol table shoudl _parallelize_ the process of checking subscopes for local items
|
||||||
|
|
||||||
* Old notes on a plan of attack:
|
* Old notes on a plan of attack:
|
||||||
|
|
||||||
1. modify visitor so it can handle scopes
|
1. modify visitor so it can handle scopes
|
||||||
|
@ -308,14 +308,15 @@ impl<'a> Reducer<'a> {
|
|||||||
impl ast::Pattern {
|
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 => Pattern::Ignored,
|
||||||
Pattern::Ignored
|
|
||||||
},
|
|
||||||
ast::Pattern::TuplePattern(subpatterns) => {
|
ast::Pattern::TuplePattern(subpatterns) => {
|
||||||
let pats: Vec<_> = subpatterns.iter().map(|pat| pat.reduce(symbol_table)).collect();
|
let items: Vec<_> = subpatterns.iter().map(|pat| pat.reduce(symbol_table)).collect();
|
||||||
let pats: Result<Vec<Pattern>, PatternError> = pats.into_iter().collect();
|
let items: Result<Vec<Pattern>, PatternError> = items.into_iter().collect();
|
||||||
let pats = pats?;
|
let items = items?;
|
||||||
Pattern::Tuple(pats)
|
Pattern::Tuple {
|
||||||
|
tag: None,
|
||||||
|
subpatterns: items,
|
||||||
|
}
|
||||||
},
|
},
|
||||||
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) {
|
||||||
@ -328,15 +329,31 @@ impl ast::Pattern {
|
|||||||
ast::PatternLiteral::StringPattern(s) => Literal::StringLit(s.clone()),
|
ast::PatternLiteral::StringPattern(s) => Literal::StringLit(s.clone()),
|
||||||
ast::PatternLiteral::BoolPattern(b) => Literal::Bool(*b),
|
ast::PatternLiteral::BoolPattern(b) => Literal::Bool(*b),
|
||||||
}),
|
}),
|
||||||
ast::Pattern::TupleStruct(_name, _subpatterns) => {
|
ast::Pattern::TupleStruct(name, subpatterns) => {
|
||||||
unimplemented!()
|
let symbol = symbol_table.lookup_symbol(&name.id).unwrap();
|
||||||
|
if let SymbolSpec::DataConstructor { index: tag, type_id, arity } = symbol.spec() {
|
||||||
|
|
||||||
|
let items: Vec<_> = subpatterns.iter().map(|pat| pat.reduce(symbol_table)).collect();
|
||||||
|
let items: Result<Vec<Pattern>, PatternError> = items.into_iter().collect();
|
||||||
|
let items = items?;
|
||||||
|
|
||||||
|
Pattern::Tuple {
|
||||||
|
tag: Some(tag as u32),
|
||||||
|
subpatterns: items,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Err("Internal error, trying to match something that's not a DataConstructor".into());
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ast::Pattern::VarOrName(name) => {
|
||||||
|
//TODO fix this symbol not existing
|
||||||
|
let symbol = symbol_table.lookup_symbol(&name.id).unwrap();
|
||||||
|
println!("VarOrName symbol: {:?}", symbol);
|
||||||
|
Pattern::Ignored
|
||||||
},
|
},
|
||||||
ast::Pattern::Record(name, /*Vec<(Rc<String>, Pattern)>*/ _) => {
|
ast::Pattern::Record(name, /*Vec<(Rc<String>, Pattern)>*/ _) => {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
},
|
},
|
||||||
ast::Pattern::VarOrName(_name) => {
|
|
||||||
unimplemented!()
|
|
||||||
},
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,10 @@ pub struct Alternative {
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Pattern {
|
pub enum Pattern {
|
||||||
Tuple(Vec<Pattern>),
|
Tuple {
|
||||||
|
subpatterns: Vec<Pattern>,
|
||||||
|
tag: Option<u32>,
|
||||||
|
},
|
||||||
Literal(Literal),
|
Literal(Literal),
|
||||||
Ignored,
|
Ignored,
|
||||||
}
|
}
|
||||||
|
@ -284,10 +284,19 @@ impl<'a> State<'a> {
|
|||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
},
|
},
|
||||||
Pattern::Tuple(subpatterns) => match scrut {
|
Pattern::Tuple { subpatterns, tag } => match tag {
|
||||||
|
None => match scrut {
|
||||||
Primitive::Tuple(items) if items.len() == subpatterns.len() =>
|
Primitive::Tuple(items) if items.len() == subpatterns.len() =>
|
||||||
items.iter().zip(subpatterns.iter()).all(|(item, subpat)| matches(item, subpat)),
|
items.iter().zip(subpatterns.iter()).all(|(item, subpat)| matches(item, subpat)),
|
||||||
_ => false //TODO should be a type error
|
_ => false //TODO should be a type error
|
||||||
|
},
|
||||||
|
Some(pattern_tag) => match scrut {
|
||||||
|
//TODO should test type_ids for runtime type checking, once those work
|
||||||
|
Primitive::Object { tag, items, .. } if tag == pattern_tag && items.len() == subpatterns.len() => {
|
||||||
|
items.iter().zip(subpatterns.iter()).all(|(item, subpat)| matches(item, subpat))
|
||||||
|
}
|
||||||
|
_ => false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,6 @@ use crate::tree_walk_eval::State;
|
|||||||
|
|
||||||
fn evaluate_input(input: &str) -> Result<String, String> {
|
fn evaluate_input(input: &str) -> Result<String, String> {
|
||||||
let ast = crate::util::quick_ast(input);
|
let ast = crate::util::quick_ast(input);
|
||||||
println!("AST: {:?}", ast);
|
|
||||||
let mut symbol_table = SymbolTable::new();
|
let mut symbol_table = SymbolTable::new();
|
||||||
symbol_table.process_ast(&ast).unwrap();
|
symbol_table.process_ast(&ast).unwrap();
|
||||||
let reduced_ir = crate::reduced_ir::reduce(&ast, &symbol_table);
|
let reduced_ir = crate::reduced_ir::reduce(&ast, &symbol_table);
|
||||||
|
Loading…
Reference in New Issue
Block a user