Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala
Original file line number Diff line number Diff line change
Expand Up @@ -472,7 +472,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
val args = argsOpt.map(_.map(_.scrutinee)).getOrElse(Nil)
// Normalization should reject cases where the user provides
// more sub-patterns than there are actual class parameters.
assert(argsOpt.isEmpty || args.length <= clsParams.length)
assert(argsOpt.isEmpty || args.length <= clsParams.length, (argsOpt, clsParams))
def mkArgs(args: Ls[TermSymbol -> BlockLocalSymbol])(using Subst): Case -> Block = args match
case Nil =>
Case.Cls(ctorSym, st) -> go(tail, topLevel = false)
Expand Down
4 changes: 2 additions & 2 deletions hkmc2/shared/src/main/scala/hkmc2/codegen/llir/Builder.scala
Original file line number Diff line number Diff line change
Expand Up @@ -107,9 +107,9 @@ final class LlirBuilder(using Elaborator.State)(tl: TraceLogger, uid: FreshInt):
private def newNamedBlockMem(name: Str) = BlockMemberSymbol(name, Nil)
private def newNamed(name: Str) = VarSymbol(Tree.Ident(name))
private def newClassSym(name: Str) =
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N, N), Tree.Ident(name))
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N), Tree.Ident(name))
private def newTupleSym(len: Int) =
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N, N), Tree.Ident(s"Tuple$len"))
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N), Tree.Ident(s"Tuple$len"))
private def newVarSym(name: Str) = VarSymbol(Tree.Ident(name))
private def newFunSym(name: Str) = BlockMemberSymbol(name, Nil)
private def newBuiltinSym(name: Str) = BuiltinSymbol(name, false, false, false, false)
Expand Down
19 changes: 15 additions & 4 deletions hkmc2/shared/src/main/scala/hkmc2/semantics/BlockImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,25 @@ trait BlockImpl(using Elaborator.State):
val desugStmts =
def desug(stmts: Ls[Tree]): Ls[Tree] =
stmts match
case PossiblyAnnotated(anns, syntax.Desugared(td: TypeDef)) :: stmts =>
val ctors = td.withPart.toList.flatMap:
case Block(sts) => sts.flatMap:
case Constructor(Block(ctors)) => ctors
case _ => Nil
case _ => Nil
PossiblyAnnotated(anns, td) :: (
ctors.map(head => PossiblyAnnotated(anns, TypeDef(syntax.Cls,
td.name match
case L(_) => head
case R(name) =>
InfixApp(head, syntax.Keyword.`extends`, name)
, N
)))
) ::: desug(stmts)
case stmt :: stmts =>
stmt.desugared match
case PossiblyAnnotated(anns, h @ Hndl(body = N)) =>
PossiblyAnnotated(anns, h.copy(body = S(Block(stmts)))) :: Nil
case PossiblyAnnotated(anns, TypeDef(syntax.Cls, Ident(name), rhs, S(Block(Constructor(Block(ctors)) :: rest)))) =>
PossiblyAnnotated(anns, TypeDef(syntax.Cls, Ident(name), rhs, if rest.isEmpty then N else S(Block(rest)))) ::
(ctors.map(head => PossiblyAnnotated(anns, TypeDef(syntax.Cls, InfixApp(head, syntax.Keyword.`extends`, Ident(name)), N, N))))
::: desug(stmts)
case stmt => stmt :: desug(stmts)
case Nil => Nil
desug(stmts)
Expand Down
81 changes: 48 additions & 33 deletions hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,8 @@ object Elaborator:
case huh => wat(huh)
protected def assumeObject(nme: Str): BlockMemberSymbol =
module.tree.definedSymbols.get(nme).getOrElse:
throw new NoSuchElementException:
s"builtin module symbol source.$nme. we have"
throw new NoSuchElementException(
s"builtin module symbol source.$nme")
object source extends VirtualModule(assumeBuiltinMod("source")):
val line = assumeObject("line")
val name = assumeObject("name")
Expand Down Expand Up @@ -202,17 +202,18 @@ object Elaborator:
val importSymbol = new VarSymbol(syntax.Tree.Ident("import"))
val runtimeSymbol = TempSymbol(N, "runtime")
val termSymbol = TempSymbol(N, "Term")
val effectSigSymbol = ClassSymbol(TypeDef(syntax.Cls, Dummy, N, N), Ident("EffectSig"))
val effectSigSymbol = ClassSymbol(DummyTypeDef(syntax.Cls), Ident("EffectSig"))
val nonLocalRetHandlerTrm =
val id = new Ident("NonLocalReturn")
val sym = ClassSymbol(TypeDef(syntax.Cls, Dummy, N, N), id)
val sym = ClassSymbol(DummyTypeDef(syntax.Cls), id)
Term.Sel(runtimeSymbol.ref(), id)(S(sym))
val nonLocalRet =
val id = new Ident("ret")
BlockMemberSymbol(id.name, Nil, true)
val matchResultClsSymbol =
val id = new Ident("MatchResult")
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("captures") :: Nil)), N, N)
// val td = DummyTypeDef(syntax.Cls)
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("captures") :: Nil)), N)
Comment on lines +215 to +216

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// val td = DummyTypeDef(syntax.Cls)
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("captures") :: Nil)), N)
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("captures") :: Nil)), N)

