Skip to content

Commit 481546f

Browse files
ChingLongTinyeungsinchunLPTK
authored
Priliminary support for staged keyword (#348)
Co-authored-by: ChingLongTin <[email protected]> Co-authored-by: TYeung <[email protected]> Co-authored-by: Lionel Parreaux <[email protected]>
1 parent ea2d7bc commit 481546f

File tree

15 files changed

+82
-5
lines changed

15 files changed

+82
-5
lines changed

hkmc2/shared/src/main/scala/hkmc2/Config.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ case class Config(
2020
sanityChecks: Opt[SanityChecks],
2121
effectHandlers: Opt[EffectHandlers],
2222
liftDefns: Opt[LiftDefns],
23+
stageCode: Bool,
2324
target: CompilationTarget,
2425
):
2526

@@ -35,6 +36,7 @@ object Config:
3536
// sanityChecks = S(SanityChecks(light = true)),
3637
effectHandlers = N,
3738
liftDefns = N,
39+
stageCode = false,
3840
target = CompilationTarget.JS
3941
)
4042

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
package hkmc2
2+
package codegen
3+
4+
import utils.*
5+
import hkmc2.Message.MessageContext
6+
7+
class Instrumentation(using Raise) extends BlockTransformer(new SymbolSubst()):
8+
def transform(prgm: Program) = Program(prgm.imports, applyBlock(prgm.main))
9+
10+
override def applyDefn(d: Defn)(k: Defn => Block): Block = d match
11+
case defn: ClsLikeDefn =>
12+
if defn.sym.defn.exists(_.hasStagedModifier.isDefined) && defn.companion.isDefined
13+
then raise(WarningReport(msg"`staged` keyword doesn't do anything currently." -> defn.sym.toLoc :: Nil))
14+
super.applyDefn(defn)(k)
15+
case b => super.applyDefn(b)(k)

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ import utils.*
1111

1212
import hkmc2.Message.MessageContext
1313

14+
import codegen.Instrumentation
15+
1416
import semantics.*, ucs.FlatPattern
1517
import hkmc2.{semantics => sem}
1618
import semantics.{Term => st}
@@ -1068,7 +1070,11 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
10681070

10691071
val bufferable = BufferableTransform().transform(lifted)
10701072

1071-
val res = MergeMatchArmTransformer.applyBlock(bufferable)
1073+
val merged = MergeMatchArmTransformer.applyBlock(bufferable)
1074+
1075+
val res =
1076+
if config.stageCode then Instrumentation(using summon).applyBlock(merged)
1077+
else merged
10721078

