1
1
package name .rayrobdod .stringContextParserCombinator
2
2
3
+ import com .eed3si9n .ifdef .ifdef
3
4
import scala .collection .immutable .Set
4
5
import scala .collection .immutable .Seq
5
6
import scala .reflect .ClassTag
@@ -34,8 +35,8 @@ import name.rayrobdod.stringContextParserCombinator.{Parser => SCPCParser}
34
35
* @groupprio Convert 2000
35
36
*/
36
37
final class Parser [Expr [_], Type [_], A ] private [stringContextParserCombinator] (
37
- protected [stringContextParserCombinator] override val impl : internal.Parser [Expr , Type , A ]
38
- ) extends VersionSpecificParser [ Expr , Type , A ] {
38
+ protected [stringContextParserCombinator] val impl : internal.Parser [Expr , Type , A ]
39
+ ) {
39
40
40
41
/**
41
42
* Returns an Interpolator that interpolates like this parser would
@@ -59,13 +60,109 @@ final class Parser[Expr[_], Type[_], A] private[stringContextParserCombinator] (
59
60
this .toInterpolator.interpolate(sc, args)
60
61
}
61
62
63
+ /**
64
+ * Parses a StringContext and its arguments into a value
65
+ *
66
+ * @example
67
+ * {{{
68
+ * def valueImpl(c:Context)(args:c.Expr[Any]*):c.Expr[Result] = {
69
+ * val myParser:Interpolator[Expr[Result]] = ???
70
+ * myParser.interpolate(c)("package.ValueStringContext")(args)
71
+ * }
72
+ *
73
+ * implicit final class ValueStringContext(val sc:scala.StringContext) extends AnyVal {
74
+ * def value(args:Any*):Result = macro valueImpl
75
+ * }
76
+ *
77
+ * // alternatively
78
+ * implicit final class ValueStringContext(val sc:scala.StringContext) {
79
+ * object value {
80
+ * def apply(args:Any*):Result = macro valueImpl
81
+ * }
82
+ * }
83
+ * }}}
84
+ * @group Parse
85
+ */
86
+ @ ifdef(" scalaEpochVersion:2" )
87
+ final def interpolate (c : scala.reflect.macros.blackbox.Context )(extensionClassName: String )(args: Seq [c.Expr [Any ]])(implicit ev: c.Expr [Any ] <:< Expr [Any ]): A = {
88
+ new Interpolator (this .impl).interpolate(c)(extensionClassName)(args)
89
+ }
90
+
91
+ /**
92
+ * Parses a StringContext and its arguments into a value
93
+ *
94
+ * @example
95
+ * ```
96
+ * def valueImpl(sc:Expr[scala.StringContext],
97
+ * args:Expr[Seq[Any]])(using Quotes):Expr[Result] = {
98
+ * val myParser:Interpolator[Expr[Result]] = ???
99
+ * myParser.interpolate(sc, args)
100
+ * }
101
+ *
102
+ * extension (inline sc:scala.StringContext)
103
+ * inline def value(inline args:Any*):Result =
104
+ * ${valueImpl('sc, 'args)}
105
+ * ```
106
+ * @group Parse
107
+ */
108
+ @ ifdef(" scalaBinaryVersion:3" )
109
+ final def interpolate (sc: scala.quoted.Expr [scala.StringContext ], args: scala.quoted.Expr [Seq [Any ]])(implicit q: scala.quoted.Quotes , ev: scala.quoted.Expr [Any ] <:< Expr [Any ]): A = {
110
+ new Interpolator (this .impl).interpolate(sc, args)
111
+ }
112
+
62
113
/**
63
114
* Extract subexpressions from the given value according to the given StringContext
64
115
* @group Parse
65
116
*/
66
117
def extract (sc: StringContext , value: A )(implicit ev: Id [Any ] =:= Expr [Any ], ev2: ClassTag [Any ] =:= Type [Any ]): Option [Seq [Any ]] =
67
118
this .toExtractor.extract(sc, value)
68
119
120
+ /**
121
+ * Build an extractor that will extract values from a value of type A based on the provided StringContext
122
+ * @group Parse
123
+ */
124
+ @ ifdef(" scalaEpochVersion:2" )
125
+ final def extractor [UnexprA ](
126
+ c : scala.reflect.macros.blackbox.Context )(
127
+ extensionClassName: String )(
128
+ value: c.Expr [UnexprA ])(
129
+ implicit ev: c.Expr [UnexprA ] <:< A ,
130
+ ev2: c.Expr [_] =:= Expr [_],
131
+ ev3: c.TypeTag [_] =:= Type [_],
132
+ ttUnexprA: c.TypeTag [UnexprA ]
133
+ ): c.Expr [Any ] = {
134
+ new Extractor (this .impl).extractor(c)(extensionClassName)(value)
135
+ }
136
+
137
+ /**
138
+ * Parses a StringContext into an extractor
139
+ *
140
+ * @example
141
+ * ```
142
+ * def valueImpl(sc:Expr[scala.StringContext])(using Quotes):Expr[Unapply[Result]] = {
143
+ * val myParser:Extractor[Expr[Result]] = ???
144
+ * myParser.extractor(sc)
145
+ * }
146
+ *
147
+ * extension (inline sc:scala.StringContext)
148
+ * inline def value:Unapply[Result] =
149
+ * ${valueImpl('sc)}
150
+ * ```
151
+ * @group Parse
152
+ */
153
+ @ ifdef(" scalaBinaryVersion:3" )
154
+ final def extractor [UnexprA ](
155
+ sc: scala.quoted.Expr [scala.StringContext ]
156
+ )(implicit
157
+ quotes : scala.quoted.Quotes ,
158
+ typeA : scala.quoted.Type [UnexprA ],
159
+ exprA : scala.quoted.Expr [UnexprA ] <:< A ,
160
+ exprBool : scala.quoted.Expr [Boolean ] =:= Expr [Boolean ],
161
+ typeBool : scala.quoted.Type [Boolean ] =:= Type [Boolean ],
162
+ ): scala.quoted.Expr [Unapply [UnexprA ]] = {
163
+ new Extractor (this .impl).extractor(sc)
164
+ }
165
+
69
166
/**
70
167
* Returns an interpolator which invokes this parser, then modifies a successful result according to fn
71
168
* @group Map
@@ -249,6 +346,21 @@ final class Parser[Expr[_], Type[_], A] private[stringContextParserCombinator] (
249
346
object Parser
250
347
extends VersionSpecificParserModule
251
348
{
349
+ @ ifdef(" scalaBinaryVersion:3" )
350
+ type Parser [A ] = SCPCParser [quoted.Expr , quoted.Type , A ]
351
+ @ ifdef(" scalaBinaryVersion:3" )
352
+ type Extractor [A ] = SCPCExtractor [quoted.Expr , quoted.Type , A ]
353
+ @ ifdef(" scalaBinaryVersion:3" )
354
+ type Interpolator [A ] = SCPCInterpolator [quoted.Expr [Any ], A ]
355
+
356
+ /**
357
+ * A parser that succeeds iff the next part of the input is an `arg` with the given type, and captures the arg's tree
358
+ * @group Arg
359
+ */
360
+ @ ifdef(" scalaBinaryVersion:3" )
361
+ def ofType [A ](implicit typA : scala.quoted.Type [A ], quoted : scala.quoted.Quotes ): SCPCParser [scala.quoted.Expr , scala.quoted.Type , scala.quoted.Expr [A ]] =
362
+ new SCPCParser (new internal.OfType [A ])
363
+
252
364
/**
253
365
* A parser that acts like the Interpolator when interpolating, and like the Extractor when extracting
254
366
* @group Misc
@@ -405,6 +517,54 @@ object Parser
405
517
new this .Parser (new internal.OfClass (tpe))
406
518
}
407
519
}
520
+
521
+ /**
522
+ * Create a Parsers that can parse Exprs belonging to the specified Context
523
+ * @group ParserGroup
524
+ */
525
+ @ ifdef(" scalaEpochVersion:2" )
526
+ def contextParsers (c: scala.reflect.macros.blackbox.Context ): Parser .Parsers [c.Expr , c.universe.Liftable , c.TypeTag ] = {
527
+ new Parser .Parsers [c.Expr , c.universe.Liftable , c.TypeTag ]
528
+ with ExprIndependentParsers [c.Expr , c.TypeTag ] {
529
+ override def `lazy` [A ](fn: Function0 [SCPCParser [c.Expr , c.TypeTag , A ]]): SCPCParser [c.Expr , c.TypeTag , A ] =
530
+ new SCPCParser (internal.DelayedConstruction .parser(() => fn().impl))
531
+
532
+ override def paired [A ](interpolator: Interpolator [A ], extractor: Extractor [A ]): SCPCParser [c.Expr , c.TypeTag , A ] =
533
+ new SCPCParser (new internal.Paired (interpolator.impl, extractor.impl))
534
+
535
+ override def ofType [A ](implicit tpe : c.TypeTag [A ]): SCPCParser [c.Expr , c.TypeTag , c.Expr [A ]] =
536
+ new SCPCParser (new internal.OfType [c.type , A ](tpe))
537
+ }
538
+ }
539
+
540
+ /**
541
+ * Create an Parsers that can parse `quoted.Expr`s
542
+ * @group ParserGroup
543
+ */
544
+ @ ifdef(" scalaBinaryVersion:3" )
545
+ def quotedParsers (implicit quotes : scala.quoted.Quotes ): Parser .Parsers [scala.quoted.Expr , scala.quoted.ToExpr , scala.quoted.Type ] = {
546
+ new Parser .Parsers [scala.quoted.Expr , scala.quoted.ToExpr , scala.quoted.Type ]
547
+ with ExprIndependentParsers [scala.quoted.Expr , scala.quoted.Type ] {
548
+ override def `lazy` [A ](fn: Function0 [SCPCParser [scala.quoted.Expr , scala.quoted.Type , A ]]): SCPCParser [scala.quoted.Expr , scala.quoted.Type , A ] =
549
+ new SCPCParser (internal.DelayedConstruction .parser(() => fn().impl))
550
+
551
+ override def paired [A ](interpolator: SCPCInterpolator [scala.quoted.Expr [Any ], A ], extractor: SCPCExtractor [scala.quoted.Expr , scala.quoted.Type , A ]): SCPCParser [scala.quoted.Expr , scala.quoted.Type , A ] =
552
+ new SCPCParser (new internal.Paired (interpolator.impl, extractor.impl))
553
+
554
+ override def ofType [A ](implicit tpe : scala.quoted.Type [A ]): SCPCParser [scala.quoted.Expr , scala.quoted.Type , scala.quoted.Expr [A ]] =
555
+ new SCPCParser (new internal.OfType [A ])
556
+ }
557
+ }
558
+ }
559
+
560
+ @ ifdef(" scalaEpochVersion:2" )
561
+ private [stringContextParserCombinator]
562
+ trait VersionSpecificParserModule {
563
+ }
564
+
565
+ @ ifdef(" scalaBinaryVersion:3" )
566
+ private [stringContextParserCombinator]
567
+ trait VersionSpecificParserModule extends ExprIndependentParsers [scala.quoted.Expr , scala.quoted.Type ] {
408
568
}
409
569
410
570
/**
0 commit comments