Skip to content
This repository has been archived by the owner on Sep 17, 2022. It is now read-only.

Commit

Permalink
Switch out recursion schemes encoding of Type for regular ADT (#72)
Browse files Browse the repository at this point in the history
* Removing recursion schemes from Type

* Fix issues with Json Codecs

* Type fixes

* Move implementations of Type related items into the types package

* Fix errors

* Remove simple warnings

* Fix formatting
  • Loading branch information
DamianReeves authored Mar 23, 2022
1 parent e9cafed commit ea2ed56
Show file tree
Hide file tree
Showing 22 changed files with 994 additions and 944 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import zio.morphir.ir.ValueModule.RawValue
import zio.morphir.ir.TypeModule
import zio.morphir.IR
import zio.morphir.ir.LiteralValue
import zio.morphir.ir.ValueModule.ValueCase.*
import zio.morphir.ir.ValueModule.ValueCase._
import zio.morphir.ir.NativeFunction
import zio.morphir.ir.FQName
import zio.morphir.ir.Pattern
import zio.morphir.ir.NativeFunction.*

import zio.morphir.ir.NativeFunction._
import zio.Chunk
import zio.prelude._

import scala.collection.immutable.ListMap
import zio.morphir.ir.ValueModule.Value
import zio.morphir.ir.TypeModule.Specification.TypeAliasSpecification
import IR._

import IR.*
import java.math.BigInteger
object Interpreter {

sealed trait Result
Expand Down Expand Up @@ -74,7 +74,7 @@ object Interpreter {
val dealiased = ir.resolveAliases(fqName)
def getRecordConstructor(name: FQName): Option[Any] =
ir.typeSpecifications.get(name).collect {
case TypeAliasSpecification(_, TypeModule.Type(TypeModule.TypeCase.RecordCase(fields), _)) =>
case TypeAliasSpecification(_, TypeModule.Type.Record(_, fields)) =>
constructFunction(fqName, fields)
}

Expand All @@ -89,7 +89,7 @@ object Interpreter {
getRecordConstructor(dealiased) orElse getTypeConstructor(dealiased) match {
case Some(fn) => fn
case None =>
throw new InterpretationError.TypeNotFound(dealiased.toString)
throw InterpretationError.TypeNotFound(dealiased.toString)
}

// case class Constructor(name FQName)
Expand All @@ -115,7 +115,7 @@ object Interpreter {
record.get(name) match {
case Some(value) => value
case None =>
throw new InterpretationError.FieldNotFound(name, s"Field $name not found in $record")
throw InterpretationError.FieldNotFound(name, s"Field $name not found in $record")
}

case FieldFunctionCase(name) =>
Expand All @@ -126,7 +126,7 @@ object Interpreter {
case Some(fieldValue) => fieldValue
case None => InterpretationError.FieldNotFound(name, s"Field $name not found in $input")
}
case _ => throw new InterpretationError.RecordExpected(s"Record expected but got $input")
case _ => throw InterpretationError.RecordExpected(s"Record expected but got $input")
}

case IfThenElseCase(condition, thenBranch, elseBranch) =>
Expand Down Expand Up @@ -160,7 +160,7 @@ object Interpreter {
}
}

if (rightHandSide eq null) throw new InterpretationError.MatchError(s"could not match $evaluatedBody")
if (rightHandSide eq null) throw InterpretationError.MatchError(s"could not match $evaluatedBody")
else loop(rightHandSide, variables ++ newVariables, references)

case RecordCase(fields) =>
Expand All @@ -173,7 +173,7 @@ object Interpreter {
references.get(name) match {
case Some(value) => value

case None => throw new InterpretationError.ReferenceNotFound(name, s"Reference $name not found")
case None => throw InterpretationError.ReferenceNotFound(name, s"Reference $name not found")
}

case TupleCase(elements) =>
Expand All @@ -185,13 +185,12 @@ object Interpreter {
case VariableCase(name) =>
variables.get(name) match {
case Some(Result.Strict(value)) => value
case Some(Result.Lazy(value, variables, references, definitions)) => {
case Some(Result.Lazy(value, variables, references, definitions)) =>
def shallow = definitions.map { case (key, value) =>
key -> Result.Lazy(value, variables, references, definitions)
}
loop(value, variables ++ shallow, references)
}
case None => throw new InterpretationError.VariableNotFound(name, s"Variable $name not found")
case None => throw InterpretationError.VariableNotFound(name, s"Variable $name not found")
}

case LetDefinitionCase(name, value, body) =>
Expand Down Expand Up @@ -227,7 +226,7 @@ object Interpreter {
val newRecord = record.asInstanceOf[ListMap[Name, Any]] ++ evaluatedFieldsToUpdate.toMap
newRecord
case _ =>
throw new InterpretationError.RecordExpected(
throw InterpretationError.RecordExpected(
s"Record expected but got $evaluatedValueToUpdate"
)
}
Expand All @@ -242,7 +241,7 @@ object Interpreter {
references
)
case Left(MatchFailure(pattern, input)) =>
throw new InterpretationError.MatchError(
throw InterpretationError.MatchError(
s"Pattern $pattern didn't match input $input"
)
}
Expand All @@ -257,7 +256,7 @@ object Interpreter {
references
)
case Left(MatchFailure(pattern, input)) =>
throw new InterpretationError.MatchError(
throw InterpretationError.MatchError(
s"Pattern $pattern didn't match input $input"
)
}
Expand Down Expand Up @@ -353,20 +352,21 @@ object Interpreter {
}

private def evalAddition(args: Chunk[Any]): Any =
if (args.length == 0)
throw new InterpretationError.InvalidArguments(args, s"Addition expected at least two argument but got none.")
if (args.isEmpty)
throw InterpretationError.InvalidArguments(args, s"Addition expected at least two argument but got none.")
else if (args(0).isInstanceOf[java.math.BigInteger])
args.asInstanceOf[Chunk[java.math.BigInteger]].reduce(_ add _)
else
args.asInstanceOf[Chunk[java.math.BigDecimal]].reduce(_ add _)

private def evalSubtraction(args: Chunk[Any]): Any =
if (args.length != 2)
throw new InterpretationError.InvalidArguments(args, s"Subtraction expected exactly two arguments.")
else if (args(0).isInstanceOf[java.math.BigInteger])
args(0).asInstanceOf[java.math.BigInteger] subtract args(1).asInstanceOf[java.math.BigInteger]
throw InterpretationError.InvalidArguments(args, s"Subtraction expected exactly two arguments.")
else
args(0).asInstanceOf[java.math.BigDecimal] subtract args(1).asInstanceOf[java.math.BigDecimal]
args(0) match {
case integer: BigInteger => integer subtract args(1).asInstanceOf[BigInteger]
case _ => args(0).asInstanceOf[java.math.BigDecimal] subtract args(1).asInstanceOf[java.math.BigDecimal]
}

// format: off
private def evalTuple(value: Chunk[Any]): Any =
Expand All @@ -393,7 +393,7 @@ object Interpreter {
case a :: b :: c :: d :: e :: f :: g :: h :: i :: j :: k :: l :: m :: n :: o :: p :: q :: r :: s :: t :: Nil => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t)
case a :: b :: c :: d :: e :: f :: g :: h :: i :: j :: k :: l :: m :: n :: o :: p :: q :: r :: s :: t :: u :: Nil => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)
case a :: b :: c :: d :: e :: f :: g :: h :: i :: j :: k :: l :: m :: n :: o :: p :: q :: r :: s :: t :: u :: v :: Nil => (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)
case _ => throw new InterpretationError.TupleTooLong(value.length)
case _ => throw InterpretationError.TupleTooLong(value.length)
}
// format: on

Expand Down Expand Up @@ -427,7 +427,7 @@ object Interpreter {
Chunk(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u)
case (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) =>
Chunk(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v)
case _ => throw new InterpretationError.MatchError("value was not a tuple")
case _ => throw InterpretationError.MatchError("value was not a tuple")
}

def applyFunction(function: Any, arguments: Chunk[Any]): Any =
Expand Down Expand Up @@ -540,7 +540,7 @@ object GenericCaseClass {
def nameToFieldName(name: Name): String =
name.toString

def named(name: FQName) = ???
// def named(name: FQName) = ???
}

// To Do List:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
package zio.morphir.value

import java.math.BigInteger
import zio.test.*
import zio.test._
import zio.morphir.ir.Name
import zio.morphir.ir.testing.CaseExample.*
import zio.morphir.ir.testing.CaseExample._
import zio.morphir.ir.ValueModule.RawValue
import zio.morphir.IR
import zio.morphir.testing.MorphirBaseSpec
Expand Down
4 changes: 2 additions & 2 deletions morphir-ir/shared/src/main/scala/zio/morphir/IR.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ final case class IR(
case Some(typeSpecification) =>
typeSpecification match {
case TypeModule.Specification.TypeAliasSpecification(_, underlyingType) =>
underlyingType.caseValue match {
case TypeModule.TypeCase.ReferenceCase(fqName, _) =>
underlyingType match {
case TypeModule.Type.Reference(_, fqName, _) =>
fqName
case _ => fqName
}
Expand Down
54 changes: 27 additions & 27 deletions morphir-ir/shared/src/main/scala/zio/morphir/ir/Pattern.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,30 @@ import zio.Chunk
sealed trait Pattern[+Attributes] { self =>
import Pattern._

def annotations: Attributes
def attributes: Attributes
final def mapAttributes[B](f: Attributes => B): Pattern[B] = self match {
case AsPattern(pattern, name, annotations) => AsPattern(pattern.mapAttributes(f), name, f(annotations))
case ConstructorPattern(constructorName, argumentPatterns, annotations) =>
ConstructorPattern(constructorName, argumentPatterns.map(_.mapAttributes(f)), f(annotations))
case EmptyListPattern(annotations) => EmptyListPattern(f(annotations))
case HeadTailPattern(headPattern, tailPattern, annotations) =>
HeadTailPattern(headPattern.mapAttributes(f), tailPattern.mapAttributes(f), f(annotations))
case LiteralPattern(literal, annotations) => LiteralPattern(literal, f(annotations))
case TuplePattern(elementPatterns, annotations) =>
TuplePattern(elementPatterns.map(_.mapAttributes(f)), f(annotations))
case UnitPattern(annotations) => UnitPattern(f(annotations))
case WildcardPattern(annotations) => WildcardPattern(f(annotations))
case AsPattern(pattern, name, attributes) => AsPattern(pattern.mapAttributes(f), name, f(attributes))
case ConstructorPattern(constructorName, argumentPatterns, attributes) =>
ConstructorPattern(constructorName, argumentPatterns.map(_.mapAttributes(f)), f(attributes))
case EmptyListPattern(attributes) => EmptyListPattern(f(attributes))
case HeadTailPattern(headPattern, tailPattern, attributes) =>
HeadTailPattern(headPattern.mapAttributes(f), tailPattern.mapAttributes(f), f(attributes))
case LiteralPattern(literal, attributes) => LiteralPattern(literal, f(attributes))
case TuplePattern(elementPatterns, attributes) =>
TuplePattern(elementPatterns.map(_.mapAttributes(f)), f(attributes))
case UnitPattern(attributes) => UnitPattern(f(attributes))
case WildcardPattern(attributes) => WildcardPattern(f(attributes))
}
}

object Pattern {

def asPattern[Attributes](
annotations: Attributes,
attributes: Attributes,
pattern: Pattern[Attributes],
name: Name
): AsPattern[Attributes] =
AsPattern(pattern, name, annotations)
AsPattern(pattern, name, attributes)

def asPattern(pattern: Pattern[Any], name: Name): AsPattern[Any] =
AsPattern(pattern, name, ())
Expand All @@ -38,49 +38,49 @@ object Pattern {

lazy val wildcardPattern: WildcardPattern[Any] = WildcardPattern[Any](())

def wildcardPattern[Attributes](annotations: Attributes): WildcardPattern[Attributes] =
WildcardPattern(annotations)
def wildcardPattern[Attributes](attributes: Attributes): WildcardPattern[Attributes] =
WildcardPattern(attributes)

// val unit: UnitPattern[Any] = UnitPattern(ZEnvironment.empty)
// def unit[Attributes](annotations: ZEnvironment[Attributes]): UnitPattern[Attributes] = UnitPattern(annotations)
// def unit[Attributes](attributes: ZEnvironment[Attributes]): UnitPattern[Attributes] = UnitPattern(attributes)
// val wildcard: Wildcard[Any] = Wildcard(ZEnvironment.empty)
// def wildcard[Attributes](annotations: ZEnvironment[Attributes]): Wildcard[Attributes] = Wildcard(annotations)
// def wildcard[Attributes](attributes: ZEnvironment[Attributes]): Wildcard[Attributes] = Wildcard(attributes)

// final case class LiteralPattern[+Attributes, +Value](value: Lit[Value], annotations: ZEnvironment[Attributes])
// final case class LiteralPattern[+Attributes, +Value](value: Lit[Value], attributes: ZEnvironment[Attributes])
// extends Pattern[Attributes]

final case class AsPattern[+Attributes](
pattern: Pattern[Attributes],
name: Name,
annotations: Attributes
attributes: Attributes
) extends Pattern[Attributes]

final case class ConstructorPattern[+Attributes](
constructorName: FQName,
argumentPatterns: Chunk[Pattern[Attributes]],
annotations: Attributes
attributes: Attributes
) extends Pattern[Attributes]

final case class EmptyListPattern[+Attributes](annotations: Attributes) extends Pattern[Attributes]
final case class EmptyListPattern[+Attributes](attributes: Attributes) extends Pattern[Attributes]

final case class HeadTailPattern[+Attributes](
headPattern: Pattern[Attributes],
tailPattern: Pattern[Attributes],
annotations: Attributes
attributes: Attributes
) extends Pattern[Attributes]

final case class LiteralPattern[+A, +Attributes](
literal: Literal[A],
annotations: Attributes
attributes: Attributes
) extends Pattern[Attributes]

final case class TuplePattern[+Attributes](
elementPatterns: Chunk[Pattern[Attributes]],
annotations: Attributes
attributes: Attributes
) extends Pattern[Attributes]

final case class UnitPattern[+Attributes](annotations: Attributes) extends Pattern[Attributes]
final case class UnitPattern[+Attributes](attributes: Attributes) extends Pattern[Attributes]

final case class WildcardPattern[+Attributes](annotations: Attributes) extends Pattern[Attributes]
final case class WildcardPattern[+Attributes](attributes: Attributes) extends Pattern[Attributes]

}
Loading

0 comments on commit ea2ed56

Please sign in to comment.