Skip to content

Commit

Permalink
Some progress on Austronesian
Browse files Browse the repository at this point in the history
  • Loading branch information
propensive committed Feb 21, 2025
1 parent c54281e commit b63a60f
Show file tree
Hide file tree
Showing 7 changed files with 128 additions and 2 deletions.
2 changes: 1 addition & 1 deletion build.mill
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ object anticipation extends SoundnessModule {

object austronesian extends SoundnessModule {
object core extends SoundnessSubModule {
def moduleDeps = Seq(wisteria.core, distillate.core)
def moduleDeps = Seq(wisteria.core, distillate.core, hellenism.core)
}

object test extends ProbablyTestModule {
Expand Down
9 changes: 9 additions & 0 deletions lib/austronesian/src/core/austronesian-core.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,18 @@
package austronesian

import anticipation.*
import hellenism.*
import prepositional.*

export Austronesian.Stdlib

extension [ValueType: Encodable in Stdlib](value: ValueType)
def stdlib: Stdlib = ValueType.encoded(value)

extension (classloader: Classloader)
inline def isolate[ResultType](inline invoke: ResultType): ResultType =
${Austronesian2.isolated('classloader, 'invoke)}

extension (context: StringContext)
def o(): Proxy = Proxy(context.parts.head.tt, true)
def c(): Proxy = Proxy(context.parts.head.tt, false)
50 changes: 49 additions & 1 deletion lib/austronesian/src/core/austronesian.Austronesian2.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,20 @@
package austronesian

import scala.compiletime.*
import scala.quoted.*

import anticipation.*
import contingency.*
import distillate.*
import fulminate.*
import hellenism.*
import prepositional.*
import proscenium.*
import rudiments.*
import wisteria.*

given Realm = realm"austronesian"

object Austronesian2:
object EncodableDerivation extends Derivation[[Type] =>> Type is Encodable in Stdlib]:

Expand Down Expand Up @@ -73,9 +79,51 @@ object Austronesian2:
summonInline[Tactic[StdlibError]].give(abort(StdlibError()))

inline def split[DerivationType: SumReflection]: DerivationType is Decodable in Stdlib =
case Array(label: String, stdlib: Stdlib) =>
case Array(label: String @unchecked, stdlib: Stdlib @unchecked) =>
delegate(label): [VariantType <: DerivationType] =>
_.decoded(stdlib)

case other =>
summonInline[Tactic[StdlibError]].give(abort(StdlibError()))

def isolated[ResultType: Type](classloader: Expr[Classloader], invoke: Expr[ResultType])
(using Quotes)
: Expr[ResultType] =

import quotes.reflect.*

invoke.asTerm match
case term => println(term)

'{???}


def proxy
(className: Expr[Text],
methodName: Expr[String],
arguments: Expr[Seq[Any]],
classloader: Expr[Classloader],
singleton: Expr[Boolean])
(using Quotes)
: Expr[Any] =

import quotes.reflect.*

val args: IArray[Expr[Stdlib]] = arguments.absolve match
case Varargs(arguments) => IArray.from(arguments).map:
case '{ $argument: argumentType } =>

val encodable = Expr.summon[argumentType is Encodable in Stdlib].getOrElse:
halt(m"${Type.of[argumentType]} is not encodable as a standard library parameter")

'{$encodable.encoded($argument)}

if singleton.valueOrAbort then
'{ val javaClass = Class.forName($className.s+"$", true, $classloader.java).nn
val instance = javaClass.getField("MODULE$").nn.get(null).nn
val method = javaClass.getMethod($methodName, classOf[Object]).nn
method.invoke(instance, null) }
else
'{ val javaClass = Class.forName($className.s, true, $classloader.java).nn
val method = javaClass.getMethod($methodName).nn
method.invoke(null, null) }
12 changes: 12 additions & 0 deletions lib/austronesian/src/core/austronesian.Proxy.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package austronesian

import language.dynamics

import anticipation.*
import hellenism.*

class Proxy(name: Text, singleton: Boolean) extends Dynamic:
transparent inline def applyDynamic(method: String)(inline arguments: Any*)
(using classloader: Classloader)
: Any =
${Austronesian2.proxy('name, 'method, 'arguments, 'classloader, 'singleton)}
39 changes: 39 additions & 0 deletions lib/austronesian/src/core/austronesian.Restorable.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package austronesian

import scala.quoted.*

import anticipation.*
import hellenism.*
import wisteria.*

object Restorable extends ProductDerivation[[Type] =>> Type is Restorable]:
given Text is Restorable:
def restore(value: Expr[Stdlib])(using Quotes, Classloader): Expr[Text] =
'{ if $value.isInstanceOf[String] then $value.asInstanceOf[Text]
else throw new RuntimeException() }

given Int is Restorable:
def restore(value: Expr[Stdlib])(using Quotes, Classloader): Expr[Int] =
'{ if $value.isInstanceOf[Int] then $value.asInstanceOf[Int]
else throw new RuntimeException() }

inline def join[DerivationType <: Product: ProductReflection]: DerivationType is Restorable =
new Restorable:
type Self = DerivationType

def restore(value: Expr[Stdlib])(using quotes: Quotes, classloader: Classloader)
: Expr[Self] =

import quotes.reflect.*
given Type[DerivationType] = compiletime.summonInline[Type[DerivationType]]

val x: Symbol = TypeRepr.of[DerivationType].typeSymbol.primaryConstructor

println(x)
???


trait Restorable:
type Self

def restore(value: Expr[Stdlib])(using Quotes, Classloader): Expr[Self]
6 changes: 6 additions & 0 deletions lib/austronesian/src/test/austronesian.Example.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package austronesian


object Example:
def run(name: Any): Unit =
println(s"Hello, $name!")
12 changes: 12 additions & 0 deletions lib/austronesian/src/test/austronesian.Tests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,15 @@ object Tests extends Suite(t"Austronesian tests"):
test(t"Roundtrip a complex datatype"):
unsafely(data.stdlib.decode[List[Something]])
. assert(_ == data)




suite(t"Proxy testing"):
test(t"Invoke a Proxy method"):
import classloaders.system
o"austronesian.Example".run(t"hello")
.assert()

test(t"Invoke the macro"):
summon[Person is Restorable]

0 comments on commit b63a60f

Please sign in to comment.