Skip to content

Commit 53d2587

Browse files
FlandiaYingmanLPTK
andauthored
Move Most Resolution to the Resolution Stage (#297)
Co-authored-by: Lionel Parreaux <[email protected]>
1 parent 8ce191f commit 53d2587

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

53 files changed

+1712
-948
lines changed

hkmc2/shared/src/main/scala/hkmc2/MLsCompiler.scala

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import utils.*
77

88
import hkmc2.semantics.MemberSymbol
99
import hkmc2.semantics.Elaborator
10-
import hkmc2.semantics.ImplicitResolver
10+
import hkmc2.semantics.Resolver
1111
import semantics.Elaborator.Ctx
1212
import hkmc2.syntax.Keyword.`override`
1313
import semantics.Elaborator.State
@@ -82,8 +82,8 @@ class MLsCompiler(preludeFile: os.Path, mkOutput: ((Str => Unit) => Unit) => Uni
8282
val elab = Elaborator(etl, wd, newCtx)
8383
val parsed = mainParse.resultBlk
8484
val (blk0, _) = elab.importFrom(parsed)
85-
val resolver = ImplicitResolver(rtl)
86-
resolver.resolveBlk(blk0)(using ImplicitResolver.ICtx.empty)
85+
val resolver = Resolver(rtl)
86+
resolver.traverseBlock(blk0)(using Resolver.ICtx.empty)
8787
val blk = new semantics.Term.Blk(
8888
semantics.Import(State.runtimeSymbol, runtimeFile.toString) :: blk0.stats,
8989
blk0.res

hkmc2/shared/src/main/scala/hkmc2/bbml/bbML.scala

+16-16
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
165165
Type.mkComposedType(typeMonoType(lhs), typeMonoType(rhs), pol)
166166
case _ =>
167167
ty.symbol.flatMap(_.asTpe) match
168-
case S(cls: (ClassSymbol | TypeAliasSymbol)) => typeAndSubstType(Term.TyApp(ty, Nil), pol)
168+
case S(cls: (ClassSymbol | TypeAliasSymbol)) => typeAndSubstType(Term.TyApp(ty, Nil)(N), pol)
169169
case S(_) => error(msg"${ty.symbol.get.getClass.toString()} is not a valid type" -> ty.toLoc :: Nil)
170170
case N => error(msg"Invalid type" -> ty.toLoc :: Nil) // TODO
171171

@@ -220,7 +220,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
220220
val nestCtx = ctx.nextLevel
221221
given BbCtx = nestCtx
222222
val bds = params.map:
223-
case Param(_, sym, _) =>
223+
case Param(sym = sym) =>
224224
val tv = freshVar(sym)
225225
val sk = freshSkolem(sym)
226226
nestCtx &= (sym, tv, sk)
@@ -239,7 +239,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
239239
constrain(lhsTy, FunType(rhsTy.reverse, resTy, Bot)) // TODO: right
240240
(resTy, lhsCtx | rhsCtx, lhsEff | rhsEff)
241241
case sel @ Term.SynthSel(Term.Ref(_: TopLevelSymbol), _) if sel.symbol.isDefined =>
242-
val (opTy, eff) = typeCheck(Ref(sel.symbol.get)(sel.nme, 666)) // FIXME 666
242+
val (opTy, eff) = typeCheck(Ref(sel.symbol.get)(sel.nme, 666, N)) // FIXME 666
243243
(tryMkMono(opTy, sel), Bot, eff)
244244
case unq @ Term.Unquoted(body) =>
245245
val (ty, eff) = typeCheck(body)
@@ -343,7 +343,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
343343
else
344344
val nestCtx = ctx.nest
345345
val argsTy = params.zip(args).map:
346-
case (Param(_, sym, _), ty) =>
346+
case (Param(sym = sym), ty) =>
347347
nestCtx += sym -> ty
348348
ty
349349
given BbCtx = nestCtx
@@ -421,7 +421,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
421421
case Term.Annotated(Annot.Untyped, _) => (Bot, Bot)
422422
case sel @ Term.SynthSel(Ref(_: TopLevelSymbol), nme)
423423
if sel.symbol.isDefined =>
424-
typeCheck(Ref(sel.symbol.get)(sel.nme, 666)) // FIXME 666
424+
typeCheck(Ref(sel.symbol.get)(sel.nme, 666, N)) // FIXME 666
425425
case Ref(sym) =>
426426
ctx.get(sym) match
427427
case Some(ty) => (ty, Bot)
@@ -442,16 +442,16 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
442442
effBuff += eff
443443
ctx += sym -> rhsTy
444444
goStats(stats)
445-
case TermDefinition(_, Fun, sym, ps :: Nil, _, sig, S(body), _, _, _) :: stats =>
446-
typeFunDef(sym, Term.Lam(ps, body), sig, ctx)
445+
case (td @ TermDefinition(k = Fun, params = ps :: Nil, sign = sig, body = S(body))) :: stats =>
446+
typeFunDef(td.sym, Term.Lam(ps, body), sig, ctx)
447447
goStats(stats)
448-
case TermDefinition(_, Fun, sym, Nil, _, sig, S(body), _, _, _) :: stats =>
449-
typeFunDef(sym, body, sig, ctx) // * may be a case expressions
448+
case (td @ TermDefinition(k = Fun, params = Nil, sign = sig, body = S(body))) :: stats =>
449+
typeFunDef(td.sym, body, sig, ctx) // * may be a case expressions
450450
goStats(stats)
451-
case TermDefinition(_, Fun, sym1, _, _, S(sig), None, _, _, _) :: (td @ TermDefinition(_, Fun, sym2, _, _, _, S(body), _, _, _)) :: stats
452-
if sym1 === sym2 => goStats(td :: stats) // * avoid type check signatures twice
453-
case TermDefinition(_, Fun, sym, _, _, S(sig), None, _, _, _) :: stats =>
454-
ctx += sym -> typeType(sig)
451+
case (td1 @ TermDefinition(k = Fun, sign = S(sig), body = None)) :: (td2 @ TermDefinition(k = Fun, body = S(body))) :: stats
452+
if td1.sym === td2.sym => goStats(td2 :: stats) // * avoid type check signatures twice
453+
case (td @ TermDefinition(k = Fun, sign = S(sig), body = None)) :: stats =>
454+
ctx += td.sym -> typeType(sig)
455455
goStats(stats)
456456
case (clsDef: ClassDef) :: stats =>
457457
goStats(stats)
@@ -475,7 +475,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
475475
val nestCtx = ctx.nest
476476
given BbCtx = nestCtx
477477
val tvs = params.map:
478-
case Param(_, sym, sign) =>
478+
case Param(_, sym, sign, _) =>
479479
val ty = sign.map(s => typeType(s)(using nestCtx)).getOrElse(freshVar(sym))
480480
nestCtx += sym -> ty
481481
ty
@@ -495,7 +495,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
495495
constrain(tryMkMono(ty, term), ClassLikeType(clsSym, targs))
496496
require(clsDfn.paramsOpt.forall(_.restParam.isEmpty))
497497
(clsDfn.paramsOpt.fold(Nil)(_.params).map {
498-
case Param(_, sym, sign) =>
498+
case Param(_, sym, sign, _) =>
499499
if sym.nme === field.name then sign else N
500500
}.filter(_.isDefined)) match
501501
case S(res) :: Nil => (typeAndSubstType(res, pol = true)(using map.toMap), eff)
@@ -527,7 +527,7 @@ class BBTyper(using elState: Elaborator.State, tl: TL):
527527
val effBuff = ListBuffer.empty[Type]
528528
require(clsDfn.paramsOpt.forall(_.restParam.isEmpty))
529529
args.iterator.zip(clsDfn.params.params).foreach {
530-
case (arg, Param(_, _, S(sign))) =>
530+
case (arg, Param(sign = S(sign))) =>
531531
val (ty, eff) = ascribe(arg, typeAndSubstType(sign, pol = true)(using map.toMap))
532532
effBuff += eff
533533
case _ => ???

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class BlockTransformer(subst: SymbolSubst):
189189
def applyParamList(pl: ParamList): ParamList =
190190
def applyParam(p: Param): Param =
191191
val sym2 = p.sym.subst
192-
if sym2 is p.sym then p else Param(p.flags, sym2, p.sign)
192+
if sym2 is p.sym then p else p.copy(sym = sym2)
193193
val params2 = pl.params.mapConserve(applyParam)
194194
val rest2 = pl.restParam.mapConserve(applyParam)
195195
if (params2 is pl.params) && (rest2 is pl.restParam)

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -459,7 +459,7 @@ class HandlerLowering(paths: HandlerPaths, opt: EffectHandlers)(using TL, Raise,
459459

460460
val handlerMtds = h.handlers.map: handler =>
461461
val lam = Value.Lam(
462-
PlainParamList(Param(FldFlags.empty, handler.resumeSym, N) :: Nil),
462+
PlainParamList(Param(FldFlags.empty, handler.resumeSym, N, Modulefulness.none) :: Nil),
463463
translateBlock(handler.body,
464464
handler.params.flatMap(_.paramSyms).toSet,
465465
handlerMtdCtx(s"Cont$$handler$$${symToStr(h.lhs)}$$${symToStr(handler.sym)}$$", handler.sym.nme)))
@@ -584,7 +584,7 @@ class HandlerLowering(paths: HandlerPaths, opt: EffectHandlers)(using TL, Raise,
584584
val resumeFnDef = FunDefn(
585585
S(clsSym), // owner
586586
resumeSym,
587-
List(PlainParamList(List(Param(FldFlags.empty, resumedVal, N)))),
587+
List(PlainParamList(List(Param(FldFlags.empty, resumedVal, N, Modulefulness.none)))),
588588
resumeBody
589589
)
590590

@@ -624,7 +624,7 @@ class HandlerLowering(paths: HandlerPaths, opt: EffectHandlers)(using TL, Raise,
624624
BlockMemberSymbol(clsSym.nme, Nil),
625625
syntax.Cls,
626626
S(PlainParamList({
627-
val p = Param(FldFlags.empty.copy(value = true), pcVar, N)
627+
val p = Param(FldFlags.empty.copy(value = true), pcVar, N, Modulefulness.none)
628628
pcVar.decl = S(p)
629629
p
630630
} :: Nil)),

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

+6-6
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
244244
val varSym = VarSymbol(Tree.Ident(nme))
245245
val fldSym = BlockMemberSymbol(nme, Nil)
246246

247-
val p = Param(FldFlags.empty.copy(value = true), varSym, None)
247+
val p = Param(FldFlags.empty.copy(value = true), varSym, N, Modulefulness.none)
248248
varSym.decl = S(p) // * Currently this is only accessed to create the class' toString method
249249

250250
val vd = ValDefn(
@@ -750,25 +750,25 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
750750
(sym, createSym(sym.nme + "$member"))
751751

752752
val extraParamsCaptures = capturesSymbols.map: // parameter list
753-
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
753+
case (d, (sym, _)) => Param(FldFlags.empty, sym, N, Modulefulness.none)
754754
val newCapturePaths = capturesSymbols.map: // mapping from sym to param symbol
755755
case (d, (_, sym)) => d -> sym.asPath
756756
.toMap
757757

758758
val extraParamsLocals = localsSymbols.map: // parameter list
759-
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
759+
case (d, (sym, _)) => Param(FldFlags.empty, sym, N, Modulefulness.none)
760760
val newLocalsPaths = localsSymbols.map: // mapping from sym to param symbol
761761
case (d, (_, sym)) => d -> sym
762762
.toMap
763763

764764
val extraParamsIsyms = isymSymbols.map: // parameter list
765-
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
765+
case (d, (sym, _)) => Param(FldFlags.empty, sym, N, Modulefulness.none)
766766
val newIsymPaths = isymSymbols.map: // mapping from sym to param symbol
767767
case (d, (_, sym)) => d -> sym
768768
.toMap
769769

770770
val extraParamsBms = bmsSymbols.map: // parameter list
771-
case (d, (sym, _)) => Param(FldFlags.empty, sym, None)
771+
case (d, (sym, _)) => Param(FldFlags.empty, sym, N, Modulefulness.none)
772772
val newBmsPaths = bmsSymbols.map: // mapping from sym to param symbol
773773
case (d, (_, sym)) => d -> sym.asPath
774774
.toMap
@@ -838,7 +838,7 @@ class Lifter(handlerPaths: Opt[HandlerPaths])(using State, Raise):
838838
acc = blk => acc(Assign(curSym, call, blk))
839839
val bod = acc(Return(Call(curSym.asPath, extraSyms.map(_.asPath.asArg))(true, false), false))
840840

841-
inline def toPlist(ls: List[VarSymbol]) = PlainParamList(ls.map(s => Param(FldFlags.empty, s, N)))
841+
inline def toPlist(ls: List[VarSymbol]) = PlainParamList(ls.map(s => Param(FldFlags.empty, s, N, Modulefulness.none)))
842842

843843
val paramPlist = paramSyms.map(toPlist)
844844
val auxPlist = auxSyms.map(toPlist)

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

+22-21
Original file line numberDiff line numberDiff line change
@@ -194,11 +194,17 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
194194
final def term(t: st, inStmtPos: Bool = false)(k: Result => Block)(using Subst): Block =
195195
tl.log(s"Lowering.term ${t.showDbg.truncate(100, "[...]")}${
196196
if inStmtPos then " (in stmt)" else ""}${
197-
t.symbol.fold("")(" – symbol " + _)}")
197+
t.resolvedSymbol.fold("")(" – symbol " + _)}")
198+
198199
def warnStmt = if inStmtPos then
199200
raise:
200201
WarningReport(msg"Pure expression in statement position" -> t.toLoc :: Nil, S(t))
202+
203+
// Funny Scala: the non-exhaustive match is actually the second match
201204
t match
205+
case t: sem.Resolvable => t.instantiate
206+
case t => t
207+
match
202208
case st.UnitVal() => k(unit)
203209
case st.Lit(lit) =>
204210
warnStmt
@@ -224,37 +230,39 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
224230
if sym.binary then
225231
val t1 = new Tree.Ident("arg1")
226232
val t2 = new Tree.Ident("arg2")
227-
val p1 = Param(FldFlags.empty, VarSymbol(t1), N)
228-
val p2 = Param(FldFlags.empty, VarSymbol(t2), N)
233+
val p1 = Param(FldFlags.empty, VarSymbol(t1), N, Modulefulness.none)
234+
val p2 = Param(FldFlags.empty, VarSymbol(t2), N, Modulefulness.none)
229235
val ps = PlainParamList(p1 :: p2 :: Nil)
230-
val bod = st.App(t, st.Tup(List(st.Ref(p1.sym)(t1, 666), st.Ref(p2.sym)(t2, 666)))
236+
val bod = st.App(t, st.Tup(List(st.Ref(p1.sym)(t1, 666, N).noIArgs, st.Ref(p2.sym)(t2, 666, N).noIArgs))
231237
(Tree.Tup(Nil // FIXME should not be required (using dummy value)
232238
)))(
233239
Tree.App(Tree.Empty(), Tree.Empty()), // FIXME should not be required (using dummy value)
240+
N,
234241
FlowSymbol(sym.nme)
235-
)
242+
).noIArgs
236243
val (paramLists, bodyBlock) = setupFunctionDef(ps :: Nil, bod, S(sym.nme))
237244
tl.log(s"Ref builtin $sym")
238245
assert(paramLists.length === 1)
239246
return k(Value.Lam(paramLists.head, bodyBlock))
240247
if sym.unary then
241248
val t1 = new Tree.Ident("arg")
242-
val p1 = Param(FldFlags.empty, VarSymbol(t1), N)
249+
val p1 = Param(FldFlags.empty, VarSymbol(t1), N, Modulefulness.none)
243250
val ps = PlainParamList(p1 :: Nil)
244-
val bod = st.App(t, st.Tup(List(st.Ref(p1.sym)(t1, 666)))
251+
val bod = st.App(t, st.Tup(List(st.Ref(p1.sym)(t1, 666, N).noIArgs))
245252
(Tree.Tup(Nil // FIXME should not be required (using dummy value)
246253
)))(
247254
Tree.App(Tree.Empty(), Tree.Empty()), // FIXME should not be required (using dummy value)
255+
N,
248256
FlowSymbol(sym.nme)
249-
)
257+
).noIArgs
250258
val (paramLists, bodyBlock) = setupFunctionDef(ps :: Nil, bod, S(sym.nme))
251259
tl.log(s"Ref builtin $sym")
252260
assert(paramLists.length === 1)
253261
return k(Value.Lam(paramLists.head, bodyBlock))
254262
case bs: BlockMemberSymbol =>
255263
bs.defn match
256264
case S(d) if d.isDeclare.isDefined =>
257-
return term(Sel(State.globalThisSymbol.ref(), ref.tree)(S(bs)))(k)
265+
return term(Sel(State.globalThisSymbol.ref().noIArgs, ref.tree)(S(bs)).noIArgs)(k)
258266
case S(td: TermDefinition) if td.k is syntax.Fun =>
259267
// * Local functions with no parameter lists are getters
260268
// * and are lowered to functions with an empty parameter list
@@ -298,7 +306,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
298306
End("error")
299307
case st.TyApp(f, ts) => term(f)(k) // * Type arguments are erased
300308
case st.App(f, arg) =>
301-
val isMlsFun = f.symbol.fold(f.isInstanceOf[st.Lam]):
309+
val isMlsFun = f.resolvedSymbol.fold(f.isInstanceOf[st.Lam]):
302310
case _: sem.BuiltinSymbol => true
303311
case sym: sem.BlockMemberSymbol =>
304312
sym.trmImplTree.fold(sym.clsTree.isDefined)(_.k is syntax.Fun)
@@ -312,17 +320,17 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
312320
subTerm_nonTail(arg): ar =>
313321
k(Call(fr, Arg(spread = true, ar) :: Nil)(isMlsFun, true).withLocOf(t))
314322
f match
315-
case t if t.symbol.isDefined && (t.symbol.get is ctx.builtins.js.try_catch) =>
323+
case t if t.resolvedSymbol.isDefined && (t.resolvedSymbol.get is ctx.builtins.js.try_catch) =>
316324
conclude(Value.Ref(State.runtimeSymbol).selN(Tree.Ident("try_catch")))
317-
case t if t.symbol.isDefined && (t.symbol.get is ctx.builtins.debug.printStack) =>
325+
case t if t.resolvedSymbol.isDefined && (t.resolvedSymbol.get is ctx.builtins.debug.printStack) =>
318326
if !config.effectHandlers.exists(_.debug) then
319327
raise(ErrorReport(
320328
msg"Debugging functions are not enabled" ->
321329
t.toLoc :: Nil,
322330
source = Diagnostic.Source.Compilation))
323331
return End("error")
324332
conclude(Value.Ref(State.runtimeSymbol).selSN("raisePrintStackEffect").withLocOf(f))
325-
case t if t.symbol.isDefined && (t.symbol.get is ctx.builtins.debug.getLocals) =>
333+
case t if t.resolvedSymbol.isDefined && (t.resolvedSymbol.get is ctx.builtins.debug.getLocals) =>
326334
if !config.effectHandlers.exists(_.debug) then
327335
raise(ErrorReport(
328336
msg"Debugging functions are not enabled" ->
@@ -532,7 +540,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
532540
Return(Call(Value.Ref(State.builtinOpsMap("super")), args)(true, true), implct = true)
533541
val clsDef = ClsLikeDefn(N, isym, sym, syntax.Cls, N, Nil, S(clsp),
534542
mtds, privateFlds, publicFlds, pctor, ctor)
535-
Define(clsDef, term_nonTail(New(sym.ref(), Nil, N))(k))
543+
Define(clsDef, term_nonTail(New(sym.ref().noIArgs, Nil, N))(k))
536544

537545
case Try(sub, finallyDo) =>
538546
val l = new TempSymbol(S(sub))
@@ -605,13 +613,6 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
605613
case sem.Fld(sem.FldFlags.benign(), idx, S(rhs)) => L(idx -> rhs)
606614
case arg @ sem.Fld(flags, value, asc) => TODO(s"Other argument forms: $arg")
607615
case spd: Spd => R(true -> spd.term)
608-
case ca: sem.CtxArg => ca.term match
609-
case S(t) =>
610-
R(false -> t)
611-
case N =>
612-
// * All contextual arguments should have been
613-
// * populated by implicit resolution before lowering.
614-
lastWords(s"Found unpopulated contextual argument: ${ca}.")
615616
// * The straightforward way to lower arguments creates too much recursion depth
616617
// * and makes Lowering stack overflow when lowering functions with lots of arguments.
617618
/*

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -287,7 +287,7 @@ final class LlirBuilder(using Elaborator.State)(tl: TraceLogger, uid: FreshInt):
287287
val tempSymbols = (0 until f.paramsSize).map(x => newNamed("arg"))
288288
val paramsList = PlainParamList(
289289
(0 until f.paramsSize).zip(tempSymbols).map((_n, sym) =>
290-
Param(FldFlags.empty, sym, N)).toList)
290+
Param(FldFlags.empty, sym, N, Modulefulness.none)).toList)
291291
val app = Call(v, tempSymbols.map(x => Arg(false, Value.Ref(x))).toList)(true, false)
292292
bLam(Value.Lam(paramsList, Return(app, false)), S(l.nme), N)(k)
293293
case None =>

0 commit comments

Comments
 (0)