Skip to content

Commit 979e441

Browse files
committed
Draft of Fraction Add / + (not working)
1 parent d1df57a commit 979e441

File tree

3 files changed

+69
-5
lines changed

3 files changed

+69
-5
lines changed

src/main/scala/singleton/ops/impl/Fraction.scala

+29-2
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,27 @@ import singleton.ops._
77
* @tparam N the numerator
88
* @tparam D the denominator
99
*/
10-
trait Fraction[N <: XInt, D <: XInt]
10+
trait Fraction[N <: XInt, D <: XInt] {
11+
val n: Int
12+
val d: Int
13+
override def toString: String = s"Fraction($n, $d)"
14+
}
1115

1216
object Fraction {
1317

18+
// get the 'Out' type resulting from resolving an implicit type
19+
object impeval {
20+
trait Out[O]
21+
def apply[I <: { type Out } ](implicit i: I): Out[i.Out] = new Out[i.Out] {}
22+
}
23+
24+
implicit def fracAddition[L <: Fraction[_, _], R <: Fraction[_, _], O <: Fraction[_, _]](implicit
25+
add: Add.Aux[L, R, O]): OpIntercept.Aux[OpId.+, L, R, W.`0`.T, O] =
26+
new OpIntercept[OpId.+, L, R, W.`0`.T] {
27+
type Out = O
28+
val value = add.value
29+
}
30+
1431
/** Typeclass for finding the greatest common divisor of two numbers using Euclid's algorithm.
1532
*
1633
* @tparam A a non-zero natural number
@@ -110,9 +127,17 @@ object Fraction {
110127
}
111128
}
112129

130+
implicit def instantiateFraction[N <: XInt, D <: XInt](implicit
131+
nv: Id[N],
132+
dv: Id[D]): Fraction[N, D] = new Fraction[N, D] {
133+
val n = nv.value.asInstanceOf[Int]
134+
val d = dv.value.asInstanceOf[Int]
135+
}
136+
113137
/** Typeclass to add two fractions */
114138
trait Add[L <: Fraction[_, _], R <: Fraction[_, _]] {
115139
type Out <: Fraction[_, _]
140+
val value: Out
116141
}
117142

118143
object Add {
@@ -132,10 +157,12 @@ object Fraction {
132157
ev1: OpInt.Aux[RN * LD, RNLD],
133158
ev2: OpInt.Aux[LNRD + RNLD, N],
134159
ev3: OpInt.Aux[LD * RD, D],
135-
ev4: Simplify.Aux[Fraction[N, D], F]
160+
ev4: Simplify.Aux[Fraction[N, D], F],
161+
f: F
136162
): Aux[Fraction[LN, LD], Fraction[RN, RD], F] =
137163
new Add[Fraction[LN, LD], Fraction[RN, RD]] {
138164
type Out = F
165+
val value = f
139166
}
140167
}
141168

src/main/scala/singleton/ops/impl/GeneralMacros.scala

+19-3
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,13 @@ trait GeneralMacros {
655655
////////////////////////////////////////////////////////////////////////
656656

657657
def abort(msg: String, annotatedSym : Option[TypeSymbol] = defaultAnnotatedSym): Nothing = {
658+
val st = java.lang.Thread.currentThread().getStackTrace()
659+
println("\n\nstack trace:")
660+
for { e <- st.filter(_.getClassName().startsWith("singleton")) } {
661+
println(s" $e")
662+
}
663+
println("\n")
664+
//java.lang.Thread.dumpStack()
658665
VerboseTraversal(s"!!!!!!aborted with: $msg at $annotatedSym, $defaultAnnotatedSym")
659666
if (annotatedSym.isDefined) setAnnotation(msg, annotatedSym.get)
660667
c.abort(c.enclosingPosition, msg)
@@ -719,6 +726,7 @@ trait GeneralMacros {
719726
}
720727

721728
def genOpTreeUnknown(opTpe : Type, calc : CalcUnknown) : Tree = {
729+
println("In genOpTreeUnknown")
722730
val outTpe = calc.tpe
723731
calc.treeOption match {
724732
case Some(valueTree) =>
@@ -898,10 +906,17 @@ trait GeneralMacros {
898906
lazy val a = aCalc
899907
lazy val b = bCalc
900908
lazy val cArg = cCalc
909+
901910
def unsupported() : Calc = {
902-
(a, b) match {
903-
case (aArg : CalcVal, bArg : CalcVal) => abort(s"Unsupported $funcType[$a, $b, $cArg]")
904-
case _ => CalcUnknown(funcType.toType, None)
911+
val itree = c.typecheck(q"implicitly[_root_.singleton.ops.impl.OpIntercept[${funcType.toType}, ${a.tpe}, ${b.tpe}, ${cArg.tpe}]]", silent = true)
912+
if (itree != EmptyTree) {
913+
println(s"\n\nitree= ${itree.tpe}\n\n")
914+
CalcUnknown(itree.tpe, Some(itree))
915+
} else {
916+
(a, b) match {
917+
case (aArg : CalcVal, bArg : CalcVal) => abort(s"Unsupported $funcType[$a, $b, $cArg]")
918+
case _ => CalcUnknown(funcType.toType, None)
919+
}
905920
}
906921
}
907922

@@ -1372,6 +1387,7 @@ trait GeneralMacros {
13721387

13731388
final class MaterializeOpAuxGen(opTpe: Type) {
13741389
def usingFuncName : Tree = {
1390+
println(s"usingFuncName: opTpe= $opTpe")
13751391
val funcType = opTpe.typeArgs.head.typeSymbol.asType
13761392
val opResult = TypeCalc(opTpe)
13771393

src/main/scala/singleton/ops/impl/OpMacros.scala

+21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,27 @@
11
package singleton.ops.impl
22
import scala.reflect.macros.whitebox
33

4+
5+
trait OpIntercept[N, S1, S2, S3] extends OpMacro[N, S2, S2, S3] {
6+
import singleton.ops.W
7+
8+
type OutWide = None.type
9+
val valueWide: OutWide = None
10+
val isLiteral: Boolean = false
11+
type OutNat = shapeless.Nat._0
12+
type OutChar = W.`'0'`.T
13+
type OutInt = W.`0`.T
14+
type OutLong = W.`0L`.T
15+
type OutFloat = W.`0f`.T
16+
type OutDouble = W.`0D`.T
17+
type OutString = W.`""`.T
18+
type OutBoolean = W.`false`.T
19+
}
20+
21+
object OpIntercept {
22+
type Aux[N, S1, S2, S3, O] = OpIntercept[N, S1, S2, S3] { type Out = O }
23+
}
24+
425
/********************************************************************************************************
526
* Three arguments type function macro
627
*******************************************************************************************************/

0 commit comments

Comments
 (0)