-
Notifications
You must be signed in to change notification settings - Fork 28
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Naïve compilation of refining patterns
- Loading branch information
Showing
20 changed files
with
1,014 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
hkmc2/shared/src/main/scala/hkmc2/semantics/ucs/DesugaringBase.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
package hkmc2 | ||
package semantics | ||
package ucs | ||
|
||
import mlscript.utils.*, shorthands.* | ||
import syntax.Tree.*, Elaborator.Ctxl | ||
|
||
/** Contains some helpers that makes UCS desugaring easier. */ | ||
trait DesugaringBase(using Elaborator.State): | ||
val elaborator: Elaborator | ||
|
||
import elaborator.{term, cls} | ||
|
||
protected transparent inline def int(i: Int) = Term.Lit(IntLit(BigInt(i))) | ||
protected transparent inline def fld(t: Term) = Fld(FldFlags.empty, t, N) | ||
protected transparent inline def tup(xs: Fld*) = Term.Tup(xs.toList)(Tup(Nil)) | ||
protected transparent inline def app(lhs: Term, rhs: Term, sym: FlowSymbol) = | ||
Term.App(lhs, rhs)(App(Empty(), Empty()), sym) | ||
|
||
protected lazy val matchResultClass = | ||
Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("MatchResult")) | ||
|
||
protected lazy val matchResultFailure = | ||
Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("MatchFailure")) | ||
|
||
protected lazy val tupleSlice: Ctxl[Term] = | ||
term(Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("tupleSlice"))) | ||
|
||
protected lazy val tupleGet: Ctxl[Term] = | ||
term(Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("tupleGet"))) | ||
|
||
protected lazy val stringStartsWith: Ctxl[Term] = | ||
term(Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("stringStartsWith"))) | ||
|
||
protected lazy val stringGet: Ctxl[Term] = | ||
term(Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("stringGet"))) | ||
|
||
protected lazy val stringDrop: Ctxl[Term] = | ||
term(Sel(Sel(Ident("globalThis"), Ident("Predef")), Ident("stringDrop"))) | ||
|
||
protected def callTupleGet(t: Term, i: Int, s: FlowSymbol): Ctxl[Term] = | ||
app(tupleGet, tup(fld(t), fld(int(i))), s) | ||
|
||
protected def callStringStartsWith(t: Term, prefix: Term, s: FlowSymbol): Ctxl[Term] = | ||
app(stringStartsWith, tup(fld(t), fld(prefix)), s) | ||
|
||
protected def callStringGet(t: Term, i: Int, s: FlowSymbol): Ctxl[Term] = | ||
app(stringGet, tup(fld(t), fld(int(i))), s) | ||
|
||
protected def callStringDrop(t: Term, n: Int, s: FlowSymbol): Ctxl[Term] = | ||
app(stringDrop, tup(fld(t), fld(int(n))), s) | ||
|
||
protected transparent inline def tempLet(term: Term)(inner: TempSymbol => Split): Split = | ||
val s = TempSymbol(N, "temp") | ||
Split.Let(s, term, inner(s)) | ||
|
||
protected transparent inline def plainTest(cond: Term, dbgName: Str = "cond")(inner: => Split): Split = | ||
val s = TempSymbol(N, dbgName) | ||
Split.Let(s, cond, Branch(s.ref(), inner) ~: Split.End) | ||
|
||
/** Make a `Branch` that calls `Pattern` symbols' `unapply` functions. */ | ||
def makeUnapplyBranch( | ||
scrut: => Term.Ref, | ||
psym: PatternSymbol, | ||
inner: => Split, | ||
method: Str = "unapply" | ||
)(fallback: Split): Ctxl[Split] = | ||
val matchResultClassTerm = cls(matchResultClass) | ||
matchResultClassTerm.symbol match | ||
case S(matchResultClassSymbol: ClassSymbol) => | ||
// def makeUnapplyBranch(scrut: => Term.Ref, pat) | ||
val resultIdent = Ident("matchResult"): Ident | ||
val resultSymbol = TempSymbol(N, "matchResult") | ||
val globalThis = term(Ident("globalThis")) | ||
val unapply = Term.Sel( | ||
prefix = Term.Sel(globalThis, Ident(psym.nme))(S(psym)), | ||
nme = Ident(method) | ||
)(N) | ||
val arguments = Term.Tup(Fld(FldFlags.empty, scrut, N) :: Nil)(Tup(Nil)) | ||
val call = Term.App(unapply, arguments)(App(Empty(), Empty()), FlowSymbol(s"result of $method")) | ||
Split.Let(resultSymbol, call, | ||
Branch( | ||
resultSymbol.ref(), | ||
Pattern.ClassLike(matchResultClassSymbol, matchResultClassTerm, N, false)(matchResultClass), | ||
inner | ||
) ~: fallback) | ||
case S(_) | N => lastWords("Cannot locate `MatchResult` class in the global scope.") | ||
|
||
/** Make a `Branch` that calls `Pattern` symbols' `unapplyStringPrefix` functions. */ | ||
def makeUnapplyStringPrefixBranch( | ||
scrut: => Term.Ref, | ||
psym: PatternSymbol, | ||
inner: (scrut: TempSymbol) => Split, | ||
method: Str = "unapplyStringPrefix" | ||
)(fallback: Split): Ctxl[Split] = | ||
val matchResultClassTerm = cls(matchResultClass) | ||
matchResultClassTerm.symbol match | ||
case S(matchResultClassSymbol: ClassSymbol) => | ||
// def makeUnapplyBranch(scrut: => Term.Ref, pat) | ||
val resultIdent = Ident("matchResult"): Ident | ||
val resultSymbol = TempSymbol(N, "matchResult") | ||
val globalThis = term(Ident("globalThis")) | ||
val unapply = Term.Sel( | ||
prefix = Term.Sel(globalThis, Ident(psym.nme))(S(psym)), | ||
nme = Ident(method) | ||
)(N) | ||
val arguments = Term.Tup(Fld(FldFlags.empty, scrut, N) :: Nil)(Tup(Nil)) | ||
val call = Term.App(unapply, arguments)(App(Empty(), Empty()), FlowSymbol(s"result of $method")) | ||
tempLet(call): resultSymbol => | ||
val argSym = TempSymbol(N, "arg") | ||
val tupleGetRes = FlowSymbol("postfix") | ||
Branch( | ||
resultSymbol.ref(), | ||
Pattern.ClassLike( | ||
matchResultClassSymbol, | ||
matchResultClassTerm, | ||
S(argSym :: Nil), | ||
false | ||
)(matchResultClass), | ||
tempLet(callTupleGet(argSym.ref(), 0, tupleGetRes))(inner) | ||
) ~: fallback | ||
case S(_) | N => lastWords("Cannot locate `MatchResult` class in the global scope.") |
Oops, something went wrong.