Skip to content

Commit ba89d62

Browse files
authored
Fix parsing of new and refactor parsing of with etc. (#313)
1 parent 4323f94 commit ba89d62

37 files changed

+353
-288
lines changed

hkmc2/shared/src/main/scala/hkmc2/codegen/Lowering.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
472472
val args = argsOpt.map(_.map(_.scrutinee)).getOrElse(Nil)
473473
// Normalization should reject cases where the user provides
474474
// more sub-patterns than there are actual class parameters.
475-
assert(argsOpt.isEmpty || args.length <= clsParams.length)
475+
assert(argsOpt.isEmpty || args.length <= clsParams.length, (argsOpt, clsParams))
476476
def mkArgs(args: Ls[TermSymbol -> BlockLocalSymbol])(using Subst): Case -> Block = args match
477477
case Nil =>
478478
Case.Cls(ctorSym, st) -> go(tail, topLevel = false)

hkmc2/shared/src/main/scala/hkmc2/codegen/llir/Builder.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,9 @@ final class LlirBuilder(using Elaborator.State)(tl: TraceLogger, uid: FreshInt):
107107
private def newNamedBlockMem(name: Str) = BlockMemberSymbol(name, Nil)
108108
private def newNamed(name: Str) = VarSymbol(Tree.Ident(name))
109109
private def newClassSym(name: Str) =
110-
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N, N), Tree.Ident(name))
110+
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N), Tree.Ident(name))
111111
private def newTupleSym(len: Int) =
112-
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N, N), Tree.Ident(s"Tuple$len"))
112+
ClassSymbol(Tree.TypeDef(hkmc2.syntax.Cls, Tree.Empty(), N), Tree.Ident(s"Tuple$len"))
113113
private def newVarSym(name: Str) = VarSymbol(Tree.Ident(name))
114114
private def newFunSym(name: Str) = BlockMemberSymbol(name, Nil)
115115
private def newBuiltinSym(name: Str) = BuiltinSymbol(name, false, false, false, false)

hkmc2/shared/src/main/scala/hkmc2/semantics/BlockImpl.scala

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,25 @@ trait BlockImpl(using Elaborator.State):
1313
val desugStmts =
1414
def desug(stmts: Ls[Tree]): Ls[Tree] =
1515
stmts match
16+
case PossiblyAnnotated(anns, syntax.Desugared(td: TypeDef)) :: stmts =>
17+
val ctors = td.withPart.toList.flatMap:
18+
case Block(sts) => sts.flatMap:
19+
case Constructor(Block(ctors)) => ctors
20+
case _ => Nil
21+
case _ => Nil
22+
PossiblyAnnotated(anns, td) :: (
23+
ctors.map(head => PossiblyAnnotated(anns, TypeDef(syntax.Cls,
24+
td.name match
25+
case L(_) => head
26+
case R(name) =>
27+
InfixApp(head, syntax.Keyword.`extends`, name)
28+
, N
29+
)))
30+
) ::: desug(stmts)
1631
case stmt :: stmts =>
1732
stmt.desugared match
1833
case PossiblyAnnotated(anns, h @ Hndl(body = N)) =>
1934
PossiblyAnnotated(anns, h.copy(body = S(Block(stmts)))) :: Nil
20-
case PossiblyAnnotated(anns, TypeDef(syntax.Cls, Ident(name), rhs, S(Block(Constructor(Block(ctors)) :: rest)))) =>
21-
PossiblyAnnotated(anns, TypeDef(syntax.Cls, Ident(name), rhs, if rest.isEmpty then N else S(Block(rest)))) ::
22-
(ctors.map(head => PossiblyAnnotated(anns, TypeDef(syntax.Cls, InfixApp(head, syntax.Keyword.`extends`, Ident(name)), N, N))))
23-
::: desug(stmts)
2435
case stmt => stmt :: desug(stmts)
2536
case Nil => Nil
2637
desug(stmts)

hkmc2/shared/src/main/scala/hkmc2/semantics/Elaborator.scala

