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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
use std::fmt::{self, Display, Formatter};
use super::value::{
BinaryOperator, Block, ConditionalBlock, FnHeader, Identifier, Literal, UnaryOperator,
};
#[derive(Debug)]
pub enum Expression {
Binary {
left: Box<Expression>,
op: BinaryOperator,
right: Box<Expression>,
},
Unary {
op: UnaryOperator,
right: Box<Expression>,
},
Group(Box<Expression>),
Block(Box<Block>),
Fn {
header: FnHeader,
body: Box<Block>,
},
If {
conditionals: Vec<ConditionalBlock>,
else_block: Option<Box<Block>>,
},
Literal(Literal),
Identifier(Identifier),
}
impl Display for Expression {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
self.nested_fmt(f, 0)
}
}
impl Expression {
pub(crate) fn nested_fmt(&self, f: &mut Formatter<'_>, depth: usize) -> fmt::Result {
let pad = " ".repeat(depth);
match self {
Expression::Binary { left, op, right } => {
writeln!(f, "{}Binary:", pad)?;
writeln!(f, "{}- Left:", pad)?;
left.nested_fmt(f, depth + 1)?;
writeln!(f, "{}- Operator: {:?}", pad, op)?;
writeln!(f, "{}- Right:", pad)?;
right.nested_fmt(f, depth + 1)?;
}
Expression::Unary { op, right } => {
writeln!(f, "{}Unary:", pad)?;
writeln!(f, "{}- Operator: {:?}", pad, op)?;
writeln!(f, "{}- Right:", pad)?;
right.nested_fmt(f, depth + 1)?;
}
Expression::Group(node) => {
writeln!(f, "{}Group:", pad)?;
node.nested_fmt(f, depth + 1)?;
}
Expression::Block(block) => {
Self::block_fmt(f, block, depth + 1)?;
}
Expression::Fn { header, body } => {
write!(f, "{}Fn (", pad)?;
// Write self receiver
if header.has_self_receiver {
write!(f, "self, ")?;
}
// Write parameters
for p in header.parameters.iter() {
write!(
f,
"{}: {}, ",
p.identifier,
p.type_constraint.as_ref().unwrap_or(&"_".into())
)?;
}
// Write return type
writeln!(
f,
") -> {}:",
header.return_type.as_ref().unwrap_or(&"_".into())
)?;
Self::block_fmt(f, body, depth + 1)?;
}
Expression::Literal(literal) => {
writeln!(f, "{}Literal: {:?}", pad, literal)?;
}
Expression::Identifier(identifier) => {
writeln!(f, "{}Identifier: {:?}", pad, identifier)?;
}
Expression::If { conditionals, else_block } => {
writeln!(f, "{}If:", pad)?;
for (i, c) in conditionals.iter().enumerate() {
writeln!(f, "{}- Condition {}:", pad, i)?;
c.condition.nested_fmt(f, depth + 1)?;
writeln!(f, "{}- Body {}:", pad, i)?;
Self::block_fmt(f, &c.block, depth + 1)?;
}
if let Some(e) = else_block {
writeln!(f, "{}- Else:", pad)?;
Self::block_fmt(f, e, depth + 1)?;
}
},
}
Ok(())
}
fn block_fmt(f: &mut Formatter<'_>, block: &Block, depth: usize) -> fmt::Result {
let pad = " ".repeat(depth);
writeln!(f, "{}Block:", pad)?;
for (i, statement) in block.statements.iter().enumerate() {
writeln!(f, "{}- {}:", pad, i)?;
statement.nested_fmt(f, depth + 1)?;
}
if let Some(tail_expression) = &block.tail_expression {
writeln!(f, "{}- Tail:", pad)?;
tail_expression.nested_fmt(f, depth + 1)?;
}
Ok(())
}
}
|