Skip to content

Commit

Permalink
added all, which currently incorporates lift
Browse files Browse the repository at this point in the history
  • Loading branch information
j-mie6 committed Apr 16, 2024
1 parent dd10fd9 commit d341b59
Show file tree
Hide file tree
Showing 12 changed files with 622 additions and 626 deletions.
2 changes: 1 addition & 1 deletion docs/cheatsheet.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ Use this form of lifting when type-inference fails you. Otherwise, for clarity,
syntactic sugar for it:

```scala mdoc:silent
import parsley.syntax.lift.{Lift2, Lift1}
import parsley.syntax.lift.{liftSyntax1, liftSyntax2}

val charCons = (c: Char, cs: List[Char]) => c :: cs

Expand Down
4 changes: 2 additions & 2 deletions docs/tutorial/basics-of-combinators.md
Original file line number Diff line number Diff line change
Expand Up @@ -700,7 +700,7 @@ less efficient) and will give a sense of how the solution works out.
```scala mdoc:silent
import parsley.Parsley, Parsley.atomic
import parsley.syntax.character.stringLift
import parsley.syntax.lift.Lift2
import parsley.syntax.lift.liftSyntax2
import parsley.syntax.zipped.Zipped2

val or = (x: Boolean, y: Boolean) => x || y
Expand Down Expand Up @@ -747,7 +747,7 @@ said, is to implement the second grammar. This is, as we'll see, a little tricke
```scala mdoc:silent:reset
import parsley.Parsley
import parsley.syntax.character.stringLift
import parsley.syntax.lift.Lift2
import parsley.syntax.lift.liftSyntax2
import parsley.combinator.option

val and = (y: Boolean) => (x: Boolean) => x && y
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorial/parser-bridge-pattern.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ object ast {
object expressions {
import parsley.expr.{precedence, Ops, InfixL, Prefix}
import parsley.combinator.sepEndBy1
import parsley.syntax.lift.Lift2
import parsley.syntax.lift.liftSyntax2

import lexer.implicits.implicitSymbol
import lexer.{number, fully, identifier}
Expand Down
34 changes: 17 additions & 17 deletions parsley/shared/src/main/scala/parsley/Parsley.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1039,7 +1039,7 @@ private [parsley] abstract class ParsleyImpl {
* @return a parser which consumes no input and produces a value `x`.
* @group basic
*/
def pure[A](x: A): Parsley[A] = new Parsley(new singletons.Pure(x))
final def pure[A](x: A): Parsley[A] = new Parsley(new singletons.Pure(x))
/** This combinator produces a '''new''' value everytime it is parsed without having any other effect.
*
* When this combinator is ran, no input is required, nor consumed, and
Expand Down Expand Up @@ -1068,7 +1068,7 @@ private [parsley] abstract class ParsleyImpl {
* @since 4.0.0
* @group basic
*/
def fresh[A](x: =>A): Parsley[A] = new Parsley(new singletons.Fresh(x))
final def fresh[A](x: =>A): Parsley[A] = new Parsley(new singletons.Fresh(x))

/** This combinator parses its first argument `either`, and then parses either `left` or `right` depending on its result.
*
Expand All @@ -1095,7 +1095,7 @@ private [parsley] abstract class ParsleyImpl {
* @return a parser that will parse one of `left` or `right` depending on `either`'s result.
* @group cond
*/
def branch[A, B, C](either: Parsley[Either[A, B]], left: =>Parsley[A => C], right: =>Parsley[B => C]): Parsley[C] = {
final def branch[A, B, C](either: Parsley[Either[A, B]], left: =>Parsley[A => C], right: =>Parsley[B => C]): Parsley[C] = {
new Parsley(new frontend.Branch(either.internal, left.internal, right.internal))
}
/** This combinator parses its first argument `p`, then parses `q` only if `p` returns a `Left`.
Expand All @@ -1120,7 +1120,7 @@ private [parsley] abstract class ParsleyImpl {
* @return a parser that will parse `p` then possibly parse `q` to transform `p`'s result into a `B`.
* @group cond
*/
def select[A, B](p: Parsley[Either[A, B]], q: =>Parsley[A => B]): Parsley[B] = branch(p, q, pure(identity[B](_)))
final def select[A, B](p: Parsley[Either[A, B]], q: =>Parsley[A => B]): Parsley[B] = branch(p, q, pure(identity[B](_)))
/** This combinator parses its argument `p`, but rolls back any consumed input on failure.
*
* If the parser `p` succeeds, then `atomic(p)` has no effect. However, if `p` failed,
Expand All @@ -1144,7 +1144,7 @@ private [parsley] abstract class ParsleyImpl {
* @since 4.4.0
* @group prim
*/
def atomic[A](p: Parsley[A]): Parsley[A] = new Parsley(new frontend.Attempt(p.internal))
final def atomic[A](p: Parsley[A]): Parsley[A] = new Parsley(new frontend.Attempt(p.internal))
/** This combinator parses its argument `p`, but does not consume input if it succeeds.
*
* If the parser `p` succeeds, then `lookAhead(p)` will roll back any input consumed
Expand All @@ -1164,7 +1164,7 @@ private [parsley] abstract class ParsleyImpl {
* @return a parser that parses `p` and never consumes input if it succeeds.
* @group prim
*/
def lookAhead[A](p: Parsley[A]): Parsley[A] = new Parsley(new frontend.Look(p.internal))
final def lookAhead[A](p: Parsley[A]): Parsley[A] = new Parsley(new frontend.Look(p.internal))
/** This combinator parses its argument `p`, and succeeds when `p` fails and vice-versa, never consuming input.
*
* If the parser `p` succeeds, then `notFollowedBy(p)` will fail, consuming no input.
Expand All @@ -1187,7 +1187,7 @@ private [parsley] abstract class ParsleyImpl {
* @return a parser which fails when `p` succeeds and succeeds otherwise, never consuming input.
* @group prim
*/
def notFollowedBy(p: Parsley[_]): Parsley[Unit] = new Parsley(new frontend.NotFollowedBy(p.internal))
final def notFollowedBy(p: Parsley[_]): Parsley[Unit] = new Parsley(new frontend.NotFollowedBy(p.internal))
/** This combinator fails immediately, with a caret of the given width and no other information.
*
* By producing basically no information, this combinator is principally for adjusting the
Expand All @@ -1199,7 +1199,7 @@ private [parsley] abstract class ParsleyImpl {
* @since 4.4.0
* @group basic
*/
def empty(caretWidth: Int): Parsley[Nothing] = new Parsley(singletons.Empty(caretWidth))
final def empty(caretWidth: Int): Parsley[Nothing] = new Parsley(singletons.Empty(caretWidth))
/** This parser fails immediately, with an unknown parse error.
*
* @example {{{
Expand All @@ -1212,7 +1212,7 @@ private [parsley] abstract class ParsleyImpl {
* @note equivalent to `empty(0)`
* @group basic
*/
val empty: Parsley[Nothing] = empty(0)
final val empty: Parsley[Nothing] = empty(0)
/** This parser produces `()` without having any other effect.
*
* When this parser is ran, no input is required, nor consumed, and
Expand All @@ -1232,7 +1232,7 @@ private [parsley] abstract class ParsleyImpl {
* @note defined as `pure(())` as a simple convenience.
* @group basic
*/
val unit: Parsley[Unit] = pure(())
final val unit: Parsley[Unit] = pure(())

/** This parser only succeeds at the end of the input.
*
Expand All @@ -1249,7 +1249,7 @@ private [parsley] abstract class ParsleyImpl {
* @group item
* @since 4.5.0
*/
val eof: Parsley[Unit] = new Parsley(singletons.Eof)
final val eof: Parsley[Unit] = new Parsley(singletons.Eof)

/** This combinator repeatedly parses a given parser '''zero''' or more times, collecting the results into a list.
*
Expand Down Expand Up @@ -1277,8 +1277,8 @@ private [parsley] abstract class ParsleyImpl {
* @since 4.5.0
* @group iter
*/
def many[A](p: Parsley[A]): Parsley[List[A]] = many(p, List)
private [parsley] def many[A, C](p: Parsley[A], factory: Factory[A, C]): Parsley[C] = {
final def many[A](p: Parsley[A]): Parsley[List[A]] = many(p, List)
private [parsley] final def many[A, C](p: Parsley[A], factory: Factory[A, C]): Parsley[C] = {
new Parsley(new frontend.Many(p.internal, factory))
}

Expand Down Expand Up @@ -1308,13 +1308,13 @@ private [parsley] abstract class ParsleyImpl {
* @since 4.5.0
* @group iter
*/
def some[A](p: Parsley[A]): Parsley[List[A]] = p <::> many(p)
private [parsley] def some[A, C](p: Parsley[A], factory: Factory[A, C]): Parsley[C] = secretSome(p, p, factory)
final def some[A](p: Parsley[A]): Parsley[List[A]] = p <::> many(p)
private [parsley] final def some[A, C](p: Parsley[A], factory: Factory[A, C]): Parsley[C] = secretSome(p, p, factory)
// This could be generalised to be the new many, where many(p, factory) = secretSome(fresh(factory.newBuilder), p, factory)
private [parsley] def secretSome[A, C](init: Parsley[A], p: Parsley[A], factory: Factory[A, C]): Parsley[C] = {
private [parsley] final def secretSome[A, C](init: Parsley[A], p: Parsley[A], factory: Factory[A, C]): Parsley[C] = {
secretSome(init.map(factory.newBuilder += _), p)
}
private [parsley] def secretSome[A, C](init: Parsley[mutable.Builder[A, C]], p: Parsley[A]): Parsley[C] = {
private [parsley] final def secretSome[A, C](init: Parsley[mutable.Builder[A, C]], p: Parsley[A]): Parsley[C] = {
val pf = pure[(mutable.Builder[A, C], A) => mutable.Builder[A, C]](_ += _)
// Can't use the regular foldLeft1 here, because we need a fresh Builder each time.
expr.infix.secretLeft1(init, p, pf).map(_.result())
Expand Down
Loading

0 comments on commit d341b59

Please sign in to comment.