steel-parser 0.8.2

Parser for use within steel
Documentation
use crate::ast::*;

use crate::ast::{
    Atom, Begin, Define, If, LambdaFunction, Let, List, Macro, Quote, Require, Return, Set,
    SyntaxRules,
};

pub use eraser::Eraser;

mod eraser {
    use crate::span::Span;

    use super::*;

    pub struct Eraser;

    impl Eraser {
        pub fn visit_many(&mut self, exprs: &mut [ExprKind]) {
            for expr in exprs {
                self.visit(expr)
            }
        }
    }

    impl VisitorMutRef for Eraser {
        type Output = ();

        fn visit_if(&mut self, if_: &mut If) {
            if_.location.span = Span::default();

            self.visit(&mut if_.test_expr);
            self.visit(&mut if_.then_expr);
            self.visit(&mut if_.else_expr);
        }

        fn visit_define(&mut self, define: &mut Define) {
            define.location.span = Span::default();

            self.visit(&mut define.name);
            self.visit(&mut define.body);
        }

        fn visit_lambda_function(&mut self, lambda_function: &mut LambdaFunction) {
            lambda_function.location.span = Span::default();

            lambda_function
                .args
                .iter_mut()
                .for_each(|arg| self.visit(arg));
            self.visit(&mut lambda_function.body);
        }

        fn visit_begin(&mut self, begin: &mut Begin) {
            begin.location.span = Span::default();

            begin.exprs.iter_mut().for_each(|expr| self.visit(expr));
        }

        fn visit_return(&mut self, return_: &mut Return) {
            return_.location.span = Span::default();

            self.visit(&mut return_.expr);
        }

        fn visit_quote(&mut self, quote: &mut Quote) {
            quote.location.span = Span::default();

            self.visit(&mut quote.expr);
        }

        fn visit_macro(&mut self, macro_: &mut Macro) {
            macro_.location.span = Span::default();

            self.visit(&mut macro_.name);
            self.visit_syntax_rules(&mut macro_.syntax_rules);
        }

        fn visit_atom(&mut self, atom: &mut Atom) {
            atom.syn.span = Span::default();
        }

        fn visit_list(&mut self, list: &mut List) {
            list.location = Span::default();

            list.args.iter_mut().for_each(|expr| self.visit(expr));
        }

        fn visit_syntax_rules(&mut self, rules: &mut SyntaxRules) {
            rules.location.span = Span::default();

            rules.syntax.iter_mut().for_each(|expr| self.visit(expr));
            rules.patterns.iter_mut().for_each(|pattern| {
                self.visit(&mut pattern.pattern);
                self.visit(&mut pattern.body);
            });
        }

        fn visit_set(&mut self, set: &mut Set) {
            set.location.span = Span::default();

            self.visit(&mut set.variable);
            self.visit(&mut set.expr);
        }

        fn visit_require(&mut self, require: &mut Require) {
            require.location.span = Span::default();

            require.modules.iter_mut().for_each(|expr| self.visit(expr));
        }

        fn visit_let(&mut self, let_: &mut Let) {
            let_.location.span = Span::default();

            let_.bindings.iter_mut().for_each(|binding| {
                self.visit(&mut binding.0);
                self.visit(&mut binding.1);
            });

            self.visit(&mut let_.body_expr);
        }

        fn visit_vector(&mut self, v: &mut Vector) -> Self::Output {
            v.span = Span::default();

            for arg in &mut v.args {
                self.visit(arg);
            }
        }
    }
}

pub trait VisitorMut {
    type Output;

    fn visit(&mut self, expr: &ExprKind) -> Self::Output {
        match expr {
            ExprKind::If(f) => self.visit_if(f),
            ExprKind::Define(d) => self.visit_define(d),
            ExprKind::LambdaFunction(l) => self.visit_lambda_function(l),
            ExprKind::Begin(b) => self.visit_begin(b),
            ExprKind::Return(r) => self.visit_return(r),
            ExprKind::Let(l) => self.visit_let(l),
            ExprKind::Quote(q) => self.visit_quote(q),
            ExprKind::Macro(m) => self.visit_macro(m),
            ExprKind::Atom(a) => self.visit_atom(a),
            ExprKind::List(l) => self.visit_list(l),
            ExprKind::SyntaxRules(s) => self.visit_syntax_rules(s),
            ExprKind::Set(s) => self.visit_set(s),
            ExprKind::Require(r) => self.visit_require(r),
            ExprKind::Vector(v) => self.visit_vector(v),
        }
    }

