summaryrefslogtreecommitdiff
path: root/src/lower/mod.rs
blob: 242fa47e144d6d08962f2429366a0afa2434a9b9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
use crate::chomp::typed::{
    Alt, Cat, Epsilon, Fix, Literal, RawTypedExpression, TypedExpression, Variable,
};

pub mod rust;

pub trait Backend: Default {
    type Id;
    type Code;

    fn gen_epsilon(&mut self, eps: Epsilon) -> Self::Id;

    fn gen_literal(&mut self, lit: Literal) -> Self::Id;

    fn gen_cat(&mut self, cat: Cat) -> Self::Id;

    fn gen_alt(&mut self, alt: Alt) -> Self::Id;

    fn gen_fix(&mut self, fix: Fix) -> Self::Id;

    fn gen_variable(&mut self, var: Variable) -> Self::Id;

    fn emit_code(self, id: Self::Id) -> Self::Code;
}

pub trait GenerateCode {
    fn gen<B: Backend>(self, backend: &mut B) -> B::Id;
}

macro_rules! generate_leaf {
    ($ty:ty, $gen:ident) => {
        impl GenerateCode for $ty {
            fn gen<B: Backend>(self, backend: &mut B) -> B::Id {
                backend.$gen(self)
            }
        }
    };
}

generate_leaf!(Epsilon, gen_epsilon);
generate_leaf!(Literal, gen_literal);
generate_leaf!(Cat, gen_cat);
generate_leaf!(Alt, gen_alt);
generate_leaf!(Fix, gen_fix);
generate_leaf!(Variable, gen_variable);

impl GenerateCode for TypedExpression {
    fn gen<B: Backend>(self, backend: &mut B) -> B::Id {
        match self.inner {
            RawTypedExpression::Epsilon(e) => e.gen(backend),
            RawTypedExpression::Literal(l) => l.gen(backend),
            RawTypedExpression::Cat(c) => c.gen(backend),
            RawTypedExpression::Alt(a) => a.gen(backend),
            RawTypedExpression::Fix(f) => f.gen(backend),
            RawTypedExpression::Variable(v) => v.gen(backend),
        }
    }
}