summaryrefslogtreecommitdiff
path: root/src/lower/mod.rs
diff options
context:
space:
mode:
authorGreg Brown <gmb60@cam.ac.uk>2021-03-02 16:08:26 +0000
committerGreg Brown <gmb60@cam.ac.uk>2021-03-02 16:08:26 +0000
commitfa69e4edd87e3ec319ac4962c619b04e2203628e (patch)
tree1ef140e9c49cb1ee9ba327b574c69dac25fefdc9 /src/lower/mod.rs
parent7934aa9af22e8fa3c33a45bc08e732a73c0cabf5 (diff)
Introduce function types.
Function types are just functions from types to check-results. Nothing more than delayed computation. Efficiency will initially be no better than current. Caching results could help, but that's a future problem. An alternative approach is introducing constraints. That would be a bigger architectural change, with more complex processing. On the other hand, adding future extensions would be easier.
Diffstat (limited to 'src/lower/mod.rs')
-rw-r--r--src/lower/mod.rs29
1 files changed, 17 insertions, 12 deletions
diff --git a/src/lower/mod.rs b/src/lower/mod.rs
index dcd0f1f..83ac6ab 100644
--- a/src/lower/mod.rs
+++ b/src/lower/mod.rs
@@ -8,10 +8,15 @@ use proc_macro2::{Ident, Span, TokenStream, TokenTree};
use quote::{format_ident, quote, quote_spanned};
use syn::{Index, LitStr};
-use crate::chomp::{Name, ast, set::FirstSet, typed::{
+use crate::chomp::{
+ ast,
+ set::FirstSet,
+ typed::{
lower::{Backend, GenerateCode},
- Alt, Cat, Epsilon, Fix, Literal, Type, Typed, TypedExpression, Variable,
- }};
+ Alt, Cat, Epsilon, Fix, GroundType, Literal, Type, Typed, TypedExpression, Variable,
+ },
+ Name,
+};
#[derive(Clone, Debug)]
struct Ty {
@@ -28,7 +33,6 @@ pub struct RustBackend {
lit_map: HashMap<String, usize>,
cat_map: HashMap<Vec<usize>, usize>,
alt_map: HashMap<Vec<usize>, usize>,
- fix_map: HashMap<TypedExpression, usize>,
var_map: HashMap<usize, usize>, // Key is fix point ID
name_map: HashMap<Ident, usize>,
can_char: BTreeSet<usize>,
@@ -139,7 +143,6 @@ impl Default for RustBackend {
lit_map: HashMap::new(),
cat_map: HashMap::new(),
alt_map: HashMap::new(),
- fix_map: HashMap::new(),
var_map: HashMap::new(),
name_map: HashMap::new(),
can_char: BTreeSet::new(),
@@ -286,6 +289,13 @@ impl Backend for RustBackend {
fn gen_alt(&mut self, name: Option<Name>, span: Option<Span>, alt: Alt) -> Self::Id {
let span = span.unwrap_or_else(Span::call_site);
let (tys, name_spans, ids) = self.recurse_exprs(alt);
+ let tys = tys
+ .into_iter()
+ .map(|ty| {
+ ty.into_ground(None)
+ .expect("alt must have ground-typed children")
+ })
+ .collect::<Vec<_>>();
if let Some(&id) = self.alt_map.get(&ids) {
return id;
@@ -302,7 +312,7 @@ impl Backend for RustBackend {
.map(|(idx, _)| name_parts[idx].clone());
let (first_alts, firsts): (Vec<_>, Vec<_>) = tys
.iter()
- .map(Type::first_set)
+ .map(GroundType::first_set)
.cloned()
.enumerate()
.filter(|(_, fs)| !fs.is_empty())
@@ -313,7 +323,7 @@ impl Backend for RustBackend {
.unzip();
let all_firsts = tys
.iter()
- .map(Type::first_set)
+ .map(GroundType::first_set)
.cloned()
.flat_map(FirstSet::into_iter);
@@ -383,12 +393,7 @@ impl Backend for RustBackend {
let span = span.unwrap_or_else(Span::call_site);
let inner = fix.unwrap();
- if let Some(&id) = self.fix_map.get(&inner) {
- return id;
- }
-
let (id, name) = self.new_type_name("Fix", name, span);
- self.fix_map.insert(inner.clone(), id);
self.data.push(Ty {
name: TokenTree::from(name.clone()).into(),