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:
@@ -2,9 +2,9 @@ use std::error::Error;
|
||||
|
||||
use doughlang::{
|
||||
ast::{
|
||||
visit::{Visit, Walk},
|
||||
*,
|
||||
types::{Literal, Path}, visit::{Visit, Walk}, *
|
||||
},
|
||||
intern::interned::Interned,
|
||||
lexer::Lexer,
|
||||
parser::{Parser, expr::Prec},
|
||||
};
|
||||
@@ -126,19 +126,15 @@ impl ToLisp {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Visit<'a> for ToLisp {
|
||||
impl<'a> Visit<'a, DefaultTypes> for ToLisp {
|
||||
type Error = ();
|
||||
|
||||
fn visit(&mut self, walk: &'a impl Walk<'a>) -> Result<(), Self::Error> {
|
||||
walk.visit_in(self)
|
||||
}
|
||||
|
||||
fn visit_expr<A: Annotation>(&mut self, expr: &'a Expr<A>) -> Result<(), Self::Error> {
|
||||
fn visit_expr(&mut self, expr: &'a Expr) -> Result<(), Self::Error> {
|
||||
match expr {
|
||||
Expr::Omitted => print!("()"),
|
||||
Expr::Id(path) => path.visit_in(self)?,
|
||||
Expr::Id(path) => self.visit_path(path)?,
|
||||
Expr::MetId(id) => print!("`{id}"),
|
||||
Expr::Lit(literal) => literal.visit_in(self)?,
|
||||
Expr::Lit(literal) => self.visit_literal(literal)?,
|
||||
Expr::Use(import) => import.visit_in(self)?,
|
||||
Expr::Bind(bind) => bind.visit_in(self)?,
|
||||
Expr::Make(make) => make.visit_in(self)?,
|
||||
@@ -155,7 +151,12 @@ impl<'a> Visit<'a> for ToLisp {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_ident(&mut self, name: &'a str) -> Result<(), Self::Error> {
|
||||
fn visit_macro_id(&mut self, name: &'a Interned<'static, str>) -> Result<(), Self::Error> {
|
||||
print!("{name}");
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_symbol(&mut self, name: &'a Interned<'static, str>) -> Result<(), Self::Error> {
|
||||
print!("{name}");
|
||||
Ok(())
|
||||
}
|
||||
@@ -165,7 +166,7 @@ impl<'a> Visit<'a> for ToLisp {
|
||||
print!("(at");
|
||||
for part in parts {
|
||||
print!(" ");
|
||||
part.visit_in(self)?;
|
||||
self.visit_symbol(part)?;
|
||||
}
|
||||
print!(")");
|
||||
Ok(())
|
||||
@@ -179,7 +180,7 @@ impl<'a> Visit<'a> for ToLisp {
|
||||
fn visit_use(&mut self, item: &'a Use) -> Result<(), Self::Error> {
|
||||
match item {
|
||||
Use::Glob => print!("(use-glob)"),
|
||||
Use::Name(name) => name.visit_in(self)?,
|
||||
Use::Name(name) => self.visit_symbol(name)?,
|
||||
Use::Alias(name, alias) => print!("(use-alias {name} {alias})"),
|
||||
Use::Path(name, tree) => {
|
||||
print!("(use-path {name} ");
|
||||
@@ -198,7 +199,7 @@ impl<'a> Visit<'a> for ToLisp {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_pat<A: Annotation>(&mut self, item: &'a Pat<A>) -> Result<(), Self::Error> {
|
||||
fn visit_pat(&mut self, item: &'a Pat) -> Result<(), Self::Error> {
|
||||
match item {
|
||||
Pat::Ignore => print!("(ignore)"),
|
||||
Pat::Never => print!("(never)"),
|
||||
@@ -217,7 +218,7 @@ impl<'a> Visit<'a> for ToLisp {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_bind<A: Annotation>(&mut self, item: &'a Bind<A>) -> Result<(), Self::Error> {
|
||||
fn visit_bind(&mut self, item: &'a Bind) -> Result<(), Self::Error> {
|
||||
let Bind(op, generics, pattern, exprs) = item;
|
||||
print!("({} ", self.bind_op(*op));
|
||||
if !generics.is_empty() {
|
||||
@@ -236,11 +237,11 @@ impl<'a> Visit<'a> for ToLisp {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_make<A: Annotation>(&mut self, item: &'a Make<A>) -> Result<(), Self::Error> {
|
||||
fn visit_make(&mut self, item: &'a Make) -> Result<(), Self::Error> {
|
||||
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) -> Result<(), Self::Error> {
|
||||
item.children(self)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user