    fn visit_if(&mut self, f: &If) -> Self::Output;
    fn visit_define(&mut self, define: &Define) -> Self::Output;
    fn visit_lambda_function(&mut self, lambda_function: &LambdaFunction) -> Self::Output;
    fn visit_begin(&mut self, begin: &Begin) -> Self::Output;
    fn visit_return(&mut self, r: &Return) -> Self::Output;
    fn visit_quote(&mut self, quote: &Quote) -> Self::Output;
    fn visit_macro(&mut self, m: &Macro) -> Self::Output;
    fn visit_atom(&mut self, a: &Atom) -> Self::Output;
    fn visit_list(&mut self, l: &List) -> Self::Output;
    fn visit_syntax_rules(&mut self, l: &SyntaxRules) -> Self::Output;
    fn visit_set(&mut self, s: &Set) -> Self::Output;
    fn visit_require(&mut self, s: &Require) -> Self::Output;
    fn visit_let(&mut self, l: &Let) -> Self::Output;
    fn visit_vector(&mut self, v: &Vector) -> Self::Output;
}

pub trait Visitor {
    type Output;

    fn visit(&self, expr: &ExprKind) -> Self::Output {
        match expr {
            ExprKind::If(f) => self.visit_if(f),
            ExprKind::Define(d) => self.visit_define(d),
            ExprKind::LambdaFunction(l) => self.visit_lambda_function(l),
            ExprKind::Begin(b) => self.visit_begin(b),
            ExprKind::Return(r) => self.visit_return(r),
            ExprKind::Let(l) => self.visit_let(l),
            ExprKind::Quote(q) => self.visit_quote(q),
            ExprKind::Macro(m) => self.visit_macro(m),
            ExprKind::Atom(a) => self.visit_atom(a),
            ExprKind::List(l) => self.visit_list(l),
            ExprKind::SyntaxRules(s) => self.visit_syntax_rules(s),
            ExprKind::Set(s) => self.visit_set(s),
            ExprKind::Require(r) => self.visit_require(r),
            ExprKind::Vector(v) => self.visit_vector(v),
        }
    }

    fn visit_if(&self, f: &If) -> Self::Output;
    fn visit_define(&self, define: &Define) -> Self::Output;
    fn visit_lambda_function(&self, lambda_function: &LambdaFunction) -> Self::Output;
    fn visit_begin(&self, begin: &Begin) -> Self::Output;
    fn visit_return(&self, r: &Return) -> Self::Output;
    fn visit_quote(&self, quote: &Quote) -> Self::Output;
    fn visit_macro(&self, m: &Macro) -> Self::Output;
    fn visit_atom(&self, a: &Atom) -> Self::Output;
    fn visit_list(&self, l: &List) -> Self::Output;
    fn visit_syntax_rules(&self, l: &SyntaxRules) -> Self::Output;
    fn visit_set(&self, s: &Set) -> Self::Output;
    fn visit_require(&self, s: &Require) -> Self::Output;
    fn visit_let(&self, l: &Let) -> Self::Output;
    fn visit_vector(&self, v: &Vector) -> Self::Output;
}

pub trait ConsumingVisitor {
    type Output;
    fn visit(&mut self, expr: ExprKind) -> Self::Output {
        match expr {
            ExprKind::If(f) => self.visit_if(f),
            ExprKind::Define(d) => self.visit_define(d),
            ExprKind::LambdaFunction(l) => self.visit_lambda_function(l),
            ExprKind::Begin(b) => self.visit_begin(b),
            ExprKind::Return(r) => self.visit_return(r),
            ExprKind::Let(l) => self.visit_let(l),
            ExprKind::Quote(q) => self.visit_quote(q),
            ExprKind::Macro(m) => self.visit_macro(m),
            ExprKind::Atom(a) => self.visit_atom(a),
            ExprKind::List(l) => self.visit_list(l),
            ExprKind::SyntaxRules(s) => self.visit_syntax_rules(s),
            ExprKind::Set(s) => self.visit_set(s),
            ExprKind::Require(r) => self.visit_require(r),
            ExprKind::Vector(v) => self.visit_vector(v),
        }
    }

    fn visit_if(&mut self, f: Box<If>) -> Self::Output;
    fn visit_define(&mut self, define: Box<Define>) -> Self::Output;
    fn visit_lambda_function(&mut self, lambda_function: Box<LambdaFunction>) -> Self::Output;
    fn visit_begin(&mut self, begin: Box<Begin>) -> Self::Output;
    fn visit_return(&mut self, r: Box<Return>) -> Self::Output;
    fn visit_quote(&mut self, quote: Box<Quote>) -> Self::Output;
    fn visit_macro(&mut self, m: Box<Macro>) -> Self::Output;
    fn visit_atom(&mut self, a: Atom) -> Self::Output;
    fn visit_list(&mut self, l: List) -> Self::Output;
    fn visit_syntax_rules(&mut self, l: Box<SyntaxRules>) -> Self::Output;
    fn visit_set(&mut self, s: Box<Set>) -> Self::Output;
    fn visit_require(&mut self, s: Box<Require>) -> Self::Output;
    fn visit_let(&mut self, l: Box<Let>) -> Self::Output;
    fn visit_vector(&mut self, v: Vector) -> Self::Output;
}

