@@ -54,29 +54,19 @@ private class BridgeImpl(using Quotes) {
5454 case (pos, _) => pos
5555 }
5656 val con = constructor[T ](cls, bridgePrimaryArgs, tyArgs, categorisedArgs, existsUniquePosition.map(_.tyRepr))
57- // TODO: look for unique position
57+ val body = synthesiseLift[ S ](existsUniquePosition, bridgePrimaryArgs.map(_._2), con, _)
5858 // TODO: ensure validation if Err is encountered (report separately, but then abort if failed (Option))
5959 bridgePrimaryArgs.map(_._2.asType) match {
60- case List (' [t1]) =>
61- ' {new Bridge1 [t1, S ] {
62- def apply (p1 : Parsley [t1]): Parsley [S ] = $ {
63- existsUniquePosition match {
64- case Some (impl@ PosImpl (_, given Type [posTy])) =>
65- ' {lift.lift2($ {con.asExprOf[(posTy, t1) => T ]}, $ {impl.parser}, p1)}
66- case None => ' {p1.map($ {con.asExprOf[t1 => T ]})}
67- }
68- }
69- }}
70- case List (' [t1], ' [t2]) =>
71- ' {new Bridge2 [t1, t2, S ] {
72- def apply (p1 : Parsley [t1], p2 : Parsley [t2]): Parsley [S ] = $ {
73- existsUniquePosition match {
74- case Some (impl@ PosImpl (_, given Type [posTy])) =>
75- ' {lift.lift3($ {con.asExprOf[(posTy, t1, t2) => T ]}, $ {impl.parser}, p1, p2)}
76- case None => ' {lift.lift2($ {con.asExprOf[(t1, t2) => T ]}, p1, p2)}
77- }
78- }
79- }}
60+ case List (' [t1]) => ' {
61+ new Bridge1 [t1, S ] {
62+ def apply (p1 : Parsley [t1]): Parsley [S ] = $ {body(List (' p1 .asTerm))}
63+ }
64+ }
65+ case List (' [t1], ' [t2]) => ' {
66+ new Bridge2 [t1, t2, S ] {
67+ def apply (p1 : Parsley [t1], p2 : Parsley [t2]): Parsley [S ] = $ {body(List (' p1 .asTerm, ' p2 .asTerm))}
68+ }
69+ }
8070 // TODO: 19 more of these
8171 case _ => ' {??? }
8272 }
@@ -146,7 +136,6 @@ private class BridgeImpl(using Quotes) {
146136 val tys : List [TypeTree ] = clsTyArgs.map(tyRep => TypeTree .of(using tyRep.asType))
147137 val objTy = New (Applied (TypeTree .ref(cls), tys))
148138 val con = objTy.select(cls.primaryConstructor).appliedToTypes(clsTyArgs)
149- // val conBridged = con.appliedToArgs(params) // TODO: this doesn't work when positions can be in the first set
150139 val kaboom : Term = ' {??? }.asTerm
151140 // at this point, we have applied the constructor to the bridge args (except for positions)
152141 // we now need to apply the other default arguments
@@ -181,6 +170,25 @@ private class BridgeImpl(using Quotes) {
181170 saturated
182171 }
183172
173+ private def synthesiseLift [R : Type ](existsUniquePosition : Option [PosImpl [? ]], argTys : List [TypeRepr ], con : Term , args : List [Term ]): Expr [Parsley [R ]] = {
174+ val tys = argTys :+ TypeRepr .of[R ]
175+ val arity = argTys.size + existsUniquePosition.size
176+ TypeRepr .of[parsley.lift$].typeSymbol.methodMember(s " lift $arity" ).headOption.map(' {parsley.lift}.asTerm.select(_)) match {
177+ case Some (lift) => existsUniquePosition match {
178+ case Some (impl@ PosImpl (_, given Type [posTy])) =>
179+ val posTyRepr = TypeRepr .of[posTy]
180+ lift.appliedToTypes(posTyRepr :: tys)
181+ .appliedToArgs(con :: impl.parser.asTerm :: args)
182+ .asExprOf[Parsley [R ]]
183+ case None =>
184+ lift.appliedToTypes(tys)
185+ .appliedToArgs(con :: args)
186+ .asExprOf[Parsley [R ]]
187+ }
188+ case None => report.errorAndAbort(s " No `lift` available for arity $arity" )
189+ }
190+ }
191+
184192 private object Bridgeable {
185193 def unapply (ty : TypeRepr ): Option [(Symbol , List [Symbol ], List [Symbol ], List [List [Symbol ]])] = {
186194 val clsDef = ty.classSymbol
0 commit comments