Lines changed: 48 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ object Elaborator:
145145
case huh => wat(huh)
146146
protected def assumeObject(nme: Str): BlockMemberSymbol =
147147
module.tree.definedSymbols.get(nme).getOrElse:
148-
throw new NoSuchElementException:
149-
s"builtin module symbol source.$nme. we have"
148+
throw new NoSuchElementException(
149+
s"builtin module symbol source.$nme")
150150
object source extends VirtualModule(assumeBuiltinMod("source")):
151151
val line = assumeObject("line")
152152
val name = assumeObject("name")
@@ -202,17 +202,18 @@ object Elaborator:
202202
val importSymbol = new VarSymbol(syntax.Tree.Ident("import"))
203203
val runtimeSymbol = TempSymbol(N, "runtime")
204204
val termSymbol = TempSymbol(N, "Term")
205-
val effectSigSymbol = ClassSymbol(TypeDef(syntax.Cls, Dummy, N, N), Ident("EffectSig"))
205+
val effectSigSymbol = ClassSymbol(DummyTypeDef(syntax.Cls), Ident("EffectSig"))
206206
val nonLocalRetHandlerTrm =
207207
val id = new Ident("NonLocalReturn")
208-
val sym = ClassSymbol(TypeDef(syntax.Cls, Dummy, N, N), id)
208+
val sym = ClassSymbol(DummyTypeDef(syntax.Cls), id)
209209
Term.Sel(runtimeSymbol.ref(), id)(S(sym))
210210
val nonLocalRet =
211211
val id = new Ident("ret")
212212
BlockMemberSymbol(id.name, Nil, true)
213213
val matchResultClsSymbol =
214214
val id = new Ident("MatchResult")
215-
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("captures") :: Nil)), N, N)
215+
// val td = DummyTypeDef(syntax.Cls)
216+
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("captures") :: Nil)), N)
216217
val cs = ClassSymbol(td, id)
217218
val flag = FldFlags.empty.copy(value = true)
218219
val ps = PlainParamList(Param(flag, VarSymbol(Ident("captures")), N, Modulefulness(N)(false)) :: Nil)
@@ -221,7 +222,7 @@ object Elaborator:
221222
cs
222223
val matchFailureClsSymbol =
223224
val id = new Ident("MatchFailure")
224-
val td = TypeDef(syntax.Cls, App(id, Tup(Ident("errors") :: Nil)), N, N)
225+
val td = DummyTypeDef(syntax.Cls)
225226
val cs = ClassSymbol(td, id)
226227
val flag = FldFlags.empty.copy(value = true)
227228
val ps = PlainParamList(Param(flag, VarSymbol(Ident("errors")), N, Modulefulness(N)(false)) :: Nil)
@@ -337,11 +338,11 @@ extends Importer:
337338
subterm(Block(d :: Unt() :: Nil))
338339
case LetLike(`let`, lhs, rhso, S(bod)) =>
339340
subterm(Block(LetLike(`let`, lhs, rhso, N) :: bod :: Nil))
340-
case LetLike(`let`, lhs, S(rhs), N) =>
341+
case LetLike(`let`, lhs, rhso, N) =>
341342
raise(ErrorReport(
342343
msg"Expected a body for let bindings in expression position" ->
343344
tree.toLoc :: Nil))
344-
block(LetLike(`let`, lhs, S(rhs), N) :: Nil, hasResult = true)._1
345+
block(LetLike(`let`, lhs, rhso, N) :: Nil, hasResult = true)._1
345346
case LetLike(`set`, lhs, S(rhs), N) =>
346347
Term.Assgn(subterm(lhs), subterm(rhs))
347348
case LetLike(`set`, lhs, S(rhs), S(bod)) =>
@@ -361,7 +362,7 @@ extends Importer:
361362
val sym = fieldOrVarSym(HandlerBind, id)
362363
log(s"Processing `handle` statement $id (${sym}) ${ctx.outer}")
363364

