Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions effekt/jvm/src/test/scala/effekt/core/OptimizerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ class OptimizerTests extends CoreTests {
test("drop pure let expressions"){
val input =
""" def main = { () =>
| let x = (add : (Int, Int) => Int @ {})(1, 2)
| let ! y = (println: (String) => Unit @ {io})("hello")
| let ! x = (add : (Int, Int) => Int @ {})(1, 2)
| let !! y = (println: (String) => Unit @ {io})("hello")
| let z = 7
| return z:Int
| }
Expand Down
4 changes: 2 additions & 2 deletions effekt/jvm/src/test/scala/effekt/core/RenamerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class RenamerTests extends CoreTests {
"""module main
|
|def foo = { () =>
| return (bar: (Int) => Int @ {})(baz:Int)
| (bar: (Int) => Int @ {})(baz:Int)
|}
|""".stripMargin
assertRenamingPreservesAlpha(code)
Expand All @@ -102,7 +102,7 @@ class RenamerTests extends CoreTests {
"""module main
|
|def foo = { () =>
| var x @ global = (foo:(Int)=>Int@{})(4) ;
| var x @ global = 4 ;
| return x:Int
|}
|""".stripMargin
Expand Down
8 changes: 4 additions & 4 deletions effekt/jvm/src/test/scala/effekt/core/TestRenamerTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,14 @@ class TestRenamerTests extends CoreTests {
"""module main
|
|def foo = { () =>
| return (bar: (Int) => Int @ {})(baz:Int)
| (bar: (Int) => Int @ {})(baz:Int)
|}
|""".stripMargin
val expected =
"""module main
|
|def foo_renamed_0() = {
| return (bar: (Int) => Int @ {})(baz: Int)
| (bar: (Int) => Int @ {})(baz: Int)
|}
|""".stripMargin

Expand Down Expand Up @@ -66,15 +66,15 @@ class TestRenamerTests extends CoreTests {
"""module main
|
|def foo = { () =>
| var x @ global = (foo:(Int)=>Int@{})(4) ;
| var x @ global = 4;
| return x:Int
|}
|""".stripMargin
val expected =
"""module main
|
|def foo_renamed_0() = {
| var x_renamed_1 @ global = (foo_renamed_0: (Int) => Int @ {})(4);
| var x_renamed_1 @ global = 4;
| return x_renamed_1: Int
|}
|""".stripMargin
Expand Down
14 changes: 7 additions & 7 deletions effekt/jvm/src/test/scala/effekt/core/TypeInferenceTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ class TypeInferenceTests extends CoreTests {

val ex3 = Stmt.Val(x,
Stmt.Return(Expr.Literal(42, TInt)),
Stmt.Return(Expr.PureApp(add, Nil, Expr.ValueVar(x, TInt) :: Expr.ValueVar(x, TInt) :: Nil)))
Stmt.ExternApp(y, Pure, add, Nil, Expr.ValueVar(x, TInt) :: Expr.ValueVar(x, TInt) :: Nil, Nil, Stmt.Return(Expr.ValueVar(y, TInt))))

val result3 = typecheck(ex3)
assertEquals(result3.tpe, TInt)
Expand All @@ -134,16 +134,16 @@ class TypeInferenceTests extends CoreTests {
// [A](Option[A], A): A
val orElse: Block.BlockVar = Block.BlockVar(f, BlockType.Function(A :: Nil, Nil, List(OptionT(ValueType.Var(A)), ValueType.Var(A)), Nil, ValueType.Var(A)), Set.empty)

shouldTypeCheckAs(TInt, Expr.PureApp(orElse, TInt :: Nil, Expr.ValueVar(x, OptionT(TInt)) :: Expr.ValueVar(y, TInt) :: Nil))
shouldTypeCheckAs(TInt, Stmt.App(orElse, TInt :: Nil, Expr.ValueVar(x, OptionT(TInt)) :: Expr.ValueVar(y, TInt) :: Nil, Nil))

// swapped arguments
intercept[TypeError] {
val res = typecheck(Expr.PureApp(orElse, TInt :: Nil, Expr.ValueVar(y, TInt) :: Expr.ValueVar(x, OptionT(TInt)) :: Nil))
val res = typecheck(Stmt.App(orElse, TInt :: Nil, Expr.ValueVar(y, TInt) :: Expr.ValueVar(x, OptionT(TInt)) :: Nil, Nil))
res.check()
}
// too few arguments
intercept[TypeError] {
val res = typecheck(Expr.PureApp(orElse, TInt :: Nil, Expr.ValueVar(x, OptionT(TInt)) :: Nil))
val res = typecheck(Stmt.App(orElse, TInt :: Nil, Expr.ValueVar(x, OptionT(TInt)) :: Nil, Nil))
res.check()
}

Expand All @@ -166,7 +166,7 @@ class TypeInferenceTests extends CoreTests {
inline def assertSameType(got: ValueType, expected: ValueType)(using DeclarationContext): Unit =
assertEquals(Type.equals(got, expected), true)

inline def shouldTypeCheckAs(expected: ValueType, expr: Expr)(using DeclarationContext): Unit =
expr.typing.check()
assertSameType(expr.tpe, expected)
inline def shouldTypeCheckAs(expected: ValueType, stmt: Stmt)(using DeclarationContext): Unit =
stmt.typing.check()
assertSameType(stmt.tpe, expected)
}
46 changes: 23 additions & 23 deletions effekt/jvm/src/test/scala/effekt/core/VMTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -674,14 +674,14 @@ class VMTests extends munit.FunSuite {
)),

examplesDir / "casestudies" / "lexer.effekt.md" -> Some(Summary(
staticDispatches = 314,
staticDispatches = 222,
dynamicDispatches = 15,
patternMatches = 232,
branches = 405,
pushedFrames = 199,
poppedFrames = 199,
pushedFrames = 156,
poppedFrames = 156,
allocations = 106,
closures = 23,
closures = 6,
variableReads = 164,
variableWrites = 51,
resets = 29,
Expand All @@ -690,14 +690,14 @@ class VMTests extends munit.FunSuite {
)),

examplesDir / "casestudies" / "parser.effekt.md" -> Some(Summary(
staticDispatches = 11414,
dynamicDispatches = 783,
staticDispatches = 8541,
dynamicDispatches = 768,
patternMatches = 9468,
branches = 14892,
pushedFrames = 7296,
poppedFrames = 7189,
allocations = 3848,
closures = 521,
pushedFrames = 6429,
poppedFrames = 6352,
allocations = 3833,
closures = 69,
variableReads = 6742,
variableWrites = 1901,
resets = 776,
Expand All @@ -706,14 +706,14 @@ class VMTests extends munit.FunSuite {
)),

examplesDir / "casestudies" / "anf.effekt.md" -> Some(Summary(
staticDispatches = 6147,
dynamicDispatches = 443,
staticDispatches = 4611,
dynamicDispatches = 431,
patternMatches = 5109,
branches = 8110,
pushedFrames = 4150,
poppedFrames = 4081,
allocations = 2143,
closures = 358,
pushedFrames = 3674,
poppedFrames = 3629,
allocations = 2131,
closures = 105,
variableReads = 4080,
variableWrites = 1343,
resets = 451,
Expand All @@ -738,13 +738,13 @@ class VMTests extends munit.FunSuite {
)),

examplesDir / "pos" / "raytracer.effekt" -> Some(Summary(
staticDispatches = 71065,
staticDispatches = 85740,
dynamicDispatches = 0,
patternMatches = 633105,
patternMatches = 763548,
branches = 65951,
pushedFrames = 31478,
poppedFrames = 31478,
allocations = 56669,
pushedFrames = 46153,
poppedFrames = 46153,
allocations = 70805,
closures = 0,
variableReads = 77886,
variableWrites = 26904,
Expand Down Expand Up @@ -1119,7 +1119,7 @@ class VMTests extends munit.FunSuite {
// resumes = 0
// )),
examplesDir / "benchmarks" / "nofib" / "fish.effekt" -> Some(Summary(
staticDispatches = 989577,
staticDispatches = 989497,
dynamicDispatches = 4840,
patternMatches = 1657577,
branches = 21,
Expand Down Expand Up @@ -1230,7 +1230,7 @@ class VMTests extends munit.FunSuite {
)),

examplesDir / "benchmarks" / "other" / "unify.effekt" -> Some(Summary(
staticDispatches = 2519232,
staticDispatches = 2511040,
dynamicDispatches = 1460350,
patternMatches = 3969252,
branches = 2791752,
Expand Down
18 changes: 13 additions & 5 deletions effekt/shared/src/main/scala/effekt/core/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -72,12 +72,14 @@ class EffektLexers extends Parsers {
lazy val `<>` = literal("<>")
lazy val `<{` = literal("<{")
lazy val `}>` = literal("}>")
lazy val `!!` = literal("!!")
lazy val `!` = literal("!")
lazy val `|` = literal("|")
lazy val `++` = literal("++")

lazy val `get` = keyword("get")
lazy val `put` = keyword("put")
lazy val `run` = keyword("run")
lazy val `let` = keyword("let")
lazy val `true` = keyword("true")
lazy val `false` = keyword("false")
Expand Down Expand Up @@ -117,7 +119,7 @@ class EffektLexers extends Parsers {
lazy val `namespace` = keyword("namespace")

def keywordStrings: List[String] = List(
"def", "let", "val", "var", "true", "false", "else", "type",
"def", "let", "run", "val", "var", "true", "false", "else", "type",
"effect", "interface", "try", "with", "case", "do", "if", "while",
"match", "module", "import", "extern", "fun",
"at", "box", "unbox", "return", "region", "new", "resource", "and", "is", "namespace",
Expand Down Expand Up @@ -264,7 +266,6 @@ class CoreParsers(names: Names) extends EffektLexers {
None
}

lazy val `run` = keyword("run")
lazy val `;` = super.literal(";")
lazy val `make` = keyword("make")

Expand Down Expand Up @@ -415,9 +416,17 @@ class CoreParsers(names: Names) extends EffektLexers {
)

lazy val stmts: P[Stmt] =
( (`let` ~ `!` ~/> id) ~ (`=` ~/> maybeParens(blockVar)) ~ maybeTypeArgs ~ valueArgs ~ blockArgs ~ stmts ^^ {
( (`run` ~ `!!` ~/> id) ~ (`=` ~/> maybeParens(blockVar)) ~ maybeTypeArgs ~ valueArgs ~ blockArgs ~ stmts ^^ {
case (name ~ callee ~ targs ~ vargs ~ bargs ~ body) =>
ImpureApp(name, callee, targs, vargs, bargs, body)
ExternApp(name, Purity.Async, callee, targs, vargs, bargs, body)
}
| (`run` ~ `!` ~/> id) ~ (`=` ~/> maybeParens(blockVar)) ~ maybeTypeArgs ~ valueArgs ~ blockArgs ~ stmts ^^ {
case (name ~ callee ~ targs ~ vargs ~ bargs ~ body) =>
ExternApp(name, Purity.Impure, callee, targs, vargs, bargs, body)
}
| (`run` ~/> id) ~ (`=` ~/> maybeParens(blockVar)) ~ maybeTypeArgs ~ valueArgs ~ blockArgs ~ stmts ^^ {
case (name ~ callee ~ targs ~ vargs ~ bargs ~ body) =>
ExternApp(name, Purity.Pure, callee, targs, vargs, bargs, body)
}
| `let` ~/> id ~ (`=` ~/> expr) ~ stmts ^^ {
case (name ~ binding ~ body) =>
Expand Down Expand Up @@ -463,7 +472,6 @@ class CoreParsers(names: Names) extends EffektLexers {
| `box` ~> captures ~ block ^^ { case capt ~ block => Expr.Box(block, capt) }
| `make` ~> dataType ~ id ~ maybeTypeArgs ~ valueArgs ^^ Expr.Make.apply
| id ~ (`:` ~> valueType) ^^ Expr.ValueVar.apply
| maybeParens(blockVar) ~ maybeTypeArgs ~ valueArgs ^^ Expr.PureApp.apply
| failure("Expected a pure expression.")
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ object PatternMatchingCompiler {
case Ignore()
case Any(id: Id)
case Or(patterns: List[Pattern])
case Literal(l: core.Literal, equals: (core.Expr, core.Expr) => core.Expr)
case Literal(l: core.Literal, equals: (core.Expr, core.Expr, core.ValueVar => core.Stmt) => core.Stmt)
}

/**
Expand All @@ -100,10 +100,11 @@ object PatternMatchingCompiler {
return binding.toStmt(compile(Clause(rest, target, targs, args) :: remainingClauses, motif))
// - We need to check a predicate
case Clause(Condition.Predicate(pred) :: rest, target, targs, args) =>
return core.If(pred,
compile(Clause(rest, target, targs, args) :: remainingClauses, motif),
compile(remainingClauses, motif)
)
val blockLit = core.BlockLit(List(), List(), List(), List(), compile(remainingClauses, motif))
val blockVar: core.BlockVar = core.BlockVar(Id("k"), blockLit.tpe, blockLit.capt)
return core.Def(blockVar.id, blockLit, core.If(pred,
compile(Clause(rest, target, targs, args) :: Clause(Nil, blockVar, List(), List()) :: Nil, motif),
core.App(blockVar, List(), List(), List())))
case Clause(Condition.Patterns(patterns) :: rest, target, targs, args) =>
patterns
}
Expand All @@ -121,7 +122,7 @@ object PatternMatchingCompiler {
}

// (3a) Match on a literal
def splitOnLiteral(lit: Literal, equals: (Expr, Expr) => Expr): core.Stmt = {
def splitOnLiteral(lit: Literal, equals: (Expr, Expr, ValueVar => Stmt) => Stmt): core.Stmt = {
// the different literal values that we match on
val variants: List[core.Literal] = normalized.collect {
case Clause(Split(Pattern.Literal(lit, _), _, _), _, _, _) => lit
Expand Down Expand Up @@ -171,7 +172,7 @@ object PatternMatchingCompiler {
case false =>
core.If(scrutinee, elsStmt, thnStmt)
case _ =>
core.If(equals(scrutinee, lit), thnStmt, elsStmt)
equals(scrutinee, lit, result => core.If(result, thnStmt, elsStmt))
}
}
}
Expand Down
10 changes: 7 additions & 3 deletions effekt/shared/src/main/scala/effekt/core/PrettyPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ class PrettyPrinter(printDetails: Boolean, printInternalIds: Boolean = true) ext
case Literal(s: String, _) => stringLiteral(s)
case Literal(value, _) => value.toString
case ValueVar(id, tpe) => toDoc(id) <> (if printDetails then ":" <+> toDoc(tpe) else emptyDoc)
case PureApp(b, targs, vargs) => (if printDetails then parens(toDoc(b)) else toDoc(b)) <> argsToDoc(targs, vargs, Nil)
case Make(data, tag, targs, vargs) =>
if printDetails then
"make" <+> toDoc(data) <+> toDoc(tag) <> argsToDoc(targs, vargs, Nil)
Expand Down Expand Up @@ -240,8 +239,13 @@ class PrettyPrinter(printDetails: Boolean, printInternalIds: Boolean = true) ext
"let" <+> toDoc(id) <+> "=" <+> toDoc(binding) <> line <>
toDocStmts(rest)

case ImpureApp(id, callee, targs, vargs, bargs, rest) =>
"let" <+> "!" <+> toDoc(id) <+> "=" <+> toDoc(callee) <> argsToDoc(targs, vargs, bargs) <> line <>
case ExternApp(id, purity, callee, targs, vargs, bargs, rest) =>
val purityKeyword = purity match {
case core.Pure => "run"
case core.Impure => "run !"
case core.Async => "run !!"
}
purityKeyword <+> toDoc(id) <+> "=" <+> toDoc(callee) <> argsToDoc(targs, vargs, bargs) <> line <>
toDocStmts(rest)

case Return(e) =>
Expand Down
3 changes: 1 addition & 2 deletions effekt/shared/src/main/scala/effekt/core/Recursive.scala
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Recursive(
def process(s: Stmt): Unit = s match {
case Stmt.Def(id, block, body) => process(id, block); process(body)
case Stmt.Let(id, binding, body) => process(binding); process(body)
case Stmt.ImpureApp(id, callee, targs, vargs, bargs, body) =>
case Stmt.ExternApp(id, purity, callee, targs, vargs, bargs, body) =>
process(callee)
vargs.foreach(process)
bargs.foreach(process)
Expand Down Expand Up @@ -94,7 +94,6 @@ class Recursive(
def process(e: Expr): Unit = e match {
case Expr.ValueVar(id, annotatedType) => ()
case Expr.Literal(value, annotatedType) => ()
case Expr.PureApp(b, targs, vargs) => process(b); vargs.foreach(process)
case Expr.Make(data, tag, targs, vargs) => vargs.foreach(process)
case Expr.Box(b, annotatedCapture) => process(b)
}
Expand Down
4 changes: 2 additions & 2 deletions effekt/shared/src/main/scala/effekt/core/Renamer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,12 @@ class Renamer(names: Names = Names(Map.empty), prefix: String = "") extends core
val resolvedBinding = rewrite(binding)
withBinding(id) { core.Let(rewrite(id), resolvedBinding, rewrite(body)) }

case core.ImpureApp(id, callee, targs, vargs, bargs, body) =>
case core.ExternApp(id, purity, callee, targs, vargs, bargs, body) =>
val resolvedCallee = rewrite(callee)
val resolvedTargs = targs map rewrite
val resolvedVargs = vargs map rewrite
val resolvedBargs = bargs map rewrite
withBinding(id) { core.ImpureApp(rewrite(id), resolvedCallee, resolvedTargs, resolvedVargs, resolvedBargs, rewrite(body)) }
withBinding(id) { core.ExternApp(rewrite(id), purity, resolvedCallee, resolvedTargs, resolvedVargs, resolvedBargs, rewrite(body)) }

case core.Val(id, binding, body) =>
val resolvedBinding = rewrite(binding)
Expand Down
Loading
Loading