Skip to content

Commit

Permalink
Draft of Fraction Add / + (not working)
Browse files Browse the repository at this point in the history
  • Loading branch information
erikerlandson committed Jun 10, 2020
1 parent d1df57a commit 979e441
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
31 changes: 29 additions & 2 deletions src/main/scala/singleton/ops/impl/Fraction.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,27 @@ import singleton.ops._
* @tparam N the numerator
* @tparam D the denominator
*/
trait Fraction[N <: XInt, D <: XInt]
trait Fraction[N <: XInt, D <: XInt] {
val n: Int
val d: Int
override def toString: String = s"Fraction($n, $d)"
}

object Fraction {

// get the 'Out' type resulting from resolving an implicit type
object impeval {
trait Out[O]
def apply[I <: { type Out } ](implicit i: I): Out[i.Out] = new Out[i.Out] {}
}

implicit def fracAddition[L <: Fraction[_, _], R <: Fraction[_, _], O <: Fraction[_, _]](implicit
add: Add.Aux[L, R, O]): OpIntercept.Aux[OpId.+, L, R, W.`0`.T, O] =
new OpIntercept[OpId.+, L, R, W.`0`.T] {
type Out = O
val value = add.value
}

/** Typeclass for finding the greatest common divisor of two numbers using Euclid's algorithm.
*
* @tparam A a non-zero natural number
Expand Down Expand Up @@ -110,9 +127,17 @@ object Fraction {
}
}

implicit def instantiateFraction[N <: XInt, D <: XInt](implicit
nv: Id[N],
dv: Id[D]): Fraction[N, D] = new Fraction[N, D] {
val n = nv.value.asInstanceOf[Int]
val d = dv.value.asInstanceOf[Int]
}

/** Typeclass to add two fractions */
trait Add[L <: Fraction[_, _], R <: Fraction[_, _]] {
type Out <: Fraction[_, _]
val value: Out
}

object Add {
Expand All @@ -132,10 +157,12 @@ object Fraction {
ev1: OpInt.Aux[RN * LD, RNLD],
ev2: OpInt.Aux[LNRD + RNLD, N],
ev3: OpInt.Aux[LD * RD, D],
ev4: Simplify.Aux[Fraction[N, D], F]
ev4: Simplify.Aux[Fraction[N, D], F],
f: F
): Aux[Fraction[LN, LD], Fraction[RN, RD], F] =
new Add[Fraction[LN, LD], Fraction[RN, RD]] {
type Out = F
val value = f
}
}

Expand Down
22 changes: 19 additions & 3 deletions src/main/scala/singleton/ops/impl/GeneralMacros.scala
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,13 @@ trait GeneralMacros {
////////////////////////////////////////////////////////////////////////

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

def genOpTreeUnknown(opTpe : Type, calc : CalcUnknown) : Tree = {
println("In genOpTreeUnknown")
val outTpe = calc.tpe
calc.treeOption match {
case Some(valueTree) =>
Expand Down Expand Up @@ -898,10 +906,17 @@ trait GeneralMacros {
lazy val a = aCalc
lazy val b = bCalc
lazy val cArg = cCalc

def unsupported() : Calc = {
(a, b) match {
case (aArg : CalcVal, bArg : CalcVal) => abort(s"Unsupported $funcType[$a, $b, $cArg]")
case _ => CalcUnknown(funcType.toType, None)
val itree = c.typecheck(q"implicitly[_root_.singleton.ops.impl.OpIntercept[${funcType.toType}, ${a.tpe}, ${b.tpe}, ${cArg.tpe}]]", silent = true)
if (itree != EmptyTree) {
println(s"\n\nitree= ${itree.tpe}\n\n")
CalcUnknown(itree.tpe, Some(itree))
} else {
(a, b) match {
case (aArg : CalcVal, bArg : CalcVal) => abort(s"Unsupported $funcType[$a, $b, $cArg]")
case _ => CalcUnknown(funcType.toType, None)
}
}
}

Expand Down Expand Up @@ -1372,6 +1387,7 @@ trait GeneralMacros {

final class MaterializeOpAuxGen(opTpe: Type) {
def usingFuncName : Tree = {
println(s"usingFuncName: opTpe= $opTpe")
val funcType = opTpe.typeArgs.head.typeSymbol.asType
val opResult = TypeCalc(opTpe)

Expand Down
21 changes: 21 additions & 0 deletions src/main/scala/singleton/ops/impl/OpMacros.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,27 @@
package singleton.ops.impl
import scala.reflect.macros.whitebox


trait OpIntercept[N, S1, S2, S3] extends OpMacro[N, S2, S2, S3] {
import singleton.ops.W

type OutWide = None.type
val valueWide: OutWide = None
val isLiteral: Boolean = false
type OutNat = shapeless.Nat._0
type OutChar = W.`'0'`.T
type OutInt = W.`0`.T
type OutLong = W.`0L`.T
type OutFloat = W.`0f`.T
type OutDouble = W.`0D`.T
type OutString = W.`""`.T
type OutBoolean = W.`false`.T
}

object OpIntercept {
type Aux[N, S1, S2, S3, O] = OpIntercept[N, S1, S2, S3] { type Out = O }
}

/********************************************************************************************************
* Three arguments type function macro
*******************************************************************************************************/
Expand Down

0 comments on commit 979e441

Please sign in to comment.