[WIP] support operator interception for non-literal types#147
[WIP] support operator interception for non-literal types#147erikerlandson wants to merge 5 commits intofthomas:masterfrom
Conversation
|
Example run of current code: scala> import singleton.ops.impl._, singleton.ops.impl.Rig._
import singleton.ops.impl._
import singleton.ops.impl.Rig._
scala> implicitly[Add[Rig[2], Rig[3]]]
usingFuncName: opTpe= singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,2,3,singleton.ops.NP]
funcType= trait +
opResult= CalcLit(Int,5)
res0: singleton.ops.impl.Rig.Add[singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3]] = singleton.ops.impl.Rig$Add$$anon$3@6fc0a38a
scala> res0.value
res1: res0.Out = Rig(5)
scala> implicitly[OpIntercept[OpId.+, Rig[2], Rig[3], 0]]
usingFuncName: opTpe= singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,2,3,singleton.ops.NP]
funcType= trait +
opResult= CalcLit(Int,5)
res2: singleton.ops.impl.OpIntercept[singleton.ops.impl.OpId.+,singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3],0] = singleton.ops.impl.Rig$$anon$2@3320bafa
scala> res2.value
res3: res2.Out = Rig(5)
scala> implicitly[Rig[2] + Rig[3]]
usingFuncName: opTpe= singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,2,3,singleton.ops.NP]
funcType= trait +
opResult= CalcLit(Int,5)
itree= singleton.ops.impl.OpIntercept[singleton.ops.impl.OpId.+,singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3],Int(0)]
usingFuncName: opTpe= singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3],singleton.ops.NP]
funcType= trait +
opResult= CalcUnknown(singleton.ops.impl.OpIntercept[singleton.ops.impl.OpId.+,singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3],Int(0)],Some(scala.Predef.implicitly[singleton.ops.impl.OpIntercept[singleton.ops.impl.OpId.+,singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3],Int(0)]](singleton.ops.impl.Rig.rigAddition[singleton.ops.impl.Rig[2], singleton.ops.impl.Rig[3], singleton.ops.impl.Rig[this.Out]](Rig.this.Add.addRig[2, 3, this.Out](impl.this.OpInt.impl[2 + 3]({
final class $anon extends AnyRef with singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,2,3,singleton.ops.NP] {
def <init>(): <$anon: singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,2,3,singleton.ops.NP]> = {
$anon.super.<init>();
()
};
type OutWide = Int;
type Out = Int(5);
type OutInt = Int(5);
final private[this] val value: Int(5) = 5;
final <stable> <accessor> def value: Int(5) = $anon.this.value;
final private[this] val isLiteral: Boolean(true) = true;
final <stable> <accessor> def isLiteral: Boolean(true) = $anon.this.isLiteral;
final private[this] val valueWide: Int = 5;
final <stable> <accessor> def valueWide: Int = $anon.this.valueWide
};
new $anon()
}))))))
stack trace:
singleton.ops.impl.GeneralMacros.abort(GeneralMacros.scala:658)
singleton.ops.impl.GeneralMacros.abort$(GeneralMacros.scala:657)
singleton.ops.impl.OpMacro$Macro.abort(OpMacros.scala:92)
singleton.ops.impl.GeneralMacros.extractionFailed(GeneralMacros.scala:757)
singleton.ops.impl.GeneralMacros.extractionFailed$(GeneralMacros.scala:755)
singleton.ops.impl.OpMacro$Macro.extractionFailed(OpMacros.scala:92)
singleton.ops.impl.GeneralMacros$MaterializeOpAuxGen.usingFuncName(GeneralMacros.scala:1405)
singleton.ops.impl.OpMacro$Macro.impl(OpMacros.scala:99)
^
error: Cannot extract value from singleton.ops.impl.OpMacro[singleton.ops.impl.OpId.+,singleton.ops.impl.Rig[2],singleton.ops.impl.Rig[3],singleton.ops.NP]
showRaw==> TypeRef(ThisType(singleton.ops.impl), singleton.ops.impl.OpMacro, List(TypeRef(SingleType(ThisType(singleton.ops.impl), singleton.ops.impl.OpId), singleton.ops.impl.OpId.$plus, List()), TypeRef(ThisType(singleton.ops.impl), singleton.ops.impl.Rig, List(LiteralType(Constant(2)))), TypeRef(ThisType(singleton.ops.impl), singleton.ops.impl.Rig, List(LiteralType(Constant(3)))), TypeRef(SingleType(SingleType(SingleType(ThisType(<root>), singleton), singleton.ops), singleton.ops.package), TypeName("NP"), List()))) |
|
OK, I know the reason. Indeed, as you suspected the
case class CalcOpIntercept(tpe : Type, tree : Tree) extends Calc {
override val primitive: Primitive = Primitive.Unknown(tpe, "OpIntercept")
}
|
|
Thanks, I'll look into that. I think I may also be loading CalcUnknown with the wrong type and tree from the call to implicitly |
Yeah, IIUC, I think I should be loading something more like the On a related note, subclassing |
Add support for This will allow to get the Out.I think it's possible to generalize it properly by checking if its a subtype/subclass.
I don't see how is this related to |
|
You know what, leave it to me, I'll try to do this over the weekend, and you can finish the fraction on top. |
OK, thanks! |
|
@soronpo did you have a chance to play with this at all? |
Sorry, still have too much on my plate. I'll get there soon though. |
|
Starting to work on it |
|
closing this in favor of #149 |
goal is to support the ability for OpMacro to attempt a call to
implicitly[OpIntercept[op, arg, arg...]]when it cannot resolve an operator with its arguments. See discussion on #140.