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

Commit

Permalink
Ir changes (#106)
Browse files Browse the repository at this point in the history
* Add scala Native support

* scalafmt fixes

* Provide support for Variable

* Additional value constructor support

* Provide support for Unit constructors

* Added FieldFunction support in the recursive Value

* Added support for Constructor

* Added Reference Value support

* Literal Value support

* Added attributed Tuple construction support

* Fix ambiguity in tuple call

* Cleanup IsNotAValue to reduce allocations

* Added attributed list constructors

* Added list support

* Support Apply

* implement isData and uncurryApply

* provide uncurryApply implementation

* Provided record constructors

* Completed valueToString and added Field constructors

* Working on pattern

* Adding Additional Pattern constructors

* Adding Destructure constructors

* Additional pattern constructors

* lambda and destructure

* IfThenElse constructors

* UpdateRexord constructor support

* Added patternMatch constructors

* Added additional Pattern constructors

* LetDefinition constructors

* Let Recursion constructors

* Apply Scalafix rules

* Added testNative
  • Loading branch information
DamianReeves authored Apr 14, 2022
1 parent 39df84d commit e05d999
Show file tree
Hide file tree
Showing 22 changed files with 2,062 additions and 151 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ jobs:
matrix:
java: ['adopt@1.8', 'adopt@1.11']
scala: ['2.13.8', '3.1.1']
platform: ['JVM', 'JS']
platform: ['JVM', 'JS', 'Native']
steps:
- name: Checkout current branch
uses: actions/checkout@v3.0.0
Expand Down
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version = 3.5.0
version = 3.5.1

maxColumn = 120
runner.dialect = scala213source3
Expand Down
5 changes: 5 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,11 @@ addCommandAlias(
Seq("coreJS/test", "irJS/test", "sexprJS/test", "jsonJS/test").mkString(";", ";", ";")
)

addCommandAlias(
"testNative",
Seq("coreNative/test", "irNative/test").mkString(";", ";", ";")
)

lazy val scala213projects = Seq[ProjectReference](
annotationJS,
annotationJVM,
Expand Down
34 changes: 34 additions & 0 deletions morphir-ir/shared/src/main/scala-2.12-2.13/zio/morphir/Not.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package zio.morphir

import scala.annotation.implicitAmbiguous

/**
* Provides implicit evidence that an instance of `A` is not in implicit scope.
*/
@implicitAmbiguous("Implicit ${A} defined.")
sealed trait Not[A]

object Not {

/**
* Derives a `Not[A]` instance when an instance of `A` is not in implciit scope.
*/
implicit def Not[A]: Not[A] =
new Not[A] {}

/**
* Derives a `Not[A]` instance when an instance of `A` is in implicit scope. Together with the instance defined below
* this will cause implicit search to fail due to ambiguous implicits, preventing an instance of `Not[A]` from being
* in implicit scope when an instance of `A` is in implicit scope.
*/
implicit def NotAmbiguous1[A](implicit ev: A): Not[A] =
new Not[A] {}

/**
* Derives a `Not[A]` instance when an instance of `A` is in implicit scope. Together with the instance defined above
* this will cause implicit search to fail due to ambiguous implicits, preventing an instance of `Not[A]` from being
* in implicit scope when an instance of `A` is in implicit scope.
*/
implicit def NotAmbiguous2[A](implicit ev: A): Not[A] =
new Not[A] {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package zio.morphir.ir

import scala.annotation.implicitAmbiguous

sealed trait IsNotAValue[-A]

object IsNotAValue extends IsNotAValue[Any] with IsNotAValueLowerPriority {

implicit def isNotAValue[A]: IsNotAValue[A] = IsNotAValue

@implicitAmbiguous(
"This operation assumes that ${A} is not a morphir IR Value node. " +
"However, ${A} is a Value."
)
implicit def isNotAValueAmbiguous1[A](implicit ev: A <:< value.recursive.Value[_, _]): IsNotAValue[A] = IsNotAValue

implicit def isNotAValueAmbiguous2[A](implicit ev: A <:< value.recursive.Value[_, _]): IsNotAValue[A] = IsNotAValue

}

trait IsNotAValueLowerPriority {

@implicitAmbiguous(
"This operation assumes that ${A} is not a morphir IR Value node. " +
"However, ${A} is a Value."
)
implicit def isNotAValueAmbiguousA[A](implicit ev: A <:< value.Value[_, _]): IsNotAValue[A] = IsNotAValue

implicit def isNotAValueAmbiguousB[A](implicit ev: A <:< value.Value[_, _]): IsNotAValue[A] = IsNotAValue
}
17 changes: 17 additions & 0 deletions morphir-ir/shared/src/main/scala-3/zio/morphir/Not.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package zio.morphir
import scala.annotation.implicitNotFound
import scala.util.NotGiven

/**
* Provides implicit evidence that an instance of `A` is not in implicit scope.
*/
@implicitNotFound("Implicit ${A} defined.")
sealed trait Not[A]
object Not {

/**
* Derives a `Not[A]` instance from a `NotGiven[A]` instance.
*/
implicit def Not[A: NotGiven]: Not[A] =
new Not[A] {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package zio.morphir.ir

import scala.annotation.implicitNotFound
import scala.util.NotGiven

sealed abstract class IsNotAValue[-A] extends Serializable

object IsNotAValue extends IsNotAValue[Any] with IsNotAValueLowerPriority {
implicit def isNotAValue[A](using NotGiven[A <:< value.Value[_, _]]): IsNotAValue[A] = IsNotAValue

}

trait IsNotAValueLowerPriority {
implicit def isNotARecursiveValue[A](using NotGiven[A <:< value.recursive.Value[_, _]]): IsNotAValue[A] = IsNotAValue
}
15 changes: 15 additions & 0 deletions morphir-ir/shared/src/main/scala/zio/morphir/ir/Literal.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,22 @@ import scala.language.implicitConversions
sealed trait Literal[+A] { self =>
def value: A
def toRawValue: RawValue = Value.Value.Literal.Raw(self)

final override def toString: java.lang.String = Literal.toString(self)
}

object Literal {
def boolean(value: Boolean): Bool = Bool(value)
def char(value: scala.Char): Char = Char(value)
def decimal(value: java.math.BigDecimal): Float = Float(value)
def decimal(value: BigDecimal): Float = Float(value.bigDecimal)
def double(value: scala.Double): Float = Float(java.math.BigDecimal.valueOf(value))
def float(value: scala.Float): Float = Float(java.math.BigDecimal.valueOf(value.toDouble))
def int(value: Int): WholeNumber = WholeNumber(java.math.BigInteger.valueOf(value.toLong))
def long(value: Long): WholeNumber = WholeNumber(java.math.BigInteger.valueOf(value))
def string(value: java.lang.String): String = Literal.String(value)
def wholeNumber(value: java.math.BigInteger): WholeNumber = WholeNumber(value)
def wholeNumber(value: scala.BigInt): WholeNumber = WholeNumber(value.bigInteger)

val False: Bool = Bool(false)
val True: Bool = boolean(true)
Expand All @@ -32,6 +37,16 @@ object Literal {
final case class WholeNumber(value: java.math.BigInteger) extends Literal[java.math.BigInteger]
final case class Float(value: java.math.BigDecimal) extends Literal[java.math.BigDecimal]

def toString(literal: Literal[_]): java.lang.String = literal match {
case Bool(true) => "True"
case Bool(false) => "False"
case Char(value) => s"'$value'"
case String(value) => s""""$value""""
case WholeNumber(value) => value.toString
case Float(value) => value.toString

}

implicit def LiteralInferredTypeOf[A]: InferredTypeOf[Literal[A]] = new InferredTypeOf[Literal[A]] {
def inferredType(value: Literal[A]): UType = value match {
case Bool(_) => sdk.Basics.boolType
Expand Down
5 changes: 5 additions & 0 deletions morphir-ir/shared/src/main/scala/zio/morphir/ir/Name.scala
Original file line number Diff line number Diff line change
Expand Up @@ -110,4 +110,9 @@ object Name {

@inline def toHumanWords(name: Name): List[String] = name.humanize

object VariableName {
def unapply(name: Name): Option[String] =
Some(name.toCamelCase)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,9 @@ object Type extends TypeExprConstructors with UnattributedTypeExprConstructors w
case _ => None
}
}
implicit val CovariantType: Covariant[Type] = new Covariant[Type] {
override def map[A, B](f: A => B): Type[A] => Type[B] = tpe => tpe.mapAttributes(f)
}

final class MapTypeAttributes[+A](val input: () => Type[A]) extends AnyVal {
def apply[B](f: A => B): Type[B] = input().map(f)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,30 @@ sealed trait Pattern[+A] { self =>

def withAttributes[B >: A](attributes: => B): Pattern[B] =
self.map(_ => attributes)

override def toString(): String = self match {
case AsPattern(WildcardPattern(_), alias, _) => alias.toCamelCase
case AsPattern(pattern, name, _) => s"$pattern as ${name.toCamelCase}"
case ConstructorPattern(constructorName, argumentPatterns, _) =>
val ctor = constructorName.toReferenceName
val args = argumentPatterns.map(_.toString).mkString(" ")
s"$ctor $args"
case EmptyListPattern(_) => "[]"
case HeadTailPattern(headPattern, tailPattern, _) => s"$headPattern :: $tailPattern"
case LiteralPattern(literal, _) => literal.toString()
case TuplePattern(elementPatterns, _) => elementPatterns.mkString("(", ", ", ")")
case UnitPattern(_) => "()"
case WildcardPattern(_) => "_"
}
}

object Pattern {
type DefaultAttributes = Any
val DefaultAttributes: DefaultAttributes = ()

type UPattern = Pattern[DefaultAttributes]
val UPattern: Pattern.type = Pattern

def asPattern[Attributes](
attributes: Attributes,
pattern: Pattern[Attributes],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
package zio.morphir.ir.value

import zio.Chunk
import zio.morphir.Not
import zio.morphir.ir.value.Pattern.DefaultAttributes
import zio.morphir.ir.{FQName, Literal, Name}

trait PatternConstructors { self =>
final def asAlias[A](attributes: A, alias: String): Pattern[A] =
Pattern.AsPattern(
attributes = attributes,
pattern = Pattern.WildcardPattern(attributes),
name = Name.fromString(alias)
)

final def asAlias[A](attributes: A, alias: Name): Pattern[A] =
Pattern.AsPattern(
attributes = attributes,
pattern = Pattern.WildcardPattern(attributes),
name = alias
)

final def asAlias(alias: String): UPattern =
Pattern.AsPattern(
attributes = DefaultAttributes,
pattern = wildcardPattern,
name = Name.fromString(alias)
)

final def asAlias(alias: Name): UPattern =
Pattern.AsPattern(
attributes = DefaultAttributes,
pattern = wildcardPattern,
name = alias
)

final def asPattern[A](attributes: A, pattern: Pattern[A], alias: Name): Pattern[A] =
Pattern.AsPattern(attributes = attributes, pattern = pattern, name = alias)

final def asPattern[A](attributes: A, pattern: Pattern[A], alias: String): Pattern[A] =
Pattern.AsPattern(attributes = attributes, pattern = pattern, name = Name.fromString(alias))

final def asPattern(pattern: UPattern, alias: Name): UPattern =
Pattern.AsPattern(attributes = DefaultAttributes, pattern = pattern, name = alias)

final def asPattern(pattern: UPattern, alias: String): UPattern =
Pattern.AsPattern(attributes = DefaultAttributes, pattern = pattern, name = Name.fromString(alias))

final def asPattern(alias: String): UPattern =
Pattern.AsPattern(
attributes = DefaultAttributes,
pattern = wildcardPattern,
name = Name.fromString(alias)
)

final def asPattern(alias: Name): UPattern =
Pattern.AsPattern(
attributes = DefaultAttributes,
pattern = wildcardPattern,
name = alias
)

final def booleanPattern[A](attributes: A, value: Boolean): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.boolean(value))

final def booleanPattern(value: Boolean): UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.boolean(value))

final def constructorPattern[A](
attributes: A,
constructorName: FQName,
argumentPatterns: Chunk[Pattern[A]]
): Pattern[A] =
Pattern.ConstructorPattern(
attributes = attributes,
constructorName = constructorName,
argumentPatterns = argumentPatterns
)

final def constructorPattern[A](
attributes: A,
constructorName: String,
argumentPatterns: Chunk[Pattern[A]]
): Pattern[A] =
Pattern.ConstructorPattern(
attributes = attributes,
constructorName = FQName.fromString(constructorName),
argumentPatterns = argumentPatterns
)

final def decimalPattern[A](attributes: A, value: BigDecimal): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.decimal(value))

final def decimalPattern(value: BigDecimal): UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.decimal(value))

final def emptyListPattern[A](attributes: A): Pattern[A] =
Pattern.EmptyListPattern(attributes)

final lazy val emptyListPattern: UPattern =
Pattern.EmptyListPattern(DefaultAttributes)

final def falsePattern[A](attributes: A): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.False)

final def falsePattern: UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.False)

final def floatPattern[A](attributes: A, value: Float): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.float(value))

final def floatPattern(value: Float): UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.float(value))

final def headTailPattern[A](attributes: A, head: Pattern[A], tail: Pattern[A]): Pattern[A] =
Pattern.HeadTailPattern(attributes = attributes, headPattern = head, tailPattern = tail)

final def headTailPattern(head: UPattern, tail: UPattern): UPattern =
Pattern.HeadTailPattern(attributes = DefaultAttributes, headPattern = head, tailPattern = tail)

final def intPattern[A](attributes: A, value: Int): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.int(value))

final def intPattern(value: Int): UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.int(value))

final def literalPattern[A, T](attributes: A, value: Literal[T]): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = value)

final def literalPattern[T](value: Literal[T]): UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = value)

final def stringPattern[A](attributes: A, value: String): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.string(value))

final def stringPattern(value: String): UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.string(value))

