summaryrefslogtreecommitdiff
path: root/chomp-bench/src/arith/nibble.rs
diff options
context:
space:
mode:
Diffstat (limited to 'chomp-bench/src/arith/nibble.rs')
-rw-r--r--chomp-bench/src/arith/nibble.rs141
1 files changed, 72 insertions, 69 deletions
diff --git a/chomp-bench/src/arith/nibble.rs b/chomp-bench/src/arith/nibble.rs
index 54d9223..9feab51 100644
--- a/chomp-bench/src/arith/nibble.rs
+++ b/chomp-bench/src/arith/nibble.rs
@@ -1,26 +1,32 @@
+use std::mem;
+
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 opt some = _ : None | some;
+ let plus iter = !(/plus/ iter . (opt plus));
+ let star iter = opt (plus iter);
- let ws = star(" ");
- let list(x, p) = (x : First).(star(p.ws.x) : Rest);
+ let ws = star " ";
+ let list inner p = !(/list/ inner . opt (p . ws . list));
- 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));
+ let digit = "0" | "1" | "2"| "3" | "4" | "5" | "6" | "7" | "8" | "9";
+ let number = plus digit;
+ let term expr =
+ (( number : Pos
+ | "-" . ws . number : Neg
+ | "(" . ws . expr . ")" : Parens
+ ) : RawTerm) . ws;
+ let prod expr = list (term expr) ("*"|"/");
+ let arith expr = list (prod expr) ("+"|"-");
- match [rec]((" ".rec : Base | arith) : Ast);
+ match !(/rec/ " ".rec | !arith);
}
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(),
+ match a {
+ Ast::Branch1(cat) => a = *cat.rec1,
+ Ast::Branch2(arith) => return arith.into(),
}
}
}
@@ -28,67 +34,28 @@ impl From<Ast> for i64 {
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;
- },
+ let acc = a.prod1.into();
+ a.opt1.into_iter().fold(acc, |acc, (p, prod)| {
+ let v: i64 = prod.into();
+ match p {
+ P2::Branch1(_) => acc + v,
+ P2::Branch2(_) => acc - v,
}
- }
+ })
}
}
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;
- }
+ fn from(p: Prod1) -> Self {
+ let acc = p.term1.into();
+ p.opt1.into_iter().fold(acc, |acc, (p, term)| {
+ let v: i64 = term.into();
+ match p {
+ P1::Branch1(_) => acc * v,
+ P1::Branch2(_) => acc / v,
}
- }
- }
-}
+ })
-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;
- }
- }
- }
}
}
@@ -97,7 +64,7 @@ impl From<Term1> for i64 {
match t.raw_term1 {
RawTerm1::Pos1(n) => n.into(),
RawTerm1::Neg1(n) => -i64::from(n.number1),
- RawTerm1::Parens1(p) => (*p.e1).into(),
+ RawTerm1::Parens1(p) => (*p.expr1).into(),
}
}
}
@@ -107,3 +74,39 @@ impl From<Pos1> for i64 {
p.to_string().parse().unwrap()
}
}
+
+impl From<Number1> for i64 {
+ fn from(p: Number1) -> Self {
+ p.to_string().parse().unwrap()
+ }
+}
+
+impl Iterator for Opt5 {
+ type Item = (P2 , Prod1);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let orig = mem::replace(self, Self::None1(Epsilon));
+ match orig {
+ Self::None1(_) => None,
+ Self::Some1(some) => {
+ *self = some.list1.opt1;
+ Some((some.p1, some.list1.prod1))
+ }
+ }
+ }
+}
+
+impl Iterator for Opt4 {
+ type Item = (P1 , Term1);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ let orig = mem::replace(self, Self::None1(Epsilon));
+ match orig {
+ Self::None1(_) => None,
+ Self::Some1(some) => {
+ *self = some.list1.opt1;
+ Some((some.p1, some.list1.term1))
+ }
+ }
+ }
+}