val cs = ClassSymbol(td, id)
val flag = FldFlags.empty.copy(value = true)
val ps = PlainParamList(Param(flag, VarSymbol(Ident("captures")), N, Modulefulness(N)(false)) :: Nil)
Expand All @@ -221,7 +222,7 @@ object Elaborator:
cs
val matchFailureClsSymbol =
val id = new Ident("MatchFailure")
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("errors") :: Nil)), N, N)
val td = DummyTypeDef(syntax.Cls)
val cs = ClassSymbol(td, id)
val flag = FldFlags.empty.copy(value = true)
val ps = PlainParamList(Param(flag, VarSymbol(Ident("errors")), N, Modulefulness(N)(false)) :: Nil)
Expand Down Expand Up @@ -337,11 +338,11 @@ extends Importer:
subterm(Block(d :: Unt() :: Nil))
case LetLike(`let`, lhs, rhso, S(bod)) =>
subterm(Block(LetLike(`let`, lhs, rhso, N) :: bod :: Nil))
case LetLike(`let`, lhs, S(rhs), N) =>
case LetLike(`let`, lhs, rhso, N) =>
raise(ErrorReport(
msg"Expected a body for let bindings in expression position" ->
tree.toLoc :: Nil))
block(LetLike(`let`, lhs, S(rhs), N) :: Nil, hasResult = true)._1
block(LetLike(`let`, lhs, rhso, N) :: Nil, hasResult = true)._1
case LetLike(`set`, lhs, S(rhs), N) =>
Term.Assgn(subterm(lhs), subterm(rhs))
case LetLike(`set`, lhs, S(rhs), S(bod)) =>
Expand All @@ -361,7 +362,7 @@ extends Importer:
val sym = fieldOrVarSym(HandlerBind, id)
log(s"Processing `handle` statement $id (${sym}) ${ctx.outer}")