10731079
Program(
10741080
imps.map(imp => imp.sym -> imp.str),
@@ -1095,6 +1101,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
10951101
def reportAnnotations(target: Statement, annotations: Ls[Annot]): Unit =
10961102
annotations.foreach:
10971103
case Annot.Untyped => ()
1104+
case Annot.Modifier(syntax.Keyword("staged")) => ()
10981105
case annot => raise:
10991106
WarningReport(msg"This annotation has no effect." -> annot.toLoc :: Nil)
11001107

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ object Printer:
8282
val docPubFlds = if publicFields.isEmpty then doc"" else doc" # ${pubFields}"
8383
val docBody = if publicFields.isEmpty && privateFields.isEmpty then doc"" else doc" { #{ ${docPrivFlds}${docPubFlds} #} # }"
8484
val docCtorParams = if clsParams.isEmpty then doc"" else doc"(${ctorParams.mkDocument(", ")})"
85-
doc"class ${own.fold("")(_.toString+"::")}${sym.nme}${docCtorParams}${docBody}"
85+
val docStaged = if sym.defn.forall(_.hasStagedModifier.isEmpty) then doc"" else doc"staged "
86+
doc"${docStaged}class ${own.fold("")(_.toString+"::")}${sym.nme}${docCtorParams}${docBody}"
8687

8788
def mkDocument(arg: Arg)(using Raise, Scope): Document =
8889
val doc = mkDocument(arg.value)

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,6 +233,8 @@ object Elaborator:
233233
val definitionMetadataSymbol = TempSymbol(N, "definitionMetadata")
234234
val prettyPrintSymbol = TempSymbol(N, "prettyPrint")
235235
val termSymbol = TempSymbol(N, "Term")
236+
val blockSymbol = TempSymbol(N, "Block")
237+
val shapeSymbol = TempSymbol(N, "Shape")
236238
val wasmSymbol = TempSymbol(N, "wasm")
237239
val effectSigSymbol = ClassSymbol(DummyTypeDef(syntax.Cls), Ident("EffectSig"))
238240
val nonLocalRetHandlerTrm =
@@ -319,7 +321,7 @@ extends Importer:
319321
case _ => N
320322

321323
def annot(tree: Tree): Ctxl[Opt[Annot]] = tree match
322-
case Keywrd(kw @ (Keyword.`abstract` | Keyword.`declare` | Keyword.`data`)) => S(Annot.Modifier(kw))
324+
case Keywrd(kw @ (Keyword.`abstract` | Keyword.`declare` | Keyword.`data` | Keyword.`staged`)) => S(Annot.Modifier(kw))
323325
case _ => term(tree) match
324326
case Term.Error => N
325327
case trm =>

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -678,6 +678,8 @@ sealed abstract class Definition extends Declaration, Statement:
678678
val annotations: Ls[Annot]
679679
def hasDeclareModifier: Opt[Annot.Modifier] = annotations.collectFirst:
680680
case mod @ Annot.Modifier(Keyword.`declare`) => mod
681+
def hasStagedModifier: Opt[Annot.Modifier] = annotations.collectFirst:
682+
case mod @ Annot.Modifier(Keyword.`staged`) => mod
681683

682684
sealed trait CompanionValue extends Definition
683685

hkmc2/shared/src/main/scala/hkmc2/syntax/Keyword.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ object Keyword:
113113
val `abstract` = Keyword("abstract", N, N)
114114
val `constructor` = Keyword("constructor", N, N)
115115
val `virtual` = Keyword("virtual", N, N)
116+
val `staged` = Keyword("staged", N, N)
116117
val `true` = Keyword("true", N, N)
117118
val `false` = Keyword("false", N, N)
118119
val `public` = Keyword("public", N, N)
@@ -168,5 +169,5 @@ object Keyword:
168169
type LetLike = `let`.type | `set`.type
169170

170171
type Modifier = `in`.type | `out`.type | `mut`.type | `abstract`.type | `declare`.type | `data`.type | `virtual`.type | `override`.type |
171-
`public`.type | `private`.type
172+
`public`.type | `private`.type | `staged`.type
172173

hkmc2/shared/src/main/scala/hkmc2/syntax/Lexer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,8 @@ object Lexer:
576576
"undefined",
577577
"abstract",
578578
"constructor",
579-
"virtual"
579+
"virtual",
580+
"staged"
580581
)
581582

582583
private val SEP = ""

hkmc2/shared/src/main/scala/hkmc2/syntax/ParseRule.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ class ParseRules(using State):
377377
modified(`public`),
378378
modified(`private`),
379379
modified(`out`),
380+
modified(`staged`),
380381
singleKw(`true`)(BoolLit(true)),
381382
singleKw(`false`)(BoolLit(false)),
382383
singleKw(`undefined`)(UnitLit(false)),

hkmc2/shared/src/main/scala/hkmc2/syntax/Tree.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,8 @@ enum Tree extends AutoLocated:
243243
Annotated(kw, s.desugared)
244244
case Modified(kw @ Keywrd(Keyword.`abstract`), s) =>
245245
Annotated(kw, s.desugared)
246+
case Modified(kw @ Keywrd(Keyword.`staged`), s) =>
247+
Annotated(kw, s.desugared)
246248
case Modified(kw @ Keywrd(Keyword.`mut`), TermDef(ImmutVal, anme, rhs)) =>
247249
TermDef(MutVal, anme, rhs).withLocOf(this).desugared
248250
case _ => m

0 commit comments

Comments
 (0)