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
|
chomp_macro::nibble! {
let opt(x) = _ : None | x : Some;
let star(x) = [rec](opt(x.rec));
let plus(x) = (x : First).(star(x) : Rest);
let ws = star(" ");
let list(x, p) = (x : First).(star(p.ws.x) : Rest);
let number = plus("0" | "1" | "2"| "3" | "4" | "5" | "6" | "7" | "8" | "9");
let term(e) = ((number : Pos | "-".ws.number : Neg | "(".ws.(e : Inner).")" : Parens) : RawTerm).ws;
let prod(e) = list(term(e), "*"|"/");
let expr(e) = list(prod(e), "+"|"-");
let arith = [e](expr(e));
match [rec]((" ".rec : Base | arith) : Ast);
}
impl From<Ast> for i64 {
fn from(mut a: Ast) -> Self {
loop {
match a.0 {
Ast1::Base1(b) => a = *b.rec1,
Ast1::Arith1(a) => return a.into(),
}
}
}
}
impl From<Arith1> for i64 {
fn from(a: Arith1) -> Self {
a.0.into()
}
}
impl From<Expr1> for i64 {
fn from(l: Expr1) -> Self {
let mut acc = l.prod1.into();
let mut rest = l.rest1;
loop {
match rest.0 {
Opt5::None1(_) => return acc,
Opt5::Some1(s) => {
let v: i64 = s.x1.prod1.into();
match s.x1.p1 {
P2::Branch1(_) => acc += v,
P2::Branch2(_) => acc -= v,
}
rest = *s.rec1;
},
}
}
}
}
impl From<Prod1> for i64 {
fn from(l: Prod1) -> Self {
let mut acc = l.term1.into();
let mut rest = l.rest1;
loop {
match rest.0 {
Opt3::None1(_) => return acc,
Opt3::Some1(s) => {
let v: i64 = s.x1.term1.into();
match s.x1.p1 {
P1::Branch1(_) => acc *= v,
P1::Branch2(_) => acc /= v,
}
rest = *s.rec1;
}
}
}
}
}
impl From<Prod2> for i64 {
fn from(l: Prod2) -> Self {
let mut acc = l.term1.into();
let mut rest = l.rest1;
loop {
match rest.0 {
Opt4::None1(_) => return acc,
Opt4::Some1(s) => {
let v: i64 = s.x1.term1.into();
match s.x1.p1 {
P1::Branch1(_) => acc *= v,
P1::Branch2(_) => acc /= v,
}
rest = *s.rec1;
}
}
}
}
}
impl From<Term1> for i64 {
fn from(t: Term1) -> Self {
match t.raw_term1 {
RawTerm1::Pos1(n) => n.into(),
RawTerm1::Neg1(n) => -i64::from(n.number1),
RawTerm1::Parens1(p) => (*p.e1).into(),
}
}
}
impl From<Pos1> for i64 {
fn from(p: Pos1) -> Self {
p.to_string().parse().unwrap()
}
}
|