val derivedClsSym = ClassSymbol(Tree.TypeDef(syntax.Cls, Tree.Error(), N, N), Tree.Ident(s"Handler$$${id.name}$$"))
val derivedClsSym = ClassSymbol(Tree.DummyTypeDef(syntax.Cls), Tree.Ident(s"Handler$$${id.name}$$"))
derivedClsSym.defn = S(ClassDef(
N, syntax.Cls, derivedClsSym,
BlockMemberSymbol(derivedClsSym.name, Nil),
Expand Down Expand Up @@ -481,9 +482,9 @@ extends Importer:
scoped("ucs:desugared"):
log(s"Desugared:\n${Split.display(des)}")
Term.IfLike(Keyword.`if`, des)
case InfixApp(lhs, Keyword.`then`, rhs) =>
case InfixApp(lhs, kw @ (Keyword.`then` | Keyword.`with`), rhs) =>
raise:
ErrorReport(msg"Unexpected infix use of 'then' keyword here" -> tree.toLoc :: Nil)
ErrorReport(msg"Unexpected infix use of keyword '${kw.name}' here" -> tree.toLoc :: Nil)
Term.Error
case OpApp(lhs, Ident("|"), rhs :: Nil) =>
Term.CompType(subterm(lhs), subterm(rhs), true)
Expand Down Expand Up @@ -585,7 +586,10 @@ extends Importer:
)
case tree @ Tup(fields) =>
Term.Tup(fields.map(fld(_)))(tree)
case New(body, rfto) => // TODO handle Under
// case New(c, rfto) =>
// assert(rfto.isEmpty)
// Term.New(cls(subterm(c), inAppPrefix = inAppPrefix), params.map(subterm(_)), bodo).withLocOf(tree)
case ProperNew(body, rfto) => // TODO handle Under
Comment on lines +589 to +592

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// case New(c, rfto) =>
// assert(rfto.isEmpty)
// Term.New(cls(subterm(c), inAppPrefix = inAppPrefix), params.map(subterm(_)), bodo).withLocOf(tree)
case ProperNew(body, rfto) => // TODO handle Under
case ProperNew(body, rfto) => // TODO handle Under

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I think this is good now:

Suggested change
// case New(c, rfto) =>
// assert(rfto.isEmpty)
// Term.New(cls(subterm(c), inAppPrefix = inAppPrefix), params.map(subterm(_)), bodo).withLocOf(tree)
case ProperNew(body, rfto) => // TODO handle Under
case ProperNew(body, rfto) =>

lazy val bodo = rfto.map: rft =>
val clsSym = new ClassSymbol(Tree.DummyTypeDef(syntax.Cls), Tree.Ident("$anon"))
ctx.nestInner(clsSym).givenIn:
Expand Down Expand Up @@ -644,7 +648,7 @@ extends Importer:
Term.Throw(subterm(body))
case Modified(Keyword.`do`, kwLoc, body) =>
Blk(subterm(body) :: Nil, unit)
case TypeDef(Mod, head, N, N) =>
case TypeDef(Mod, head, N) =>
subterm(head)
case Tree.Region(id: Tree.Ident, body) =>
val sym = VarSymbol(id)
Expand All @@ -667,7 +671,7 @@ extends Importer:
case TermDef(k, nme, rhs) =>
raise(ErrorReport(msg"Illegal definition in term position." -> tree.toLoc :: Nil))
Term.Error
case TypeDef(k, head, rhs, body) =>
case TypeDef(k, head, rhs) =>
raise(ErrorReport(msg"Illegal type declaration in term position." -> tree.toLoc :: Nil))
Term.Error
case Modified(kw, kwLoc, body) =>
Expand Down Expand Up @@ -815,6 +819,9 @@ extends Importer:
case Nil =>
reportUnusedAnnotations
(mkBlk(acc, N, hasResult), ctx)
case Constructor(Block(ctors)) :: sts =>
// TODO properly handle (it currently desugars to sibling classes)
go(sts, annotations, acc)
case Open(bod) :: sts =>
reportUnusedAnnotations
bod match
Expand Down Expand Up @@ -922,7 +929,7 @@ extends Importer:
LetDecl(sym, annotations) :: acc
(ctx + (id.name -> sym)) givenIn:
go(sts, Nil, newAcc)
case (tree @ LetLike(`let`, lhs, S(rhs), N)) :: sts =>
case (tree @ LetLike(`let`, lhs, _, N)) :: sts =>
raise(ErrorReport(msg"Unsupported let binding shape" -> tree.toLoc :: Nil))
go(sts, Nil, Term.Error :: acc)
case Def(lhs, rhs) :: sts =>
Expand Down Expand Up @@ -990,7 +997,7 @@ extends Importer:
// TypeDef(Mod, _, N, N) indicates if the function marks
// its result as "module". e.g, `fun f: module M`
// ^^^^^^
case S(TypeDef(Mod, _, N, N)) =>
case S(TypeDef(Mod, _, N)) =>
Modulefulness.ofSign(s)(true)
case _ =>
Modulefulness.none
Expand All @@ -1005,8 +1012,11 @@ extends Importer:
reportUnusedAnnotations
raise(d)
go(sts, Nil, acc)
case (td @ TypeDef(k, head, rhs, body)) :: sts =>
case (td @ TypeDef(k, head, rhs)) :: sts =>

assert((k is Als) || (k is Cls) || (k is Mod) || (k is Obj) || (k is Pat), k)
val body = td.withPart

td.symbName match
case S(L(d)) => raise(d)
case _ => ()
Expand All @@ -1016,9 +1026,11 @@ extends Importer:
raise(d)
return go(sts, Nil, acc)
val sym = members.getOrElse(nme.name, lastWords(s"Symbol not found: ${nme.name}"))

var newCtx = S(td.symbol).collectFirst:
case s: InnerSymbol => s
.fold(ctx.nest(OuterCtx.NonReturnContext))(ctx.nestInner(_))

val tps = td.typeParams match
case S(ts) =>
ts.tys.flatMap: targ =>
Expand All @@ -1034,10 +1046,13 @@ extends Importer:
vs.decl = S(res)
res :: Nil
case N => Nil

newCtx ++= tps.map(tp => tp.sym.name -> tp.sym) // TODO: correct ++?

val isDataClass = annotations.exists:
case Annot.Modifier(Keyword.`data`) => true
case _ => false

val ps =
td.paramLists.match
case Nil => N
Expand All @@ -1054,6 +1069,7 @@ extends Importer:
params(ps, isDataClass)
newCtx = newCtx2
res

def withFields(using Ctx)(fn: (Ctx) ?=> (Term.Blk, Ctx)): (Term.Blk, Ctx) =
val fields: Opt[List[TermDefinition | LetDecl | DefineVar]] = ps.map: ps =>
ps.params.flatMap: p =>
Expand Down Expand Up @@ -1084,7 +1100,6 @@ extends Importer:
val decl = LetDecl(psym, Nil)
val defn = DefineVar(psym, p.sym.ref())
decl :: defn :: Nil

val ctxWithFields = ctx
.withMembers(
fields.fold(Nil)(_.collect:
Expand All @@ -1097,6 +1112,16 @@ extends Importer:
val (blk, c) = fn(using ctxWithFields)
val blkWithFields = fields.fold[Term.Blk](blk)(fs => blk.copy(stats = fs ::: blk.stats))
(blkWithFields, c)

def mkBody(using Ctx) = withFields:
body match
case N | S(Error()) => (new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
case S(b: Tree.Block) => block(b, hasResult = false)
case S(t) =>
raise(ErrorReport(
msg"Illegal body of ${k.desc} definition (should be a block; found ${t.describe})." -> t.toLoc :: Nil))
(new Blk(Nil, Term.Lit(UnitLit(false))), ctx)

val defn = k match
case Als =>
val alsSym = td.symbol.asInstanceOf[TypeAliasSymbol] // TODO improve `asInstanceOf`
Expand Down Expand Up @@ -1148,12 +1173,7 @@ extends Importer:
newCtx.nestInner(clsSym).givenIn:
log(s"Processing type definition $nme")
val cd =
val (bod, c) = withFields:
body match
case S(b: Tree.Block) => block(b, hasResult = false)
// case S(t) => block(t :: Nil)
case S(t) => ???
case N => (new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
val (bod, c) = mkBody
ModuleDef(owner, clsSym, sym, tps, ps, newOf(td), k, ObjBody(bod), annotations)
clsSym.defn = S(cd)
cd
Expand All @@ -1163,12 +1183,7 @@ extends Importer:
newCtx.nestInner(clsSym).givenIn:
log(s"Processing type definition $nme")
val cd =
val (bod, c) = withFields:
body match
case S(b: Tree.Block) => block(b, hasResult = false)
// case S(t) => block(t :: Nil)
case S(t) => ???
case N => (new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
val (bod, c) = mkBody
ClassDef(owner, Cls, clsSym, sym, tps, ps, newOf(td), ObjBody(bod), annotations)
clsSym.defn = S(cd)
cd
Expand Down Expand Up @@ -1204,7 +1219,7 @@ extends Importer:
def newOf(td: TypeDef)(using Ctx): Opt[Term.New] =
td.extension
match
case S(ext) => S(term(New(S(ext), N)))
case S(ext) => S(term(ProperNew(S(ext), N)))
case N => N
match
case S(n: Term.New) => S(n)
Expand All @@ -1222,9 +1237,9 @@ extends Importer:
def param(t: Tree, inUsing: Bool, inDataClass: Bool): Ctxl[Opt[Opt[Bool] -> Param]] =
// mm: `module`-modified
def go(t: Tree, inUsing: Bool, flags: FldFlags, mm: Bool): Ctxl[Opt[Opt[Bool] -> Param]] = t match
case TypeDef(Mod, inner, N, N) =>
case TypeDef(Mod, inner, N) =>
go(inner, inUsing, flags, true)
case TypeDef(Pat, inner, N, N) =>
case TypeDef(Pat, inner, N) =>
go(inner, inUsing, flags.copy(pat = true), mm)
case TermDef(ImmutVal, inner, _) =>
go(inner, inUsing, flags.copy(value = true), mm)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ object DeBrujinSplit:
case App(ctor: (Ident | Sel), Tup(params)) => dealWithCtor(ctor, params)
case OpApp(lhs, op: Ident, rhs :: Nil) => dealWithCtor(op, Ls(lhs, rhs))
case literal: syntax.Literal => Branch(_, Literal(literal), _, _)
case Tree.TypeDef(syntax.Pat, body, N, N) => go(body)
case Tree.TypeDef(syntax.Pat, body, N) => go(body)
scoped("ucs:rp:elaborate"):
log(s"tree: ${tree.showDbg}")
Binder(go(tree)(Outermost, Accept(0), Reject))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -453,7 +453,7 @@ class Desugarer(elaborator: Elaborator)(using Ctx, Raise, State, UnderCtx) exten
val matches = scrutinees.iterator.zip(args).map:
case (symbol, tree) =>
val argument = tree match
case TypeDef(syntax.Pat, body, N, N) => S(DeBrujinSplit.elaborate(Nil, body, elaborator))
case TypeDef(syntax.Pat, body, N) => S(DeBrujinSplit.elaborate(Nil, body, elaborator))
case td @ TypeDef(k = syntax.Pat) =>
error(msg"Ill-formed pattern argument" -> td.toLoc); N
case _ => N
Expand Down
Loading
Loading