From dfc08ff2c6580bbeb3951b223e0332546ba3b0d9 Mon Sep 17 00:00:00 2001 From: Greg Brown Date: Thu, 6 May 2021 19:40:59 +0100 Subject: Introduce lambda expressions. --- chomp-bench/src/arith/nibble.rs | 141 ++++++++++++++++++++-------------------- 1 file changed, 72 insertions(+), 69 deletions(-) (limited to 'chomp-bench/src/arith') 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 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 for i64 { impl From for i64 { fn from(a: Arith1) -> Self { - a.0.into() - } -} - -impl From 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 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 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 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 for i64 { p.to_string().parse().unwrap() } } + +impl From 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 { + 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 { + 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)) + } + } + } +} -- cgit v1.2.3