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
|
use crate::tokenizer::If;
use std::{fmt::Display, iter::Peekable};
use crate::parser::{Expr, ExprT, Metadata, Scope};
#[derive(Clone, Debug)]
pub enum DepthExpr<'a> {
Decision {
cond: Box<&'a str>, // TODO: take DepthExpr
t: Scope,
then_branch: Box<Vec<DepthExpr<'a>>>,
else_branch: Option<Box<Vec<DepthExpr<'a>>>>,
},
IO(&'a str),
Process(&'a str),
}
impl<'a> Display for DepthExpr<'a> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"{}",
match self {
DepthExpr::IO(s) => s.to_string(),
DepthExpr::Process(s) => s.to_string(),
_ => panic!("Cannot convert complex field to string"),
}
)
}
}
pub fn parse<'a>(vec: &Vec<Expr<'a>>) -> Vec<DepthExpr<'a>> {
let mut exprs: Vec<DepthExpr<'a>> = Vec::new();
let mut it = vec
.iter()
.peekable();
while let Some(e) = it.next() {
match e.expr {
ExprT::Decision((cond, scope)) => {
let then_branch = parse(&entire_scopes(&mut it));
let else_branch = if let Some(n) = it.peek() {
match n.expr {
ExprT::Decision((_, scope)) => {
if let Scope::If(If::Else) = scope {
it.next();
Some(Box::new(parse(&entire_scopes(&mut it))))
} else {
None
}
}
_ => None,
}
} else {
None
};
exprs.push(DepthExpr::Decision {
cond: Box::new(cond),
t: scope,
then_branch: Box::new(then_branch),
else_branch,
});
}
ExprT::IO(s) => {
if !s.is_empty() {
exprs.push(DepthExpr::IO(s))
}
}
ExprT::Process(s) => {
if !s.is_empty() {
exprs.push(DepthExpr::Process(s))
}
}
ExprT::StartOrStop(_) => {}
}
}
exprs
}
fn entire_scopes<'a>(it: &mut Peekable<std::slice::Iter<'_, Expr<'a>>>) -> Vec<Expr<'a>> {
let mut exprs: Vec<Expr<'a>> = Vec::new();
let mut scope_count: u32 = 1; // assume we already entered the scope
for i in it {
if let Some(meta) = i.meta {
match meta {
Metadata::StartScope => {
scope_count = scope_count
.checked_add(1)
.expect("Scopes nested too deep")
}
Metadata::EndScope => {
scope_count = scope_count
.checked_sub(1)
.expect("Closed not opened scope")
}
}
}
exprs.push(*i);
if scope_count == 0 {
break;
}
}
exprs
}
|