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
59
60
61
62
63
64
65
|
use std::rc::Rc;
use super::Context;
#[derive(Debug)]
pub struct Name;
#[derive(Debug)]
pub enum Shape {
Epsilon,
Literal(String),
Variable(usize),
Cat(Vec<Rc<Shape>>),
Alt(Vec<Rc<Shape>>),
Fix(Rc<Shape>),
Call(Vec<Rc<Shape>>),
Lambda(Vec<Name>, Rc<Shape>),
Let(Name, Rc<Shape>, Rc<Shape>),
}
pub(crate) fn as_tree(ctx: &mut Context, shape: &Rc<Shape>) -> Rc<super::ast::Tree> {
fn lambda_as_tree(ctx: &mut Context, count: usize, inner: &Rc<Shape>) -> Rc<super::ast::Tree> {
if count == 0 {
ctx.as_tree(inner)
} else {
ctx.new_lambda(|ctx| lambda_as_tree(ctx, count - 1, inner))
}
}
match shape.as_ref() {
Shape::Epsilon => ctx.tree_interner.epsilon(),
Shape::Literal(l) => ctx.tree_interner.literal(l.to_owned()),
Shape::Variable(idx) => ctx.lookup_tree_variable(*idx),
Shape::Cat(v) => {
let epsilon = ctx.tree_interner.epsilon();
v.into_iter().fold(epsilon, |front, back| {
let back = ctx.as_tree(back);
ctx.tree_interner.cat(front, back)
})
}
Shape::Alt(v) => {
let bottom = ctx.tree_interner.bottom();
v.into_iter().fold(bottom, |left, right| {
let right = ctx.as_tree(right);
ctx.tree_interner.alt(left, right)
})
}
Shape::Fix(inner) => {
let inner = ctx.as_tree(inner);
ctx.tree_interner.fix(inner)
}
Shape::Call(v) => {
let identity = ctx.tree_interner.identity();
v.into_iter().fold(identity, |fun, arg| {
let arg = ctx.as_tree(arg);
ctx.tree_interner.call(fun, arg)
})
}
Shape::Lambda(names, inner) => lambda_as_tree(ctx, names.len(), inner),
Shape::Let(_, bind, inner) => {
let bind = ctx.as_tree(bind);
ctx.new_let(bind, |ctx| ctx.as_tree(inner))
}
}
}
|