final def truePattern[A](attributes: A): Pattern[A] =
Pattern.LiteralPattern(attributes = attributes, literal = Literal.True)

final def truePattern: UPattern =
Pattern.LiteralPattern(attributes = DefaultAttributes, literal = Literal.True)

final def tuplePattern[A](attributes: A, patterns: Chunk[Pattern[A]]): Pattern[A] =
Pattern.TuplePattern(attributes = attributes, elementPatterns = patterns)

final def tuplePattern[A](attributes: A, patterns: Pattern[A]*)(implicit ev: Not[A <:< Pattern[_]]): Pattern[A] =
Pattern.TuplePattern(attributes = attributes, elementPatterns = Chunk.fromIterable(patterns))

final def tuplePattern(patterns: Chunk[UPattern]): UPattern =
Pattern.TuplePattern(attributes = DefaultAttributes, elementPatterns = patterns)

final def tuplePattern(patterns: UPattern*): UPattern =
Pattern.TuplePattern(attributes = DefaultAttributes, elementPatterns = Chunk.fromIterable(patterns))

final def wildcardPattern[A](attributes: A): Pattern[A] = Pattern.WildcardPattern(attributes)

final lazy val wildcardPattern: UPattern = Pattern.WildcardPattern(Pattern.DefaultAttributes)

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ package object value {
type UDefinition = Definition[Any, Any]
val UDefinition: Definition.type = Definition

type UPattern = Pattern[Any]
val UPattern: Pattern.type = Pattern
type UPattern = zio.morphir.ir.value.Pattern.UPattern
val UPattern: Pattern.type = zio.morphir.ir.value.Pattern.UPattern

type USpecification = Specification[Any]
val USpecification: Specification.type = Specification
Expand Down
Loading

0 comments on commit e05d999

Please sign in to comment.