@@ -63,20 +63,113 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
6363 def unit : Path =
6464 Select (Value .Ref (State .runtimeSymbol), Tree .Ident (" Unit" ))(S (summon[Ctx ].builtins.Unit ))
6565
66+
67+ type Rcd = List [RcdArg ]
68+
6669 def returnedTerm (t : st)(using Subst ): Block = term(t)(Ret )
6770
6871 // * Used to work around Scala's @tailrec annotation for those few calls that are not in tail position.
6972 final def term_nonTail (t : st, inStmtPos : Bool = false )(k : Result => Block )(using Subst ): Block =
7073 term(t : st, inStmtPos : Bool )(k)
7174
75+ def block (stats : Ls [Statement ], res : Rcd \/ Term )(k : Result => Block )(using Subst ): Block =
76+ stats match
77+ case (t : sem.Term ) :: stats =>
78+ subTerm(t, inStmtPos = true ): r =>
79+ block(stats, res)(r => k(r))
80+ case Nil =>
81+ res match
82+ case R (res) => term(res)(k)
83+ case L (flds) =>
84+ k(Value .Rcd (flds.reverse))
85+ case RcdField (lhs, rhs) :: stats =>
86+ res match
87+ case R (_) => wat(" RcdField in non-Rcd context" , res)
88+ case L (flds) =>
89+ subTerm(lhs): l =>
90+ subTerm_nonTail(rhs): r =>
91+ block(stats, L (RcdArg (S (l), r) :: flds))(k)
92+ case (decl @ LetDecl (sym, annotations)) :: (stats @ ((_ : DefineVar ) :: _)) =>
93+ reportAnnotations(decl, annotations)
94+ block(stats, res)(k)
95+ case (decl @ LetDecl (sym, annotations)) :: stats =>
96+ reportAnnotations(decl, annotations)
97+ block(DefineVar (sym, Term .Lit (Tree .UnitLit (false ))) :: stats, res)(k)
98+ case DefineVar (sym, rhs) :: stats =>
99+ subTerm(rhs): r =>
100+ Assign (sym, r, block(stats, res)(k))
101+ case (imp @ Import (sym, path)) :: stats =>
102+ raise(ErrorReport (
103+ msg " Imports must be at the top level " ->
104+ imp.toLoc :: Nil ,
105+ source = Diagnostic .Source .Compilation ))
106+ block(stats, res)(k)
107+ case (d : Declaration ) :: stats =>
108+ d match
109+ case td : TermDefinition =>
110+ reportAnnotations(td, td.extraAnnotations)
111+ td.body match
112+ case N => // abstract declarations have no lowering
113+ block(stats, res)(k)
114+ case S (bod) =>
115+ td.k match
116+ case knd : syntax.Val =>
117+ assert(td.params.isEmpty)
118+ subTerm_nonTail(bod)(r =>
119+ // Assign(td.sym, r,
120+ // term(st.Blk(stats, res))(k)))
121+ Define (ValDefn (td.owner, knd, td.sym, r),
122+ block(stats, res)(k)))
123+ case syntax.Fun =>
124+ val (paramLists, bodyBlock) = setupFunctionOrByNameDef(td.params, bod, S (td.sym.nme))
125+ Define (FunDefn (td.owner, td.sym, paramLists, bodyBlock),
126+ block(stats, res)(k))
127+ case syntax.Ins =>
128+ // Implicit instances are not parameterized for now.
129+ assert(td.params.isEmpty)
130+ subTerm(bod)(r =>
131+ Define (ValDefn (td.owner, syntax.ImmutVal , td.sym, r),
132+ block(stats, res)(k)))
133+ case cls : ClassLikeDef if cls.sym.defn.exists(_.isDeclare.isDefined) =>
134+ // * Declarations have no lowering
135+ block(stats, res)(k)
136+ case cls : ClassLikeDef =>
137+ reportAnnotations(cls, cls.extraAnnotations)
138+ val (mtds, publicFlds, privateFlds, ctor) = gatherMembers(cls.body)
139+ cls.ext match
140+ case N =>
141+ Define (ClsLikeDefn (cls.owner, cls.sym, cls.bsym, cls.kind, cls.paramsOpt, Nil , N ,
142+ mtds,
143+ privateFlds,
144+ publicFlds,
145+ End (),
146+ ctor
147+ ),
148+ block(stats, res)(k))
149+ case S (ext) =>
150+ assert(k isnt syntax.Mod ) // modules can't extend things and can't have super calls
151+ subTerm(ext.cls): clsp =>
152+ val pctor = // TODO dedup with New case
153+ args(ext.args): args =>
154+ Return (Call (Value .Ref (State .builtinOpsMap(" super" )), args)(true , true ), implct = true )
155+ Define (
156+ ClsLikeDefn (
157+ cls.owner, cls.sym, cls.bsym, cls.kind, cls.paramsOpt, Nil , S (clsp),
158+ mtds, privateFlds, publicFlds, pctor, ctor
159+ ),
160+ block(stats, res)(k)
161+ )
162+ case td : TypeDef => // * Type definitions are erased
163+ block(stats, res)(k)
164+
72165 @ tailrec
73166 final def term (t : st, inStmtPos : Bool = false )(k : Result => Block )(using Subst ): Block =
74167 tl.log(s " Lowering.term ${t.showDbg.truncate(100 , " [...]" )}${
75168 if inStmtPos then " (in stmt)" else " " }${
76169 t.symbol.fold(" " )(" – symbol " + _)}" )
77170 def warnStmt = if inStmtPos then
78- raise( WarningReport :
79- msg " Pure expression in statement position " -> t.toLoc :: Nil )
171+ raise :
172+ WarningReport ( msg " Pure expression in statement position " -> t.toLoc :: Nil , S (t) )
80173 t match
81174 case st.UnitVal () => k(unit)
82175 case st.Lit (lit) =>
@@ -234,8 +327,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
234327 subTerm(prefix): p =>
235328 conclude(Select (p, nme)(sel.sym))
236329 case _ => subTerm(f)(conclude)
237-
238- case st.Blk ((h @ Handle (lhs, rhs, as, cls, defs)) :: stmts, res) =>
330+ case h @ Handle (lhs, rhs, as, cls, defs, bod) =>
239331 if ! lowerHandlers then
240332 raise(ErrorReport (
241333 msg " Effect handlers are not enabled " ->
@@ -255,83 +347,9 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
255347 subTerm(rhs): par =>
256348 subTerms(as): asr =>
257349 HandleBlock (lhs, resSym, par, asr, cls, handlers,
258- term_nonTail(st. Blk (stmts, res) )(HandleBlockReturn (_)),
350+ term_nonTail(bod )(HandleBlockReturn (_)),
259351 k(Value .Ref (resSym)))
260-
261- case st.TyApp (lhs, _) => term(lhs)(k)
262- case st.Blk (Nil , res) => term(res)(k)
263- case st.Blk ((t : sem.Term ) :: stats, res) =>
264- subTerm(t, inStmtPos = true )(r => term_nonTail(st.Blk (stats, res))(k))
265- case st.Blk ((d : Declaration ) :: stats, res) =>
266- d match
267- case td : TermDefinition =>
268- reportAnnotations(td, td.extraAnnotations)
269- td.body match
270- case N => // abstract declarations have no lowering
271- term(st.Blk (stats, res))(k)
272- case S (bod) =>
273- td.k match
274- case knd : syntax.Val =>
275- assert(td.params.isEmpty)
276- subTerm_nonTail(bod)(r =>
277- // Assign(td.sym, r,
278- // term(st.Blk(stats, res))(k)))
279- Define (ValDefn (td.owner, knd, td.sym, r),
280- term_nonTail(st.Blk (stats, res))(k)))
281- case syntax.Fun =>
282- val (paramLists, bodyBlock) = setupFunctionOrByNameDef(td.params, bod, S (td.sym.nme))
283- Define (FunDefn (td.owner, td.sym, paramLists, bodyBlock),
284- term_nonTail(st.Blk (stats, res))(k))
285- case syntax.Ins =>
286- // Implicit instances are not parameterized for now.
287- assert(td.params.isEmpty)
288- subTerm(bod)(r =>
289- Define (ValDefn (td.owner, syntax.ImmutVal , td.sym, r),
290- term_nonTail(st.Blk (stats, res))(k)))
291- case cls : ClassLikeDef if cls.sym.defn.exists(_.isDeclare.isDefined) =>
292- // * Declarations have no lowering
293- term(st.Blk (stats, res))(k)
294- case cls : ClassLikeDef =>
295- reportAnnotations(cls, cls.extraAnnotations)
296- val (mtds, publicFlds, privateFlds, ctor) = gatherMembers(cls.body)
297- cls.ext match
298- case N =>
299- Define (
300- ClsLikeDefn (cls.owner, cls.sym, cls.bsym, cls.kind, cls.paramsOpt, Nil , N ,
301- mtds, privateFlds, publicFlds, End (), ctor),
302- term_nonTail(st.Blk (stats, res))(k)
303- )
304- case S (ext) =>
305- assert(k isnt syntax.Mod ) // modules can't extend things and can't have super calls
306- subTerm(ext.cls): clsp =>
307- val pctor = // TODO dedup with `New` case
308- args(ext.args): args =>
309- Return (Call (Value .Ref (State .builtinOpsMap(" super" )), args)(true , true ), implct = true )
310- Define (
311- ClsLikeDefn (cls.owner, cls.sym, cls.bsym, cls.kind, cls.paramsOpt, Nil , S (clsp),
312- mtds, privateFlds, publicFlds, pctor, ctor),
313- term_nonTail(st.Blk (stats, res))(k)
314- )
315- case _ =>
316- // TODO handle
317- term(st.Blk (stats, res))(k)
318- case st.Blk ((decl @ LetDecl (sym, annotations)) :: (stats @ ((_ : DefineVar ) :: _)), res) =>
319- reportAnnotations(decl, annotations)
320- term(st.Blk (stats, res))(k)
321- case st.Blk ((decl @ LetDecl (sym, annotations)) :: stats, res) =>
322- reportAnnotations(decl, annotations)
323- term(st.Blk (DefineVar (sym, Term .Lit (Tree .UnitLit (false ))) :: stats, res))(k)
324- case st.Blk (DefineVar (sym, rhs) :: stats, res) =>
325- val oldSubst = subst
326- rhs match
327- // * This is currently wrong because if `r` is mutable, we can't substitute `sym` with `r`
328- // * TODO: Distinguish mutable from immutable local variables
329- // case Ref(r) =>
330- // given Subst = oldSubst + (sym -> Value.Ref(r))
331- // term(st.Blk(stats, res))(k)
332- case _ =>
333- subTerm(rhs): r =>
334- Assign (sym, r, term_nonTail(st.Blk (stats, res))(k))
352+ case st.Blk (sts, res) => block(sts, R (res))(k)
335353 case Assgn (lhs, rhs) =>
336354 lhs match
337355 case Ref (sym) =>
@@ -493,13 +511,13 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
493511 subTerm(prefix): p =>
494512 subTerm_nonTail(fld): f =>
495513 k(DynSelect (p, f, ai))
496-
514+
497515
498516 case New (cls, as, N ) =>
499517 subTerm(cls): sr =>
500518 subTerms(as): asr =>
501519 k(Instantiate (sr, asr))
502-
520+
503521 case New (cls, as, S ((isym, rft))) =>
504522 subTerm(cls): clsp =>
505523 val sym = new BlockMemberSymbol (isym.name, Nil )
@@ -510,15 +528,15 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
510528 val clsDef = ClsLikeDefn (N , isym, sym, syntax.Cls , N , Nil , S (clsp),
511529 mtds, privateFlds, publicFlds, pctor, ctor)
512530 Define (clsDef, term_nonTail(New (sym.ref(), Nil , N ))(k))
513-
531+
514532 case Try (sub, finallyDo) =>
515533 val l = new TempSymbol (S (sub))
516534 TryBlock (
517535 subTerm_nonTail(sub)(p => Assign (l, p, End ())),
518536 subTerm_nonTail(finallyDo)(_ => End ()),
519537 k(Value .Ref (l))
520538 )
521-
539+
522540 // * BbML-specific cases: t.Cls#field and mutable operations
523541 case sp @ SelProj (prefix, _, proj) =>
524542 setupSelection(prefix, proj, sp.sym)(k)
@@ -536,6 +554,9 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
536554 subTerm_nonTail(rhs): value =>
537555 AssignField (ref, Tree .Ident (" value" ), value, k(value))(N )
538556
557+ case Rcd (stats) =>
558+ block(stats, L (Nil ))(k)
559+
539560 case Neg (_) =>
540561 raise(ErrorReport (
541562 msg " Unexpected type annotations ${t.show}" ->
0 commit comments