doughlang: symbol interning and AST reparameterization
- intern: Add interners from cl-intern - ast: - Break AST into ternimals (AstTypes) and nonterminals (Expr, Pat, Bind, Make, Use) - Make AST generic over terminals (except operators, for now)
This commit is contained in:
@@ -5,11 +5,13 @@ use std::{convert::Infallible, error::Error};
|
||||
use doughlang::{
|
||||
ast::{
|
||||
fold::{Fold, Foldable},
|
||||
types::{Literal, Path, Symbol},
|
||||
visit::{Visit, Walk},
|
||||
*,
|
||||
},
|
||||
lexer::Lexer,
|
||||
parser::{Parser, expr::Prec},
|
||||
span::Span,
|
||||
};
|
||||
|
||||
const CODE: &str = r#"
|
||||
@@ -86,6 +88,7 @@ fn main() -> Result<(), Box<dyn Error>> {
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq)]
|
||||
struct CountNodes {
|
||||
exprs: usize,
|
||||
macro_ids: usize,
|
||||
idents: usize,
|
||||
paths: usize,
|
||||
literals: usize,
|
||||
@@ -102,50 +105,54 @@ impl CountNodes {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visit<'a> for CountNodes {
|
||||
impl<'a, A: AstTypes> Visit<'a, A> for CountNodes {
|
||||
type Error = Infallible;
|
||||
|
||||
fn visit_expr<A: Annotation>(&mut self, expr: &'a Expr<A>) -> Result<(), Self::Error> {
|
||||
fn visit_macro_id(&mut self, _name: &'a A::MacroId) -> Result<(), Self::Error> {
|
||||
self.macro_ids += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_symbol(&mut self, _name: &'a A::Symbol) -> Result<(), Self::Error> {
|
||||
self.idents += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, _path: &'a A::Path) -> Result<(), Self::Error> {
|
||||
self.paths += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_literal(&mut self, _lit: &'a A::Literal) -> Result<(), Self::Error> {
|
||||
self.literals += 1;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_use(&mut self, item: &'a Use<A>) -> Result<(), Self::Error> {
|
||||
self.uses += 1;
|
||||
item.children(self)
|
||||
}
|
||||
fn visit_expr(&mut self, expr: &'a Expr<A>) -> Result<(), Self::Error> {
|
||||
self.exprs += 1;
|
||||
expr.children(self)
|
||||
}
|
||||
|
||||
fn visit_ident(&mut self, name: &'a str) -> Result<(), Self::Error> {
|
||||
self.idents += 1;
|
||||
name.children(self)
|
||||
}
|
||||
|
||||
fn visit_path(&mut self, path: &'a Path) -> Result<(), Self::Error> {
|
||||
self.paths += 1;
|
||||
path.children(self)
|
||||
}
|
||||
|
||||
fn visit_literal(&mut self, lit: &'a Literal) -> Result<(), Self::Error> {
|
||||
self.literals += 1;
|
||||
lit.children(self)
|
||||
}
|
||||
|
||||
fn visit_use(&mut self, item: &'a Use) -> Result<(), Self::Error> {
|
||||
self.uses += 1;
|
||||
item.children(self)
|
||||
}
|
||||
|
||||
fn visit_pat<A: Annotation>(&mut self, item: &'a Pat<A>) -> Result<(), Self::Error> {
|
||||
fn visit_pat(&mut self, item: &'a Pat<A>) -> Result<(), Self::Error> {
|
||||
self.patterns += 1;
|
||||
item.children(self)
|
||||
}
|
||||
|
||||
fn visit_bind<A: Annotation>(&mut self, item: &'a Bind<A>) -> Result<(), Self::Error> {
|
||||
fn visit_bind(&mut self, item: &'a Bind<A>) -> Result<(), Self::Error> {
|
||||
self.binds += 1;
|
||||
item.children(self)
|
||||
}
|
||||
|
||||
fn visit_make<A: Annotation>(&mut self, item: &'a Make<A>) -> Result<(), Self::Error> {
|
||||
fn visit_make(&mut self, item: &'a Make<A>) -> Result<(), Self::Error> {
|
||||
self.makes += 1;
|
||||
item.children(self)
|
||||
}
|
||||
|
||||
fn visit_makearm<A: Annotation>(&mut self, item: &'a MakeArm<A>) -> Result<(), Self::Error> {
|
||||
fn visit_makearm(&mut self, item: &'a MakeArm<A>) -> Result<(), Self::Error> {
|
||||
self.makearms += 1;
|
||||
item.children(self)
|
||||
}
|
||||
@@ -153,10 +160,26 @@ impl<'a> Visit<'a> for CountNodes {
|
||||
|
||||
struct Sevenfold;
|
||||
|
||||
impl<A: Annotation> Fold<A> for Sevenfold {
|
||||
impl Fold<DefaultTypes> for Sevenfold {
|
||||
type Error = ();
|
||||
|
||||
fn fold_annotation(&mut self, anno: Span) -> Result<Span, Self::Error> {
|
||||
Ok(anno)
|
||||
}
|
||||
|
||||
fn fold_literal(&mut self, _lit: Literal) -> Result<Literal, Self::Error> {
|
||||
Ok(Literal::Int(7, 10))
|
||||
}
|
||||
|
||||
fn fold_macro_id(&mut self, name: Symbol) -> Result<Symbol, Self::Error> {
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
fn fold_symbol(&mut self, name: Symbol) -> Result<Symbol, Self::Error> {
|
||||
Ok(name)
|
||||
}
|
||||
|
||||
fn fold_path(&mut self, path: Path) -> Result<Path, Self::Error> {
|
||||
Ok(path)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user