pub trait ConsumingVisitorRef {
    type Output;
    fn visit(&self, expr: ExprKind) -> Self::Output {
        match expr {
            ExprKind::If(f) => self.visit_if(f),
            ExprKind::Define(d) => self.visit_define(d),
            ExprKind::LambdaFunction(l) => self.visit_lambda_function(l),
            ExprKind::Begin(b) => self.visit_begin(b),
            ExprKind::Return(r) => self.visit_return(r),
            ExprKind::Let(l) => self.visit_let(l),
            ExprKind::Quote(q) => self.visit_quote(q),
            ExprKind::Macro(m) => self.visit_macro(m),
            ExprKind::Atom(a) => self.visit_atom(a),
            ExprKind::List(l) => self.visit_list(l),
            ExprKind::SyntaxRules(s) => self.visit_syntax_rules(s),
            ExprKind::Set(s) => self.visit_set(s),
            ExprKind::Require(r) => self.visit_require(r),
            ExprKind::Vector(v) => self.visit_vector(v),
        }
    }

    fn visit_if(&self, f: Box<If>) -> Self::Output;
    fn visit_define(&self, define: Box<Define>) -> Self::Output;
    fn visit_lambda_function(&self, lambda_function: Box<LambdaFunction>) -> Self::Output;
    fn visit_begin(&self, begin: Box<Begin>) -> Self::Output;
    fn visit_return(&self, r: Box<Return>) -> Self::Output;
    fn visit_quote(&self, quote: Box<Quote>) -> Self::Output;
    fn visit_macro(&self, m: Box<Macro>) -> Self::Output;
    fn visit_atom(&self, a: Atom) -> Self::Output;
    fn visit_list(&self, l: List) -> Self::Output;
    fn visit_syntax_rules(&self, l: Box<SyntaxRules>) -> Self::Output;
    fn visit_set(&self, s: Box<Set>) -> Self::Output;
    fn visit_require(&self, s: Box<Require>) -> Self::Output;
    fn visit_let(&self, l: Box<Let>) -> Self::Output;
    fn visit_vector(&self, v: Vector) -> Self::Output;
}

pub trait VisitorMutRef {
    type Output;

    fn visit(&mut self, expr: &mut ExprKind) -> Self::Output {
        match expr {
            ExprKind::If(f) => self.visit_if(f),
            ExprKind::Define(d) => self.visit_define(d),
            ExprKind::LambdaFunction(l) => self.visit_lambda_function(l),
            ExprKind::Begin(b) => self.visit_begin(b),
            ExprKind::Return(r) => self.visit_return(r),
            ExprKind::Let(l) => self.visit_let(l),
            ExprKind::Quote(q) => self.visit_quote(q),
            ExprKind::Macro(m) => self.visit_macro(m),
            ExprKind::Atom(a) => self.visit_atom(a),
            ExprKind::List(l) => self.visit_list(l),
            ExprKind::SyntaxRules(s) => self.visit_syntax_rules(s),
            ExprKind::Set(s) => self.visit_set(s),
            ExprKind::Require(r) => self.visit_require(r),
            ExprKind::Vector(v) => self.visit_vector(v),
        }
    }

    fn visit_if(&mut self, f: &mut If) -> Self::Output;
    fn visit_define(&mut self, define: &mut Define) -> Self::Output;
    fn visit_lambda_function(&mut self, lambda_function: &mut LambdaFunction) -> Self::Output;
    fn visit_begin(&mut self, begin: &mut Begin) -> Self::Output;
    fn visit_return(&mut self, r: &mut Return) -> Self::Output;
    fn visit_quote(&mut self, quote: &mut Quote) -> Self::Output;
    fn visit_macro(&mut self, m: &mut Macro) -> Self::Output;
    fn visit_atom(&mut self, a: &mut Atom) -> Self::Output;
    fn visit_list(&mut self, l: &mut List) -> Self::Output;
    fn visit_syntax_rules(&mut self, l: &mut SyntaxRules) -> Self::Output;
    fn visit_set(&mut self, s: &mut Set) -> Self::Output;
    fn visit_require(&mut self, s: &mut Require) -> Self::Output;
    fn visit_let(&mut self, l: &mut Let) -> Self::Output;
    fn visit_vector(&mut self, v: &mut Vector) -> Self::Output;
}