Skip to content

Commit 5193c3d

Browse files
phischub-studios
andauthored
Delete core expressions (#1117)
Co-authored-by: Jonathan Brachthäuser <[email protected]>
1 parent 92ddab6 commit 5193c3d

29 files changed

+471
-440
lines changed

effekt/jvm/src/test/scala/effekt/core/OptimizerTests.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ class OptimizerTests extends CoreTests {
108108
val input =
109109
""" def main = { () =>
110110
| let x = (add : (Int, Int) => Int @ {})(1, 2)
111-
| let y = !(println: (String) => Unit @ {io})("hello")
111+
| let ! y = (println: (String) => Unit @ {io})("hello")
112112
| let z = 7
113113
| return z:Int
114114
| }
115115
|""".stripMargin
116116

117117
val expected =
118118
""" def main = { () =>
119-
| let y = !(println: (String) => Unit @ {io})("hello")
119+
| let ! y = (println: (String) => Unit @ {io})("hello")
120120
| let z = 7
121121
| return z:Int
122122
| }

effekt/jvm/src/test/scala/effekt/core/PatternMatchingTests.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class PatternMatchingTests extends CoreTests {
1919
def block(name: String, args: ValueType*): core.BlockVar =
2020
core.BlockVar(Id(name), core.BlockType.Function(Nil, Nil, args.toList, Nil, TUnit), Set.empty)
2121

22-
def jump(label: BlockVar, args: Pure*) =
22+
def jump(label: BlockVar, args: Expr*) =
2323
App(label, Nil, args.toList, Nil)
2424

2525
def variable(name: String, tpe: ValueType): core.ValueVar =

effekt/jvm/src/test/scala/effekt/core/PolymorphismBoxingTests.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package core
33

44
import effekt.{core, source, symbols}
55
import effekt.context.Context
6-
import effekt.core.{Block, DirectApp, PolymorphismBoxing, Pure, Stmt}
6+
import effekt.core.{Block, PolymorphismBoxing, Expr, Stmt}
77
import effekt.source.{IdDef, Include, Span}
88
import effekt.util.messages
99
import effekt.util.messages.DebugMessaging
@@ -94,14 +94,14 @@ class PolymorphismBoxingTests extends AbstractPolymorphismBoxingTests {
9494
assertTransformsTo(from, to)
9595
}
9696

97-
test("DirectApp with [Int] gets wrapped correctly"){
97+
test("ImpureApp with [Int] gets wrapped correctly"){
9898
val from =
9999
"""module main
100100
|
101101
|def id = { ['A](a: 'A) => return a: 'A }
102102
|def idInt = { (x: Int) =>
103103
| {
104-
| let res = !(id: ['A]('A) => 'A @ {})[Int](x: Int)
104+
| let ! res = (id: ['A]('A) => 'A @ {})[Int](x: Int)
105105
| return res: Int
106106
| }
107107
|}
@@ -111,7 +111,7 @@ class PolymorphismBoxingTests extends AbstractPolymorphismBoxingTests {
111111
|
112112
|def id = { ['A](a: 'A) => return a: 'A }
113113
|def idInt = { (x: Int) =>
114-
| let boxed = !(id: ['A]('A) => 'A @ {})[BoxedInt]((coerceIntPos: (Int) => BoxedInt @ {})(x: Int))
114+
| let ! boxed = (id: ['A]('A) => 'A @ {})[BoxedInt]((coerceIntPos: (Int) => BoxedInt @ {})(x: Int))
115115
| let unboxed = (coercePosInt: (BoxedInt) => Int @ {})(boxed:BoxedInt)
116116
| return unboxed: Int
117117
|}

effekt/jvm/src/test/scala/effekt/core/TestRenamer.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,13 @@ class TestRenamer(names: Names = Names(Map.empty), prefix: String = "") extends
5757
val resolvedBinding = rewrite(binding)
5858
withBinding(id) { core.Let(rewrite(id), rewrite(tpe), resolvedBinding, rewrite(body)) }
5959

60+
case core.ImpureApp(id, callee, targs, vargs, bargs, body) =>
61+
val resolvedCallee = rewrite(callee)
62+
val resolvedTargs = targs map rewrite
63+
val resolvedVargs = vargs map rewrite
64+
val resolvedBargs = bargs map rewrite
65+
withBinding(id) { core.ImpureApp(rewrite(id), resolvedCallee, resolvedTargs, resolvedVargs, resolvedBargs, rewrite(body)) }
66+
6067
case core.Val(id, tpe, binding, body) =>
6168
val resolvedBinding = rewrite(binding)
6269
withBinding(id) { core.Val(rewrite(id), rewrite(tpe), resolvedBinding, rewrite(body)) }

effekt/jvm/src/test/scala/effekt/core/VMTests.scala

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -642,14 +642,14 @@ class VMTests extends munit.FunSuite {
642642
)),
643643

644644
examplesDir / "casestudies" / "buildsystem.effekt.md" -> Some(Summary(
645-
staticDispatches = 43,
646-
dynamicDispatches = 57,
645+
staticDispatches = 32,
646+
dynamicDispatches = 51,
647647
patternMatches = 31,
648648
branches = 40,
649649
pushedFrames = 24,
650650
poppedFrames = 21,
651651
allocations = 15,
652-
closures = 36,
652+
closures = 34,
653653
variableReads = 7,
654654
variableWrites = 3,
655655
resets = 9,
@@ -674,19 +674,19 @@ class VMTests extends munit.FunSuite {
674674
)),
675675

676676
examplesDir / "casestudies" / "lexer.effekt.md" -> Some(Summary(
677-
staticDispatches = 302,
678-
dynamicDispatches = 18,
677+
staticDispatches = 301,
678+
dynamicDispatches = 15,
679679
patternMatches = 205,
680680
branches = 405,
681-
pushedFrames = 187,
682-
poppedFrames = 187,
681+
pushedFrames = 184,
682+
poppedFrames = 184,
683683
allocations = 109,
684-
closures = 27,
684+
closures = 23,
685685
variableReads = 164,
686686
variableWrites = 51,
687-
resets = 31,
688-
shifts = 11,
689-
resumes = 11
687+
resets = 30,
688+
shifts = 8,
689+
resumes = 8
690690
)),
691691

692692
examplesDir / "casestudies" / "parser.effekt.md" -> Some(Summary(

effekt/shared/src/main/scala/effekt/core/Parser.scala

Lines changed: 21 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -291,20 +291,25 @@ class CoreParsers(names: Names) extends EffektLexers {
291291
// ----------
292292
lazy val stmt: P[Stmt] =
293293
( `{` ~/> stmts <~ `}`
294-
| `return` ~> pure ^^ Stmt.Return.apply
294+
| `return` ~> expr ^^ Stmt.Return.apply
295295
| block ~ (`.` ~> id ~ (`:` ~> blockType)).? ~ maybeTypeArgs ~ valueArgs ~ blockArgs ^^ {
296296
case (recv ~ Some(method ~ tpe) ~ targs ~ vargs ~ bargs) => Invoke(recv, method, tpe, targs, vargs, bargs)
297297
case (recv ~ None ~ targs ~ vargs ~ bargs) => App(recv, targs, vargs, bargs)
298298
}
299-
| (`if` ~> `(` ~/> pure <~ `)`) ~ stmt ~ (`else` ~> stmt) ^^ Stmt.If.apply
299+
| (`if` ~> `(` ~/> expr <~ `)`) ~ stmt ~ (`else` ~> stmt) ^^ Stmt.If.apply
300300
| `region` ~> blockLit ^^ Stmt.Region.apply
301301
| `<>` ^^^ Hole(effekt.source.Span.missing)
302-
| (pure <~ `match`) ~/ (`{` ~> many(clause) <~ `}`) ~ (`else` ~> stmt).? ^^ Stmt.Match.apply
302+
| (expr <~ `match`) ~/ (`{` ~> many(clause) <~ `}`) ~ (`else` ~> stmt).? ^^ Stmt.Match.apply
303303
)
304304

305305
lazy val stmts: P[Stmt] =
306-
( `let` ~/> id ~ maybeTypeAnnotation ~ (`=` ~/> expr) ~ stmts ^^ {
307-
case (name ~ tpe ~ binding ~ body) => Let(name, tpe.getOrElse(binding.tpe), binding, body)
306+
( (`let` ~ `!` ~/> id) ~ (`=` ~/> maybeParens(blockVar)) ~ maybeTypeArgs ~ valueArgs ~ blockArgs ~ stmts ^^ {
307+
case (name ~ callee ~ targs ~ vargs ~ bargs ~ body) =>
308+
ImpureApp(name, callee, targs, vargs, bargs, body)
309+
}
310+
| `let` ~/> id ~ maybeTypeAnnotation ~ (`=` ~/> expr) ~ stmts ^^ {
311+
case (name ~ tpe ~ binding ~ body) =>
312+
Let(name, tpe.getOrElse(binding.tpe), binding, body)
308313
}
309314
| `def` ~> id ~ (`=` ~/> block) ~ stmts ^^ Stmt.Def.apply
310315
| `def` ~> id ~ parameters ~ (`=` ~/> stmt) ~ stmts ^^ {
@@ -314,8 +319,8 @@ class CoreParsers(names: Names) extends EffektLexers {
314319
| `val` ~> id ~ maybeTypeAnnotation ~ (`=` ~> stmt) ~ (`;` ~> stmts) ^^ {
315320
case id ~ tpe ~ binding ~ body => Val(id, tpe.getOrElse(binding.tpe), binding, body)
316321
}
317-
| `var` ~> id ~ (`in` ~> id) ~ (`=` ~> pure) ~ (`;` ~> stmts) ^^ { case id ~ region ~ init ~ body => Alloc(id, init, region, body) }
318-
| `var` ~> id ~ (`@` ~> id) ~ (`=` ~> pure) ~ (`;` ~> stmts) ^^ { case id ~ cap ~ init ~ body => Var(id, init, cap, body) }
322+
| `var` ~> id ~ (`in` ~> id) ~ (`=` ~> expr) ~ (`;` ~> stmts) ^^ { case id ~ region ~ init ~ body => Alloc(id, init, region, body) }
323+
| `var` ~> id ~ (`@` ~> id) ~ (`=` ~> expr) ~ (`;` ~> stmts) ^^ { case id ~ cap ~ init ~ body => Var(id, init, cap, body) }
319324
| stmt
320325
)
321326

@@ -335,42 +340,34 @@ class CoreParsers(names: Names) extends EffektLexers {
335340

336341
// Pure Expressions
337342
// ----------------
338-
lazy val pure: P[Pure] =
343+
lazy val expr: P[Expr] =
339344
( literal
340-
| id ~ (`:` ~> valueType) ^^ Pure.ValueVar.apply
341-
| `box` ~> captures ~ block ^^ { case capt ~ block => Pure.Box(block, capt) }
342-
| `make` ~> dataType ~ id ~ maybeTypeArgs ~ valueArgs ^^ Pure.Make.apply
343-
| maybeParens(blockVar) ~ maybeTypeArgs ~ valueArgs ^^ Pure.PureApp.apply
345+
| id ~ (`:` ~> valueType) ^^ Expr.ValueVar.apply
346+
| `box` ~> captures ~ block ^^ { case capt ~ block => Expr.Box(block, capt) }
347+
| `make` ~> dataType ~ id ~ maybeTypeArgs ~ valueArgs ^^ Expr.Make.apply
348+
| maybeParens(blockVar) ~ maybeTypeArgs ~ valueArgs ^^ Expr.PureApp.apply
344349
| failure("Expected a pure expression.")
345350
)
346351

347-
lazy val literal: P[Pure] = int | bool | string | unit | double
352+
lazy val literal: P[Expr] = int | bool | string | unit | double
348353

349354

350355
// Calls
351356
// -----
352-
lazy val valueArgs: P[List[Pure]] =
353-
`(` ~> manySep(pure, `,`) <~ `)`
357+
lazy val valueArgs: P[List[Expr]] =
358+
`(` ~> manySep(expr, `,`) <~ `)`
354359

355360
lazy val blockArgs: P[List[Block]] =
356361
many(blockLit | `{` ~> block <~ `}`)
357362

358-
359-
// Expressions
360-
// -----------
361-
lazy val expr: P[Expr] =
362-
( pure
363-
| (`!` ~/> maybeParens(blockVar)) ~ maybeTypeArgs ~ valueArgs ~ blockArgs ^^ DirectApp.apply
364-
)
365-
366363
def maybeParens[T](p: P[T]): P[T] = (p | `(` ~> p <~ `)`)
367364

368365

369366
// Blocks
370367
// ------
371368
lazy val block: P[Block] =
372369
( blockVar
373-
| `unbox` ~> pure ^^ Block.Unbox.apply
370+
| `unbox` ~> expr ^^ Block.Unbox.apply
374371
| `new` ~> implementation ^^ Block.New.apply
375372
| blockLit
376373
// TODO check left associative nesting (also for select)

effekt/shared/src/main/scala/effekt/core/PatternMatchingCompiler.scala

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,10 +60,11 @@ object PatternMatchingCompiler {
6060
// all of the patterns need to match for this condition to be met
6161
case Patterns(patterns: Map[ValueVar, Pattern])
6262
// a boolean predicate that needs to be branched on at runtime
63-
case Predicate(pred: Pure)
63+
case Predicate(pred: Expr)
6464
// a predicate trivially met by running and binding the statement
6565
case Val(x: Id, tpe: core.ValueType, binding: Stmt)
6666
case Let(x: Id, tpe: core.ValueType, binding: Expr)
67+
case ImpureApp(x: Id, callee: Block.BlockVar, targs: List[ValueType], vargs: List[Expr], bargs: List[Block])
6768
}
6869

6970
enum Pattern {
@@ -76,7 +77,7 @@ object PatternMatchingCompiler {
7677
case Ignore()
7778
case Any(id: Id)
7879
case Or(patterns: List[Pattern])
79-
case Literal(l: core.Literal, equals: (core.Pure, core.Pure) => core.Pure)
80+
case Literal(l: core.Literal, equals: (core.Expr, core.Expr) => core.Expr)
8081
}
8182

8283
/**
@@ -102,6 +103,8 @@ object PatternMatchingCompiler {
102103
// - We need to perform a computation
103104
case Clause(Condition.Let(x, tpe, binding) :: rest, target, targs, args) =>
104105
return core.Let(x, tpe, binding, compile(Clause(rest, target, targs, args) :: remainingClauses))
106+
case Clause(Condition.ImpureApp(x, callee, targs_, vargs_, bargs_) :: rest, target, targs, args) =>
107+
return core.ImpureApp(x, callee, targs_, vargs_, bargs_, compile(Clause(rest, target, targs, args) :: remainingClauses))
105108
// - We need to check a predicate
106109
case Clause(Condition.Predicate(pred) :: rest, target, targs, args) =>
107110
return core.If(pred,
@@ -125,7 +128,7 @@ object PatternMatchingCompiler {
125128
}
126129

127130
// (3a) Match on a literal
128-
def splitOnLiteral(lit: Literal, equals: (Pure, Pure) => Pure): core.Stmt = {
131+
def splitOnLiteral(lit: Literal, equals: (Expr, Expr) => Expr): core.Stmt = {
129132
// the different literal values that we match on
130133
val variants: List[core.Literal] = normalized.collect {
131134
case Clause(Split(Pattern.Literal(lit, _), _, _), _, _, _) => lit
@@ -322,6 +325,14 @@ object PatternMatchingCompiler {
322325
val (resCond, resSubst) = normalize(Map.empty, rest, substitution)
323326
(prefix(patterns, Condition.Let(x, tpe, substitutedBinding) :: resCond), resSubst)
324327

328+
case Condition.ImpureApp(x, callee, targs, vargs, bargs) :: rest =>
329+
val (resCond, resSubst) = normalize(Map.empty, rest, substitution)
330+
val calleeT = core.substitutions.substitute(callee)(using subst)
331+
val targsT = targs.map(core.substitutions.substitute(_)(using subst))
332+
val vargsT = vargs.map(core.substitutions.substitute(_)(using subst))
333+
val bargsT = bargs.map(core.substitutions.substitute(_)(using subst))
334+
(prefix(patterns, Condition.ImpureApp(x, calleeT.asInstanceOf[Block.BlockVar], targsT, vargsT, bargsT) :: resCond), resSubst)
335+
325336
case Condition.Predicate(p) :: rest =>
326337
val substitutedPredicate = core.substitutions.substitute(p)(using subst)
327338
val (resCond, resSubst) = normalize(Map.empty, rest, substitution)
@@ -332,7 +343,6 @@ object PatternMatchingCompiler {
332343
}
333344
}
334345

335-
336346
// For development and debugging
337347
// -----------------------------
338348

@@ -346,6 +356,7 @@ object PatternMatchingCompiler {
346356
case Condition.Predicate(pred) => util.show(pred) + "?"
347357
case Condition.Val(x, tpe, binding) => s"val ${util.show(x)} = ${util.show(binding)}"
348358
case Condition.Let(x, tpe, binding) => s"let ${util.show(x)} = ${util.show(binding)}"
359+
case Condition.ImpureApp(x, callee, targs, vargs, bargs) => s"let ${util.show(x)} = ${util.show(callee)}(${vargs.map(util.show).mkString(", ")})"
349360
}
350361

351362
def show(p: Pattern): String = p match {

0 commit comments

Comments
 (0)