364-
val derivedClsSym = ClassSymbol(Tree.TypeDef(syntax.Cls, Tree.Error(), N, N), Tree.Ident(s"Handler$$${id.name}$$"))
365+
val derivedClsSym = ClassSymbol(Tree.DummyTypeDef(syntax.Cls), Tree.Ident(s"Handler$$${id.name}$$"))
365366
derivedClsSym.defn = S(ClassDef(
366367
N, syntax.Cls, derivedClsSym,
367368
BlockMemberSymbol(derivedClsSym.name, Nil),
@@ -481,9 +482,9 @@ extends Importer:
481482
scoped("ucs:desugared"):
482483
log(s"Desugared:\n${Split.display(des)}")
483484
Term.IfLike(Keyword.`if`, des)
484-
case InfixApp(lhs, Keyword.`then`, rhs) =>
485+
case InfixApp(lhs, kw @ (Keyword.`then` | Keyword.`with`), rhs) =>
485486
raise:
486-
ErrorReport(msg"Unexpected infix use of 'then' keyword here" -> tree.toLoc :: Nil)
487+
ErrorReport(msg"Unexpected infix use of keyword '${kw.name}' here" -> tree.toLoc :: Nil)
487488
Term.Error
488489
case OpApp(lhs, Ident("|"), rhs :: Nil) =>
489490
Term.CompType(subterm(lhs), subterm(rhs), true)
@@ -585,7 +586,10 @@ extends Importer:
585586
)
586587
case tree @ Tup(fields) =>
587588
Term.Tup(fields.map(fld(_)))(tree)
588-
case New(body, rfto) => // TODO handle Under
589+
// case New(c, rfto) =>
590+
// assert(rfto.isEmpty)
591+
// Term.New(cls(subterm(c), inAppPrefix = inAppPrefix), params.map(subterm(_)), bodo).withLocOf(tree)
592+
case ProperNew(body, rfto) => // TODO handle Under
589593
lazy val bodo = rfto.map: rft =>
590594
val clsSym = new ClassSymbol(Tree.DummyTypeDef(syntax.Cls), Tree.Ident("$anon"))
591595
ctx.nestInner(clsSym).givenIn:
@@ -644,7 +648,7 @@ extends Importer:
644648
Term.Throw(subterm(body))
645649
case Modified(Keyword.`do`, kwLoc, body) =>
646650
Blk(subterm(body) :: Nil, unit)
647-
case TypeDef(Mod, head, N, N) =>
651+
case TypeDef(Mod, head, N) =>
648652
subterm(head)
649653
case Tree.Region(id: Tree.Ident, body) =>
650654
val sym = VarSymbol(id)
@@ -667,7 +671,7 @@ extends Importer:
667671
case TermDef(k, nme, rhs) =>
668672
raise(ErrorReport(msg"Illegal definition in term position." -> tree.toLoc :: Nil))
669673
Term.Error
670-
case TypeDef(k, head, rhs, body) =>
674+
case TypeDef(k, head, rhs) =>
671675
raise(ErrorReport(msg"Illegal type declaration in term position." -> tree.toLoc :: Nil))
672676
Term.Error
673677
case Modified(kw, kwLoc, body) =>
@@ -815,6 +819,9 @@ extends Importer:
815819
case Nil =>
816820
reportUnusedAnnotations
817821
(mkBlk(acc, N, hasResult), ctx)
822+
case Constructor(Block(ctors)) :: sts =>
823+
// TODO properly handle (it currently desugars to sibling classes)
824+
go(sts, annotations, acc)
818825
case Open(bod) :: sts =>
819826
reportUnusedAnnotations
820827
bod match
@@ -922,7 +929,7 @@ extends Importer:
922929
LetDecl(sym, annotations) :: acc
923930
(ctx + (id.name -> sym)) givenIn:
924931
go(sts, Nil, newAcc)
925-
case (tree @ LetLike(`let`, lhs, S(rhs), N)) :: sts =>
932+
case (tree @ LetLike(`let`, lhs, _, N)) :: sts =>
926933
raise(ErrorReport(msg"Unsupported let binding shape" -> tree.toLoc :: Nil))
927934
go(sts, Nil, Term.Error :: acc)
928935
case Def(lhs, rhs) :: sts =>
@@ -990,7 +997,7 @@ extends Importer:
990997
// TypeDef(Mod, _, N, N) indicates if the function marks
991998
// its result as "module". e.g, `fun f: module M`
992999
// ^^^^^^
993-
case S(TypeDef(Mod, _, N, N)) =>
1000+
case S(TypeDef(Mod, _, N)) =>
9941001
Modulefulness.ofSign(s)(true)
9951002
case _ =>
9961003
Modulefulness.none
@@ -1005,8 +1012,11 @@ extends Importer:
10051012
reportUnusedAnnotations
10061013
raise(d)
10071014
go(sts, Nil, acc)
1008-
case (td @ TypeDef(k, head, rhs, body)) :: sts =>
1015+
case (td @ TypeDef(k, head, rhs)) :: sts =>
1016+
10091017
assert((k is Als) || (k is Cls) || (k is Mod) || (k is Obj) || (k is Pat), k)
1018+
val body = td.withPart
1019+
10101020
td.symbName match
10111021
case S(L(d)) => raise(d)
10121022
case _ => ()
@@ -1016,9 +1026,11 @@ extends Importer:
10161026
raise(d)
10171027
return go(sts, Nil, acc)
10181028
val sym = members.getOrElse(nme.name, lastWords(s"Symbol not found: ${nme.name}"))
1029+
10191030
var newCtx = S(td.symbol).collectFirst:
10201031
case s: InnerSymbol => s
10211032
.fold(ctx.nest(OuterCtx.NonReturnContext))(ctx.nestInner(_))
1033+
10221034
val tps = td.typeParams match
10231035
case S(ts) =>
10241036
ts.tys.flatMap: targ =>
@@ -1034,10 +1046,13 @@ extends Importer:
10341046
vs.decl = S(res)
10351047
res :: Nil
10361048
case N => Nil
1049+
10371050
newCtx ++= tps.map(tp => tp.sym.name -> tp.sym) // TODO: correct ++?
1051+
10381052
val isDataClass = annotations.exists:
10391053
case Annot.Modifier(Keyword.`data`) => true
10401054
case _ => false
1055+
10411056
val ps =
10421057
td.paramLists.match
10431058
case Nil => N
@@ -1054,6 +1069,7 @@ extends Importer:
10541069
params(ps, isDataClass)
10551070
newCtx = newCtx2
10561071
res
1072+
10571073
def withFields(using Ctx)(fn: (Ctx) ?=> (Term.Blk, Ctx)): (Term.Blk, Ctx) =
10581074
val fields: Opt[List[TermDefinition | LetDecl | DefineVar]] = ps.map: ps =>
10591075
ps.params.flatMap: p =>
@@ -1084,7 +1100,6 @@ extends Importer:
10841100
val decl = LetDecl(psym, Nil)
10851101
val defn = DefineVar(psym, p.sym.ref())
10861102
decl :: defn :: Nil
1087-
10881103
val ctxWithFields = ctx
10891104
.withMembers(
10901105
fields.fold(Nil)(_.collect:
@@ -1097,6 +1112,16 @@ extends Importer:
10971112
val (blk, c) = fn(using ctxWithFields)
10981113
val blkWithFields = fields.fold[Term.Blk](blk)(fs => blk.copy(stats = fs ::: blk.stats))
10991114
(blkWithFields, c)
1115+
1116+
def mkBody(using Ctx) = withFields:
1117+
body match
1118+
case N | S(Error()) => (new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
1119+
case S(b: Tree.Block) => block(b, hasResult = false)
1120+
case S(t) =>
1121+
raise(ErrorReport(
1122+
msg"Illegal body of ${k.desc} definition (should be a block; found ${t.describe})." -> t.toLoc :: Nil))
1123+
(new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
1124+
11001125
val defn = k match
11011126
case Als =>
11021127
val alsSym = td.symbol.asInstanceOf[TypeAliasSymbol] // TODO improve `asInstanceOf`
@@ -1148,12 +1173,7 @@ extends Importer:
11481173
newCtx.nestInner(clsSym).givenIn:
11491174
log(s"Processing type definition $nme")
11501175
val cd =
1151-
val (bod, c) = withFields:
1152-
body match
1153-
case S(b: Tree.Block) => block(b, hasResult = false)
1154-
// case S(t) => block(t :: Nil)
1155-
case S(t) => ???
1156-
case N => (new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
1176+
val (bod, c) = mkBody
11571177
ModuleDef(owner, clsSym, sym, tps, ps, newOf(td), k, ObjBody(bod), annotations)
11581178
clsSym.defn = S(cd)
11591179
cd
@@ -1163,12 +1183,7 @@ extends Importer:
11631183
newCtx.nestInner(clsSym).givenIn:
11641184
log(s"Processing type definition $nme")
11651185
val cd =
1166-
val (bod, c) = withFields:
1167-
body match
1168-
case S(b: Tree.Block) => block(b, hasResult = false)
1169-
// case S(t) => block(t :: Nil)
1170-
case S(t) => ???
1171-
case N => (new Blk(Nil, Term.Lit(UnitLit(false))), ctx)
1186+
val (bod, c) = mkBody
11721187
ClassDef(owner, Cls, clsSym, sym, tps, ps, newOf(td), ObjBody(bod), annotations)
11731188
clsSym.defn = S(cd)
11741189
cd
@@ -1204,7 +1219,7 @@ extends Importer:
12041219
def newOf(td: TypeDef)(using Ctx): Opt[Term.New] =
12051220
td.extension
12061221
match
1207-
case S(ext) => S(term(New(S(ext), N)))
1222+
case S(ext) => S(term(ProperNew(S(ext), N)))
12081223
case N => N
12091224
match
12101225
case S(n: Term.New) => S(n)
@@ -1222,9 +1237,9 @@ extends Importer:
12221237
def param(t: Tree, inUsing: Bool, inDataClass: Bool): Ctxl[Opt[Opt[Bool] -> Param]] =
12231238
// mm: `module`-modified
12241239
def go(t: Tree, inUsing: Bool, flags: FldFlags, mm: Bool): Ctxl[Opt[Opt[Bool] -> Param]] = t match
1225-
case TypeDef(Mod, inner, N, N) =>
1240+
case TypeDef(Mod, inner, N) =>
12261241
go(inner, inUsing, flags, true)
1227-
case TypeDef(Pat, inner, N, N) =>
1242+
case TypeDef(Pat, inner, N) =>
12281243
go(inner, inUsing, flags.copy(pat = true), mm)
12291244
case TermDef(ImmutVal, inner, _) =>
12301245
go(inner, inUsing, flags.copy(value = true), mm)

hkmc2/shared/src/main/scala/hkmc2/semantics/ucs/DeBrujinSplit.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ object DeBrujinSplit:
113113
case App(ctor: (Ident | Sel), Tup(params)) => dealWithCtor(ctor, params)
114114
case OpApp(lhs, op: Ident, rhs :: Nil) => dealWithCtor(op, Ls(lhs, rhs))
115115
case literal: syntax.Literal => Branch(_, Literal(literal), _, _)
116-
case Tree.TypeDef(syntax.Pat, body, N, N) => go(body)
116+
case Tree.TypeDef(syntax.Pat, body, N) => go(body)
117117
scoped("ucs:rp:elaborate"):
118118
log(s"tree: ${tree.showDbg}")
119119
Binder(go(tree)(Outermost, Accept(0), Reject))

hkmc2/shared/src/main/scala/hkmc2/semantics/ucs/Desugarer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -453,7 +453,7 @@ class Desugarer(elaborator: Elaborator)(using Ctx, Raise, State, UnderCtx) exten
453453
val matches = scrutinees.iterator.zip(args).map:
454454
case (symbol, tree) =>
455455
val argument = tree match
456-
case TypeDef(syntax.Pat, body, N, N) => S(DeBrujinSplit.elaborate(Nil, body, elaborator))
456+
case TypeDef(syntax.Pat, body, N) => S(DeBrujinSplit.elaborate(Nil, body, elaborator))
457457
case td @ TypeDef(k = syntax.Pat) =>
458458
error(msg"Ill-formed pattern argument" -> td.toLoc); N
459459
case _ => N

0 commit comments

Comments
 (0)