diff --git a/src/operator.rs b/src/operator.rs index 88f0e8b8df..f5fa56619b 100644 --- a/src/operator.rs +++ b/src/operator.rs @@ -8,8 +8,8 @@ pub enum Operator { Star, Slash, DoubleSlash, - TildeSlash, Percent, + DoublePercent, Plus, Minus, Equals, @@ -54,7 +54,7 @@ impl Operator { use self::Associativity::*; match self { - Pizza | Star | Slash | DoubleSlash | TildeSlash | Percent | Plus | Minus => { + Pizza | Star | Slash | DoubleSlash | DoublePercent | Percent | Plus | Minus => { LeftAssociative } And | Or | Caret => RightAssociative, @@ -65,7 +65,7 @@ impl Operator { fn precedence(&self) -> u8 { match self { Caret => 7, - Star | Slash | DoubleSlash | TildeSlash | Percent => 6, + Star | Slash | DoubleSlash | DoublePercent | Percent => 6, Plus | Minus => 5, Equals | LessThan | GreaterThan | LessThanOrEq | GreaterThanOrEq => 4, And => 3, diff --git a/src/parse/mod.rs b/src/parse/mod.rs index 2bbf184439..8b14fad3f0 100644 --- a/src/parse/mod.rs +++ b/src/parse/mod.rs @@ -31,10 +31,10 @@ use parse::blankspace::{ use parse::ident::{ident, Ident, MaybeQualified}; use parse::number_literal::number_literal; use parse::parser::{ - and, attempt, between, char, either, loc, map, map_with_arena, not_followed_by, one_of2, - one_of4, one_of5, one_of9, one_or_more, optional, sep_by0, skip_first, skip_second, string, - then, unexpected, unexpected_eof, zero_or_more, Either, Fail, FailReason, ParseResult, Parser, - State, + and, attempt, between, char, either, loc, map, map_with_arena, not_followed_by, one_of16, + one_of2, one_of4, one_of5, one_of9, one_or_more, optional, sep_by0, skip_first, skip_second, + string, then, unexpected, unexpected_eof, zero_or_more, Either, Fail, FailReason, ParseResult, + Parser, State, }; use parse::string_literal::string_literal; use region::Located; @@ -660,11 +660,25 @@ fn ident_to_expr<'a>(src: Ident<'a>) -> Expr<'a> { } pub fn operator<'a>() -> impl Parser<'a, Operator> { - one_of4( + one_of16( + // Sorted from highest to lowest predicted usage in practice, + // so that successful matches shorrt-circuit as early as possible. + map(string("|>"), |_| Operator::Pizza), + map(string("=="), |_| Operator::Equals), + map(string("&&"), |_| Operator::And), + map(string("||"), |_| Operator::Or), map(char('+'), |_| Operator::Plus), map(char('-'), |_| Operator::Minus), map(char('*'), |_| Operator::Star), map(char('/'), |_| Operator::Slash), + map(char('<'), |_| Operator::LessThan), + map(char('>'), |_| Operator::GreaterThan), + map(string("<="), |_| Operator::LessThanOrEq), + map(string(">="), |_| Operator::GreaterThanOrEq), + map(char('^'), |_| Operator::Caret), + map(char('%'), |_| Operator::Percent), + map(string("//"), |_| Operator::DoubleSlash), + map(string("%%"), |_| Operator::DoublePercent), ) } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index dc900e6812..e1aea11570 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -929,6 +929,224 @@ where one_of2(p1, one_of9(p2, p3, p4, p5, p6, p7, p8, p9, p10)) } +pub fn one_of11<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, A>( + p1: P1, + p2: P2, + p3: P3, + p4: P4, + p5: P5, + p6: P6, + p7: P7, + p8: P8, + p9: P9, + p10: P10, + p11: P11, +) -> impl Parser<'a, A> +where + P1: Parser<'a, A>, + P2: Parser<'a, A>, + P3: Parser<'a, A>, + P4: Parser<'a, A>, + P5: Parser<'a, A>, + P6: Parser<'a, A>, + P7: Parser<'a, A>, + P8: Parser<'a, A>, + P9: Parser<'a, A>, + P10: Parser<'a, A>, + P11: Parser<'a, A>, +{ + one_of2(p1, one_of10(p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)) +} + +pub fn one_of12<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, A>( + p1: P1, + p2: P2, + p3: P3, + p4: P4, + p5: P5, + p6: P6, + p7: P7, + p8: P8, + p9: P9, + p10: P10, + p11: P11, + p12: P12, +) -> impl Parser<'a, A> +where + P1: Parser<'a, A>, + P2: Parser<'a, A>, + P3: Parser<'a, A>, + P4: Parser<'a, A>, + P5: Parser<'a, A>, + P6: Parser<'a, A>, + P7: Parser<'a, A>, + P8: Parser<'a, A>, + P9: Parser<'a, A>, + P10: Parser<'a, A>, + P11: Parser<'a, A>, + P12: Parser<'a, A>, +{ + one_of2(p1, one_of11(p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12)) +} + +pub fn one_of13<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, A>( + p1: P1, + p2: P2, + p3: P3, + p4: P4, + p5: P5, + p6: P6, + p7: P7, + p8: P8, + p9: P9, + p10: P10, + p11: P11, + p12: P12, + p13: P13, +) -> impl Parser<'a, A> +where + P1: Parser<'a, A>, + P2: Parser<'a, A>, + P3: Parser<'a, A>, + P4: Parser<'a, A>, + P5: Parser<'a, A>, + P6: Parser<'a, A>, + P7: Parser<'a, A>, + P8: Parser<'a, A>, + P9: Parser<'a, A>, + P10: Parser<'a, A>, + P11: Parser<'a, A>, + P12: Parser<'a, A>, + P13: Parser<'a, A>, +{ + one_of2( + p1, + one_of12(p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13), + ) +} + +pub fn one_of14<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, A>( + p1: P1, + p2: P2, + p3: P3, + p4: P4, + p5: P5, + p6: P6, + p7: P7, + p8: P8, + p9: P9, + p10: P10, + p11: P11, + p12: P12, + p13: P13, + p14: P14, +) -> impl Parser<'a, A> +where + P1: Parser<'a, A>, + P2: Parser<'a, A>, + P3: Parser<'a, A>, + P4: Parser<'a, A>, + P5: Parser<'a, A>, + P6: Parser<'a, A>, + P7: Parser<'a, A>, + P8: Parser<'a, A>, + P9: Parser<'a, A>, + P10: Parser<'a, A>, + P11: Parser<'a, A>, + P12: Parser<'a, A>, + P13: Parser<'a, A>, + P14: Parser<'a, A>, +{ + one_of2( + p1, + one_of13(p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14), + ) +} + +pub fn one_of15<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, A>( + p1: P1, + p2: P2, + p3: P3, + p4: P4, + p5: P5, + p6: P6, + p7: P7, + p8: P8, + p9: P9, + p10: P10, + p11: P11, + p12: P12, + p13: P13, + p14: P14, + p15: P15, +) -> impl Parser<'a, A> +where + P1: Parser<'a, A>, + P2: Parser<'a, A>, + P3: Parser<'a, A>, + P4: Parser<'a, A>, + P5: Parser<'a, A>, + P6: Parser<'a, A>, + P7: Parser<'a, A>, + P8: Parser<'a, A>, + P9: Parser<'a, A>, + P10: Parser<'a, A>, + P11: Parser<'a, A>, + P12: Parser<'a, A>, + P13: Parser<'a, A>, + P14: Parser<'a, A>, + P15: Parser<'a, A>, +{ + one_of2( + p1, + one_of14(p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15), + ) +} + +pub fn one_of16<'a, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16, A>( + p1: P1, + p2: P2, + p3: P3, + p4: P4, + p5: P5, + p6: P6, + p7: P7, + p8: P8, + p9: P9, + p10: P10, + p11: P11, + p12: P12, + p13: P13, + p14: P14, + p15: P15, + p16: P16, +) -> impl Parser<'a, A> +where + P1: Parser<'a, A>, + P2: Parser<'a, A>, + P3: Parser<'a, A>, + P4: Parser<'a, A>, + P5: Parser<'a, A>, + P6: Parser<'a, A>, + P7: Parser<'a, A>, + P8: Parser<'a, A>, + P9: Parser<'a, A>, + P10: Parser<'a, A>, + P11: Parser<'a, A>, + P12: Parser<'a, A>, + P13: Parser<'a, A>, + P14: Parser<'a, A>, + P15: Parser<'a, A>, + P16: Parser<'a, A>, +{ + one_of2( + p1, + one_of15( + p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15, p16, + ), + ) +} + // DEBUG COMBINATORS // // These use dyn for runtime dynamic dispatch. It prevents combinatoric