All Downloads are FREE. Search and download functionalities are using the official Maven repository.

dc10.scala.Symbol.scala Maven / Gradle / Ivy

package dc10.scala

import cats.{Eval, Functor}
import cats.free.Cofree
import java.nio.file.Path

sealed trait Symbol

object Symbol:

  // Templates ////////////////////////////////////////////////////////////////
  sealed trait Template extends Symbol
  case class Extension(field: Statement, body: List[Statement]) extends Template
  sealed abstract class CaseClass[Z, T] extends Template:
    def nme: String
    def tpe: Term.Type[Z, T]
    def fields: List[Statement]
    def body: List[Statement]

  object CaseClass:
    def apply[T](
      q: Option[Long],
      n: String,
      fs: List[Statement],
    ): CaseClass[Unit, T] =
      new CaseClass[Unit, T]:
        def nme = n
        def tpe: Term.Type[Unit, T] = Cofree((), Eval.now(Term.TypeLevel.Var.UserDefinedType(q, n, None)))
        def fields = fs
        def body = Nil

  // Object ///////////////////////////////////////////////////////////////////
  sealed abstract class Object[Z, T] extends Symbol:
    def nme: String
    def par: Option[Term.Type[Z, T]]
    def tpe: Term.Type[Z, T]
    def body: List[Statement]

  object Object:
    def apply[T](
      q: Option[Long],
      n: String,
      p: Option[Term.Type[Unit, T]],
      b: List[Statement],
    ): Object[Unit, T] =
      new Object[Unit, T]:
        def nme = n
        def par = p
        def tpe: Term.Type[Unit, T] = Cofree((), Eval.now(
          p.fold(
            Term.TypeLevel.Var.UserDefinedType(q, n, None)
          )(i => i.tail.value)
        ))
        def body: List[Statement] = b

  // Package //////////////////////////////////////////////////////////////////
  sealed abstract class Package extends Symbol

  object Package:

    extension (pkg: Package)
      def getPath: Path =
        pkg match
          case Basic(nme, nst) => Path.of(nme).resolve(nst.pkg.getPath)
          case Empty(ms) => Path.of("")

      def addMember(stmt: Statement): Package =
        pkg match
          case Basic(nme, nst) => nst.pkg.addMember(stmt)
          case Empty(ms) => Empty(ms :+ stmt)

    case class Basic(
      nme: String,
      nst: Statement.PackageDef
    ) extends Package

    case class Empty(
      ms : List[Statement]
    ) extends Package

  // Term /////////////////////////////////////////////////////////////////////
  sealed abstract class Term extends Symbol:
    def qnt: Option[Long]

  object Term:

    type Type[Z, T] = Cofree[[X] =>> TypeLevel[T, X], Z]
    sealed trait TypeLevel[T, +X] extends Term
    object TypeLevel:

      given F[X, T]: Functor[[X] =>> TypeLevel[T, X]] =
        new Functor[[X] =>> TypeLevel[T, X]]:
          def map[A, B](fa: TypeLevel[T, A])(f: A => B): TypeLevel[T, B] =
            fa.asInstanceOf[TypeLevel[T, B]] 

      type __
      case class App1[Y, Z, T[_], U, A, X](qnt: Option[Long], tfun: Type[Z, T[U]], targ: Type[Y, A]) extends TypeLevel[T[A], X]
      case class App2[Z, T[_,_], A, B, X](qnt: Option[Long], tfun: Type[Z, T[__,__]], ta: Type[Z, A], tb: Type[Z, B]) extends TypeLevel[T[A, B], X]
      case class App3[Z, T[_,_,_], A, B, X](qnt: Option[Long], tfun: Type[Z, T[__,__,__]], ta1: Type[Z, A], ta2: Type[Z, A], tb: Type[Z, B]) extends TypeLevel[T[A, A, B], X]
      sealed abstract class Var[Z, T, +X] extends TypeLevel[T, X]
      object Var:
        case class BooleanType[Z, X](qnt: Option[Long]) extends Var[Z, Boolean, X]
        case class IntType[Z, X](qnt: Option[Long]) extends Var[Z, Int, X]
        case class StringType[Z, X](qnt: Option[Long]) extends Var[Z, String, X]
        case class Function1Type[Z, X](qnt: Option[Long]) extends Var[Z, __ => __, X]
        case class Function2Type[Z, X](qnt: Option[Long]) extends Var[Z, (__, __) => __, X]
        case class ListType[Z, G[_] <: List[?], X](qnt: Option[Long]) extends Var[Z, G[__], X]
        case class OptionType[Z, G[_] <: Option[?], X](qnt: Option[Long]) extends Var[Z, G[__], X]
        object OptionType:
          case class SomeType[Z, X](qnt: Option[Long]) extends Var[Z, Option[__], X]
        case class UserDefinedType[Z, T, X <: TypeLevel[T, X]](qnt: Option[Long], nme: String, impl: Option[Type[Z, T]]) extends Var[Z, T, X]
    
    type Value[Z, T] = Cofree[[X] =>> ValueLevel[T, X], Z]
    object Value:
      extension [Z, T] (v: Value[Z, T])
        def findImpl: Option[Value[Z, T]] =
          v.tail.value match
            case Term.ValueLevel.App.App1(qnt, fun, arg, tpe) => Some(v)
            case Term.ValueLevel.App.AppCtor1(qnt, tpe, arg) => Some(v)
            case Term.ValueLevel.App.AppPure(qnt, fun, arg, tpe) => Some(v)
            case Term.ValueLevel.App.AppVargs(qnt, fun, tpe, vargs*) => Some(v)
            case Term.ValueLevel.App.Dot1(qnt, fun, arg1, arg2) => Some(v)
            case Term.ValueLevel.App.Dotless(qnt, fun, arg1, arg2) => Some(v)
            case Term.ValueLevel.Lam.Lam1(qnt, a, b) => Some(v)
            case Term.ValueLevel.Lam.Lam2(qnt, a1, a2, b) => Some(v)
            case Term.ValueLevel.Var.BooleanLiteral(qnt, b) => Some(v)
            case Term.ValueLevel.Var.IntLiteral(qnt, i) => Some(v)
            case Term.ValueLevel.Var.StringLiteral(qnt, s) => Some(v)
            case Term.ValueLevel.Var.ListCtor(qnt) => Some(v)
            case Term.ValueLevel.Var.OptionCtor(qnt) => Some(v)
            case Term.ValueLevel.Var.OptionCtor.SomeCtor(qnt) => Some(v)
            case Term.ValueLevel.Var.Println(qnt, s) => Some(v)
            case [email protected](qnt, nme, tpe, impl) => u.findImpl.asInstanceOf[Option[Value[Z, T]]]

        def findVargs[Y, A]: Option[Seq[Value[Y, A]]] =
          v.findImpl.fold(???)(i => i.tail.value match
            case Term.ValueLevel.App.App1(qnt, fun, arg, tpe) => None 
            case Term.ValueLevel.App.AppCtor1(qnt, tpe, arg) => None
            case Term.ValueLevel.App.AppPure(qnt, fun, arg, tpe) => None
            case Term.ValueLevel.App.AppVargs(qnt, fun, tpe, vargs*) => Some(vargs.asInstanceOf[Seq[Value[Y, A]]])
            case Term.ValueLevel.App.Dot1(qnt, fun, arg1, arg2) => None
            case Term.ValueLevel.App.Dotless(qnt, fun, arg1, arg2) => None
            case Term.ValueLevel.Lam.Lam1(qnt, a, b) => None
            case Term.ValueLevel.Lam.Lam2(qnt, a1, a2, b) => None
            case Term.ValueLevel.Var.BooleanLiteral(qnt, b) => None
            case Term.ValueLevel.Var.IntLiteral(qnt, i) => None
            case Term.ValueLevel.Var.StringLiteral(qnt, s) => None
            case Term.ValueLevel.Var.ListCtor(qnt) => None
            case Term.ValueLevel.Var.OptionCtor(qnt) => None
            case Term.ValueLevel.Var.OptionCtor.SomeCtor(qnt) => None
            case Term.ValueLevel.Var.Println(qnt, s) => None
            case Term.ValueLevel.Var.UserDefinedValue(qnt, nme, tpe, impl) => None
          
            
          )
          
          
   
    sealed trait ValueLevel[T, +X] extends Term:
      type Zed
      def tpe: Type[Zed, T]

    object ValueLevel:

      given F[X, T]: Functor[[X] =>> ValueLevel[T, X]] =
        new Functor[[X] =>> ValueLevel[T, X]]:
          def map[A, B](fa: ValueLevel[T, A])(f: A => B): ValueLevel[T, B] =
            fa.asInstanceOf[ValueLevel[T, B]] 


      sealed abstract class App[Z, T, X] extends Term.ValueLevel[T, X]:
        type Zed = Z
      object App:
        case class App1[Z, A, B, X](qnt: Option[Long], fun: Value[Z, A => B], arg: Value[Z, A], tpe: Type[Z, B]) extends Term.ValueLevel.App[Z, B, X]
        case class AppCtor1[Z, T, A, X](qnt: Option[Long], tpe: Type[Z, T], arg: Value[Z, A]) extends Term.ValueLevel.App[Z, T, X]
        case class AppPure[G[_], Z, A, X](qnt: Option[Long], fun: Value[Z, A => G[A]], arg: Value[Z, A], tpe: Type[Z, G[A]]) extends Term.ValueLevel.App[Z, G[A], X]
        case class AppVargs[G[_], Y, Z, A, B, X](qnt: Option[Long], fun: Value[Z, G[A] => G[A]], tpe: Type[Z, G[A]], vargs: Value[Y, A]*) extends Term.ValueLevel.App[Z, G[A], X]
        case class Dot1[Z, A, B, C, D, X](qnt: Option[Long], fun: Value[Z, D], arg1: Value[Z, A], arg2: Value[Z, B]) extends Term.ValueLevel.App[Z, C, X]:
          def tpe: Type[Z, C] = ???
        case class Dotless[Z, A, B, C, D, X](qnt: Option[Long], fun: Value[Z, D], arg1: Value[Z, A], arg2: Value[Z, B]) extends Term.ValueLevel.App[Z, C, X]:
          def tpe: Type[Z, C] = ???
      sealed abstract class Lam[Z, T, X] extends Term.ValueLevel[T, X]:
        type Zed = Z
      object Lam:
        case class Lam1[Z, A, B, X](qnt: Option[Long], a: Value[Z, A], b: Value[Z, B]) extends Term.ValueLevel.Lam[Z, A => B, X]:
          def tpe: Type[Z, A => B] = Cofree(a.head, Eval.now(Term.TypeLevel.App2[Z, Function1, A, B, Nothing](None, Cofree(b.head, Eval.now(Term.TypeLevel.Var.Function1Type(None))), a.tail.value.tpe.asInstanceOf[Term.Type[Z, A]], b.tail.value.tpe.map(_ => a.head.asInstanceOf[Z]))))
        case class Lam2[Z, A, B, X](qnt: Option[Long], a1: Value[Z, A], a2: Value[Z, A], b: Value[Z, B]) extends Term.ValueLevel.Lam[Z, (A, A) => B, X]:
          def tpe: Type[Z, (A, A) => B] = ???

      sealed abstract class Var[Z, T, X] extends Term.ValueLevel[T, X]:
        type Zed = Z
      object Var:
        case class BooleanLiteral[X](qnt: Option[Long], b: Boolean) extends Var[Unit, Boolean, X]:
          def tpe: Type[Unit, Boolean] = Cofree((), Eval.now(Term.TypeLevel.Var.BooleanType(None)))
        case class IntLiteral[X](qnt: Option[Long], i: Int) extends Var[Unit, Int, X]:
          def tpe: Type[Unit, Int] = Cofree((), Eval.now(Term.TypeLevel.Var.IntType(None)))
        case class StringLiteral[X](qnt: Option[Long], s: String) extends Var[Unit, String, X]:
          def tpe: Type[Unit, String] = Cofree((), Eval.now(Term.TypeLevel.Var.StringType(None)))
        case class ListCtor[A, X](qnt: Option[Long]) extends Var[Unit, List[A] => List[A], X]:
          def tpe: Type[Unit, List[A] => List[A]] = ???
        case class OptionCtor[A, X](qnt: Option[Long]) extends Var[Unit, A => Option[A], X]:
          def tpe: Type[Unit, A => Option[A]] = ???
        object OptionCtor:
          case class SomeCtor[A, X](qnt: Option[Long]) extends Var[Unit, A => Some[A], X]:
            def tpe: Type[Unit, A => Some[A]] = Cofree((), Eval.now(Term.TypeLevel.App2(None, Cofree((), Eval.now(Term.TypeLevel.Var.Function1Type(None))), Cofree((), Eval.now(Term.TypeLevel.Var.UserDefinedType(None, "A", None))), Cofree((), Eval.now(Term.TypeLevel.Var.UserDefinedType(None, "A", None))))))
        case class Println[Z, F[_], X](qnt: Option[Long], s: Value[Unit, String]) extends Var[Z, F[Unit], X]:
          def tpe: Type[Z, F[Unit]] = ???//Cofree((), Eval.now(Term.TypeLevel.Var.UserDefinedType(None, "cats.effect.IO[Unit]", None)))
        case class UserDefinedValue[Z, T, X <: ValueLevel[T, X]](qnt: Option[Long], nme: String, tpe: Type[Z, T], impl: Option[Value[Z, T]]) extends Var[Z, T, X]
        object UserDefinedValue:
          extension [Z, T, X <: ValueLevel[T, X]] (u: UserDefinedValue[Z, T, X])
            def findImpl: Option[Value[Z, T]] =
              u.impl.fold(None)(i => i.tail.value match
                case Term.ValueLevel.App.App1(qnt, fun, arg, tpe) => u.impl 
                case Term.ValueLevel.App.AppCtor1(qnt, tpe, arg) => u.impl
                case Term.ValueLevel.App.AppPure(qnt, fun, arg, tpe) => u.impl
                case Term.ValueLevel.App.AppVargs(qnt, fun, tpe, vargs*) => u.impl
                case Term.ValueLevel.App.Dot1(qnt, fun, arg1, arg2) => u.impl
                case Term.ValueLevel.App.Dotless(qnt, fun, arg1, arg2) => u.impl
                case Term.ValueLevel.Lam.Lam1(qnt, a, b) => u.impl
                case Term.ValueLevel.Lam.Lam2(qnt, a1, a2, b) => u.impl
                case Term.ValueLevel.Var.BooleanLiteral(qnt, b) => u.impl
                case Term.ValueLevel.Var.IntLiteral(qnt, i) => u.impl
                case Term.ValueLevel.Var.StringLiteral(qnt, s) => u.impl
                case Term.ValueLevel.Var.ListCtor(qnt) => u.impl
                case Term.ValueLevel.Var.OptionCtor(qnt) => u.impl
                case Term.ValueLevel.Var.OptionCtor.SomeCtor(qnt) => u.impl
                case Term.ValueLevel.Var.Println(qnt, s) => u.impl
                case [email protected](qnt, nme, tpe, impl) => v.findImpl.asInstanceOf[Option[Value[Z, T]]]
              )
              




© 2015 - 2025 Weber Informatics LLC | Privacy Policy