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
11 changes: 5 additions & 6 deletions effekt/jvm/src/test/scala/effekt/ParserTests.scala
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ class ParserTests extends munit.FunSuite {
parseExpr("resume(42)")
parseExpr("in(42)")

parseExpr("fun() { foo(()) }")
parseExpr("box { foo(()) }")

parseExpr("10.seconds")

Expand All @@ -338,10 +338,9 @@ class ParserTests extends munit.FunSuite {

test("Boxing") {
parseExpr("box f")
parseExpr("unbox f")
assertEqualModuloSpans(
parseExpr("unbox box f"),
parseExpr("unbox (box f)")
parseExpr("box f"),
parseExpr("(box f)")
)
assertNotEqualModuloSpans(
parseExpr("box { 42 }"),
Expand Down Expand Up @@ -532,7 +531,7 @@ class ParserTests extends munit.FunSuite {
"""return x;
|""".stripMargin)

parseStmts("fun() { x = x + 1; x }")
parseStmts("box { x = x + 1; x }")
}

test("Definition statements") {
Expand All @@ -544,7 +543,7 @@ class ParserTests extends munit.FunSuite {

parseStmts("val (left, right) = list; return left")

parseStmts("val g: () => Unit / Exc at {exc} = fun() { closure() }; ()")
parseStmts("val g: () => Unit / Exc at {exc} = box { closure() }; ()")
}

test("Pattern-matching val parses with correct span") {
Expand Down
4 changes: 2 additions & 2 deletions effekt/shared/src/main/scala/effekt/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import effekt.core.Transformer
import effekt.namer.Namer
import effekt.source.{AnnotateCaptures, ExplicitCapabilities, ModuleDecl, ResolveExternDefs}
import effekt.symbols.Module
import effekt.typer.{BoxUnboxInference, Typer, Wellformedness}
import effekt.typer.{UnboxInference, Typer, Wellformedness}
import effekt.util.messages.{CompilerPanic, FatalPhaseError}
import effekt.util.{SourceTask, Task, VirtualSource, paths}
import kiama.output.PrettyPrinterTypes.Document
Expand Down Expand Up @@ -207,7 +207,7 @@ trait Compiler[Executable] {
* Explicit box transformation
* [[NameResolved]] --> [[NameResolved]]
*/
BoxUnboxInference andThen
UnboxInference andThen
/**
* Wellformedness checks (exhaustivity, non-escape)
* [[Typechecked]] --> [[Typechecked]]
Expand Down
6 changes: 2 additions & 4 deletions effekt/shared/src/main/scala/effekt/Lexer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,11 @@ enum TokenKind {
case `with`
case `case`
case `do`
case `fun`
case `match`
case `def`
case `extern`
case `record`
case `box`
case `unbox`
case `return`
case `region`
case `resource`
Expand Down Expand Up @@ -178,8 +176,8 @@ object TokenKind {

val keywords = Vector(
`let`, `true`, `false`, `val`, `var`, `if`, `else`, `while`, `type`, `effect`, `interface`,
`try`, `with`, `case`, `do`, `fun`, `match`, `def`, `module`, `import`, `export`, `extern`,
`include`, `record`, `box`, `unbox`, `return`, `region`, `resource`, `new`, `and`, `is`,
`try`, `with`, `case`, `do`, `match`, `def`, `module`, `import`, `export`, `extern`,
`include`, `record`, `box`, `return`, `region`, `resource`, `new`, `and`, `is`,
`namespace`, `pure`, `private`
)

Expand Down
6 changes: 1 addition & 5 deletions effekt/shared/src/main/scala/effekt/Namer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ object Namer extends Phase[Parsed, NameResolved] {
args.foreach(resolve)
}

case source.Unbox(term, _) => resolve(term)
case source.Unbox(term, _) => resolve(term) // shouldn't occur since unbox is not part of the source

case source.New(impl, _) => resolve(impl)

Expand Down Expand Up @@ -513,10 +513,6 @@ object Namer extends Phase[Parsed, NameResolved] {
if !Context.resolveOverloadedOperation(target)
then Context.abort(pp"Cannot resolve operation ${target}, called on a receiver that is a computation.")
}
// (unbox term).bar(args) = Invoke(Unbox(term), bar, args)
case source.Unbox(term, _) =>
if !Context.resolveOverloadedOperation(target)
then Context.abort(pp"Cannot resolve operation ${target}, called on an unboxed computation.")

// expr.bar(args) = Call(bar, expr :: args)
case term =>
Expand Down
14 changes: 1 addition & 13 deletions effekt/shared/src/main/scala/effekt/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ class Parser(positions: Positions, tokens: Seq[Token], source: Source) {
some(ident, `/`).mkString("/") labelled "module name"

def isToplevel: Boolean = peek.kind match {
case `val` | `fun` | `def` | `type` | `effect` | `namespace` | `interface` | `type` | `record` | `var` | `include` | `extern` => true
case `val` | `def` | `type` | `effect` | `namespace` | `interface` | `type` | `record` | `var` | `include` | `extern` => true
case _ => false
}

Expand Down Expand Up @@ -861,16 +861,6 @@ class Parser(positions: Positions, tokens: Seq[Token], source: Source) {
Box(captures, expr, span())
}

// TODO deprecate
def funExpr(): Term =
nonterminal:
val blockLiteral = `fun` ~> BlockLiteral(Nil, valueParams().unspan, Nil, braces { stmts(inBraces = true) }, span())
Box(Maybe.None(Span(source, pos(), pos(), Synthesized)), blockLiteral, blockLiteral.span.synthesized)

def unboxExpr(): Term =
nonterminal:
Unbox(`unbox` ~> expr(), span())

def newExpr(): Term =
nonterminal:
New(`new` ~> implementation(), span())
Expand Down Expand Up @@ -1183,8 +1173,6 @@ class Parser(positions: Positions, tokens: Seq[Token], source: Source) {
case `try` => tryExpr()
case `region` => regionExpr()
case `box` => boxExpr()
case `unbox` => unboxExpr()
case `fun` => funExpr()
case `new` => newExpr()
case `do` => doExpr()
case _ if isString => templateString()
Expand Down
5 changes: 1 addition & 4 deletions effekt/shared/src/main/scala/effekt/core/Parser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ class EffektLexers(positions: Positions) extends Parsers(positions) {
lazy val `with` = keyword("with")
lazy val `case` = keyword("case")
lazy val `do` = keyword("do")
lazy val `fun` = keyword("fun")
lazy val `resume` = keyword("resume")
lazy val `match` = keyword("match")
lazy val `def` = keyword("def")
Expand All @@ -93,7 +92,6 @@ class EffektLexers(positions: Positions) extends Parsers(positions) {
lazy val `at` = keyword("at")
lazy val `in` = keyword("in")
lazy val `box` = keyword("box")
lazy val `unbox` = keyword("unbox")
lazy val `return` = keyword("return")
lazy val `region` = keyword("region")
lazy val `resource` = keyword("resource")
Expand All @@ -106,7 +104,7 @@ class EffektLexers(positions: Positions) extends Parsers(positions) {
"def", "let", "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"
"at", "box", "return", "region", "new", "resource", "and", "is", "namespace"
)

def keyword(kw: String): Parser[String] =
Expand Down Expand Up @@ -419,7 +417,6 @@ class CoreParsers(positions: Positions, names: Names) extends EffektLexers(posit
// ------
lazy val block: P[Block] =
( blockVar
| `unbox` ~> pure ^^ Block.Unbox.apply
| `new` ~> implementation ^^ Block.New.apply
| blockLit
// TODO check left associative nesting (also for select)
Expand Down
2 changes: 1 addition & 1 deletion effekt/shared/src/main/scala/effekt/source/Tree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ enum Term extends Tree {
case Do(effect: Option[TypeRef], id: IdRef, targs: List[ValueType], vargs: List[ValueArg], bargs: List[Term], span: Span) extends Term, Reference

/**
* A call to either an expression, i.e., `(fun() { ...})()`; or a named function, i.e., `foo()`
* A call to either an expression, i.e., `(box { () => ... })()`; or a named function, i.e., `foo()`
*/
case Call(target: CallTarget, targs: List[ValueType], vargs: List[ValueArg], bargs: List[Term], span: Span)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ package typer
import effekt.context.{ Annotations, Context, ContextOps }
import effekt.symbols.*

object BoxUnboxInference extends Phase[NameResolved, NameResolved] {
object UnboxInference extends Phase[NameResolved, NameResolved] {

import source._

val phaseName = "box-unbox"
val phaseName = "unbox"

def run(input: NameResolved)(using Context) = {
val transformedTree = Context.timed(phaseName, input.source.name) { rewrite(input.tree) }
Expand Down Expand Up @@ -52,12 +52,18 @@ object BoxUnboxInference extends Phase[NameResolved, NameResolved] {
case v: Var => v.definition match {
// TODO maybe we should synthesize a call to get here already?
case sym: (ValueSymbol | symbols.RefBinder) => v
case sym: BlockSymbol => Box(Maybe.None(v.span.emptyAfter), v, v.span.synthesized).inheritPosition(v)
case sym: BlockSymbol =>
C.error(pp"Computation ${sym} is used in an expression position, which requires boxing (e.g. `box ${sym}`")
v
}

case n: New => Box(Maybe.None(n.span.emptyAfter), rewriteAsBlock(n), n.span.synthesized).inheritPosition(n)
case n: New =>
C.error(pp"Creating an instance in an expression requires boxing (e.g. `box new ${n.impl.id}[...] { ... }`")
rewriteAsBlock(n)

case b: BlockLiteral => Box(Maybe.None(b.span.emptyAfter), rewriteAsBlock(b), b.span.synthesized).inheritPosition(b)
case b: BlockLiteral =>
C.error(pp"Function literals in expression position require boxing (e.g. `box { (${b.vparams.map(_.id).mkString(", ")}) => ... `")
rewriteAsBlock(b)

case l: Literal => l

Expand Down
4 changes: 2 additions & 2 deletions effekt/shared/src/main/scala/effekt/util/AnsiHighlight.scala
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,10 @@ object AnsiHighlight {
// keywords
case
`let` | `val` | `var` | `if` | `else` | `while` |
`type` | `effect` | `interface` | `fun` | `do` | `case` | `with` | `try` |
`type` | `effect` | `interface` | `do` | `case` | `with` | `try` |
`true` | `false` |
`match` | `def` | `module`| `import`| `export`| `extern`| `include`|
`record`| `box`| `unbox`| `return`| `region`|
`record`| `box`| `return`| `region`|
`resource`| `new`| `and`| `is`| `namespace`| `pure` => keyword(text)

case _ => text
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmarks/are_we_fast_yet/bounce.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ def randomBall { rand: Random }: Ball at {global} = {
val y = ref(toDouble(rand.next().mod(500)));
val xVel = ref(toDouble(rand.next().mod(300) - 150));
val yVel = ref(toDouble(rand.next().mod(300) - 150));
new Ball {
box new Ball {
def bounce() = {
val xLimit = 500.0;
val yLimit = 500.0;
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmarks/other/generator.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def generator { prog: => Unit / Yield } {r: Region}: Generator at {prog, r} = {
cont = box { resume(()) }
}
}
new Generator {
box new Generator {
def value() = v
def next() = cont()
}
Expand Down
2 changes: 1 addition & 1 deletion examples/benchmarks/other/nbe.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ def reify(v: Value): Term / fresh = v match {
/// strong normalization of the term
def normalize(t: Term): Term = {
var i = 0
try reify(eval(empty[Name, Value](compareInt), t))
try reify(eval(empty[Name, Value](box compareInt), t))
with fresh { i = i + 1; resume(i) }
}

Expand Down
2 changes: 1 addition & 1 deletion examples/benchmarks/other/variadic_combinators.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def f3(fs: List[=> (Int => Int at {}) at {}]) =
else first(fs)()(n - 1)
}

def mod3(x: Int): Int = first(vfix([f1, f2, f3]))()(x)
def mod3(x: Int): Int = first(vfix([box f1, box f2, box f3]))()(x)

def run(n: Int) = {
mod3(n) + mod3(n + 1) + mod3(n + 2)
Expand Down
4 changes: 2 additions & 2 deletions examples/llvm/issue1012.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ def use { g: (Int) => Int } : Int = {
}

def main() : Unit = {
val t = [f]
val t = [box f]
list::map(t) { y => use {y} }
println("hi")
}
}
2 changes: 1 addition & 1 deletion examples/llvm/nosuchelement.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ def id[A](f: ((A) => Unit at {io, global}) => Unit at {io, global}): ((A) => Uni
// [error] java.util.NoSuchElementException: key not found: h
def main() = {
val f = box { (n: Int) => println(n) }
def h = id(g);
def h = id(box g);
val x = h(f);
println(x)
}
4 changes: 2 additions & 2 deletions examples/llvm/prompt-duplication.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ def main() : Unit = {
} with E { () =>
def f() = { () }
def g() = {
resume(f)
resume(box f)
}
resume(g)
resume(box g)
}
}
4 changes: 2 additions & 2 deletions examples/neg/blocks_in_value_pos.check
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,5 @@
Unit
but got type
() => Unit / { MyPrint } at ?C
resume(prog);
^^^^
resume(box prog);
^^^^^^^^
2 changes: 1 addition & 1 deletion examples/neg/blocks_in_value_pos.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ effect MyPrint(n: Int): Unit

def main { prog: => Unit / MyPrint } =
try { prog(); prog() } with MyPrint { (n: Int) =>
resume(prog);
resume(box prog);
println(n)
}
2 changes: 1 addition & 1 deletion examples/neg/issue362.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ def main() = {
val cap = try {
foo {arr}
} with arr: Exc { def op() = resume(println("hey")) }
(unbox cap)()
cap()
}
4 changes: 2 additions & 2 deletions examples/neg/issue365.check
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[error] examples/neg/issue365.effekt:8:28: Not allowed {io}
val unboxed: Cap at {} = myCap;
^^^^^
val unboxed: Cap at {} = box myCap;
^^^^^^^^^
4 changes: 2 additions & 2 deletions examples/neg/issue365.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ extern io def cap(): Cap at {} = default { <> }

def main() = {
def myCap = cap()
val unboxed: Cap at {} = myCap;
val unboxed: Cap at {} = box myCap;
()
}
}
4 changes: 2 additions & 2 deletions examples/neg/issue50.check
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[error] examples/neg/issue50.effekt:16:11: Not allowed {Effect2}
k = fun (x: Unit) { resume(x) };
^^^^^^^^^^^^^^^^^^^^^^^^^^^
k = box { x => resume(x) };
^^^^^^^^^^^^^^^^^^^^^^
8 changes: 4 additions & 4 deletions examples/neg/issue50.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,19 @@ def handle2 { prog: () => Unit / { Effect2 } }: Unit = {
}

def escape { prog: () => Unit / { Effect1, Effect2 } }: Unit = region this {
var k: (Unit) => Unit at { this, prog } in this = fun (x: Unit) { () }
var k: (Unit) => Unit at { this, prog } in this = box { x => () }
handle2 {
try {
prog()
} with Effect1 { () =>
k = fun (x: Unit) { resume(x) };
k = box { x => resume(x) };
resume(())
}
}

(unbox k)(())
k(())
}

def main() = {
escape { do Effect1(); do Effect2() }
}
}
4 changes: 2 additions & 2 deletions examples/neg/issue512.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ def main() = {
def myref =
region r1 { // ERROR r1
var x in r1 = "hoho";
new Ref[String] {
box new Ref[String] {
def get() = x
}
}
println(myref.get())
}
}
2 changes: 1 addition & 1 deletion examples/neg/issue548a.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ def withTime[A] { prog: { Time } => A }: A =
def main() = {
def b { t: Time }: Time at {t} = box t; // this is fine
val cap = withTime {b} // ERROR escape
def t2: Time = unbox cap
def t2: Time = cap
t2.now();
()
}
Loading