From fda1f553dbf9d87be3a7ad58a066593d6b2b6781 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 25 Aug 2025 13:25:29 +0200 Subject: [PATCH 01/40] basic set up --- .../main/scala/effekt/core/ArityRaising.scala | 87 +++++++++++++++++++ .../effekt/generator/js/JavaScript.scala | 3 +- 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 effekt/shared/src/main/scala/effekt/core/ArityRaising.scala diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala new file mode 100644 index 0000000000..0540d732b4 --- /dev/null +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -0,0 +1,87 @@ +package effekt +package core +import effekt.context.Context +import effekt.core.optimizer.Deadcode +import effekt.typer.Typer.checkMain + +object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { + override val phaseName: String = "arity raising" + + + override def run(input: CoreTransformed)(using C: Context): Option[CoreTransformed] = input match { + case CoreTransformed(source, tree, mod, core) => { + implicit val pctx: DeclarationContext = new DeclarationContext(core.declarations, core.externs) + Context.module = mod + val main = C.ensureMainExists(mod) + val res = Deadcode.remove(main, core) + val transformed = Context.timed(phaseName, source.name) { transform(res) } + println(PrettyPrinter.format(transformed)) + Some(CoreTransformed(source, tree, mod, transformed)) + } + } + + def transform(decl: ModuleDecl)(using Context, DeclarationContext): ModuleDecl = decl match { + case ModuleDecl(path, includes, declarations, externs, definitions, exports) => + ModuleDecl(path, includes, declarations, externs, definitions map transform, exports) + } + + def transform(toplevel: Toplevel)(using Context, DeclarationContext): Toplevel = toplevel match { + case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) + case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) + } + + def transform(block: Block.BlockLit)(using Context, DeclarationContext): Block.BlockLit = block match { + case Block.BlockLit(tparams, cparams, vparams, bparams, body) => + Block.BlockLit(tparams, cparams, vparams, bparams, transform(body)) + } + + def transform(block: Block)(using Context, DeclarationContext): Block = block match { + case Block.BlockVar(id, annotatedTpe, annotatedCapt) => block + case b: Block.BlockLit => transform(b) + case Block.Unbox(pure) => Block.Unbox(transform(pure)) + case Block.New(impl) => block + } + + def transform(stmt: Stmt)(using Context, DeclarationContext): Stmt = stmt match { + case Stmt.Def(id, block, rest) => + Stmt.Def(id, transform(block), transform(rest)) + case Stmt.Let(id, tpe, binding, rest) => + Stmt.Let(id, tpe, transform(binding), transform(rest)) + case Stmt.Return(expr) => + Stmt.Return(transform(expr)) + case Stmt.Val(id, tpe, binding, body) => + Stmt.Val(id, tpe, transform(binding), transform(body)) + case Stmt.App(callee, targs, vargs, bargs) => + Stmt.App(transform(callee), targs, vargs map transform, bargs map transform) // possible args + case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => + Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) // possible args + case Stmt.If(cond, thn, els) => + Stmt.If(transform(cond), transform(thn), transform(els)) + case Stmt.Match(scrutinee, clauses, default) => + Stmt.Match(transform(scrutinee), clauses.map { case (id, clause) => (id, transform(clause)) }, default map transform) + case _ => stmt + } + + def transform(expr: Expr)(using Context, DeclarationContext): Expr = expr match { + case DirectApp(b, targs, vargs, bargs) => + DirectApp(b, targs, vargs map transform, bargs map transform) // possible args + case pure: Pure => + transform(pure) + } + + def transform(pure: Pure)(using Context, DeclarationContext): Pure = pure match { + case Pure.ValueVar(id, annotatedType) => pure + case Pure.Literal(value, annotatedType) => pure + case Pure.Box(b, annotatedCapture) => pure + case Pure.PureApp(b, targs, vargs) => + Pure.PureApp(b, targs, vargs map transform) // possible args + case Pure.Make(data, tag, targs, vargs) => + Pure.Make(data, tag, targs, vargs map transform) // possibe args + + } + + def transform(valueType: ValueType.Data)(using Context, DeclarationContext): ValueType.Data = valueType match { + case ValueType.Data(symbol, targs) => valueType // trainsform + } + +} \ No newline at end of file diff --git a/effekt/shared/src/main/scala/effekt/generator/js/JavaScript.scala b/effekt/shared/src/main/scala/effekt/generator/js/JavaScript.scala index 1c860b065d..6f1823194e 100644 --- a/effekt/shared/src/main/scala/effekt/generator/js/JavaScript.scala +++ b/effekt/shared/src/main/scala/effekt/generator/js/JavaScript.scala @@ -7,6 +7,7 @@ import effekt.context.Context import effekt.core.optimizer.{ DropBindings, Optimizer } import kiama.output.PrettyPrinterTypes.Document import kiama.util.Source +import effekt.core.ArityRaising class JavaScript(additionalFeatureFlags: List[String] = Nil) extends Compiler[String] { @@ -44,7 +45,7 @@ class JavaScript(additionalFeatureFlags: List[String] = Nil) extends Compiler[St Frontend andThen Middleend } - lazy val Optimized = allToCore(Core) andThen Aggregate andThen Optimizer andThen DropBindings map { + lazy val Optimized = allToCore(Core) andThen Aggregate andThen ArityRaising andThen Optimizer andThen DropBindings map { case input @ CoreTransformed(source, tree, mod, core) => val mainSymbol = Context.ensureMainExists(mod) val mainFile = path(mod) From 1296ba91fd14140a3d44d44c92562bab12ae06cb Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 7 Oct 2025 12:01:01 +0200 Subject: [PATCH 02/40] Very simple modification of function --- .../main/scala/effekt/core/ArityRaising.scala | 59 ++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 0540d732b4..d0df47857c 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -16,6 +16,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val res = Deadcode.remove(main, core) val transformed = Context.timed(phaseName, source.name) { transform(res) } println(PrettyPrinter.format(transformed)) + println("\n\n\nparts\n\n") Some(CoreTransformed(source, tree, mod, transformed)) } } @@ -25,8 +26,29 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { ModuleDecl(path, includes, declarations, externs, definitions map transform, exports) } - def transform(toplevel: Toplevel)(using Context, DeclarationContext): Toplevel = toplevel match { - case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) + def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { + case Toplevel.Def(id, BlockLit(tparams, cparams, List(ValueParam(param, ValueType.Data(name, targs))), bparams, body)) => + println("### id : ") + println(param) + println(name) + println(targs) + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(test, List(Field(x, tpe1), Field(y, tpe2)))))) => + println(test) + val vparams = List(ValueParam(x, tpe1), ValueParam(y, tpe2)) + val transformedBody = Let(param, ValueType.Data(name, targs), + Make(ValueType.Data(name, targs), test, List(), List(ValueVar(x, tpe1), ValueVar(y, tpe2))), transform(body)) + Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, transformedBody)) + + case _ => toplevel + } + + case Toplevel.Def(id, block) => + println("\n\nid:") + println(doIndentation(id.toString)) + println("block:") + println(doIndentation(block.toString)) + Toplevel.Def(id, transform(block)) case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) } @@ -44,6 +66,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(stmt: Stmt)(using Context, DeclarationContext): Stmt = stmt match { case Stmt.Def(id, block, rest) => + // here too Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, tpe, binding, rest) => Stmt.Let(id, tpe, transform(binding), transform(rest)) @@ -52,6 +75,8 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Stmt.Val(id, tpe, binding, body) => Stmt.Val(id, tpe, transform(binding), transform(body)) case Stmt.App(callee, targs, vargs, bargs) => + println(doIndentation(stmt.toString())) + print(doIndentation(vargs.head.tpe.toString())) Stmt.App(transform(callee), targs, vargs map transform, bargs map transform) // possible args case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) // possible args @@ -84,4 +109,34 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case ValueType.Data(symbol, targs) => valueType // trainsform } + + def doIndentation(input: String): String = { + val sb = new StringBuilder + var indent = 0 + var i = 0 + + while (i < input.length) { + input(i) match { + case '(' => + sb.append("(\n") + indent += 1 + sb.append(" " * indent) + case ')' => + sb.append("\n") + indent -= 1 + sb.append(" " * indent) + sb.append(")") + case ',' => + sb.append(",\n") + sb.append(" " * indent) + case c if c.isWhitespace => + // skip extra whitespace + case c => + sb.append(c) + } + i += 1 + } + sb.toString + } + } \ No newline at end of file From 15451442030c265ca8814fad8f09e57fe8973dcb Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 7 Oct 2025 12:30:32 +0200 Subject: [PATCH 03/40] Hopefully implemented rename --- .../main/scala/effekt/core/ArityRaising.scala | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index d0df47857c..5d1094d15f 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -33,7 +33,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { println(name) println(targs) DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(test, List(Field(x, tpe1), Field(y, tpe2)))))) => + case Some(Data(_, List(), List(Constructor(test, List(Field(x, tpe1)), List(Field(y, tpe2)))))) => println(test) val vparams = List(ValueParam(x, tpe1), ValueParam(y, tpe2)) val transformedBody = Let(param, ValueType.Data(name, targs), @@ -87,22 +87,14 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case _ => stmt } - def transform(expr: Expr)(using Context, DeclarationContext): Expr = expr match { - case DirectApp(b, targs, vargs, bargs) => - DirectApp(b, targs, vargs map transform, bargs map transform) // possible args - case pure: Pure => - transform(pure) - } - - def transform(pure: Pure)(using Context, DeclarationContext): Pure = pure match { - case Pure.ValueVar(id, annotatedType) => pure - case Pure.Literal(value, annotatedType) => pure - case Pure.Box(b, annotatedCapture) => pure - case Pure.PureApp(b, targs, vargs) => - Pure.PureApp(b, targs, vargs map transform) // possible args - case Pure.Make(data, tag, targs, vargs) => - Pure.Make(data, tag, targs, vargs map transform) // possibe args - + def transform(pure: Expr)(using Context, DeclarationContext): Expr = pure match { + case Expr.ValueVar(id, annotatedType) => pure + case Expr.Literal(value, annotatedType) => pure + case Expr.Box(b, annotatedCapture) => pure + case Expr.PureApp(b, targs, vargs) => + Expr.PureApp(b, targs, vargs map transform) // possible args + case Expr.Make(data, tag, targs, vargs) => + Expr.Make(data, tag, targs, vargs map transform) // possibe args } def transform(valueType: ValueType.Data)(using Context, DeclarationContext): ValueType.Data = valueType match { From 6384319a5483208ca499e4db98d426da21c6d75c Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 7 Oct 2025 12:44:33 +0200 Subject: [PATCH 04/40] Now working as before --- .../src/main/scala/effekt/core/ArityRaising.scala | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 5d1094d15f..120532a749 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -33,21 +33,24 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { println(name) println(targs) DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(test, List(Field(x, tpe1)), List(Field(y, tpe2)))))) => + case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => println(test) val vparams = List(ValueParam(x, tpe1), ValueParam(y, tpe2)) val transformedBody = Let(param, ValueType.Data(name, targs), Make(ValueType.Data(name, targs), test, List(), List(ValueVar(x, tpe1), ValueVar(y, tpe2))), transform(body)) Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, transformedBody)) - case _ => toplevel + case s => + println("broken") + println(s) + toplevel } case Toplevel.Def(id, block) => - println("\n\nid:") - println(doIndentation(id.toString)) - println("block:") - println(doIndentation(block.toString)) + // println("\n\nid:") + // println(doIndentation(id.toString)) + // println("block:") + // println(doIndentation(block.toString)) Toplevel.Def(id, transform(block)) case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) } From 9e4deb71c031fe22658ab391f0affc6699bb44bb Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 7 Oct 2025 14:07:01 +0200 Subject: [PATCH 05/40] Starting to modify function calls, bind by match still missing --- .../main/scala/effekt/core/ArityRaising.scala | 78 ++++++++++++++----- 1 file changed, 58 insertions(+), 20 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 120532a749..11c8ff6213 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -40,17 +40,15 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Make(ValueType.Data(name, targs), test, List(), List(ValueVar(x, tpe1), ValueVar(y, tpe2))), transform(body)) Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, transformedBody)) - case s => - println("broken") - println(s) + case _ => toplevel } case Toplevel.Def(id, block) => - // println("\n\nid:") - // println(doIndentation(id.toString)) - // println("block:") - // println(doIndentation(block.toString)) + println("\n\nid:") + println(doIndentation(id.toString)) + println("block:") + println(doIndentation(block.toString)) Toplevel.Def(id, transform(block)) case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) } @@ -67,10 +65,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Block.New(impl) => block } - def transform(stmt: Stmt)(using Context, DeclarationContext): Stmt = stmt match { + def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { case Stmt.Def(id, block, rest) => // here too - Stmt.Def(id, transform(block), transform(rest)) + Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, tpe, binding, rest) => Stmt.Let(id, tpe, transform(binding), transform(rest)) case Stmt.Return(expr) => @@ -78,9 +76,30 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Stmt.Val(id, tpe, binding, body) => Stmt.Val(id, tpe, transform(binding), transform(body)) case Stmt.App(callee, targs, vargs, bargs) => - println(doIndentation(stmt.toString())) - print(doIndentation(vargs.head.tpe.toString())) - Stmt.App(transform(callee), targs, vargs map transform, bargs map transform) // possible args + callee match { + case BlockVar(id, BlockType.Function(List(), List(), List(ValueType.Data(name, List())), List(), returnTpe), annotatedCapt) => + println("id") + println(id) + println("tpe") + + println("capt") + println(annotatedCapt) + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => + val transformedVargs = List(ValueVar(x, tpe1), ValueVar(y, tpe2)) + val res = Stmt.App(BlockVar(id, BlockType.Function(List(), List(), List(tpe1, tpe2), List(), returnTpe), annotatedCapt), targs, transformedVargs, bargs) + println("res $$$$###") + println(res) + println(vargs) + res + + case _ => + stmt + + } + + case _ => stmt + } case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) // possible args case Stmt.If(cond, thn, els) => @@ -113,25 +132,44 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { while (i < input.length) { input(i) match { case '(' => - sb.append("(\n") - indent += 1 - sb.append(" " * indent) + // Look ahead to see if it's a short List(...) with no commas + val closing = input.indexOf(')', i) + val inside = if (closing > i) input.substring(i + 1, closing) else "" + if (inside.contains(',') || inside.contains('(') || inside.contains(')')) { + sb.append("(\n") + indent += 1 + sb.append(" " * indent) + } else { + sb.append('(') + } + case ')' => - sb.append("\n") - indent -= 1 - sb.append(" " * indent) - sb.append(")") + val prev = if (i > 0) input(i - 1) else ' ' + if (prev == '(' || prev.isLetterOrDigit) { + sb.append(')') + } else { + sb.append("\n") + indent -= 1 + sb.append(" " * indent) + sb.append(")") + } + case ',' => sb.append(",\n") sb.append(" " * indent) + case c if c.isWhitespace => - // skip extra whitespace + // skip + case c => sb.append(c) } i += 1 } + sb.toString } + + } \ No newline at end of file From 6cfb38635c7624b53e7b2c04f394f09e1001cae5 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 27 Oct 2025 08:48:39 +0100 Subject: [PATCH 06/40] Forgot to commit and push, both sides working now for 2 arguments --- .../main/scala/effekt/core/ArityRaising.scala | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 11c8ff6213..b580a2a6d2 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -14,6 +14,8 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Context.module = mod val main = C.ensureMainExists(mod) val res = Deadcode.remove(main, core) + println("Before") + println(PrettyPrinter.format(res)) val transformed = Context.timed(phaseName, source.name) { transform(res) } println(PrettyPrinter.format(transformed)) println("\n\n\nparts\n\n") @@ -28,10 +30,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { case Toplevel.Def(id, BlockLit(tparams, cparams, List(ValueParam(param, ValueType.Data(name, targs))), bparams, body)) => - println("### id : ") - println(param) - println(name) - println(targs) DC.findData(name) match { case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => println(test) @@ -45,11 +43,11 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } case Toplevel.Def(id, block) => - println("\n\nid:") - println(doIndentation(id.toString)) - println("block:") - println(doIndentation(block.toString)) - Toplevel.Def(id, transform(block)) + val res = Toplevel.Def(id, transform(block)) + println("\n\nres:") + println(doIndentation(res.toString)) + res + case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) } @@ -88,10 +86,15 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => val transformedVargs = List(ValueVar(x, tpe1), ValueVar(y, tpe2)) val res = Stmt.App(BlockVar(id, BlockType.Function(List(), List(), List(tpe1, tpe2), List(), returnTpe), annotatedCapt), targs, transformedVargs, bargs) + val latermatch: BlockLit = Block.BlockLit(List(), List(), List(ValueParam(x,tpe1), ValueParam(y, tpe2)), List(), res) + val newMatch = Stmt.Match(vargs.head, List((test, latermatch)), None) println("res $$$$###") - println(res) - println(vargs) - res + println(stmt) + println(name) + println(test) + println(vargs.head) + println(newMatch) + newMatch case _ => stmt @@ -106,6 +109,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Stmt.If(transform(cond), transform(thn), transform(els)) case Stmt.Match(scrutinee, clauses, default) => Stmt.Match(transform(scrutinee), clauses.map { case (id, clause) => (id, transform(clause)) }, default map transform) + case _ => stmt } From 662bc6614a492bc9e889138fb33546735157ebfa Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 25 Nov 2025 15:53:16 +0100 Subject: [PATCH 07/40] need to use fresh --- .../src/main/scala/effekt/core/ArityRaising.scala | 6 ++++-- project/metals.sbt | 13 +++++++++++++ project/project/metals.sbt | 14 ++++++++++++++ project/project/project/metals.sbt | 8 ++++++++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 project/metals.sbt create mode 100644 project/project/metals.sbt create mode 100644 project/project/project/metals.sbt diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index b580a2a6d2..7f07397107 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -33,6 +33,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { DC.findData(name) match { case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => println(test) + //new names val vparams = List(ValueParam(x, tpe1), ValueParam(y, tpe2)) val transformedBody = Let(param, ValueType.Data(name, targs), Make(ValueType.Data(name, targs), test, List(), List(ValueVar(x, tpe1), ValueVar(y, tpe2))), transform(body)) @@ -84,9 +85,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { println(annotatedCapt) DC.findData(name) match { case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => - val transformedVargs = List(ValueVar(x, tpe1), ValueVar(y, tpe2)) + val xfresh = Id(x.name) + val transformedVargs = List(ValueVar(xfresh, tpe1), ValueVar(y, tpe2)) val res = Stmt.App(BlockVar(id, BlockType.Function(List(), List(), List(tpe1, tpe2), List(), returnTpe), annotatedCapt), targs, transformedVargs, bargs) - val latermatch: BlockLit = Block.BlockLit(List(), List(), List(ValueParam(x,tpe1), ValueParam(y, tpe2)), List(), res) + val latermatch: BlockLit = Block.BlockLit(List(), List(), List(ValueParam(xfresh,tpe1), ValueParam(y, tpe2)), List(), res) val newMatch = Stmt.Match(vargs.head, List((test, latermatch)), None) println("res $$$$###") println(stmt) diff --git a/project/metals.sbt b/project/metals.sbt new file mode 100644 index 0000000000..f320ea721a --- /dev/null +++ b/project/metals.sbt @@ -0,0 +1,13 @@ +// format: off +// DO NOT EDIT! This file is auto-generated. + +// This plugin enables semantic information to be produced by sbt. +// It also adds support for debugging using the Debug Adapter Protocol + +addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.3") + +// This plugin adds the BSP debug capability to sbt server. + +addSbtPlugin("ch.epfl.scala" % "sbt-debug-adapter" % "4.2.8") + +// format: on diff --git a/project/project/metals.sbt b/project/project/metals.sbt new file mode 100644 index 0000000000..47bad96feb --- /dev/null +++ b/project/project/metals.sbt @@ -0,0 +1,14 @@ +// format: off +// DO NOT EDIT! This file is auto-generated. + +// This plugin enables semantic information to be produced by sbt. +// It also adds support for debugging using the Debug Adapter Protocol + +addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.3") + +// This plugin makes sure that the JDI tools are in the sbt classpath. +// JDI tools are used by the debug adapter server. + +addSbtPlugin("com.github.sbt" % "sbt-jdi-tools" % "1.2.0") + +// format: on diff --git a/project/project/project/metals.sbt b/project/project/project/metals.sbt new file mode 100644 index 0000000000..69465cb550 --- /dev/null +++ b/project/project/project/metals.sbt @@ -0,0 +1,8 @@ +// format: off +// DO NOT EDIT! This file is auto-generated. + +// This file enables sbt-bloop to create bloop config files. + +addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "2.0.13") + +// format: on From b4dceee0b99e294f66a328e6c10832ccf42e3cca Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 25 Nov 2025 16:41:48 +0100 Subject: [PATCH 08/40] Booth sides fresh --- .../main/scala/effekt/core/ArityRaising.scala | 54 +++++++------------ 1 file changed, 19 insertions(+), 35 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 7f07397107..a192a10ee4 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -7,18 +7,17 @@ import effekt.typer.Typer.checkMain object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { override val phaseName: String = "arity raising" - override def run(input: CoreTransformed)(using C: Context): Option[CoreTransformed] = input match { case CoreTransformed(source, tree, mod, core) => { implicit val pctx: DeclarationContext = new DeclarationContext(core.declarations, core.externs) Context.module = mod val main = C.ensureMainExists(mod) val res = Deadcode.remove(main, core) - println("Before") - println(PrettyPrinter.format(res)) + // println("Before") + // println(PrettyPrinter.format(res)) val transformed = Context.timed(phaseName, source.name) { transform(res) } - println(PrettyPrinter.format(transformed)) - println("\n\n\nparts\n\n") + // println(PrettyPrinter.format(transformed)) + // println("\n\n\nparts\n\n") Some(CoreTransformed(source, tree, mod, transformed)) } } @@ -32,11 +31,13 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Toplevel.Def(id, BlockLit(tparams, cparams, List(ValueParam(param, ValueType.Data(name, targs))), bparams, body)) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => - println(test) + //println(test) //new names - val vparams = List(ValueParam(x, tpe1), ValueParam(y, tpe2)) + val p1 = Id(x.name) + val p2 = Id(y.name) + val vparams = List(ValueParam(p1, tpe1), ValueParam(p2, tpe2)) val transformedBody = Let(param, ValueType.Data(name, targs), - Make(ValueType.Data(name, targs), test, List(), List(ValueVar(x, tpe1), ValueVar(y, tpe2))), transform(body)) + Make(ValueType.Data(name, targs), test, List(), List(ValueVar(p1, tpe1), ValueVar(p2, tpe2))), transform(body)) Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, transformedBody)) case _ => @@ -45,8 +46,8 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Toplevel.Def(id, block) => val res = Toplevel.Def(id, transform(block)) - println("\n\nres:") - println(doIndentation(res.toString)) + //println("\n\nres:") + //println(doIndentation(res.toString)) res case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) @@ -66,7 +67,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { case Stmt.Def(id, block, rest) => - // here too Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, tpe, binding, rest) => Stmt.Let(id, tpe, transform(binding), transform(rest)) @@ -77,36 +77,23 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Stmt.App(callee, targs, vargs, bargs) => callee match { case BlockVar(id, BlockType.Function(List(), List(), List(ValueType.Data(name, List())), List(), returnTpe), annotatedCapt) => - println("id") - println(id) - println("tpe") - - println("capt") - println(annotatedCapt) DC.findData(name) match { case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => - val xfresh = Id(x.name) - val transformedVargs = List(ValueVar(xfresh, tpe1), ValueVar(y, tpe2)) + val p1 = Id(x.name) + val p2 = Id(y.name) + val transformedVargs = List(ValueVar(p1, tpe1), ValueVar(p2, tpe2)) val res = Stmt.App(BlockVar(id, BlockType.Function(List(), List(), List(tpe1, tpe2), List(), returnTpe), annotatedCapt), targs, transformedVargs, bargs) - val latermatch: BlockLit = Block.BlockLit(List(), List(), List(ValueParam(xfresh,tpe1), ValueParam(y, tpe2)), List(), res) - val newMatch = Stmt.Match(vargs.head, List((test, latermatch)), None) - println("res $$$$###") - println(stmt) - println(name) - println(test) - println(vargs.head) - println(newMatch) - newMatch + val latermatch: BlockLit = Block.BlockLit(List(), List(), List(ValueParam(p1,tpe1), ValueParam(p2, tpe2)), List(), res) + Stmt.Match(vargs.head, List((test, latermatch)), None) case _ => stmt - } case _ => stmt } case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => - Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) // possible args + Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) case Stmt.If(cond, thn, els) => Stmt.If(transform(cond), transform(thn), transform(els)) case Stmt.Match(scrutinee, clauses, default) => @@ -120,16 +107,15 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Expr.Literal(value, annotatedType) => pure case Expr.Box(b, annotatedCapture) => pure case Expr.PureApp(b, targs, vargs) => - Expr.PureApp(b, targs, vargs map transform) // possible args + Expr.PureApp(b, targs, vargs map transform) case Expr.Make(data, tag, targs, vargs) => - Expr.Make(data, tag, targs, vargs map transform) // possibe args + Expr.Make(data, tag, targs, vargs map transform) } def transform(valueType: ValueType.Data)(using Context, DeclarationContext): ValueType.Data = valueType match { case ValueType.Data(symbol, targs) => valueType // trainsform } - def doIndentation(input: String): String = { val sb = new StringBuilder var indent = 0 @@ -176,6 +162,4 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { sb.toString } - - } \ No newline at end of file From f2f892ebcdd8091f7738968362e5becacc44f163 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 25 Nov 2025 20:17:25 +0100 Subject: [PATCH 09/40] Made it create match --- .../main/scala/effekt/core/ArityRaising.scala | 135 +++++++++++++----- 1 file changed, 99 insertions(+), 36 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index a192a10ee4..cadcbcbe96 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -3,6 +3,8 @@ package core import effekt.context.Context import effekt.core.optimizer.Deadcode import effekt.typer.Typer.checkMain +import effekt.symbols.Symbol.fresh +import effekt.lexer.TokenKind object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { override val phaseName: String = "arity raising" @@ -16,8 +18,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { // println("Before") // println(PrettyPrinter.format(res)) val transformed = Context.timed(phaseName, source.name) { transform(res) } - // println(PrettyPrinter.format(transformed)) - // println("\n\n\nparts\n\n") + println(PrettyPrinter.format(transformed)) Some(CoreTransformed(source, tree, mod, transformed)) } } @@ -28,22 +29,47 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { - case Toplevel.Def(id, BlockLit(tparams, cparams, List(ValueParam(param, ValueType.Data(name, targs))), bparams, body)) => - DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => - //println(test) - //new names - val p1 = Id(x.name) - val p2 = Id(y.name) - val vparams = List(ValueParam(p1, tpe1), ValueParam(p2, tpe2)) - val transformedBody = Let(param, ValueType.Data(name, targs), - Make(ValueType.Data(name, targs), test, List(), List(ValueVar(p1, tpe1), ValueVar(p2, tpe2))), transform(body)) - Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, transformedBody)) - - case _ => - toplevel - } - + + case Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, body)) => + // does this for all params, so id should be able to handle def myFun(a: Record, b: Record) + // we return the param and the necesarry information to recreate the record later on + val (newParams, rec) = vparams.map { param => + param match{ + case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => + // finding the constructor + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => + // handling all fields, so it handles Record(a, b, c, ...) + // still TODO nested records + val newFields = fields.map { case Field(fieldName, fieldType) => + val freshId = Id(fieldName.name) + (ValueParam(freshId, fieldType), ValueVar(freshId, fieldType)) + } + + val (params, args) = newFields.unzip + + val make = Make(tpe, ctor, List(), args) + // giving back params and how to recreate the record in the body + (params, Some((paramId, tpe, make))) + case _ => + (List(param), None) + } + case _ => + (List(param), None) + } + }.unzip + + val allNewParams = newParams.flatten + val bindings = rec.flatten + + // this is needed since we can only do a single stmt, so we nest the Let statments + val newBody = bindings.foldRight(transform(body)) { + case ((originalId, originalType, expr), currentbody) => + Let(originalId, originalType, expr, currentbody) + } + + Toplevel.Def(id, BlockLit(tparams, cparams, allNewParams, bparams, newBody)) + case Toplevel.Def(id, block) => val res = Toplevel.Def(id, transform(block)) //println("\n\nres:") @@ -66,6 +92,61 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { + + case Stmt.App(callee, targs, vargs, bargs) => + callee match { + case BlockVar(id, BlockType.Function(List(), List(), vparamsTypes, List(), returnTpe), annotatedCapt) => + val (newVargs, types, preparedMatches ) = (vargs zip vparamsTypes).map { case (arg, argType) => + argType match{ + case ValueType.Data(name, targs) => + // finding the constructor + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => + val fieldInf = fields.map { case Field(fieldName, fieldType) => + val freshId = Id(fieldName.name) + + (ValueVar(freshId, fieldType), ValueParam(freshId, fieldType), fieldType) + } + + val (newVars, newParams, types) = fieldInf.unzip3 + + val preparedmatch = (innerBody: Stmt) => { + val matchBlock: BlockLit = BlockLit(List(), List(), newParams, List(), innerBody) + Stmt.Match(arg, List((ctor, matchBlock)), None) + } + + (newVars, types, preparedmatch) + + case _ => (List(arg), List(argType), (s:Stmt) => s ) + + } + + case _ => (List(arg), List(argType), (s: Stmt) => s) + } + }.unzip3 + + val finalArgs = newVargs.flatten + val finalArgTypes = types.flatten + + val newCalleeType = BlockType.Function(List(), List(), finalArgTypes, List(), returnTpe) + val newCallee = BlockVar(id, newCalleeType, annotatedCapt) + println("HERE") + println(finalArgs) + println(finalArgTypes) + println(preparedMatches) + + val innerApp = Stmt.App(newCallee, targs, finalArgs, bargs) + + val finalStmt = preparedMatches.foldRight(innerApp) { (wrapper, acc) => + wrapper(acc) + } + + finalStmt + + case _ => stmt + + } + case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, tpe, binding, rest) => @@ -74,24 +155,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Stmt.Return(transform(expr)) case Stmt.Val(id, tpe, binding, body) => Stmt.Val(id, tpe, transform(binding), transform(body)) - case Stmt.App(callee, targs, vargs, bargs) => - callee match { - case BlockVar(id, BlockType.Function(List(), List(), List(ValueType.Data(name, List())), List(), returnTpe), annotatedCapt) => - DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(test, List(), List(Field(x, tpe1), Field(y, tpe2)))))) => - val p1 = Id(x.name) - val p2 = Id(y.name) - val transformedVargs = List(ValueVar(p1, tpe1), ValueVar(p2, tpe2)) - val res = Stmt.App(BlockVar(id, BlockType.Function(List(), List(), List(tpe1, tpe2), List(), returnTpe), annotatedCapt), targs, transformedVargs, bargs) - val latermatch: BlockLit = Block.BlockLit(List(), List(), List(ValueParam(p1,tpe1), ValueParam(p2, tpe2)), List(), res) - Stmt.Match(vargs.head, List((test, latermatch)), None) - - case _ => - stmt - } - - case _ => stmt - } case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) case Stmt.If(cond, thn, els) => From 1d77886bae186957c43740b7db8e90e6deb403f2 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 25 Nov 2025 20:22:52 +0100 Subject: [PATCH 10/40] Added comments so i dont forget why i did certain things --- .../shared/src/main/scala/effekt/core/ArityRaising.scala | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index cadcbcbe96..34a6a6ab05 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -72,8 +72,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Toplevel.Def(id, block) => val res = Toplevel.Def(id, transform(block)) - //println("\n\nres:") - //println(doIndentation(res.toString)) res case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) @@ -110,6 +108,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val (newVars, newParams, types) = fieldInf.unzip3 + // preparing the match statement so we only have to fill the body later val preparedmatch = (innerBody: Stmt) => { val matchBlock: BlockLit = BlockLit(List(), List(), newParams, List(), innerBody) Stmt.Match(arg, List((ctor, matchBlock)), None) @@ -117,6 +116,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { (newVars, types, preparedmatch) + // this makes sure that we just return the argument as it is. case _ => (List(arg), List(argType), (s:Stmt) => s ) } @@ -130,13 +130,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val newCalleeType = BlockType.Function(List(), List(), finalArgTypes, List(), returnTpe) val newCallee = BlockVar(id, newCalleeType, annotatedCapt) - println("HERE") - println(finalArgs) - println(finalArgTypes) - println(preparedMatches) val innerApp = Stmt.App(newCallee, targs, finalArgs, bargs) + // wrapping the inner app with all prepared matches val finalStmt = preparedMatches.foldRight(innerApp) { (wrapper, acc) => wrapper(acc) } From 595cd9b6f4b57a127df494658ebd0c39c0ed3697 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 2 Dec 2025 21:19:19 +0100 Subject: [PATCH 11/40] app side working i think --- .../main/scala/effekt/core/ArityRaising.scala | 166 ++++++++---------- 1 file changed, 74 insertions(+), 92 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 34a6a6ab05..751c310ebd 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -30,49 +30,44 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { - case Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, body)) => - // does this for all params, so id should be able to handle def myFun(a: Record, b: Record) - // we return the param and the necesarry information to recreate the record later on - val (newParams, rec) = vparams.map { param => - param match{ - case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => - // finding the constructor - DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => - // handling all fields, so it handles Record(a, b, c, ...) - // still TODO nested records - val newFields = fields.map { case Field(fieldName, fieldType) => - val freshId = Id(fieldName.name) - (ValueParam(freshId, fieldType), ValueVar(freshId, fieldType)) - } - - val (params, args) = newFields.unzip - - val make = Make(tpe, ctor, List(), args) - // giving back params and how to recreate the record in the body - (params, Some((paramId, tpe, make))) - case _ => - (List(param), None) - } - case _ => - (List(param), None) - } - }.unzip - - val allNewParams = newParams.flatten - val bindings = rec.flatten - - // this is needed since we can only do a single stmt, so we nest the Let statments - val newBody = bindings.foldRight(transform(body)) { - case ((originalId, originalType, expr), currentbody) => - Let(originalId, originalType, expr, currentbody) - } - - Toplevel.Def(id, BlockLit(tparams, cparams, allNewParams, bparams, newBody)) - - case Toplevel.Def(id, block) => - val res = Toplevel.Def(id, transform(block)) - res + case Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, body)) => { + // Recursively flatten a parameter into (params, bindings to reconstruct records) + def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, ValueType, Expr)]) = param match { + case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => + // Recursively flatten each field + val flattened = fields.map { case Field(fieldName, fieldType) => + val freshId = Id(fieldName.name) + flattenParam(ValueParam(freshId, fieldType)) + } + + val (allParams, nestedBindings) = flattened.unzip + val flatParams = allParams.flatten + val allBindings = nestedBindings.flatten + + // Create binding to reconstruct this record + val vars = flatParams.map(p => ValueVar(p.id, p.tpe)) + val binding = (paramId, tpe, Make(tpe, ctor, List(), vars)) + + (flatParams, binding :: allBindings) + + case _ => (List(param), List()) + } + case _ => (List(param), List()) + } + + val flattened = vparams.map(flattenParam) + val (allParams, allBindings) = flattened.unzip + + val newBody = allBindings.flatten.foldRight(transform(body)) { + case ((id, tpe, expr), body) => Let(id, tpe, expr, body) + } + + Toplevel.Def(id, BlockLit(tparams, cparams, allParams.flatten, bparams, newBody)) + } + + case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) } @@ -91,58 +86,45 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { - case Stmt.App(callee, targs, vargs, bargs) => - callee match { - case BlockVar(id, BlockType.Function(List(), List(), vparamsTypes, List(), returnTpe), annotatedCapt) => - val (newVargs, types, preparedMatches ) = (vargs zip vparamsTypes).map { case (arg, argType) => - argType match{ - case ValueType.Data(name, targs) => - // finding the constructor - DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => - val fieldInf = fields.map { case Field(fieldName, fieldType) => - val freshId = Id(fieldName.name) - - (ValueVar(freshId, fieldType), ValueParam(freshId, fieldType), fieldType) - } - - val (newVars, newParams, types) = fieldInf.unzip3 - - // preparing the match statement so we only have to fill the body later - val preparedmatch = (innerBody: Stmt) => { - val matchBlock: BlockLit = BlockLit(List(), List(), newParams, List(), innerBody) - Stmt.Match(arg, List((ctor, matchBlock)), None) - } - - (newVars, types, preparedmatch) - - // this makes sure that we just return the argument as it is. - case _ => (List(arg), List(argType), (s:Stmt) => s ) - - } - - case _ => (List(arg), List(argType), (s: Stmt) => s) + case Stmt.App(callee @ BlockVar(id, BlockType.Function(List(), List(), vparamsTypes, List(), returnTpe), annotatedCapt), targs, vargs, bargs) => + // Recursively flatten an argument + def flattenArg(arg: Expr, argType: ValueType): (List[Expr], List[ValueType], List[(Expr, Id, List[ValueParam])]) = argType match { + case ValueType.Data(name, targs) => + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => + val fieldInfo = fields.map { case Field(fieldName, fieldType) => + val freshId = Id(fieldName.name) + val freshVar = ValueVar(freshId, fieldType) + val freshParam = ValueParam(freshId, fieldType) + + // Recursively flatten if this field is also a record + val (nestedVars, nestedTypes, nestedMatches) = flattenArg(freshVar, fieldType) + (freshVar, freshParam, fieldType, nestedVars, nestedTypes, nestedMatches) } - }.unzip3 - - val finalArgs = newVargs.flatten - val finalArgTypes = types.flatten - - val newCalleeType = BlockType.Function(List(), List(), finalArgTypes, List(), returnTpe) - val newCallee = BlockVar(id, newCalleeType, annotatedCapt) - - val innerApp = Stmt.App(newCallee, targs, finalArgs, bargs) - - // wrapping the inner app with all prepared matches - val finalStmt = preparedMatches.foldRight(innerApp) { (wrapper, acc) => - wrapper(acc) + + val vars = fieldInfo.flatMap(_._4) + val types = fieldInfo.flatMap(_._5) + val params = fieldInfo.map(_._2) + val nestedMatches = fieldInfo.flatMap(_._6) + val thisMatch = (arg, ctor, params) + + (vars, types, thisMatch :: nestedMatches) + + case _ => (List(arg), List(argType), List()) } - - finalStmt + case _ => (List(arg), List(argType), List()) + } - case _ => stmt - - } + val flattened = (vargs zip vparamsTypes).map { case (arg, tpe) => flattenArg(arg, tpe) } + val (allArgs, allTypes, allMatches) = flattened.unzip3 + + val newCallee = BlockVar(id, BlockType.Function(List(), List(), allTypes.flatten, List(), returnTpe), annotatedCapt) + val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, bargs) + + allMatches.flatten.foldRight(innerApp) { + case ((scrutinee, ctor, params), body) => + Stmt.Match(scrutinee, List((ctor, BlockLit(List(), List(), params, List(), body))), None) + } case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) From b0c146434fdc07c8b8157e23b897525a9d4565f2 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 2 Dec 2025 21:49:35 +0100 Subject: [PATCH 12/40] Booth sides working llvm test work, js some not --- .../src/main/scala/effekt/core/ArityRaising.scala | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 751c310ebd..23691c6a4f 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -31,12 +31,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { case Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, body)) => { - // Recursively flatten a parameter into (params, bindings to reconstruct records) def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, ValueType, Expr)]) = param match { case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => - // Recursively flatten each field val flattened = fields.map { case Field(fieldName, fieldType) => val freshId = Id(fieldName.name) flattenParam(ValueParam(freshId, fieldType)) @@ -47,10 +45,12 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val allBindings = nestedBindings.flatten // Create binding to reconstruct this record - val vars = flatParams.map(p => ValueVar(p.id, p.tpe)) - val binding = (paramId, tpe, Make(tpe, ctor, List(), vars)) + val fieldVars = fields.map { case Field(fieldName, fieldType) => + ValueVar(Id(fieldName.name), fieldType) + } + val binding = (paramId, tpe, Make(tpe, ctor, List(), fieldVars)) - (flatParams, binding :: allBindings) + (flatParams, allBindings :+ binding) case _ => (List(param), List()) } @@ -87,7 +87,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { case Stmt.App(callee @ BlockVar(id, BlockType.Function(List(), List(), vparamsTypes, List(), returnTpe), annotatedCapt), targs, vargs, bargs) => - // Recursively flatten an argument def flattenArg(arg: Expr, argType: ValueType): (List[Expr], List[ValueType], List[(Expr, Id, List[ValueParam])]) = argType match { case ValueType.Data(name, targs) => DC.findData(name) match { @@ -97,7 +96,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val freshVar = ValueVar(freshId, fieldType) val freshParam = ValueParam(freshId, fieldType) - // Recursively flatten if this field is also a record val (nestedVars, nestedTypes, nestedMatches) = flattenArg(freshVar, fieldType) (freshVar, freshParam, fieldType, nestedVars, nestedTypes, nestedMatches) } From 3d680e7d599dfafbaa73168f4dd109cb4c14dec5 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Wed, 3 Dec 2025 10:38:09 +0100 Subject: [PATCH 13/40] clean up --- effekt/shared/src/main/scala/effekt/core/ArityRaising.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 23691c6a4f..a8a6481251 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -35,12 +35,11 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => - val flattened = fields.map { case Field(fieldName, fieldType) => + val (allParams, nestedBindings) = fields.map { case Field(fieldName, fieldType) => val freshId = Id(fieldName.name) flattenParam(ValueParam(freshId, fieldType)) - } + }.unzip - val (allParams, nestedBindings) = flattened.unzip val flatParams = allParams.flatten val allBindings = nestedBindings.flatten From b0c93a76cf2d06e135e42d9c4a0ff28bb40a634b Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 15 Dec 2025 11:58:52 +0100 Subject: [PATCH 14/40] rebased --- .../main/scala/effekt/core/ArityRaising.scala | 108 ++++++++++-------- .../scala/effekt/generator/llvm/LLVM.scala | 3 +- 2 files changed, 60 insertions(+), 51 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index a8a6481251..b4417b7308 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -5,6 +5,7 @@ import effekt.core.optimizer.Deadcode import effekt.typer.Typer.checkMain import effekt.symbols.Symbol.fresh import effekt.lexer.TokenKind +import effekt.core.Type.instantiate object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { override val phaseName: String = "arity raising" @@ -18,7 +19,8 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { // println("Before") // println(PrettyPrinter.format(res)) val transformed = Context.timed(phaseName, source.name) { transform(res) } - println(PrettyPrinter.format(transformed)) + // println("\n\n\n\nhello") + // println(PrettyPrinter.format(transformed)) Some(CoreTransformed(source, tree, mod, transformed)) } } @@ -29,27 +31,25 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { - - case Toplevel.Def(id, BlockLit(tparams, cparams, vparams, bparams, body)) => { - def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, ValueType, Expr)]) = param match { + case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) + case Toplevel.Val(id, binding) => Toplevel.Val(id, transform(binding)) + } + + def transform(block: Block)(using C: Context, DC: DeclarationContext): Block = block match { + case Block.BlockVar(id, annotatedTpe, annotatedCapt) => block + case Block.BlockLit(tparams, cparams, vparams, bparams, body) => + def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, Expr)]) = param match { case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => - val (allParams, nestedBindings) = fields.map { case Field(fieldName, fieldType) => + val (flatParams, allBindings, fieldVars) = fields.map { case Field(fieldName, fieldType) => val freshId = Id(fieldName.name) - flattenParam(ValueParam(freshId, fieldType)) - }.unzip + val (params, bindings) = flattenParam(ValueParam(freshId, fieldType)) + (params, bindings, ValueVar(freshId, fieldType)) + }.unzip3 - val flatParams = allParams.flatten - val allBindings = nestedBindings.flatten - - // Create binding to reconstruct this record - val fieldVars = fields.map { case Field(fieldName, fieldType) => - ValueVar(Id(fieldName.name), fieldType) - } - val binding = (paramId, tpe, Make(tpe, ctor, List(), fieldVars)) - - (flatParams, allBindings :+ binding) + val binding = (paramId, Make(tpe, ctor, List(), fieldVars)) + (flatParams.flatten, allBindings.flatten :+ binding) case _ => (List(param), List()) } @@ -60,32 +60,16 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val (allParams, allBindings) = flattened.unzip val newBody = allBindings.flatten.foldRight(transform(body)) { - case ((id, tpe, expr), body) => Let(id, tpe, expr, body) + case ((id, expr), body) => Let(id, expr, body) } - - Toplevel.Def(id, BlockLit(tparams, cparams, allParams.flatten, bparams, newBody)) - } - - case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) - - case Toplevel.Val(id, tpe, binding) => Toplevel.Val(id, tpe, transform(binding)) - } - - def transform(block: Block.BlockLit)(using Context, DeclarationContext): Block.BlockLit = block match { - case Block.BlockLit(tparams, cparams, vparams, bparams, body) => - Block.BlockLit(tparams, cparams, vparams, bparams, transform(body)) - } - - def transform(block: Block)(using Context, DeclarationContext): Block = block match { - case Block.BlockVar(id, annotatedTpe, annotatedCapt) => block - case b: Block.BlockLit => transform(b) + + Block.BlockLit(tparams, cparams, allParams.flatten, bparams, newBody) case Block.Unbox(pure) => Block.Unbox(transform(pure)) case Block.New(impl) => block } def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { - - case Stmt.App(callee @ BlockVar(id, BlockType.Function(List(), List(), vparamsTypes, List(), returnTpe), annotatedCapt), targs, vargs, bargs) => + case Stmt.App(callee @ BlockVar(id, BlockType.Function(tparams, cparams, vparamsTypes, bparams, returnTpe), annotatedCapt), targs, vargs, bargs) => def flattenArg(arg: Expr, argType: ValueType): (List[Expr], List[ValueType], List[(Expr, Id, List[ValueParam])]) = argType match { case ValueType.Data(name, targs) => DC.findData(name) match { @@ -115,30 +99,54 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val flattened = (vargs zip vparamsTypes).map { case (arg, tpe) => flattenArg(arg, tpe) } val (allArgs, allTypes, allMatches) = flattened.unzip3 - val newCallee = BlockVar(id, BlockType.Function(List(), List(), allTypes.flatten, List(), returnTpe), annotatedCapt) - val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, bargs) + val newCalleTpe: BlockType.Function = BlockType.Function(tparams, cparams, allTypes.flatten, bparams, returnTpe) + val newCallee = BlockVar(id, newCalleTpe, annotatedCapt) + val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, bargs map transform) allMatches.flatten.foldRight(innerApp) { case ((scrutinee, ctor, params), body) => - Stmt.Match(scrutinee, List((ctor, BlockLit(List(), List(), params, List(), body))), None) - } + val resultTpe = instantiate(newCalleTpe, targs, bargs.map(_.capt)).result + Stmt.Match(scrutinee, resultTpe, List((ctor, BlockLit(List(), List(), params, List(), body))), None) + } + + // Generic case for all other applications: just recurse into arguments / blocks + case Stmt.App(callee, targs, vargs, bargs) => + Stmt.App(callee, targs, vargs map transform, bargs map transform) case Stmt.Def(id, block, rest) => - Stmt.Def(id, transform(block), transform(rest)) - case Stmt.Let(id, tpe, binding, rest) => - Stmt.Let(id, tpe, transform(binding), transform(rest)) + Stmt.Def(id, transform(block), transform(rest)) + case Stmt.Let(id, binding, rest) => + Stmt.Let(id, transform(binding), transform(rest)) case Stmt.Return(expr) => Stmt.Return(transform(expr)) - case Stmt.Val(id, tpe, binding, body) => - Stmt.Val(id, tpe, transform(binding), transform(body)) + case Stmt.Val(id, binding, body) => + Stmt.Val(id, transform(binding), transform(body)) case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) case Stmt.If(cond, thn, els) => Stmt.If(transform(cond), transform(thn), transform(els)) - case Stmt.Match(scrutinee, clauses, default) => - Stmt.Match(transform(scrutinee), clauses.map { case (id, clause) => (id, transform(clause)) }, default map transform) - - case _ => stmt + case Stmt.Match(scrutinee, tpe, clauses, default) => + Stmt.Match(transform(scrutinee), tpe, clauses.map { case (id, BlockLit(tparams, cparams, vparams, bparams, body)) => (id, BlockLit(tparams, cparams, vparams, bparams, transform(body))) }, default map transform) + case Stmt.ImpureApp(callee, ret, targs, vargs, bargs, retCallee) => + Stmt.ImpureApp(callee, ret, targs, vargs map transform, bargs map transform, retCallee) + case Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, body)) => + Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, transform(body))) + case Stmt.Alloc(id, tpe, init, rest) => + Stmt.Alloc(id, tpe, init, transform(rest)) + case Stmt.Var(id, tpe, init, rest) => + Stmt.Var(id, tpe, init, transform(rest)) + case Stmt.Get(id, tpe, region, slot, rest) => + Stmt.Get(id, tpe, region, slot, transform(rest)) + case Stmt.Put(region, slot, value, rest) => + Stmt.Put(region, slot, transform(value), transform(rest)) + case Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, body)) => + Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, transform(body))) + case Stmt.Shift(id, k, body) => + Stmt.Shift(id, k, transform(body)) + case Stmt.Resume(k, value) => + Stmt.Resume(k, transform(value)) + case Stmt.Hole(tpe, span) => + Stmt.Hole(tpe, span) } def transform(pure: Expr)(using Context, DeclarationContext): Expr = pure match { diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/LLVM.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/LLVM.scala index 79c58984ba..a816fee69b 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/LLVM.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/LLVM.scala @@ -7,6 +7,7 @@ import effekt.core.optimizer import effekt.machine import kiama.output.PrettyPrinterTypes.{ Document, emptyLinks } import kiama.util.Source +import effekt.core.ArityRaising class LLVM extends Compiler[String] { @@ -54,7 +55,7 @@ class LLVM extends Compiler[String] { // ----------------------------------- object steps { // intermediate steps for VSCode - val afterCore = allToCore(Core) andThen Aggregate andThen optimizer.Optimizer + val afterCore = allToCore(Core) andThen Aggregate andThen ArityRaising andThen optimizer.Optimizer val afterMachine = afterCore andThen Machine map { case (mod, main, prog) => prog } val afterLLVM = afterMachine map { case machine.Program(decls, defns, entry) => From a505d754612a1074a14c341e49c2c573dfdc3f70 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 8 Dec 2025 11:17:47 +0100 Subject: [PATCH 15/40] renaming --- .../src/main/scala/effekt/core/ArityRaising.scala | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index b4417b7308..57243eba52 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -109,10 +109,8 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Stmt.Match(scrutinee, resultTpe, List((ctor, BlockLit(List(), List(), params, List(), body))), None) } - // Generic case for all other applications: just recurse into arguments / blocks case Stmt.App(callee, targs, vargs, bargs) => Stmt.App(callee, targs, vargs map transform, bargs map transform) - case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, binding, rest) => @@ -135,10 +133,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Stmt.Alloc(id, tpe, init, transform(rest)) case Stmt.Var(id, tpe, init, rest) => Stmt.Var(id, tpe, init, transform(rest)) - case Stmt.Get(id, tpe, region, slot, rest) => - Stmt.Get(id, tpe, region, slot, transform(rest)) - case Stmt.Put(region, slot, value, rest) => - Stmt.Put(region, slot, transform(value), transform(rest)) + case Stmt.Get(id, tpe, region, capt, rest) => + Stmt.Get(id, tpe, region, capt, transform(rest)) + case Stmt.Put(region, capt, value, rest) => + Stmt.Put(region, capt, transform(value), transform(rest)) case Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, body)) => Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, transform(body))) case Stmt.Shift(id, k, body) => From 1d5796544c8032d7d84363cad092f1514f89f5f2 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 9 Dec 2025 17:18:10 +0100 Subject: [PATCH 16/40] HOF working, except for when giving a direct reference --- .../main/scala/effekt/core/ArityRaising.scala | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 57243eba52..174b4b42b5 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -98,6 +98,26 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val flattened = (vargs zip vparamsTypes).map { case (arg, tpe) => flattenArg(arg, tpe) } val (allArgs, allTypes, allMatches) = flattened.unzip3 + + val transformedBargs = bargs.map { barg => + barg match { + // case direct reference here + // transform to lambda and then do the same as below for blocklit + case BlockVar(id, annotatedTpe, annotatedCapt) => + println(barg.tpe) + transform(barg) + + case BlockLit(btparams, bcparams, bvparams, bbparams, body) => + // Keep the signature unchanged + // But recursively transform the body + val transformedBody = transform(body) + println(barg.tpe) + BlockLit(btparams, bcparams, bvparams, bbparams, transformedBody) + + case _ => + transform(barg) + } + } val newCalleTpe: BlockType.Function = BlockType.Function(tparams, cparams, allTypes.flatten, bparams, returnTpe) val newCallee = BlockVar(id, newCalleTpe, annotatedCapt) From a348be943db7891f87a2a2d526a72c4e1b6e4105 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 9 Dec 2025 19:09:41 +0100 Subject: [PATCH 17/40] transformed map{myfunc} to map{t => myfunc{t}) --- .../main/scala/effekt/core/ArityRaising.scala | 25 +++++++++++++++---- 1 file changed, 20 insertions(+), 5 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 174b4b42b5..22c2603592 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -101,17 +101,32 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val transformedBargs = bargs.map { barg => barg match { - // case direct reference here - // transform to lambda and then do the same as below for blocklit + // this handles: + // val res = myList.map {myFunc} + // by making it: + // val res = myList.map {t => myFunc(t)} case BlockVar(id, annotatedTpe, annotatedCapt) => - println(barg.tpe) - transform(barg) + annotatedTpe match { + case BlockType.Function(tparams, cparams, vparams, bparams, result) => + val params = vparams.map { tpe => + // need to fix for propper implementation + val freshId = Id("x_" + scala.util.Random.nextInt()) + (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) + } + val call = Stmt.App(barg, List(), params.map(_._2), List()) + val transformedBody = transform(call) + + // empty List for Bargs should be fine, since myList.map {myFunc} the myFunc cant have any bargs?? + BlockLit(tparams, cparams, params.map(_._1), List(), transformedBody) + + case _ => transform(barg) + } + case BlockLit(btparams, bcparams, bvparams, bbparams, body) => // Keep the signature unchanged // But recursively transform the body val transformedBody = transform(body) - println(barg.tpe) BlockLit(btparams, bcparams, bvparams, bbparams, transformedBody) case _ => From d50e10066c412eb1ea189da5ad873de21daf5260 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 15 Dec 2025 11:34:26 +0100 Subject: [PATCH 18/40] further bargs fixing --- .../main/scala/effekt/core/ArityRaising.scala | 18 ++++++++++++------ project/metals.sbt | 2 +- project/project/metals.sbt | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 22c2603592..acdc6777e8 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -108,16 +108,22 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case BlockVar(id, annotatedTpe, annotatedCapt) => annotatedTpe match { case BlockType.Function(tparams, cparams, vparams, bparams, result) => - val params = vparams.map { tpe => - // need to fix for propper implementation - val freshId = Id("x_" + scala.util.Random.nextInt()) + val types = tparams.map {id => + + } + val values = vparams.map { tpe => + val freshId = Id("x") (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) } - val call = Stmt.App(barg, List(), params.map(_._2), List()) + val blocks = bparams.zip(cparams).map { case (tpe, capt)=> + val freshId = Id("f") + (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) + } + + val call = Stmt.App(barg, List(), values.map(_._2), List()) val transformedBody = transform(call) - // empty List for Bargs should be fine, since myList.map {myFunc} the myFunc cant have any bargs?? - BlockLit(tparams, cparams, params.map(_._1), List(), transformedBody) + BlockLit(tparams, cparams, values.map(_._1), List(), transformedBody) case _ => transform(barg) } diff --git a/project/metals.sbt b/project/metals.sbt index f320ea721a..97e76fdf15 100644 --- a/project/metals.sbt +++ b/project/metals.sbt @@ -4,7 +4,7 @@ // This plugin enables semantic information to be produced by sbt. // It also adds support for debugging using the Debug Adapter Protocol -addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.3") +addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.4") // This plugin adds the BSP debug capability to sbt server. diff --git a/project/project/metals.sbt b/project/project/metals.sbt index 47bad96feb..0571d55559 100644 --- a/project/project/metals.sbt +++ b/project/project/metals.sbt @@ -4,7 +4,7 @@ // This plugin enables semantic information to be produced by sbt. // It also adds support for debugging using the Debug Adapter Protocol -addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.3") +addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.4") // This plugin makes sure that the JDI tools are in the sbt classpath. // JDI tools are used by the debug adapter server. From 3175a2e2aa3c592bee609223de9ecc5551f7fdde Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 15 Dec 2025 13:46:46 +0100 Subject: [PATCH 19/40] still some issues --- .../src/main/scala/effekt/core/ArityRaising.scala | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index acdc6777e8..c45f7869ae 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -30,6 +30,8 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { ModuleDecl(path, includes, declarations, externs, definitions map transform, exports) } + + def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) case Toplevel.Val(id, binding) => Toplevel.Val(id, transform(binding)) @@ -108,10 +110,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case BlockVar(id, annotatedTpe, annotatedCapt) => annotatedTpe match { case BlockType.Function(tparams, cparams, vparams, bparams, result) => - val types = tparams.map {id => - - } - val values = vparams.map { tpe => + val values = vparams.map { tpe => val freshId = Id("x") (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) } @@ -120,10 +119,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) } - val call = Stmt.App(barg, List(), values.map(_._2), List()) - val transformedBody = transform(call) + // Don't transform the call - the BlockVar keeps its original signature + val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) - BlockLit(tparams, cparams, values.map(_._1), List(), transformedBody) + BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), call) case _ => transform(barg) } @@ -142,7 +141,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val newCalleTpe: BlockType.Function = BlockType.Function(tparams, cparams, allTypes.flatten, bparams, returnTpe) val newCallee = BlockVar(id, newCalleTpe, annotatedCapt) - val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, bargs map transform) + val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, transformedBargs) allMatches.flatten.foldRight(innerApp) { case ((scrutinee, ctor, params), body) => From c90155c8064a51d48475c4e4e3e67934b8485798 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Fri, 2 Jan 2026 13:08:10 +0100 Subject: [PATCH 20/40] Prevent endless recursion and added a missing transform --- .../main/scala/effekt/core/ArityRaising.scala | 39 ++++++++++++------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index c45f7869ae..9457aca8df 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -30,8 +30,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { ModuleDecl(path, includes, declarations, externs, definitions map transform, exports) } - - def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) case Toplevel.Val(id, binding) => Toplevel.Val(id, transform(binding)) @@ -49,11 +47,11 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val (params, bindings) = flattenParam(ValueParam(freshId, fieldType)) (params, bindings, ValueVar(freshId, fieldType)) }.unzip3 - + val binding = (paramId, Make(tpe, ctor, List(), fieldVars)) (flatParams.flatten, allBindings.flatten :+ binding) - - case _ => (List(param), List()) + + case _ => (List(param), List()) } case _ => (List(param), List()) } @@ -67,7 +65,11 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Block.BlockLit(tparams, cparams, allParams.flatten, bparams, newBody) case Block.Unbox(pure) => Block.Unbox(transform(pure)) - case Block.New(impl) => block + case Block.New(Implementation(interface, operations)) => + Block.New(Implementation(interface, operations.map { + case Operation(name, tparams, cparams, vparams, bparams, body) => + Operation(name, tparams, cparams, vparams, bparams, transform(body)) + })) } def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { @@ -101,20 +103,32 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val flattened = (vargs zip vparamsTypes).map { case (arg, tpe) => flattenArg(arg, tpe) } val (allArgs, allTypes, allMatches) = flattened.unzip3 + // Helper to check if a type needs flattening + def needsFlattening(tpe: ValueType): Boolean = tpe match { + case ValueType.Data(name, _) => + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(_, List(), _)))) => true + case _ => false + } + case _ => false + } + val transformedBargs = bargs.map { barg => barg match { - // this handles: + // This handles: // val res = myList.map {myFunc} // by making it: // val res = myList.map {t => myFunc(t)} + // but only if the arity of myFunc changes case BlockVar(id, annotatedTpe, annotatedCapt) => annotatedTpe match { - case BlockType.Function(tparams, cparams, vparams, bparams, result) => - val values = vparams.map { tpe => + case BlockType.Function(tparams, cparams, vparams, bparams, result) + if vparams.exists(needsFlattening) => + val values = vparams.map { tpe => val freshId = Id("x") (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) } - val blocks = bparams.zip(cparams).map { case (tpe, capt)=> + val blocks = bparams.zip(cparams).map { case (tpe, capt) => val freshId = Id("f") (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) } @@ -122,12 +136,11 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { // Don't transform the call - the BlockVar keeps its original signature val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) - BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), call) + BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)) case _ => transform(barg) } - case BlockLit(btparams, bcparams, bvparams, bbparams, body) => // Keep the signature unchanged // But recursively transform the body @@ -247,4 +260,4 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { sb.toString } -} \ No newline at end of file +} From 8c51c789a8799c98b4891c259352307e934f3395 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Sun, 11 Jan 2026 15:47:45 +0100 Subject: [PATCH 21/40] llvm working, but reparse breaks --- .../main/scala/effekt/core/ArityRaising.scala | 103 ++++++++++-------- 1 file changed, 60 insertions(+), 43 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 9457aca8df..022c8ac7ee 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -6,6 +6,8 @@ import effekt.typer.Typer.checkMain import effekt.symbols.Symbol.fresh import effekt.lexer.TokenKind import effekt.core.Type.instantiate +import effekt.generator.llvm.Transformer.BlockContext +import effekt.machine.Transformer.BlocksParamsContext object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { override val phaseName: String = "arity raising" @@ -31,19 +33,21 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } def transform(toplevel: Toplevel)(using C: Context, DC: DeclarationContext): Toplevel = toplevel match { - case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)) - case Toplevel.Val(id, binding) => Toplevel.Val(id, transform(binding)) + case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)(using C, DC, Set.empty)) + case Toplevel.Val(id, binding) => Toplevel.Val(id, transform(binding)(using C, DC, Set.empty)) } - def transform(block: Block)(using C: Context, DC: DeclarationContext): Block = block match { + def transform(block: Block)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Block = block match { case Block.BlockVar(id, annotatedTpe, annotatedCapt) => block case Block.BlockLit(tparams, cparams, vparams, bparams, body) => + // Add bparams to the set of bargs for the body + val newBargs = bargs ++ bparams.map(_.id) def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, Expr)]) = param match { case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => val (flatParams, allBindings, fieldVars) = fields.map { case Field(fieldName, fieldType) => - val freshId = Id(fieldName.name) + val freshId = Id(fieldName) val (params, bindings) = flattenParam(ValueParam(freshId, fieldType)) (params, bindings, ValueVar(freshId, fieldType)) }.unzip3 @@ -59,7 +63,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val flattened = vparams.map(flattenParam) val (allParams, allBindings) = flattened.unzip - val newBody = allBindings.flatten.foldRight(transform(body)) { + val newBody = allBindings.flatten.foldRight(transform(body)(using C, DC, newBargs)) { case ((id, expr), body) => Let(id, expr, body) } @@ -67,19 +71,22 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Block.Unbox(pure) => Block.Unbox(transform(pure)) case Block.New(Implementation(interface, operations)) => Block.New(Implementation(interface, operations.map { - case Operation(name, tparams, cparams, vparams, bparams, body) => - Operation(name, tparams, cparams, vparams, bparams, transform(body)) + case Operation(name, tparams, cparams, vparams, bparams, body) => + val opBargs = bargs ++ bparams.map(_.id) + Operation(name, tparams, cparams, vparams, bparams, transform(body)(using C, DC, opBargs)) })) } - def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext): Stmt = stmt match { - case Stmt.App(callee @ BlockVar(id, BlockType.Function(tparams, cparams, vparamsTypes, bparams, returnTpe), annotatedCapt), targs, vargs, bargs) => + def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Stmt = stmt match { + // Only arity-raise if the callee is NOT a barg + case Stmt.App(callee @ BlockVar(id, BlockType.Function(tparams, cparams, vparamsTypes, bparamTypes, returnTpe), annotatedCapt), targs, vargs, appBargs) + if !bargs.contains(id) => def flattenArg(arg: Expr, argType: ValueType): (List[Expr], List[ValueType], List[(Expr, Id, List[ValueParam])]) = argType match { case ValueType.Data(name, targs) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => val fieldInfo = fields.map { case Field(fieldName, fieldType) => - val freshId = Id(fieldName.name) + val freshId = Id(fieldName) val freshVar = ValueVar(freshId, fieldType) val freshParam = ValueParam(freshId, fieldType) @@ -113,7 +120,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case _ => false } - val transformedBargs = bargs.map { barg => + val transformedBargs = appBargs.map { barg => barg match { // This handles: // val res = myList.map {myFunc} @@ -122,29 +129,32 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { // but only if the arity of myFunc changes case BlockVar(id, annotatedTpe, annotatedCapt) => annotatedTpe match { - case BlockType.Function(tparams, cparams, vparams, bparams, result) + case BlockType.Function(tparams, cparams, vparams, bparamTpes, result) if vparams.exists(needsFlattening) => val values = vparams.map { tpe => val freshId = Id("x") (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) } - val blocks = bparams.zip(cparams).map { case (tpe, capt) => + val blocks = bparamTpes.zip(cparams).map { case (tpe, capt) => val freshId = Id("f") (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) } // Don't transform the call - the BlockVar keeps its original signature val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) - - BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)) + + // Add the new block params to bargs when transforming the call + val wrapperBargs = bargs ++ blocks.map(_._1.id) + BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, wrapperBargs)) case _ => transform(barg) } case BlockLit(btparams, bcparams, bvparams, bbparams, body) => // Keep the signature unchanged - // But recursively transform the body - val transformedBody = transform(body) + // But recursively transform the body, adding bbparams to bargs + val litBargs = bargs ++ bbparams.map(_.id) + val transformedBody = transform(body)(using C, DC, litBargs) BlockLit(btparams, bcparams, bvparams, bbparams, transformedBody) case _ => @@ -152,18 +162,18 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } } - val newCalleTpe: BlockType.Function = BlockType.Function(tparams, cparams, allTypes.flatten, bparams, returnTpe) + val newCalleTpe: BlockType.Function = BlockType.Function(tparams, cparams, allTypes.flatten, bparamTypes, returnTpe) val newCallee = BlockVar(id, newCalleTpe, annotatedCapt) val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, transformedBargs) allMatches.flatten.foldRight(innerApp) { case ((scrutinee, ctor, params), body) => - val resultTpe = instantiate(newCalleTpe, targs, bargs.map(_.capt)).result + val resultTpe = instantiate(newCalleTpe, targs, appBargs.map(_.capt)).result Stmt.Match(scrutinee, resultTpe, List((ctor, BlockLit(List(), List(), params, List(), body))), None) } - case Stmt.App(callee, targs, vargs, bargs) => - Stmt.App(callee, targs, vargs map transform, bargs map transform) + case Stmt.App(callee, targs, vargs, appBargs) => + Stmt.App(callee, targs, vargs map transform, appBargs map transform) case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, binding, rest) => @@ -172,45 +182,52 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Stmt.Return(transform(expr)) case Stmt.Val(id, binding, body) => Stmt.Val(id, transform(binding), transform(body)) - case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => - Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) + case Stmt.Invoke(callee, method, methodTpe, targs, vargs, invokeBargs) => + Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, invokeBargs map transform) case Stmt.If(cond, thn, els) => Stmt.If(transform(cond), transform(thn), transform(els)) case Stmt.Match(scrutinee, tpe, clauses, default) => - Stmt.Match(transform(scrutinee), tpe, clauses.map { case (id, BlockLit(tparams, cparams, vparams, bparams, body)) => (id, BlockLit(tparams, cparams, vparams, bparams, transform(body))) }, default map transform) - case Stmt.ImpureApp(callee, ret, targs, vargs, bargs, retCallee) => - Stmt.ImpureApp(callee, ret, targs, vargs map transform, bargs map transform, retCallee) + Stmt.Match(transform(scrutinee), tpe, clauses.map { case (id, BlockLit(tparams, cparams, vparams, bparams, body)) => + val clauseBargs = bargs ++ bparams.map(_.id) + (id, BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, clauseBargs))) + }, default map transform) + case Stmt.ImpureApp(id, callee, targs, vargs, impureBargs, body) => + Stmt.ImpureApp(id, callee, targs, vargs map transform, impureBargs map transform, transform(body)) case Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, body)) => - Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, transform(body))) - case Stmt.Alloc(id, tpe, init, rest) => - Stmt.Alloc(id, tpe, init, transform(rest)) - case Stmt.Var(id, tpe, init, rest) => - Stmt.Var(id, tpe, init, transform(rest)) - case Stmt.Get(id, tpe, region, capt, rest) => - Stmt.Get(id, tpe, region, capt, transform(rest)) - case Stmt.Put(region, capt, value, rest) => - Stmt.Put(region, capt, transform(value), transform(rest)) + val regionBargs = bargs ++ bparams.map(_.id) + Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, regionBargs))) + case Stmt.Alloc(id, init, region, body) => + Stmt.Alloc(id, transform(init), region, transform(body)) + case Stmt.Var(ref, init, capture, body) => + Stmt.Var(ref, transform(init), capture, transform(body)) + case Stmt.Get(id, annotatedTpe, ref, annotatedCapt, body) => + Stmt.Get(id, annotatedTpe, ref, annotatedCapt, transform(body)) + case Stmt.Put(ref, annotatedCapt, value, body) => + Stmt.Put(ref, annotatedCapt, transform(value), transform(body)) case Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, body)) => - Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, transform(body))) - case Stmt.Shift(id, k, body) => - Stmt.Shift(id, k, transform(body)) - case Stmt.Resume(k, value) => - Stmt.Resume(k, transform(value)) + val resetBargs = bargs ++ bparams.map(_.id) + Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, resetBargs))) + case Stmt.Shift(prompt, k, body) => + // k is a continuation (block param), so add it to bargs + val shiftBargs = bargs + k.id + Stmt.Shift(prompt, k, transform(body)(using C, DC, shiftBargs)) + case Stmt.Resume(k, body) => + Stmt.Resume(k, transform(body)) case Stmt.Hole(tpe, span) => Stmt.Hole(tpe, span) } - def transform(pure: Expr)(using Context, DeclarationContext): Expr = pure match { + def transform(pure: Expr)(using C: Context, DC: DeclarationContext, bargIds: Set[Id]): Expr = pure match { case Expr.ValueVar(id, annotatedType) => pure case Expr.Literal(value, annotatedType) => pure - case Expr.Box(b, annotatedCapture) => pure + case Expr.Box(b, annotatedCapture) => Expr.Box(transform(b), annotatedCapture) case Expr.PureApp(b, targs, vargs) => Expr.PureApp(b, targs, vargs map transform) case Expr.Make(data, tag, targs, vargs) => Expr.Make(data, tag, targs, vargs map transform) } - def transform(valueType: ValueType.Data)(using Context, DeclarationContext): ValueType.Data = valueType match { + def transform(valueType: ValueType.Data)(using C: Context, DC: DeclarationContext): ValueType.Data = valueType match { case ValueType.Data(symbol, targs) => valueType // trainsform } From a9333392f9620605efe1038f077c94baf21de05c Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 12 Jan 2026 10:51:31 +0100 Subject: [PATCH 22/40] one more transform that might is necesarry --- effekt/shared/src/main/scala/effekt/core/ArityRaising.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 022c8ac7ee..7f99d5e665 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -173,7 +173,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } case Stmt.App(callee, targs, vargs, appBargs) => - Stmt.App(callee, targs, vargs map transform, appBargs map transform) + Stmt.App(transform(callee), targs, vargs map transform, appBargs map transform) case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, binding, rest) => From 7836a0cbc2a1c2041589a981f5a8c064f68c2758 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 12 Jan 2026 15:21:25 +0100 Subject: [PATCH 23/40] Fixing last error in llvm tests --- .../main/scala/effekt/core/ArityRaising.scala | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 7f99d5e665..9e904200e3 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -40,7 +40,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { def transform(block: Block)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Block = block match { case Block.BlockVar(id, annotatedTpe, annotatedCapt) => block case Block.BlockLit(tparams, cparams, vparams, bparams, body) => - // Add bparams to the set of bargs for the body val newBargs = bargs ++ bparams.map(_.id) def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, Expr)]) = param match { case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => @@ -76,9 +75,17 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Operation(name, tparams, cparams, vparams, bparams, transform(body)(using C, DC, opBargs)) })) } +// Helper to check if a type needs flattening + def needsFlattening(tpe: ValueType)(using DC:DeclarationContext): Boolean = tpe match { + case ValueType.Data(name, _) => + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(_, List(), _)))) => true + case _ => false + } + case _ => false + } def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Stmt = stmt match { - // Only arity-raise if the callee is NOT a barg case Stmt.App(callee @ BlockVar(id, BlockType.Function(tparams, cparams, vparamsTypes, bparamTypes, returnTpe), annotatedCapt), targs, vargs, appBargs) if !bargs.contains(id) => def flattenArg(arg: Expr, argType: ValueType): (List[Expr], List[ValueType], List[(Expr, Id, List[ValueParam])]) = argType match { @@ -110,15 +117,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val flattened = (vargs zip vparamsTypes).map { case (arg, tpe) => flattenArg(arg, tpe) } val (allArgs, allTypes, allMatches) = flattened.unzip3 - // Helper to check if a type needs flattening - def needsFlattening(tpe: ValueType): Boolean = tpe match { - case ValueType.Data(name, _) => - DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(_, List(), _)))) => true - case _ => false - } - case _ => false - } + val transformedBargs = appBargs.map { barg => barg match { @@ -143,7 +142,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { // Don't transform the call - the BlockVar keeps its original signature val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) - // Add the new block params to bargs when transforming the call val wrapperBargs = bargs ++ blocks.map(_._1.id) BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, wrapperBargs)) @@ -152,7 +150,6 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case BlockLit(btparams, bcparams, bvparams, bbparams, body) => // Keep the signature unchanged - // But recursively transform the body, adding bbparams to bargs val litBargs = bargs ++ bbparams.map(_.id) val transformedBody = transform(body)(using C, DC, litBargs) BlockLit(btparams, bcparams, bvparams, bbparams, transformedBody) @@ -173,7 +170,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { } case Stmt.App(callee, targs, vargs, appBargs) => - Stmt.App(transform(callee), targs, vargs map transform, appBargs map transform) + Stmt.App(callee, targs, vargs map transform, appBargs map transform) case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) case Stmt.Let(id, binding, rest) => @@ -217,9 +214,31 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { Stmt.Hole(tpe, span) } - def transform(pure: Expr)(using C: Context, DC: DeclarationContext, bargIds: Set[Id]): Expr = pure match { + def transform(pure: Expr)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Expr = pure match { case Expr.ValueVar(id, annotatedType) => pure case Expr.Literal(value, annotatedType) => pure + case Expr.Box(barg @ BlockVar(id, annotatedTpe, annotatedCapt), annotatedCapture) => + annotatedTpe match { + case BlockType.Function(tparams, cparams, vparams, bparamTpes, result) + if vparams.exists(needsFlattening) => + val values = vparams.map { tpe => + val freshId = Id("x") + (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) + } + val blocks = bparamTpes.zip(cparams).map { case (tpe, capt) => + val freshId = Id("f") + (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) + } + + // Don't transform the call - the BlockVar keeps its original signature + val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) + + val wrapperBargs = bargs ++ blocks.map(_._1.id) + Expr.Box(BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, wrapperBargs)), annotatedCapture) + + case _ => Expr.Box(transform(barg), annotatedCapture) + } + case Expr.Box(b, annotatedCapture) => Expr.Box(transform(b), annotatedCapture) case Expr.PureApp(b, targs, vargs) => Expr.PureApp(b, targs, vargs map transform) From 20fc2e069b1dc97fbf4669b8c1076c75fce0ca14 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 12 Jan 2026 16:31:38 +0100 Subject: [PATCH 24/40] Refactoring for ease of readabilit, formating and removing unneeded code. --- .../main/scala/effekt/core/ArityRaising.scala | 271 +++++++----------- 1 file changed, 100 insertions(+), 171 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index 9e904200e3..ce27d374f3 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -13,18 +13,13 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { override val phaseName: String = "arity raising" override def run(input: CoreTransformed)(using C: Context): Option[CoreTransformed] = input match { - case CoreTransformed(source, tree, mod, core) => { + case CoreTransformed(source, tree, mod, core) => implicit val pctx: DeclarationContext = new DeclarationContext(core.declarations, core.externs) Context.module = mod val main = C.ensureMainExists(mod) val res = Deadcode.remove(main, core) - // println("Before") - // println(PrettyPrinter.format(res)) val transformed = Context.timed(phaseName, source.name) { transform(res) } - // println("\n\n\n\nhello") - // println(PrettyPrinter.format(transformed)) Some(CoreTransformed(source, tree, mod, transformed)) - } } def transform(decl: ModuleDecl)(using Context, DeclarationContext): ModuleDecl = decl match { @@ -36,11 +31,10 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Toplevel.Def(id, block) => Toplevel.Def(id, transform(block)(using C, DC, Set.empty)) case Toplevel.Val(id, binding) => Toplevel.Val(id, transform(binding)(using C, DC, Set.empty)) } - - def transform(block: Block)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Block = block match { + + def transform(block: Block)(using C: Context, DC: DeclarationContext, boundBlockParams: Set[Id]): Block = block match { case Block.BlockVar(id, annotatedTpe, annotatedCapt) => block case Block.BlockLit(tparams, cparams, vparams, bparams, body) => - val newBargs = bargs ++ bparams.map(_.id) def flattenParam(param: ValueParam): (List[ValueParam], List[(Id, Expr)]) = param match { case ValueParam(paramId, tpe @ ValueType.Data(name, targs)) => DC.findData(name) match { @@ -53,62 +47,70 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val binding = (paramId, Make(tpe, ctor, List(), fieldVars)) (flatParams.flatten, allBindings.flatten :+ binding) - - case _ => (List(param), List()) + + case _ => (List(param), List()) } case _ => (List(param), List()) } val flattened = vparams.map(flattenParam) val (allParams, allBindings) = flattened.unzip - - val newBody = allBindings.flatten.foldRight(transform(body)(using C, DC, newBargs)) { + + val newBody = allBindings.flatten.foldRight(transform(body)(using C, DC, boundBlockParams ++ bparams.map(_.id))) { case ((id, expr), body) => Let(id, expr, body) } - - Block.BlockLit(tparams, cparams, allParams.flatten, bparams, newBody) - case Block.Unbox(pure) => Block.Unbox(transform(pure)) - case Block.New(Implementation(interface, operations)) => + + Block.BlockLit(tparams, cparams, allParams.flatten, bparams, newBody) + + case Block.Unbox(pure) => + Block.Unbox(transform(pure)) + + case Block.New(Implementation(interface, operations)) => Block.New(Implementation(interface, operations.map { case Operation(name, tparams, cparams, vparams, bparams, body) => - val opBargs = bargs ++ bparams.map(_.id) - Operation(name, tparams, cparams, vparams, bparams, transform(body)(using C, DC, opBargs)) - })) + Operation(name, tparams, cparams, vparams, bparams, transform(body)(using C, DC, boundBlockParams ++ bparams.map(_.id))) + })) } -// Helper to check if a type needs flattening - def needsFlattening(tpe: ValueType)(using DC:DeclarationContext): Boolean = tpe match { - case ValueType.Data(name, _) => - DC.findData(name) match { - case Some(Data(_, List(), List(Constructor(_, List(), _)))) => true - case _ => false - } + + // Helper to check if a type needs flattening + def needsFlattening(tpe: ValueType)(using DC: DeclarationContext): Boolean = tpe match { + case ValueType.Data(name, _) => + DC.findData(name) match { + case Some(Data(_, List(), List(Constructor(_, List(), _)))) => true case _ => false } + case _ => false + } + + def wrapBlockVarIfNeeded(barg: BlockVar, annotatedTpe: BlockType)(using C: Context, DC: DeclarationContext, boundBlockParams: Set[Id]): Block = + annotatedTpe match { + case BlockType.Function(tparams, cparams, vparams, bparamTpes, result) if vparams.exists(needsFlattening) => + val values = vparams.map { tpe => + val freshId = Id("x") + (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) + } + val blocks = bparamTpes.zip(cparams).map { case (tpe, capt) => + val freshId = Id("f") + (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) + } + val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) + BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, boundBlockParams ++ blocks.map(_._1.id))) - def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Stmt = stmt match { - case Stmt.App(callee @ BlockVar(id, BlockType.Function(tparams, cparams, vparamsTypes, bparamTypes, returnTpe), annotatedCapt), targs, vargs, appBargs) - if !bargs.contains(id) => + case _ => transform(barg) + } + + def transform(stmt: Stmt)(using C: Context, DC: DeclarationContext, boundBlockParams: Set[Id]): Stmt = stmt match { + case Stmt.App(callee @ BlockVar(id, BlockType.Function(tparams, cparams, vparamsTypes, bparamTypes, returnTpe), annotatedCapt), targs, vargs, bargs) if !boundBlockParams.contains(id) => def flattenArg(arg: Expr, argType: ValueType): (List[Expr], List[ValueType], List[(Expr, Id, List[ValueParam])]) = argType match { case ValueType.Data(name, targs) => DC.findData(name) match { case Some(Data(_, List(), List(Constructor(ctor, List(), fields)))) => - val fieldInfo = fields.map { case Field(fieldName, fieldType) => - val freshId = Id(fieldName) - val freshVar = ValueVar(freshId, fieldType) - val freshParam = ValueParam(freshId, fieldType) - - val (nestedVars, nestedTypes, nestedMatches) = flattenArg(freshVar, fieldType) - (freshVar, freshParam, fieldType, nestedVars, nestedTypes, nestedMatches) - } - - val vars = fieldInfo.flatMap(_._4) - val types = fieldInfo.flatMap(_._5) - val params = fieldInfo.map(_._2) - val nestedMatches = fieldInfo.flatMap(_._6) - val thisMatch = (arg, ctor, params) - - (vars, types, thisMatch :: nestedMatches) - + val fieldParams = fields.map { case Field(name, tpe) => ValueParam(Id(name), tpe) } + val nestedResults = fieldParams.map { param => flattenArg(ValueVar(param.id, param.tpe), param.tpe) } + val (nestedVars, nestedTypes, nestedMatches) = nestedResults.unzip3 + val thisMatch = (arg, ctor, fieldParams) + (nestedVars.flatten, nestedTypes.flatten, thisMatch :: nestedMatches.flatten) + case _ => (List(arg), List(argType), List()) } case _ => (List(arg), List(argType), List()) @@ -117,183 +119,110 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val flattened = (vargs zip vparamsTypes).map { case (arg, tpe) => flattenArg(arg, tpe) } val (allArgs, allTypes, allMatches) = flattened.unzip3 - - - val transformedBargs = appBargs.map { barg => + val transformedBargs = bargs.map { barg => barg match { - // This handles: - // val res = myList.map {myFunc} + // This handles: + // val res = myList.map {myFunc} // by making it: // val res = myList.map {t => myFunc(t)} // but only if the arity of myFunc changes - case BlockVar(id, annotatedTpe, annotatedCapt) => - annotatedTpe match { - case BlockType.Function(tparams, cparams, vparams, bparamTpes, result) - if vparams.exists(needsFlattening) => - val values = vparams.map { tpe => - val freshId = Id("x") - (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) - } - val blocks = bparamTpes.zip(cparams).map { case (tpe, capt) => - val freshId = Id("f") - (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) - } - - // Don't transform the call - the BlockVar keeps its original signature - val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) - - val wrapperBargs = bargs ++ blocks.map(_._1.id) - BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, wrapperBargs)) - - case _ => transform(barg) - } + case bvar @ BlockVar(id, annotatedTpe, annotatedCapt) => + wrapBlockVarIfNeeded(bvar, annotatedTpe) case BlockLit(btparams, bcparams, bvparams, bbparams, body) => - // Keep the signature unchanged - val litBargs = bargs ++ bbparams.map(_.id) - val transformedBody = transform(body)(using C, DC, litBargs) - BlockLit(btparams, bcparams, bvparams, bbparams, transformedBody) - - case _ => + BlockLit(btparams, bcparams, bvparams, bbparams, transform(body)(using C, DC, boundBlockParams ++ bbparams.map(_.id))) + + case _ => transform(barg) } } - + val newCalleTpe: BlockType.Function = BlockType.Function(tparams, cparams, allTypes.flatten, bparamTypes, returnTpe) val newCallee = BlockVar(id, newCalleTpe, annotatedCapt) val innerApp = Stmt.App(newCallee, targs, allArgs.flatten, transformedBargs) - + allMatches.flatten.foldRight(innerApp) { case ((scrutinee, ctor, params), body) => - val resultTpe = instantiate(newCalleTpe, targs, appBargs.map(_.capt)).result + val resultTpe = instantiate(newCalleTpe, targs, bargs.map(_.capt)).result Stmt.Match(scrutinee, resultTpe, List((ctor, BlockLit(List(), List(), params, List(), body))), None) } - case Stmt.App(callee, targs, vargs, appBargs) => - Stmt.App(callee, targs, vargs map transform, appBargs map transform) + case Stmt.App(callee, targs, vargs, bargs) => + Stmt.App(callee, targs, vargs map transform, bargs map transform) + case Stmt.Def(id, block, rest) => Stmt.Def(id, transform(block), transform(rest)) + case Stmt.Let(id, binding, rest) => Stmt.Let(id, transform(binding), transform(rest)) + case Stmt.Return(expr) => Stmt.Return(transform(expr)) + case Stmt.Val(id, binding, body) => Stmt.Val(id, transform(binding), transform(body)) - case Stmt.Invoke(callee, method, methodTpe, targs, vargs, invokeBargs) => - Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, invokeBargs map transform) + + case Stmt.Invoke(callee, method, methodTpe, targs, vargs, bargs) => + Stmt.Invoke(transform(callee), method, methodTpe, targs, vargs map transform, bargs map transform) + case Stmt.If(cond, thn, els) => Stmt.If(transform(cond), transform(thn), transform(els)) case Stmt.Match(scrutinee, tpe, clauses, default) => Stmt.Match(transform(scrutinee), tpe, clauses.map { case (id, BlockLit(tparams, cparams, vparams, bparams, body)) => - val clauseBargs = bargs ++ bparams.map(_.id) - (id, BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, clauseBargs))) + (id, BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, boundBlockParams ++ bparams.map(_.id)))) }, default map transform) - case Stmt.ImpureApp(id, callee, targs, vargs, impureBargs, body) => - Stmt.ImpureApp(id, callee, targs, vargs map transform, impureBargs map transform, transform(body)) + + case Stmt.ImpureApp(id, callee, targs, vargs, bargs, body) => + Stmt.ImpureApp(id, callee, targs, vargs map transform, bargs map transform, transform(body)) + case Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, body)) => - val regionBargs = bargs ++ bparams.map(_.id) - Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, regionBargs))) + Stmt.Region(BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, boundBlockParams ++ bparams.map(_.id)))) + case Stmt.Alloc(id, init, region, body) => Stmt.Alloc(id, transform(init), region, transform(body)) + case Stmt.Var(ref, init, capture, body) => Stmt.Var(ref, transform(init), capture, transform(body)) + case Stmt.Get(id, annotatedTpe, ref, annotatedCapt, body) => Stmt.Get(id, annotatedTpe, ref, annotatedCapt, transform(body)) + case Stmt.Put(ref, annotatedCapt, value, body) => Stmt.Put(ref, annotatedCapt, transform(value), transform(body)) + case Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, body)) => - val resetBargs = bargs ++ bparams.map(_.id) - Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, resetBargs))) + Stmt.Reset(BlockLit(tparams, cparams, vparams, bparams, transform(body)(using C, DC, boundBlockParams ++ bparams.map(_.id)))) + case Stmt.Shift(prompt, k, body) => - // k is a continuation (block param), so add it to bargs - val shiftBargs = bargs + k.id - Stmt.Shift(prompt, k, transform(body)(using C, DC, shiftBargs)) + // k is a continuation (block param), so add it to boundBlockParams + Stmt.Shift(prompt, k, transform(body)(using C, DC, boundBlockParams + k.id)) + case Stmt.Resume(k, body) => Stmt.Resume(k, transform(body)) + case Stmt.Hole(tpe, span) => Stmt.Hole(tpe, span) } - def transform(pure: Expr)(using C: Context, DC: DeclarationContext, bargs: Set[Id]): Expr = pure match { + def transform(pure: Expr)(using C: Context, DC: DeclarationContext, boundBlockParams: Set[Id]): Expr = pure match { case Expr.ValueVar(id, annotatedType) => pure - case Expr.Literal(value, annotatedType) => pure - case Expr.Box(barg @ BlockVar(id, annotatedTpe, annotatedCapt), annotatedCapture) => - annotatedTpe match { - case BlockType.Function(tparams, cparams, vparams, bparamTpes, result) - if vparams.exists(needsFlattening) => - val values = vparams.map { tpe => - val freshId = Id("x") - (ValueParam(freshId, tpe), ValueVar(freshId, tpe)) - } - val blocks = bparamTpes.zip(cparams).map { case (tpe, capt) => - val freshId = Id("f") - (BlockParam(freshId, tpe, Set(capt)), BlockVar(freshId, tpe, Set(capt))) - } - - // Don't transform the call - the BlockVar keeps its original signature - val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) - - val wrapperBargs = bargs ++ blocks.map(_._1.id) - Expr.Box(BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, wrapperBargs)), annotatedCapture) - - case _ => Expr.Box(transform(barg), annotatedCapture) - } - - case Expr.Box(b, annotatedCapture) => Expr.Box(transform(b), annotatedCapture) - case Expr.PureApp(b, targs, vargs) => - Expr.PureApp(b, targs, vargs map transform) - case Expr.Make(data, tag, targs, vargs) => - Expr.Make(data, tag, targs, vargs map transform) - } - def transform(valueType: ValueType.Data)(using C: Context, DC: DeclarationContext): ValueType.Data = valueType match { - case ValueType.Data(symbol, targs) => valueType // trainsform - } - - def doIndentation(input: String): String = { - val sb = new StringBuilder - var indent = 0 - var i = 0 - - while (i < input.length) { - input(i) match { - case '(' => - // Look ahead to see if it's a short List(...) with no commas - val closing = input.indexOf(')', i) - val inside = if (closing > i) input.substring(i + 1, closing) else "" - if (inside.contains(',') || inside.contains('(') || inside.contains(')')) { - sb.append("(\n") - indent += 1 - sb.append(" " * indent) - } else { - sb.append('(') - } - - case ')' => - val prev = if (i > 0) input(i - 1) else ' ' - if (prev == '(' || prev.isLetterOrDigit) { - sb.append(')') - } else { - sb.append("\n") - indent -= 1 - sb.append(" " * indent) - sb.append(")") - } + case Expr.Literal(value, annotatedType) => pure - case ',' => - sb.append(",\n") - sb.append(" " * indent) + case Expr.Box(bvar @ BlockVar(id, annotatedTpe, annotatedCapt), annotatedCapture) => + Expr.Box(wrapBlockVarIfNeeded(bvar, annotatedTpe), annotatedCapture) - case c if c.isWhitespace => - // skip + case Expr.Box(b, annotatedCapture) => + Expr.Box(transform(b), annotatedCapture) - case c => - sb.append(c) - } - i += 1 - } + case Expr.PureApp(b, targs, vargs) => + Expr.PureApp(b, targs, vargs map transform) - sb.toString + case Expr.Make(data, tag, targs, vargs) => + Expr.Make(data, tag, targs, vargs map transform) } + def transform(valueType: ValueType.Data)(using C: Context, DC: DeclarationContext): ValueType.Data = valueType match { + case ValueType.Data(symbol, targs) => valueType + } } From dca12213157d578ac9a00680efab36d52616cdd0 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 10:45:31 +0100 Subject: [PATCH 25/40] performancegit add effekt/ --- effekt/shared/src/main/scala/effekt/core/ArityRaising.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala index ce27d374f3..38664eeca3 100644 --- a/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala +++ b/effekt/shared/src/main/scala/effekt/core/ArityRaising.scala @@ -96,6 +96,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { val call = Stmt.App(barg, List(), values.map(_._2), blocks.map(_._2)) BlockLit(tparams, cparams, values.map(_._1), blocks.map(_._1), transform(call)(using C, DC, boundBlockParams ++ blocks.map(_._1.id))) + case _ => transform(barg) } @@ -126,7 +127,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { // by making it: // val res = myList.map {t => myFunc(t)} // but only if the arity of myFunc changes - case bvar @ BlockVar(id, annotatedTpe, annotatedCapt) => + case bvar @ BlockVar(id, annotatedTpe, annotatedCapt) if !boundBlockParams.contains(id) => wrapBlockVarIfNeeded(bvar, annotatedTpe) case BlockLit(btparams, bcparams, bvparams, bbparams, body) => @@ -209,7 +210,7 @@ object ArityRaising extends Phase[CoreTransformed, CoreTransformed] { case Expr.Literal(value, annotatedType) => pure - case Expr.Box(bvar @ BlockVar(id, annotatedTpe, annotatedCapt), annotatedCapture) => + case Expr.Box(bvar @ BlockVar(id, annotatedTpe, annotatedCapt), annotatedCapture) if !boundBlockParams.contains(id) => Expr.Box(wrapBlockVarIfNeeded(bvar, annotatedTpe), annotatedCapture) case Expr.Box(b, annotatedCapture) => From 4c579f10ec23fb9fcd3f754c068722fb5e4a4992 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 12:08:05 +0100 Subject: [PATCH 26/40] benchmark file --- benchmark-compare.sh | 225 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100755 benchmark-compare.sh diff --git a/benchmark-compare.sh b/benchmark-compare.sh new file mode 100755 index 0000000000..dae46fe3bb --- /dev/null +++ b/benchmark-compare.sh @@ -0,0 +1,225 @@ +#!/bin/bash + +# Benchmark comparison script for Effekt +# Compares current branch against main branch + +set -e + +# Parse command-line arguments +SKIP_COMPILE=0 +while [[ $# -gt 0 ]]; do + case $1 in + --skip-compile) + SKIP_COMPILE=1 + shift + ;; + *) + echo "Unknown option: $1" + echo "Usage: $0 [--skip-compile]" + exit 1 + ;; + esac +done + +# Configuration (hardcoded) +BACKENDS=("llvm") +WARMUP=5 +RUNS=50 +TARGET_BRANCH="main" +OUTPUT_DIR="benchmark-results" +TIMESTAMP=$(date +%Y%m%d_%H%M%S) +CURRENT_BRANCH=$(git branch --show-current) +CURRENT_BRANCH_SAFE="${CURRENT_BRANCH//\//-}" + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' + +if ! command -v hyperfine &> /dev/null; then + echo "Error: hyperfine is not installed" + exit 1 +fi + +# Stash any uncommitted changes +if ! git diff-index --quiet HEAD --; then + echo -e "${YELLOW}Stashing uncommitted changes...${NC}" + git stash push -m "benchmark-compare temporary stash" + STASHED=1 +else + STASHED=0 +fi + +# Check if we're on main branch +if [ "$CURRENT_BRANCH" = "$TARGET_BRANCH" ]; then + echo "Error: You are currently on the $TARGET_BRANCH branch" + echo "Please switch to your feature branch first" + exit 1 +fi + +mkdir -p "$OUTPUT_DIR" + +# Define benchmarks with their parameters +declare -A BENCHMARKS=( + ["arity_raising/record_addition"]="5000000" + ["arity_raising/nested_records"]="2500000" + ["arity_raising/record_map"]="10000" + ["are_we_fast_yet/bounce"]="100000" + ["are_we_fast_yet/list_tail"]="100" + ["are_we_fast_yet/mandelbrot"]="1000" + ["are_we_fast_yet/nbody"]="50000" + ["are_we_fast_yet/permute"]="10" + ["are_we_fast_yet/queens"]="20" + ["are_we_fast_yet/sieve"]="10000000" + ["are_we_fast_yet/storage"]="5000" + ["are_we_fast_yet/towers"]="25" + ["duality_of_compilation/erase_unused"]="10000" + ["duality_of_compilation/factorial_accumulator"]="500000000" + ["# duality_of_compilation/fibonacci_recursive"]="42" + ["duality_of_compilation/iterate_increment"]="500000000" + ["duality_of_compilation/lookup_tree"]="10000000" + ["duality_of_compilation/match_options"]="10000000" + ["duality_of_compilation/sum_range"]="5000000" + ["effect_handlers_bench/countdown"]="100000000" + ["effect_handlers_bench/iterator"]="100000000" + ["effect_handlers_bench/nqueens"]="10" + ["effect_handlers_bench/parsing_dollars"]="10000" + ["effect_handlers_bench/product_early"]="100000" + ["effect_handlers_bench/resume_nontail"]="100000" + ["effect_handlers_bench/tree_explore"]="14" + ["effect_handlers_bench/triples"]="100" + ["input_output/large_file"]="60000" + ["input_output/small_files"]="20000" + ["input_output/interleave_promises"]="300" + ["input_output/word_count_ascii"]="20000" + ["input_output/word_count_utf8"]="80000" + ["input_output/dyck_one"]="3000" + ["input_output/number_matrix"]="2000" + ["input_output/financial_format"]="200000" +) + +echo -e "${BLUE}Comparing: $CURRENT_BRANCH vs $TARGET_BRANCH${NC}" +echo "Backends: ${BACKENDS[*]}" +echo "Runs: $RUNS, Warmup: $WARMUP" +echo "Skip compilation: $([ $SKIP_COMPILE -eq 1 ] && echo 'yes' || echo 'no')" +echo "" + +# Create output directories +for backend in "${BACKENDS[@]}"; do + OUT_CURRENT="out-${CURRENT_BRANCH_SAFE}-${backend}" + OUT_MAIN="out-main-${backend}" + mkdir -p "$OUT_CURRENT" "$OUT_MAIN" +done + +if [ $SKIP_COMPILE -eq 0 ]; then + # Build compiler and compile benchmarks on current branch + echo -e "${YELLOW}=== Building compiler on $CURRENT_BRANCH ===${NC}" + sbt install + echo "" + + echo -e "${YELLOW}=== Compiling benchmarks on $CURRENT_BRANCH ===${NC}" + for backend in "${BACKENDS[@]}"; do + OUT_CURRENT="out-${CURRENT_BRANCH_SAFE}-${backend}" + echo -e "${GREEN}Backend: $backend${NC}" + + for bench_path in "${!BENCHMARKS[@]}"; do + bench_name=$(basename "$bench_path") + source_file="examples/benchmarks/${bench_path}.effekt" + echo " $bench_name" + effekt --backend="$backend" --build -o "$OUT_CURRENT" "$source_file" + done + done + echo "" + + # Build compiler and compile benchmarks on main branch + echo -e "${YELLOW}=== Building compiler on $TARGET_BRANCH ===${NC}" + git checkout -q "$TARGET_BRANCH" + sbt install + echo "" + + echo -e "${YELLOW}=== Compiling benchmarks on $TARGET_BRANCH ===${NC}" + for backend in "${BACKENDS[@]}"; do + OUT_MAIN="out-main-${backend}" + echo -e "${GREEN}Backend: $backend${NC}" + + for bench_path in "${!BENCHMARKS[@]}"; do + bench_name=$(basename "$bench_path") + source_file="examples/benchmarks/${bench_path}.effekt" + echo " $bench_name" + effekt --backend="$backend" --build -o "$OUT_MAIN" "$source_file" + done + done + echo "" + + # Switch back to current branch + echo -e "${YELLOW}=== Switching back to $CURRENT_BRANCH ===${NC}" + git checkout -q "$CURRENT_BRANCH" + echo "" +else + echo -e "${YELLOW}=== Skipping compilation (using existing binaries) ===${NC}" + echo "" +fi + +# Restore stashed changes if any +if [ $STASHED -eq 1 ]; then + echo -e "${YELLOW}Restoring stashed changes...${NC}" + git stash pop + echo "" +fi + +echo -e "${BLUE}=== Starting benchmarks ===${NC}" +echo "" + +# Now run benchmarks using pre-compiled binaries +for backend in "${BACKENDS[@]}"; do + echo -e "${YELLOW}=== Benchmarking backend: $backend ===${NC}" + + OUT_CURRENT="out-${CURRENT_BRANCH_SAFE}-${backend}" + OUT_MAIN="out-main-${backend}" + + comparison_file="${OUTPUT_DIR}/comparison_${backend}_${CURRENT_BRANCH_SAFE}_vs_main_${TIMESTAMP}.md" + echo "# $CURRENT_BRANCH vs main ($backend)" > "$comparison_file" + echo "Date: $(date)" >> "$comparison_file" + echo "Runs: $RUNS, Warmup: $WARMUP" >> "$comparison_file" + echo "" >> "$comparison_file" + + for bench_path in "${!BENCHMARKS[@]}"; do + bench_name=$(basename "$bench_path") + params=${BENCHMARKS[$bench_path]} + + echo -e "${GREEN} $bench_name${NC}" + + # Set executable paths based on backend + case $backend in + llvm) + current_exec="./$OUT_CURRENT/${bench_name}" + target_exec="./$OUT_MAIN/${bench_name}" + ;; + js) + current_exec="node $OUT_CURRENT/${bench_name}.js" + target_exec="node $OUT_MAIN/${bench_name}.js" + ;; + chez-callcc) + current_exec="scheme --script $OUT_CURRENT/${bench_name}.ss" + target_exec="scheme --script $OUT_MAIN/${bench_name}.ss" + ;; + esac + + # Run comparison + echo "## $bench_name" >> "$comparison_file" + hyperfine \ + --warmup "$WARMUP" \ + --runs "$RUNS" \ + --export-markdown - \ + --command-name "main" "$target_exec $params" \ + --command-name "$CURRENT_BRANCH" "$current_exec $params" \ + 2>&1 | tee -a "$comparison_file" + echo "" >> "$comparison_file" + done + + echo -e "${GREEN}Results: $comparison_file${NC}" + echo "" +done + +echo -e "${GREEN}Done! Results in: $OUTPUT_DIR/${NC}" From 12e3225d627fc7435544c75b4820dcb3270763a2 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 12:50:44 +0100 Subject: [PATCH 27/40] modified benchmark script --- benchmark-compare.sh | 63 +++++++++++--------------------------------- 1 file changed, 15 insertions(+), 48 deletions(-) diff --git a/benchmark-compare.sh b/benchmark-compare.sh index dae46fe3bb..346b4b5582 100755 --- a/benchmark-compare.sh +++ b/benchmark-compare.sh @@ -42,15 +42,6 @@ if ! command -v hyperfine &> /dev/null; then exit 1 fi -# Stash any uncommitted changes -if ! git diff-index --quiet HEAD --; then - echo -e "${YELLOW}Stashing uncommitted changes...${NC}" - git stash push -m "benchmark-compare temporary stash" - STASHED=1 -else - STASHED=0 -fi - # Check if we're on main branch if [ "$CURRENT_BRANCH" = "$TARGET_BRANCH" ]; then echo "Error: You are currently on the $TARGET_BRANCH branch" @@ -65,38 +56,6 @@ declare -A BENCHMARKS=( ["arity_raising/record_addition"]="5000000" ["arity_raising/nested_records"]="2500000" ["arity_raising/record_map"]="10000" - ["are_we_fast_yet/bounce"]="100000" - ["are_we_fast_yet/list_tail"]="100" - ["are_we_fast_yet/mandelbrot"]="1000" - ["are_we_fast_yet/nbody"]="50000" - ["are_we_fast_yet/permute"]="10" - ["are_we_fast_yet/queens"]="20" - ["are_we_fast_yet/sieve"]="10000000" - ["are_we_fast_yet/storage"]="5000" - ["are_we_fast_yet/towers"]="25" - ["duality_of_compilation/erase_unused"]="10000" - ["duality_of_compilation/factorial_accumulator"]="500000000" - ["# duality_of_compilation/fibonacci_recursive"]="42" - ["duality_of_compilation/iterate_increment"]="500000000" - ["duality_of_compilation/lookup_tree"]="10000000" - ["duality_of_compilation/match_options"]="10000000" - ["duality_of_compilation/sum_range"]="5000000" - ["effect_handlers_bench/countdown"]="100000000" - ["effect_handlers_bench/iterator"]="100000000" - ["effect_handlers_bench/nqueens"]="10" - ["effect_handlers_bench/parsing_dollars"]="10000" - ["effect_handlers_bench/product_early"]="100000" - ["effect_handlers_bench/resume_nontail"]="100000" - ["effect_handlers_bench/tree_explore"]="14" - ["effect_handlers_bench/triples"]="100" - ["input_output/large_file"]="60000" - ["input_output/small_files"]="20000" - ["input_output/interleave_promises"]="300" - ["input_output/word_count_ascii"]="20000" - ["input_output/word_count_utf8"]="80000" - ["input_output/dyck_one"]="3000" - ["input_output/number_matrix"]="2000" - ["input_output/financial_format"]="200000" ) echo -e "${BLUE}Comparing: $CURRENT_BRANCH vs $TARGET_BRANCH${NC}" @@ -132,6 +91,15 @@ if [ $SKIP_COMPILE -eq 0 ]; then done echo "" + # Stash any uncommitted changes before switching branches + if ! git diff-index --quiet HEAD --; then + echo -e "${YELLOW}Stashing uncommitted changes before switching to $TARGET_BRANCH...${NC}" + git stash push -m "benchmark-compare temporary stash" + STASHED=1 + else + STASHED=0 + fi + # Build compiler and compile benchmarks on main branch echo -e "${YELLOW}=== Building compiler on $TARGET_BRANCH ===${NC}" git checkout -q "$TARGET_BRANCH" @@ -155,19 +123,18 @@ if [ $SKIP_COMPILE -eq 0 ]; then # Switch back to current branch echo -e "${YELLOW}=== Switching back to $CURRENT_BRANCH ===${NC}" git checkout -q "$CURRENT_BRANCH" + + # Restore stashed changes if any + if [ $STASHED -eq 1 ]; then + echo -e "${YELLOW}Restoring stashed changes...${NC}" + git stash pop + fi echo "" else echo -e "${YELLOW}=== Skipping compilation (using existing binaries) ===${NC}" echo "" fi -# Restore stashed changes if any -if [ $STASHED -eq 1 ]; then - echo -e "${YELLOW}Restoring stashed changes...${NC}" - git stash pop - echo "" -fi - echo -e "${BLUE}=== Starting benchmarks ===${NC}" echo "" From 4fbfca600bb6b75231fee1cbe19e0a0f8d0a4b9c Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 14:13:46 +0100 Subject: [PATCH 28/40] adding arity raising to scheme --- .../src/main/scala/effekt/generator/chez/ChezSchemeCPS.scala | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/chez/ChezSchemeCPS.scala b/effekt/shared/src/main/scala/effekt/generator/chez/ChezSchemeCPS.scala index 1260bc4625..d68fe2e65c 100644 --- a/effekt/shared/src/main/scala/effekt/generator/chez/ChezSchemeCPS.scala +++ b/effekt/shared/src/main/scala/effekt/generator/chez/ChezSchemeCPS.scala @@ -6,6 +6,7 @@ import effekt.context.Context import effekt.core.optimizer.{DropBindings, Optimizer} import kiama.util.Source import kiama.output.PrettyPrinterTypes.Document +import effekt.core.ArityRaising class ChezSchemeCPS extends Compiler[String] { @@ -37,7 +38,7 @@ class ChezSchemeCPS extends Compiler[String] { Frontend andThen Middleend } - lazy val Optimized = allToCore(Core) andThen Aggregate andThen Optimizer map { + lazy val Optimized = allToCore(Core) andThen Aggregate andThen ArityRaising andThen Optimizer map { case input @ CoreTransformed(source, tree, mod, core) => val mainSymbol = Context.ensureMainExists(mod) val mainFile = path(mod) @@ -66,4 +67,4 @@ class ChezSchemeCPS extends Compiler[String] { def pretty(expr: chez.Expr): Document = chez.PrettyPrinter.pretty(chez.PrettyPrinter.toDoc(expr), 100) -} \ No newline at end of file +} From da5bd0e8f98eb1f01876fe68af953de045d09f99 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 17:58:29 +0100 Subject: [PATCH 29/40] modified benchmark --- benchmark-compare.sh | 104 ++++++++++++++++--------------------------- 1 file changed, 38 insertions(+), 66 deletions(-) diff --git a/benchmark-compare.sh b/benchmark-compare.sh index 346b4b5582..5991caaba4 100755 --- a/benchmark-compare.sh +++ b/benchmark-compare.sh @@ -1,29 +1,13 @@ #!/bin/bash - -# Benchmark comparison script for Effekt -# Compares current branch against main branch - set -e -# Parse command-line arguments SKIP_COMPILE=0 -while [[ $# -gt 0 ]]; do - case $1 in - --skip-compile) - SKIP_COMPILE=1 - shift - ;; - *) - echo "Unknown option: $1" - echo "Usage: $0 [--skip-compile]" - exit 1 - ;; - esac -done +if [ "$1" = "--skip-compile" ]; then + SKIP_COMPILE=1 +fi -# Configuration (hardcoded) BACKENDS=("llvm") -WARMUP=5 +WARMUP=10 RUNS=50 TARGET_BRANCH="main" OUTPUT_DIR="benchmark-results" @@ -31,18 +15,23 @@ TIMESTAMP=$(date +%Y%m%d_%H%M%S) CURRENT_BRANCH=$(git branch --show-current) CURRENT_BRANCH_SAFE="${CURRENT_BRANCH//\//-}" -# Colors -GREEN='\033[0;32m' -BLUE='\033[0;34m' -YELLOW='\033[1;33m' -NC='\033[0m' +cleanup() { + local current=$(git branch --show-current) + if [ "$current" != "$CURRENT_BRANCH" ]; then + echo "" + echo "Interrupted! Switching back to $CURRENT_BRANCH..." + git checkout -q "$CURRENT_BRANCH" + fi + exit 1 +} + +trap cleanup SIGINT SIGTERM if ! command -v hyperfine &> /dev/null; then echo "Error: hyperfine is not installed" exit 1 fi -# Check if we're on main branch if [ "$CURRENT_BRANCH" = "$TARGET_BRANCH" ]; then echo "Error: You are currently on the $TARGET_BRANCH branch" echo "Please switch to your feature branch first" @@ -51,20 +40,17 @@ fi mkdir -p "$OUTPUT_DIR" -# Define benchmarks with their parameters declare -A BENCHMARKS=( - ["arity_raising/record_addition"]="5000000" - ["arity_raising/nested_records"]="2500000" - ["arity_raising/record_map"]="10000" + ["arity_raising/record_passing"]="25000000" + ["arity_raising/matrix_determinant"]="2000000" ) -echo -e "${BLUE}Comparing: $CURRENT_BRANCH vs $TARGET_BRANCH${NC}" +echo "Comparing: $CURRENT_BRANCH vs $TARGET_BRANCH" echo "Backends: ${BACKENDS[*]}" echo "Runs: $RUNS, Warmup: $WARMUP" echo "Skip compilation: $([ $SKIP_COMPILE -eq 1 ] && echo 'yes' || echo 'no')" echo "" -# Create output directories for backend in "${BACKENDS[@]}"; do OUT_CURRENT="out-${CURRENT_BRANCH_SAFE}-${backend}" OUT_MAIN="out-main-${backend}" @@ -72,15 +58,21 @@ for backend in "${BACKENDS[@]}"; do done if [ $SKIP_COMPILE -eq 0 ]; then - # Build compiler and compile benchmarks on current branch - echo -e "${YELLOW}=== Building compiler on $CURRENT_BRANCH ===${NC}" + + if ! git diff-index --quiet HEAD --; then + echo "Error: You have uncommitted changes" + echo "Please commit or stash your changes before running this script" + exit 1 + fi + + echo "=== Building compiler on $CURRENT_BRANCH ===" sbt install echo "" - echo -e "${YELLOW}=== Compiling benchmarks on $CURRENT_BRANCH ===${NC}" + echo "=== Compiling benchmarks on $CURRENT_BRANCH ===" for backend in "${BACKENDS[@]}"; do OUT_CURRENT="out-${CURRENT_BRANCH_SAFE}-${backend}" - echo -e "${GREEN}Backend: $backend${NC}" + echo "Backend: $backend" for bench_path in "${!BENCHMARKS[@]}"; do bench_name=$(basename "$bench_path") @@ -91,25 +83,15 @@ if [ $SKIP_COMPILE -eq 0 ]; then done echo "" - # Stash any uncommitted changes before switching branches - if ! git diff-index --quiet HEAD --; then - echo -e "${YELLOW}Stashing uncommitted changes before switching to $TARGET_BRANCH...${NC}" - git stash push -m "benchmark-compare temporary stash" - STASHED=1 - else - STASHED=0 - fi - - # Build compiler and compile benchmarks on main branch - echo -e "${YELLOW}=== Building compiler on $TARGET_BRANCH ===${NC}" + echo "=== Building compiler on $TARGET_BRANCH ===" git checkout -q "$TARGET_BRANCH" sbt install echo "" - echo -e "${YELLOW}=== Compiling benchmarks on $TARGET_BRANCH ===${NC}" + echo "=== Compiling benchmarks on $TARGET_BRANCH ===" for backend in "${BACKENDS[@]}"; do OUT_MAIN="out-main-${backend}" - echo -e "${GREEN}Backend: $backend${NC}" + echo "Backend: $backend" for bench_path in "${!BENCHMARKS[@]}"; do bench_name=$(basename "$bench_path") @@ -120,27 +102,19 @@ if [ $SKIP_COMPILE -eq 0 ]; then done echo "" - # Switch back to current branch - echo -e "${YELLOW}=== Switching back to $CURRENT_BRANCH ===${NC}" + echo "=== Switching back to $CURRENT_BRANCH ===" git checkout -q "$CURRENT_BRANCH" - - # Restore stashed changes if any - if [ $STASHED -eq 1 ]; then - echo -e "${YELLOW}Restoring stashed changes...${NC}" - git stash pop - fi echo "" else - echo -e "${YELLOW}=== Skipping compilation (using existing binaries) ===${NC}" + echo "=== Skipping compilation (using existing binaries) ===" echo "" fi -echo -e "${BLUE}=== Starting benchmarks ===${NC}" +echo "=== Starting benchmarks ===" echo "" -# Now run benchmarks using pre-compiled binaries for backend in "${BACKENDS[@]}"; do - echo -e "${YELLOW}=== Benchmarking backend: $backend ===${NC}" + echo "=== Benchmarking backend: $backend ===" OUT_CURRENT="out-${CURRENT_BRANCH_SAFE}-${backend}" OUT_MAIN="out-main-${backend}" @@ -155,9 +129,8 @@ for backend in "${BACKENDS[@]}"; do bench_name=$(basename "$bench_path") params=${BENCHMARKS[$bench_path]} - echo -e "${GREEN} $bench_name${NC}" + echo " $bench_name" - # Set executable paths based on backend case $backend in llvm) current_exec="./$OUT_CURRENT/${bench_name}" @@ -173,7 +146,6 @@ for backend in "${BACKENDS[@]}"; do ;; esac - # Run comparison echo "## $bench_name" >> "$comparison_file" hyperfine \ --warmup "$WARMUP" \ @@ -185,8 +157,8 @@ for backend in "${BACKENDS[@]}"; do echo "" >> "$comparison_file" done - echo -e "${GREEN}Results: $comparison_file${NC}" + echo "Results: $comparison_file" echo "" done -echo -e "${GREEN}Done! Results in: $OUTPUT_DIR/${NC}" +echo "Done! Results in: $OUTPUT_DIR/" From 338826bef05e5d7fb20b3433396fcee98c70c6a9 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 18:07:19 +0100 Subject: [PATCH 30/40] added my benchmarks to show the best case performance increase --- .../arity_raising/matrix_determinant.effekt | 56 +++++++++++++++++++ .../arity_raising/record_passing.effekt | 18 ++++++ 2 files changed, 74 insertions(+) create mode 100644 examples/benchmarks/arity_raising/matrix_determinant.effekt create mode 100644 examples/benchmarks/arity_raising/record_passing.effekt diff --git a/examples/benchmarks/arity_raising/matrix_determinant.effekt b/examples/benchmarks/arity_raising/matrix_determinant.effekt new file mode 100644 index 0000000000..d1c908a104 --- /dev/null +++ b/examples/benchmarks/arity_raising/matrix_determinant.effekt @@ -0,0 +1,56 @@ +import examples/benchmarks/runner + +record Vec4(a: Int, b: Int, c: Int, d: Int) + +record Matrix4(row1: Vec4, row2: Vec4, row3: Vec4, row4: Vec4) + +record Vec3(a: Int, b: Int, c: Int) +record Matrix3(row1: Vec3, row2: Vec3, row3: Vec3) + +def det3(m: Matrix3): Int = { + m.row1.a * (m.row2.b * m.row3.c - m.row2.c * m.row3.b) - + m.row1.b * (m.row2.a * m.row3.c - m.row2.c * m.row3.a) + + m.row1.c * (m.row2.a * m.row3.b - m.row2.b * m.row3.a) +} + +def det4(m: Matrix4): Int = { + val c1 = m.row1.a * det3(Matrix3( + Vec3(m.row2.b, m.row2.c, m.row2.d), + Vec3(m.row3.b, m.row3.c, m.row3.d), + Vec3(m.row4.b, m.row4.c, m.row4.d) + )) + val c2 = m.row1.b * det3(Matrix3( + Vec3(m.row2.a, m.row2.c, m.row2.d), + Vec3(m.row3.a, m.row3.c, m.row3.d), + Vec3(m.row4.a, m.row4.c, m.row4.d) + )) + val c3 = m.row1.c * det3(Matrix3( + Vec3(m.row2.a, m.row2.b, m.row2.d), + Vec3(m.row3.a, m.row3.b, m.row3.d), + Vec3(m.row4.a, m.row4.b, m.row4.d) + )) + val c4 = m.row1.d * det3(Matrix3( + Vec3(m.row2.a, m.row2.b, m.row2.c), + Vec3(m.row3.a, m.row3.b, m.row3.c), + Vec3(m.row4.a, m.row4.b, m.row4.c) + )) + c1 - c2 + c3 - c4 +} + +def runBenchmark(n: Int): Int = { + def loop(i: Int, acc: Int): Int = { + if (i <= 0) { acc } + else { + val m = Matrix4( + Vec4(i, i + 1, i + 2, i + 3), + Vec4(i + 4, i + 5, i + 6, i + 7), + Vec4(i + 8, i + 9, i + 10, i + 11), + Vec4(i + 12, i + 13, i + 14, i + 15) + ) + loop(i - 1, acc + det4(m)) + } + } + loop(n, 0) +} + +def main() = benchmark(1000000){ n => runBenchmark(n) } diff --git a/examples/benchmarks/arity_raising/record_passing.effekt b/examples/benchmarks/arity_raising/record_passing.effekt new file mode 100644 index 0000000000..15185f2e77 --- /dev/null +++ b/examples/benchmarks/arity_raising/record_passing.effekt @@ -0,0 +1,18 @@ +import examples/benchmarks/runner + +record Point(x: Int, y: Int) + +def add(p: Point, depth: Int): Int = { + if (depth <= 0) { p.x + p.y } + else { add(Point(p.y, p.x), depth - 1) } +} + +def runBenchmark(n: Int): Int = { + def loop(i: Int, acc: Int): Int = { + if (i <= 0) { acc } + else { loop(i - 1, acc + add(Point(i, i + 1), 2)) } + } + loop(n, 0) +} + +def main() = benchmark(250000000){ n => runBenchmark(n) } From 417cfa2d163e086aaa3c1812890ec27da996815d Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 18:09:21 +0100 Subject: [PATCH 31/40] removed acidentally commited metals --- project/metals.sbt | 13 ------------- project/project/metals.sbt | 14 -------------- project/project/project/metals.sbt | 8 -------- 3 files changed, 35 deletions(-) delete mode 100644 project/metals.sbt delete mode 100644 project/project/metals.sbt delete mode 100644 project/project/project/metals.sbt diff --git a/project/metals.sbt b/project/metals.sbt deleted file mode 100644 index 97e76fdf15..0000000000 --- a/project/metals.sbt +++ /dev/null @@ -1,13 +0,0 @@ -// format: off -// DO NOT EDIT! This file is auto-generated. - -// This plugin enables semantic information to be produced by sbt. -// It also adds support for debugging using the Debug Adapter Protocol - -addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.4") - -// This plugin adds the BSP debug capability to sbt server. - -addSbtPlugin("ch.epfl.scala" % "sbt-debug-adapter" % "4.2.8") - -// format: on diff --git a/project/project/metals.sbt b/project/project/metals.sbt deleted file mode 100644 index 0571d55559..0000000000 --- a/project/project/metals.sbt +++ /dev/null @@ -1,14 +0,0 @@ -// format: off -// DO NOT EDIT! This file is auto-generated. - -// This plugin enables semantic information to be produced by sbt. -// It also adds support for debugging using the Debug Adapter Protocol - -addSbtPlugin("org.scalameta" % "sbt-metals" % "1.6.4") - -// This plugin makes sure that the JDI tools are in the sbt classpath. -// JDI tools are used by the debug adapter server. - -addSbtPlugin("com.github.sbt" % "sbt-jdi-tools" % "1.2.0") - -// format: on diff --git a/project/project/project/metals.sbt b/project/project/project/metals.sbt deleted file mode 100644 index 69465cb550..0000000000 --- a/project/project/project/metals.sbt +++ /dev/null @@ -1,8 +0,0 @@ -// format: off -// DO NOT EDIT! This file is auto-generated. - -// This file enables sbt-bloop to create bloop config files. - -addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "2.0.13") - -// format: on From 4eca678ac1f68aad34b23682503fab52afb52d0c Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Mon, 19 Jan 2026 18:49:57 +0100 Subject: [PATCH 32/40] Added check files to satisfy tests --- examples/benchmarks/arity_raising/matrix_determinant.check | 1 + examples/benchmarks/arity_raising/record_passing.check | 1 + 2 files changed, 2 insertions(+) create mode 100644 examples/benchmarks/arity_raising/matrix_determinant.check create mode 100644 examples/benchmarks/arity_raising/record_passing.check diff --git a/examples/benchmarks/arity_raising/matrix_determinant.check b/examples/benchmarks/arity_raising/matrix_determinant.check new file mode 100644 index 0000000000..573541ac97 --- /dev/null +++ b/examples/benchmarks/arity_raising/matrix_determinant.check @@ -0,0 +1 @@ +0 diff --git a/examples/benchmarks/arity_raising/record_passing.check b/examples/benchmarks/arity_raising/record_passing.check new file mode 100644 index 0000000000..d774a2872f --- /dev/null +++ b/examples/benchmarks/arity_raising/record_passing.check @@ -0,0 +1 @@ +62500000500000000 \ No newline at end of file From 28898969f3dba2e93c6e2bd454dd7e86638553b9 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Sun, 15 Feb 2026 10:59:54 +0100 Subject: [PATCH 33/40] creating parameterized benchmarks --- benchmark-compare.sh | 4 +++ python_benchmark/create.sh | 16 ++++++++++ python_benchmark/create_large_record.py | 30 ++++++++++++++++++ python_benchmark/create_nested_record.py | 40 ++++++++++++++++++++++++ 4 files changed, 90 insertions(+) create mode 100755 python_benchmark/create.sh create mode 100644 python_benchmark/create_large_record.py create mode 100644 python_benchmark/create_nested_record.py diff --git a/benchmark-compare.sh b/benchmark-compare.sh index 5991caaba4..59b693dc3c 100755 --- a/benchmark-compare.sh +++ b/benchmark-compare.sh @@ -43,6 +43,10 @@ mkdir -p "$OUTPUT_DIR" declare -A BENCHMARKS=( ["arity_raising/record_passing"]="25000000" ["arity_raising/matrix_determinant"]="2000000" + ["large_records/10"]="2000000" + ["large_records/20"]="2000000" + ["nested_records/10"]="2000000" + ["nested_records/20"]="2000000" ) echo "Comparing: $CURRENT_BRANCH vs $TARGET_BRANCH" diff --git a/python_benchmark/create.sh b/python_benchmark/create.sh new file mode 100755 index 0000000000..548dc675c7 --- /dev/null +++ b/python_benchmark/create.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +MAX_NESTED_RECORD_SIZE=20 + +for i in $(seq 1 $MAX_NESTED_RECORD_SIZE); do + python create_nested_record.py $i > ../examples/benchmarks/nested_records/$i.effekt +done + +echo "Generated files from 1 to $MAX_NESTED_RECORD_SIZE for nested records" + +MAX_LARGE_RECORD_SIZE=20 +for i in $(seq 1 $MAX_LARGE_RECORD_SIZE); do + python create_large_record.py $i > ../examples/benchmarks/large_records/$i.effekt +done + +echo "Generated files from 1 to $MAX_LARGE_RECORD_SIZE for large records" diff --git a/python_benchmark/create_large_record.py b/python_benchmark/create_large_record.py new file mode 100644 index 0000000000..037f3605f8 --- /dev/null +++ b/python_benchmark/create_large_record.py @@ -0,0 +1,30 @@ +import sys + +length = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +list = [ str(i) for i in range(length)] + +rec = f"record Rec(x{": Int, x".join(list)}: Int)" +recfunc = f"""def recfunc(m: Rec): Int = {{ + m.x{" + m.x".join(list)} +}} +""" +print(rec) +print(recfunc) + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + rec = Rec(i + {" , i + ".join(list)}) + loop(i - 1, acc + recfunc(rec)) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") diff --git a/python_benchmark/create_nested_record.py b/python_benchmark/create_nested_record.py new file mode 100644 index 0000000000..26f26d27b6 --- /dev/null +++ b/python_benchmark/create_nested_record.py @@ -0,0 +1,40 @@ +import sys + +nesting = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +endrecord = "record Rec0(a: Int, b: Int)" +endfunc = """def recfunc0(m: Rec0): Int = { + m.a + m.b +} +""" + +recacc = "Rec0(1, 1)" + +for i in range(nesting): + if i == 0: + print(endrecord) + print(endfunc) + else: + recacc = f"Rec{i}({recacc}, 1)" + print(f"record Rec{i}(a: Rec{i-1}, b: Int)") + print(f"""def recfunc{i}(m: Rec{i}): Int = {{ + recfunc{i-1}(m.a) + m.b +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + rec = {recacc} + loop(i - 1, acc + recfunc{nesting}(rec)) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") From f7ba9a0a0264898709086fbfb3eac0905302b964 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Sun, 15 Feb 2026 11:06:58 +0100 Subject: [PATCH 34/40] added val keyword --- python_benchmark/create_large_record.py | 2 +- python_benchmark/create_nested_record.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/python_benchmark/create_large_record.py b/python_benchmark/create_large_record.py index 037f3605f8..f2baa44e53 100644 --- a/python_benchmark/create_large_record.py +++ b/python_benchmark/create_large_record.py @@ -19,7 +19,7 @@ def runBenchmark(n: Int): Int = {{ def loop(i: Int, acc: Int): Int = {{ if (i <= 0) {{ acc }} else {{ - rec = Rec(i + {" , i + ".join(list)}) + val rec = Rec(i + {" , i + ".join(list)}) loop(i - 1, acc + recfunc(rec)) }} }} diff --git a/python_benchmark/create_nested_record.py b/python_benchmark/create_nested_record.py index 26f26d27b6..b2cf8a82a1 100644 --- a/python_benchmark/create_nested_record.py +++ b/python_benchmark/create_nested_record.py @@ -29,7 +29,7 @@ def runBenchmark(n: Int): Int = {{ def loop(i: Int, acc: Int): Int = {{ if (i <= 0) {{ acc }} else {{ - rec = {recacc} + val rec = {recacc} loop(i - 1, acc + recfunc{nesting}(rec)) }} }} From 6cc5de0e2daade552b54cbab7ca0ece95b2a0e28 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Sun, 15 Feb 2026 11:08:32 +0100 Subject: [PATCH 35/40] index error --- python_benchmark/create_nested_record.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python_benchmark/create_nested_record.py b/python_benchmark/create_nested_record.py index b2cf8a82a1..71a14cbc76 100644 --- a/python_benchmark/create_nested_record.py +++ b/python_benchmark/create_nested_record.py @@ -30,7 +30,7 @@ def loop(i: Int, acc: Int): Int = {{ if (i <= 0) {{ acc }} else {{ val rec = {recacc} - loop(i - 1, acc + recfunc{nesting}(rec)) + loop(i - 1, acc + recfunc{nesting - 1}(rec)) }} }} loop(n, 0) From 35c98aeb1165d12e71eebdc0a98ca4c9200af91f Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Sun, 15 Feb 2026 11:13:07 +0100 Subject: [PATCH 36/40] changed names --- python_benchmark/create.sh | 8 ++++---- python_benchmark/create_large_record.py | 22 +++++++++++++--------- python_benchmark/create_nested_record.py | 23 +++++++++++------------ 3 files changed, 28 insertions(+), 25 deletions(-) diff --git a/python_benchmark/create.sh b/python_benchmark/create.sh index 548dc675c7..81daceaf5b 100755 --- a/python_benchmark/create.sh +++ b/python_benchmark/create.sh @@ -1,16 +1,16 @@ #!/bin/bash -MAX_NESTED_RECORD_SIZE=20 +MAX_NESTED_RECORD_SIZE=100 for i in $(seq 1 $MAX_NESTED_RECORD_SIZE); do - python create_nested_record.py $i > ../examples/benchmarks/nested_records/$i.effekt + python create_nested_record.py $i > ../examples/benchmarks/nested_records/nested_records_$i.effekt done echo "Generated files from 1 to $MAX_NESTED_RECORD_SIZE for nested records" -MAX_LARGE_RECORD_SIZE=20 +MAX_LARGE_RECORD_SIZE=100 for i in $(seq 1 $MAX_LARGE_RECORD_SIZE); do - python create_large_record.py $i > ../examples/benchmarks/large_records/$i.effekt + python create_large_record.py $i > ../examples/benchmarks/large_records/large_records_$i.effekt done echo "Generated files from 1 to $MAX_LARGE_RECORD_SIZE for large records" diff --git a/python_benchmark/create_large_record.py b/python_benchmark/create_large_record.py index f2baa44e53..228edafc0d 100644 --- a/python_benchmark/create_large_record.py +++ b/python_benchmark/create_large_record.py @@ -4,23 +4,27 @@ print("import examples/benchmarks/runner") -list = [ str(i) for i in range(length)] +fields = [str(i) for i in range(length)] +field_types = ", ".join([f"x{i}: Int" for i in fields]) +field_sum = " + ".join([f"m.x{i}" for i in fields]) +field_values = ", ".join([f"i + {i}" for i in fields]) +shifted_fields = ", ".join([f"m.x{i}" for i in (fields[-1:] + fields[:-1])]) -rec = f"record Rec(x{": Int, x".join(list)}: Int)" -recfunc = f"""def recfunc(m: Rec): Int = {{ - m.x{" + m.x".join(list)} +print(f"record Rec({field_types})") +print(f""" +def recfunc(m: Rec, depth: Int): Int = {{ + if (depth <= 0) {{ {field_sum} }} + else {{recfunc(Rec({shifted_fields}), depth - 1)}} }} -""" -print(rec) -print(recfunc) +""") print(f""" def runBenchmark(n: Int): Int = {{ def loop(i: Int, acc: Int): Int = {{ if (i <= 0) {{ acc }} else {{ - val rec = Rec(i + {" , i + ".join(list)}) - loop(i - 1, acc + recfunc(rec)) + val rec = Rec({field_values}) + loop(i - 1, acc + recfunc(rec, 2)) }} }} loop(n, 0) diff --git a/python_benchmark/create_nested_record.py b/python_benchmark/create_nested_record.py index 71a14cbc76..73c3a775f0 100644 --- a/python_benchmark/create_nested_record.py +++ b/python_benchmark/create_nested_record.py @@ -4,22 +4,21 @@ print("import examples/benchmarks/runner") -endrecord = "record Rec0(a: Int, b: Int)" -endfunc = """def recfunc0(m: Rec0): Int = { - m.a + m.b -} -""" - -recacc = "Rec0(1, 1)" +rec_constructor = "Rec0(1, 1)" for i in range(nesting): if i == 0: - print(endrecord) - print(endfunc) + print("record Rec0(a: Int, b: Int)") + print(""" +def recfunc0(m: Rec0): Int = { + m.a + m.b +} +""") else: - recacc = f"Rec{i}({recacc}, 1)" + rec_constructor = f"Rec{i}({rec_constructor}, 1)" print(f"record Rec{i}(a: Rec{i-1}, b: Int)") - print(f"""def recfunc{i}(m: Rec{i}): Int = {{ + print(f""" +def recfunc{i}(m: Rec{i}): Int = {{ recfunc{i-1}(m.a) + m.b }} """) @@ -29,7 +28,7 @@ def runBenchmark(n: Int): Int = {{ def loop(i: Int, acc: Int): Int = {{ if (i <= 0) {{ acc }} else {{ - val rec = {recacc} + val rec = {rec_constructor} loop(i - 1, acc + recfunc{nesting - 1}(rec)) }} }} From 84c7ab5ee6ad5f8a28acfa097be374ef627445a2 Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Thu, 19 Feb 2026 19:15:44 +0100 Subject: [PATCH 37/40] tryint to prevent constant folding --- python_benchmark/create.sh | 2 +- python_benchmark/create_nested_record.py | 13 ++-- python_benchmark/plot_speedup.py | 80 +++++++++++++++++++++++ python_benchmark/speedup_comparison.png | Bin 0 -> 213248 bytes 4 files changed, 89 insertions(+), 6 deletions(-) create mode 100644 python_benchmark/plot_speedup.py create mode 100644 python_benchmark/speedup_comparison.png diff --git a/python_benchmark/create.sh b/python_benchmark/create.sh index 81daceaf5b..cb60e9f538 100755 --- a/python_benchmark/create.sh +++ b/python_benchmark/create.sh @@ -1,6 +1,6 @@ #!/bin/bash -MAX_NESTED_RECORD_SIZE=100 +MAX_NESTED_RECORD_SIZE=1000 for i in $(seq 1 $MAX_NESTED_RECORD_SIZE); do python create_nested_record.py $i > ../examples/benchmarks/nested_records/nested_records_$i.effekt diff --git a/python_benchmark/create_nested_record.py b/python_benchmark/create_nested_record.py index 73c3a775f0..bee9f6d173 100644 --- a/python_benchmark/create_nested_record.py +++ b/python_benchmark/create_nested_record.py @@ -10,16 +10,19 @@ if i == 0: print("record Rec0(a: Int, b: Int)") print(""" -def recfunc0(m: Rec0): Int = { +def recfunc0(m: Rec0, depth: Int): Int = { m.a + m.b } """) else: - rec_constructor = f"Rec{i}({rec_constructor}, 1)" + rec_constructor = f"Rec{i}({rec_constructor}, {i} - i)" print(f"record Rec{i}(a: Rec{i-1}, b: Int)") print(f""" -def recfunc{i}(m: Rec{i}): Int = {{ - recfunc{i-1}(m.a) + m.b +def recfunc{i}(m: Rec{i}, depth: Int): Int = {{ + + if (depth <= 0) {{ recfunc{i-1}(m.a, 2) + m.b }} + else {{ recfunc{i}(Rec{i}(m.a, m.b + 1), depth - 1) + m.b }} + }} """) @@ -29,7 +32,7 @@ def loop(i: Int, acc: Int): Int = {{ if (i <= 0) {{ acc }} else {{ val rec = {rec_constructor} - loop(i - 1, acc + recfunc{nesting - 1}(rec)) + loop(i - 1, acc + recfunc{nesting - 1}(rec, 2)) }} }} loop(n, 0) diff --git a/python_benchmark/plot_speedup.py b/python_benchmark/plot_speedup.py new file mode 100644 index 0000000000..95c037323e --- /dev/null +++ b/python_benchmark/plot_speedup.py @@ -0,0 +1,80 @@ +import matplotlib.pyplot as plt +import numpy as np + +# Data from benchmark results +record_sizes = [1, 5, 10, 15, 20] +speedups = [21.67, 23.91, 46.66, 58.50, 77.26] +errors = [0.98, 0.82, 1.99, 2.95, 4.78] + +# Set style +plt.style.use('seaborn-v0_8-darkgrid') +fig, ax = plt.subplots(figsize=(12, 7), facecolor='white') + +# Create gradient background +ax.set_facecolor('#f8f9fa') + +# Main plot with enhanced styling +line = ax.errorbar(record_sizes, speedups, yerr=errors, + marker='o', markersize=12, + capsize=6, capthick=2.5, + linewidth=3, + color='#0066cc', + ecolor='#cc0066', + elinewidth=2, + markerfacecolor='#0066cc', + markeredgecolor='white', + markeredgewidth=2, + label='arity-raising speedup', + zorder=3) + +# Add filled area under the curve +ax.fill_between(record_sizes, 0, speedups, alpha=0.15, color='#0066cc', zorder=1) + +# Customize the plot with better typography +ax.set_xlabel('Record Size', fontsize=15, fontweight='bold', color='#2c3e50', labelpad=10) +ax.set_ylabel('Speedup Factor (×)', fontsize=15, fontweight='bold', color='#2c3e50', labelpad=10) +ax.set_title('Performance Improvement: konradbausch/arity-raising vs main', + fontsize=17, fontweight='bold', color='#1a252f', pad=20) + +# Enhanced grid +ax.grid(True, alpha=0.3, linestyle='-', linewidth=0.8, color='#bdc3c7', zorder=0) +ax.set_axisbelow(True) + +# Set axis limits and ticks +ax.set_xlim(-1, 22) +ax.set_ylim(0, max(speedups) + max(errors) + 10) +ax.set_xticks([0, 5, 10, 15, 20]) +ax.tick_params(labelsize=12, colors='#34495e', width=1.5, length=6) + +# Add value labels with better styling +for size, speedup, error in zip(record_sizes, speedups, errors): + ax.annotate(f'{speedup:.1f}×', + xy=(size, speedup), + xytext=(0, 12), + textcoords='offset points', + ha='center', + fontsize=11, + fontweight='bold', + color='#2c3e50', + bbox=dict(boxstyle='round,pad=0.5', + facecolor='white', + edgecolor='#0066cc', + linewidth=2, + alpha=0.95), + zorder=4) + +# Enhanced legend +legend = ax.legend(fontsize=12, frameon=True, shadow=True, + fancybox=True, framealpha=0.95, + edgecolor='#34495e', loc='upper left') +legend.get_frame().set_facecolor('white') + +# Add subtle border +for spine in ax.spines.values(): + spine.set_edgecolor('#95a5a6') + spine.set_linewidth(1.5) + +plt.tight_layout() +plt.savefig('speedup_comparison.png', dpi=300, bbox_inches='tight', facecolor='white') +print("✓ Plot saved as 'speedup_comparison.png'") +plt.show() diff --git a/python_benchmark/speedup_comparison.png b/python_benchmark/speedup_comparison.png new file mode 100644 index 0000000000000000000000000000000000000000..d3f2be9ffa8f53ecf3f492ae5c9a1c279d7c9cae GIT binary patch literal 213248 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 Date: Sun, 22 Feb 2026 18:51:00 +0100 Subject: [PATCH 38/40] automatic nice plot --- python_benchmark/plot_speedup.py | 255 +++++++++++++++++------- python_benchmark/speedup_comparison.png | Bin 213248 -> 0 bytes 2 files changed, 178 insertions(+), 77 deletions(-) delete mode 100644 python_benchmark/speedup_comparison.png diff --git a/python_benchmark/plot_speedup.py b/python_benchmark/plot_speedup.py index 95c037323e..c550771115 100644 --- a/python_benchmark/plot_speedup.py +++ b/python_benchmark/plot_speedup.py @@ -1,80 +1,181 @@ +""" +Plot speedup results from hyperfine benchmark markdown files. + +Produces two publication-quality subplots – nested_records and large_records – +with the same visual vocabulary as the learning-curve reference: + • CI band (fill_between, low alpha) + • Raw values as a faint thin line + • Smoothed trend as the main foreground line with markers +""" +from __future__ import annotations + +import glob +import re +import time +from pathlib import Path + import matplotlib.pyplot as plt +import matplotlib.ticker as ticker import numpy as np +import pandas as pd +from tueplots import bundles, figsizes +from tueplots.constants.color import rgb + +# ─── Config ────────────────────────────────────────────────────────────────── +BENCHMARK_DIR = Path(__file__).parent.parent / "benchmark-results" +BACKEND = "llvm" + +# ─── Helpers ───────────────────────────────────────────────────────────────── +def _to_ms(value: str, unit: str) -> float: + """Convert a hyperfine time value (value + unit string) to milliseconds.""" + v = float(value.replace(",", "")) + u = unit.strip() + if u == "µs": return v / 1_000 + if u == "ms": return v + if u == "s": return v * 1_000 + raise ValueError(f"Unknown time unit: {u!r}") + + +# ─── Parser ────────────────────────────────────────────────────────────────── +_TIME_RE = re.compile( + r"Time \(mean ± σ\):\s+([\d.,]+)\s+(µs|ms|s)\s+±\s+([\d.,]+)\s+(µs|ms|s)" +) +_SUMMARY_RE = re.compile( + r"(konradbausch/arity-raising|main) ran\s+([\d.]+) ± ([\d.]+) times faster than", + re.DOTALL, +) + + +def parse_file(path: Path) -> pd.DataFrame: + """Return a DataFrame with one row per successfully benchmarked program.""" + text = path.read_text() + rows = [] + + for section in re.split(r"^## ", text, flags=re.MULTILINE)[1:]: + name = section.splitlines()[0].strip() + m = re.match(r"^(nested_records|large_records)_(\d+)$", name) + if not m: + continue + family, n = m.group(1), int(m.group(2)) + + if "non-zero exit code" in section or "Error:" in section: + continue + + times = _TIME_RE.findall(section) + if len(times) < 2: + continue + + main_mean = _to_ms(times[0][0], times[0][1]) + main_std = _to_ms(times[0][2], times[0][3]) + ar_mean = _to_ms(times[1][0], times[1][1]) + ar_std = _to_ms(times[1][2], times[1][3]) + + sm = _SUMMARY_RE.search(section) + if sm: + winner, sp, se = sm.group(1), float(sm.group(2)), float(sm.group(3)) + if winner == "main": # arity-raising is the *loser* + sp = 1.0 / sp + se = se / (sp ** 2) # propagate 1/x uncertainty + else: + sp = main_mean / ar_mean + se = sp * np.sqrt((main_std / main_mean) ** 2 + (ar_std / ar_mean) ** 2) + + rows.append(dict( + name=name, family=family, n=n, + main_mean=main_mean, main_std=main_std, + ar_mean=ar_mean, ar_std=ar_std, + speedup=sp, speedup_err=se, + )) + + return pd.DataFrame(rows) + + +def latest_file(backend: str) -> Path: + pattern = str( + BENCHMARK_DIR / f"comparison_{backend}_konradbausch-arity-raising_vs_main_*.md" + ) + files = sorted(glob.glob(pattern)) + if not files: + raise FileNotFoundError(f"No files matching {pattern}") + return Path(files[-1]) + + +# ─── Plot ──────────────────────────────────────────────────────────────────── +def make_plot(df: pd.DataFrame, outpath: Path | None = None) -> None: + t0 = time.perf_counter() + + plt.rcParams.update(bundles.icml2022()) + + fig, (ax_nested, ax_large) = plt.subplots( + 1, 2, + figsize=(7.0, 2.6), + constrained_layout=True, + ) + + panels = [ + ("nested_records", ax_nested, rgb.pn_orange, + "Record depth $n$", + "Speedup of arity-raising over main\n(nested records)"), + ("large_records", ax_large, rgb.tue_blue, + "Number of record fields $n$", + "Speedup of arity-raising over main\n(large records)"), + ] + + for family, ax, color, xlabel, title in panels: + sub = df[df["family"] == family].sort_values("n") + if sub.empty: + ax.set_visible(False) + continue + + x = sub["n"].to_numpy(dtype=float) + y = sub["speedup"].to_numpy() + lo = y - sub["speedup_err"].to_numpy() + hi = y + sub["speedup_err"].to_numpy() + + # Deviation band + ax.fill_between(x, lo, hi, alpha=0.18, linewidth=0, color=color, zorder=1) + + # Speedup line + ax.plot( + x, y, + linewidth=1.3, + marker="o", + markersize=2.2, + color=color, + zorder=3, + label="arity-raising vs main", + ) + + # Reference line at y = 1 (no speedup) + ax.axhline(1.0, linewidth=0.6, linestyle="--", color="0.55", zorder=0) + + ax.set_xlabel(xlabel) + ax.set_ylabel("Speedup (×)") + ax.set_title(title) + ax.xaxis.set_minor_locator(ticker.AutoMinorLocator()) + ax.grid(axis="y", which="major", color="0.88", linewidth=0.6) + ax.margins(x=0.03) + ax.set_ylim(bottom=0) + + if outpath is not None: + outpath.parent.mkdir(parents=True, exist_ok=True) + fig.savefig(outpath, dpi=300, bbox_inches="tight") + print(f"✓ Saved → {outpath}") + + plt.savefig( + Path(__file__).parent / "speedup_comparison.png", + dpi=300, bbox_inches="tight", + ) + print(f"✓ Saved → {Path(__file__).parent / 'speedup_comparison.png'}") + plt.show() + plt.close(fig) + print(f"[plot_speedup] total time: {time.perf_counter() - t0:.2f}s") + -# Data from benchmark results -record_sizes = [1, 5, 10, 15, 20] -speedups = [21.67, 23.91, 46.66, 58.50, 77.26] -errors = [0.98, 0.82, 1.99, 2.95, 4.78] - -# Set style -plt.style.use('seaborn-v0_8-darkgrid') -fig, ax = plt.subplots(figsize=(12, 7), facecolor='white') - -# Create gradient background -ax.set_facecolor('#f8f9fa') - -# Main plot with enhanced styling -line = ax.errorbar(record_sizes, speedups, yerr=errors, - marker='o', markersize=12, - capsize=6, capthick=2.5, - linewidth=3, - color='#0066cc', - ecolor='#cc0066', - elinewidth=2, - markerfacecolor='#0066cc', - markeredgecolor='white', - markeredgewidth=2, - label='arity-raising speedup', - zorder=3) - -# Add filled area under the curve -ax.fill_between(record_sizes, 0, speedups, alpha=0.15, color='#0066cc', zorder=1) - -# Customize the plot with better typography -ax.set_xlabel('Record Size', fontsize=15, fontweight='bold', color='#2c3e50', labelpad=10) -ax.set_ylabel('Speedup Factor (×)', fontsize=15, fontweight='bold', color='#2c3e50', labelpad=10) -ax.set_title('Performance Improvement: konradbausch/arity-raising vs main', - fontsize=17, fontweight='bold', color='#1a252f', pad=20) - -# Enhanced grid -ax.grid(True, alpha=0.3, linestyle='-', linewidth=0.8, color='#bdc3c7', zorder=0) -ax.set_axisbelow(True) - -# Set axis limits and ticks -ax.set_xlim(-1, 22) -ax.set_ylim(0, max(speedups) + max(errors) + 10) -ax.set_xticks([0, 5, 10, 15, 20]) -ax.tick_params(labelsize=12, colors='#34495e', width=1.5, length=6) - -# Add value labels with better styling -for size, speedup, error in zip(record_sizes, speedups, errors): - ax.annotate(f'{speedup:.1f}×', - xy=(size, speedup), - xytext=(0, 12), - textcoords='offset points', - ha='center', - fontsize=11, - fontweight='bold', - color='#2c3e50', - bbox=dict(boxstyle='round,pad=0.5', - facecolor='white', - edgecolor='#0066cc', - linewidth=2, - alpha=0.95), - zorder=4) - -# Enhanced legend -legend = ax.legend(fontsize=12, frameon=True, shadow=True, - fancybox=True, framealpha=0.95, - edgecolor='#34495e', loc='upper left') -legend.get_frame().set_facecolor('white') - -# Add subtle border -for spine in ax.spines.values(): - spine.set_edgecolor('#95a5a6') - spine.set_linewidth(1.5) - -plt.tight_layout() -plt.savefig('speedup_comparison.png', dpi=300, bbox_inches='tight', facecolor='white') -print("✓ Plot saved as 'speedup_comparison.png'") -plt.show() +# ─── Entry point ───────────────────────────────────────────────────────────── +if __name__ == "__main__": + src = latest_file(BACKEND) + print(f"Parsing: {src.name}") + df = parse_file(src) + print(df[["name", "speedup", "speedup_err"]].to_string(index=False)) + make_plot(df) diff --git a/python_benchmark/speedup_comparison.png b/python_benchmark/speedup_comparison.png deleted file mode 100644 index d3f2be9ffa8f53ecf3f492ae5c9a1c279d7c9cae..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 213248 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 Date: Tue, 24 Feb 2026 14:09:30 +0100 Subject: [PATCH 39/40] trying without record reconstruction --- python_benchmark/create.sh | 2 + .../create_large_record_no_rec.py | 33 +++++++++++++++ .../create_nested_record_no_rec.py | 42 +++++++++++++++++++ 3 files changed, 77 insertions(+) create mode 100644 python_benchmark/create_large_record_no_rec.py create mode 100644 python_benchmark/create_nested_record_no_rec.py diff --git a/python_benchmark/create.sh b/python_benchmark/create.sh index cb60e9f538..772b06978f 100755 --- a/python_benchmark/create.sh +++ b/python_benchmark/create.sh @@ -4,6 +4,7 @@ MAX_NESTED_RECORD_SIZE=1000 for i in $(seq 1 $MAX_NESTED_RECORD_SIZE); do python create_nested_record.py $i > ../examples/benchmarks/nested_records/nested_records_$i.effekt + python create_nested_record_no_rec.py $i > ../examples/benchmarks/nested_records/nested_records_no_rec_$i.effekt done echo "Generated files from 1 to $MAX_NESTED_RECORD_SIZE for nested records" @@ -11,6 +12,7 @@ echo "Generated files from 1 to $MAX_NESTED_RECORD_SIZE for nested records" MAX_LARGE_RECORD_SIZE=100 for i in $(seq 1 $MAX_LARGE_RECORD_SIZE); do python create_large_record.py $i > ../examples/benchmarks/large_records/large_records_$i.effekt + python create_large_record_no_rec.py $i > ../examples/benchmarks/large_records/large_records_no_rec_$i.effekt done echo "Generated files from 1 to $MAX_LARGE_RECORD_SIZE for large records" diff --git a/python_benchmark/create_large_record_no_rec.py b/python_benchmark/create_large_record_no_rec.py new file mode 100644 index 0000000000..da6399bb1e --- /dev/null +++ b/python_benchmark/create_large_record_no_rec.py @@ -0,0 +1,33 @@ +import sys + +length = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +fields = [str(i) for i in range(length)] +field_types = ", ".join([f"x{i}: Int" for i in fields]) +field_sum = " + ".join([f"m.x{i}" for i in fields]) +field_values = ", ".join([f"i + {i}" for i in fields]) + +print(f"record Rec({field_types})") +print(f""" +def recfunc(m: Rec, depth: Int): Int = {{ + if (depth <= 0) {{ {field_sum} }} + else {{recfunc(m, depth - 1)}} +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + val rec = Rec({field_values}) + loop(i - 1, acc + recfunc(rec, 2)) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") diff --git a/python_benchmark/create_nested_record_no_rec.py b/python_benchmark/create_nested_record_no_rec.py new file mode 100644 index 0000000000..9f572a87ae --- /dev/null +++ b/python_benchmark/create_nested_record_no_rec.py @@ -0,0 +1,42 @@ +import sys + +nesting = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +rec_constructor = "Rec0(1, 1)" + +for i in range(nesting): + if i == 0: + print("record Rec0(a: Int, b: Int)") + print(""" +def recfunc0(m: Rec0, depth: Int): Int = { + m.a + m.b +} +""") + else: + rec_constructor = f"Rec{i}({rec_constructor}, {i} - i)" + print(f"record Rec{i}(a: Rec{i-1}, b: Int)") + print(f""" +def recfunc{i}(m: Rec{i}, depth: Int): Int = {{ + + if (depth <= 0) {{ recfunc{i-1}(m.a, 2) + m.b }} + else {{ recfunc{i}(m, depth - 1) + m.b }} + +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + val rec = {rec_constructor} + loop(i - 1, acc + recfunc{nesting - 1}(rec, 2)) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") From 19af48a5b409d63487c86c3b44015a6a75a111cb Mon Sep 17 00:00:00 2001 From: Konrad Bausch Date: Tue, 24 Feb 2026 15:55:58 +0100 Subject: [PATCH 40/40] made benchmark script output json, read from yml --- python_benchmark/benchmark.py | 169 ++++++++++++++++++ python_benchmark/benchmark.yml | 92 ++++++++++ python_benchmark/benchmark_to_csv.py | 75 ++++++++ python_benchmark/create.sh | 18 +- .../create_return_int_recreate.py} | 0 .../create_return_int_reuse.py} | 0 .../create_return_record_recreate.py | 35 ++++ .../create_return_record_reuse.py | 34 ++++ .../create_return_int_recreate.py} | 0 .../create_return_int_reuse.py} | 0 .../create_return_record_recreate.py | 43 +++++ .../create_return_record_reuse.py | 43 +++++ 12 files changed, 505 insertions(+), 4 deletions(-) create mode 100755 python_benchmark/benchmark.py create mode 100644 python_benchmark/benchmark.yml create mode 100755 python_benchmark/benchmark_to_csv.py rename python_benchmark/{create_large_record.py => large_record/create_return_int_recreate.py} (100%) rename python_benchmark/{create_large_record_no_rec.py => large_record/create_return_int_reuse.py} (100%) create mode 100644 python_benchmark/large_record/create_return_record_recreate.py create mode 100644 python_benchmark/large_record/create_return_record_reuse.py rename python_benchmark/{create_nested_record.py => nested_record/create_return_int_recreate.py} (100%) rename python_benchmark/{create_nested_record_no_rec.py => nested_record/create_return_int_reuse.py} (100%) create mode 100644 python_benchmark/nested_record/create_return_record_recreate.py create mode 100644 python_benchmark/nested_record/create_return_record_reuse.py diff --git a/python_benchmark/benchmark.py b/python_benchmark/benchmark.py new file mode 100755 index 0000000000..b594228397 --- /dev/null +++ b/python_benchmark/benchmark.py @@ -0,0 +1,169 @@ +#!/usr/bin/env python3 +""" +Compares benchmarks between the current branch and main. +Usage: ./benchmark.py [--skip-compile] [--config benchmark.yml] +""" + +import argparse +import os +import shutil +import signal +import subprocess +import sys +import yaml +from datetime import datetime +from pathlib import Path + +# Run from the repo root so git/sbt/effekt resolve correctly +REPO_ROOT = Path(__file__).parent.parent + +# ── Helpers ─────────────────────────────────────────────────────────────────── + +def run(cmd, **kwargs): + """Run a command from the repo root, inheriting stdio so output streams to the terminal.""" + subprocess.run(cmd, check=True, cwd=REPO_ROOT, **kwargs) + +def git_current_branch() -> str: + return subprocess.check_output( + ["git", "branch", "--show-current"], text=True, cwd=REPO_ROOT + ).strip() + +def bench_exec(backend: str, out_dir: str, bench_name: str, params: str) -> str: + match backend: + case "llvm": + return f"./{out_dir}/{bench_name} {params}" + case "js": + return f"node {out_dir}/{bench_name}.js {params}" + case "chez-callcc": + return f"scheme --script {out_dir}/{bench_name}.ss {params}" + case _: + raise ValueError(f"Unknown backend: {backend}") + +# ── Main ────────────────────────────────────────────────────────────────────── + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--skip-compile", action="store_true") + parser.add_argument("--config", default=Path(__file__).parent / "benchmark.yml", + type=Path, help="Path to benchmark config YAML") + args = parser.parse_args() + + cfg = yaml.safe_load(args.config.read_text()) + BACKENDS = cfg["backends"] + WARMUP = cfg["warmup"] + RUNS = cfg["runs"] + BRANCH = cfg["branch"] + TARGET_BRANCH = cfg["target_branch"] + OUTPUT_DIR = REPO_ROOT / cfg.get("output_dir", "benchmark-results") + # benchmarks: list of {path, n} + BENCHMARKS = {b["path"]: str(b["n"]) for b in cfg["benchmarks"]} + + current_branch = git_current_branch() # saved only to restore at the end + branch_safe = BRANCH.replace("/", "-") + target_safe = TARGET_BRANCH.replace("/", "-") + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + + # Restore branch on Ctrl-C + def on_interrupt(sig, frame): + if git_current_branch() != current_branch: + print(f"\nInterrupted! Switching back to {current_branch}...") + subprocess.run(["git", "checkout", "-q", current_branch]) + sys.exit(1) + signal.signal(signal.SIGINT, on_interrupt) + signal.signal(signal.SIGTERM, on_interrupt) + + if not shutil.which("hyperfine"): + sys.exit("Error: hyperfine is not installed") + + if BRANCH == TARGET_BRANCH: + sys.exit(f"Error: branch and target_branch are both '{TARGET_BRANCH}'. They must differ.") + + target_safe = TARGET_BRANCH.replace("/", "-") + + OUTPUT_DIR.mkdir(parents=True, exist_ok=True) + + for backend in BACKENDS: + Path(REPO_ROOT / f"out-{branch_safe}-{backend}").mkdir(exist_ok=True) + Path(REPO_ROOT / f"out-{target_safe}-{backend}").mkdir(exist_ok=True) + + print(f"Comparing: {BRANCH} vs {TARGET_BRANCH}") + print(f"Backends: {', '.join(BACKENDS)}") + print(f"Runs: {RUNS}, Warmup: {WARMUP}") + print(f"Skip compilation: {'yes' if args.skip_compile else 'no'}\n") + + if not args.skip_compile: + result = subprocess.run(["git", "diff-index", "--quiet", "HEAD", "--"], cwd=REPO_ROOT) + if result.returncode != 0: + sys.exit("Error: you have uncommitted changes. Commit or stash them first.") + + print(f"=== Building compiler on {BRANCH} ===") + run(["git", "checkout", "-q", BRANCH]) + run(["sbt", "install"]) + + print(f"\n=== Compiling benchmarks on {BRANCH} ===") + for backend in BACKENDS: + out_current = f"out-{branch_safe}-{backend}" + print(f"Backend: {backend}") + for bench_path in BENCHMARKS: + bench_name = Path(bench_path).name + source_file = f"examples/benchmarks/{bench_path}.effekt" + print(f" {bench_name}") + run(["effekt", f"--backend={backend}", "--build", "-o", out_current, source_file]) + + print(f"\n=== Building compiler on {TARGET_BRANCH} ===") + run(["git", "checkout", "-q", TARGET_BRANCH]) + run(["sbt", "install"]) + + print(f"\n=== Compiling benchmarks on {TARGET_BRANCH} ===") + for backend in BACKENDS: + out_target = f"out-{target_safe}-{backend}" + print(f"Backend: {backend}") + for bench_path in BENCHMARKS: + bench_name = Path(bench_path).name + source_file = f"examples/benchmarks/{bench_path}.effekt" + print(f" {bench_name}") + run(["effekt", f"--backend={backend}", "--build", "-o", out_target, source_file]) + + print(f"\n=== Switching back to {current_branch} ===") + run(["git", "checkout", "-q", current_branch]) + else: + print("=== Skipping compilation (using existing binaries) ===\n") + + print("=== Starting benchmarks ===\n") + + try: + for backend in BACKENDS: + print(f"=== Benchmarking backend: {backend} ===") + out_current = f"out-{branch_safe}-{backend}" + out_main = f"out-{target_safe}-{backend}" + results_dir = OUTPUT_DIR / f"comparison_{backend}_{branch_safe}_vs_{target_safe}_{timestamp}" + results_dir.mkdir(parents=True, exist_ok=True) + + for bench_path, n in BENCHMARKS.items(): + bench_name = Path(bench_path).name + print(f" {bench_name}") + result = subprocess.run([ + "hyperfine", + "--warmup", str(WARMUP), + "--runs", str(RUNS), + "--export-json", str(results_dir / f"{bench_name}.json"), + "--command-name", TARGET_BRANCH, + bench_exec(backend, out_main, bench_name, n), + "--command-name", BRANCH, + bench_exec(backend, out_current, bench_name, n), + ], cwd=REPO_ROOT) + if result.returncode != 0: + print(f" (skipped {bench_name} — hyperfine failed)") + + print(f"Results: {results_dir}/\n") + finally: + # Always make sure we end up on the original branch + if git_current_branch() != current_branch: + print(f"=== Switching back to {current_branch} ===") + run(["git", "checkout", "-q", current_branch]) + + print(f"Done! Results in: {OUTPUT_DIR}/") + + +if __name__ == "__main__": + main() diff --git a/python_benchmark/benchmark.yml b/python_benchmark/benchmark.yml new file mode 100644 index 0000000000..53ffa0ec47 --- /dev/null +++ b/python_benchmark/benchmark.yml @@ -0,0 +1,92 @@ +backends: + - llvm + +warmup: 10 +runs: 50 +branch: konradbausch/arity-raising +target_branch: main +output_dir: benchmark-results + +benchmarks: + # - path: arity_raising/bad_mark + # n: 160000 + - path: arity_raising/bad_mark_2 + n: 160000 + + # - path: large_record/return_int_recreate_1 + # n: 160000000 + # - path: large_record/return_int_recreate_2 + # n: 140000000 + # - path: large_record/return_int_recreate_3 + # n: 4000000000 + # - path: large_record/return_int_recreate_4 + # n: 150000000 + # - path: large_record/return_int_recreate_5 + # n: 150000000 + # - path: large_record/return_int_recreate_6 + # n: 130000000 + # - path: large_record/return_int_recreate_7 + # n: 95000000 + # - path: large_record/return_int_recreate_8 + # n: 85000000 + # - path: large_record/return_int_recreate_9 + # n: 75000000 + # - path: large_record/return_int_recreate_10 + # n: 75000000 + # - path: large_record/return_int_recreate_11 + # n: 70000000 + # - path: large_record/return_int_recreate_12 + # n: 65000000 + # - path: large_record/return_int_recreate_13 + # n: 65000000 + # - path: large_record/return_int_recreate_14 + # n: 37000000 + # - path: large_record/return_int_recreate_15 + # n: 55000000 + # - path: large_record/return_int_recreate_16 + # n: 55000000 + # - path: large_record/return_int_recreate_17 + # n: 50000000 + # - path: large_record/return_int_recreate_18 + # n: 50000000 + # - path: large_record/return_int_recreate_19 + # n: 45000000 + # - path: large_record/return_int_recreate_20 + # n: 40000000 + + # - path: nested_record/return_int_recreate_0 + # n: 2000 + # - path: nested_record/return_int_recreate_25 + # n: 240000 + # - path: nested_record/return_int_recreate_50 + # n: 120000 + # - path: nested_record/return_int_recreate_75 + # n: 83000 + # - path: nested_record/return_int_recreate_100 + # n: 62000 + # - path: nested_record/return_int_recreate_125 + # n: 47000 + # - path: nested_record/return_int_recreate_150 + # n: 38000 + # - path: nested_record/return_int_recreate_175 + # n: 30000 + # - path: nested_record/return_int_recreate_200 + # n: 25000 + # - path: nested_record/return_int_recreate_225 + # n: 20000 + # - path: nested_record/return_int_recreate_250 + # n: 16000 + # - path: nested_record/return_int_recreate_275 + # n: 13000 + # - path: nested_record/return_int_recreate_300 + # n: 11000 + # - path: nested_record/return_int_recreate_325 + # n: 9000 + # - path: nested_record/return_int_recreate_350 + # n: 7500 + # - path: nested_record/return_int_recreate_375 + # n: 6500 + # - path: nested_record/return_int_recreate_400 + # n: 6000 + # - path: nested_record/return_int_recreate_425 + # n: 5000 diff --git a/python_benchmark/benchmark_to_csv.py b/python_benchmark/benchmark_to_csv.py new file mode 100755 index 0000000000..e0ecbc7d13 --- /dev/null +++ b/python_benchmark/benchmark_to_csv.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +""" +Converts a directory of per-benchmark hyperfine JSON files to CSV. +Usage: ./benchmark_to_csv.py [output.csv] + If output.csv is omitted, prints to stdout. +""" + +import sys +import re +import csv +import json +import math +from pathlib import Path + +if len(sys.argv) < 2: + print(f"Usage: {sys.argv[0]} [output.csv]", file=sys.stderr) + sys.exit(1) + +results_dir = Path(sys.argv[1]) +output = sys.argv[2] if len(sys.argv) > 2 else None + +results = [] + +for json_file in results_dir.glob('*.json'): + entry = json.loads(json_file.read_text()) + name = json_file.stem + by_cmd = {r['command']: r for r in entry['results']} + + if 'main' not in by_cmd or len(by_cmd) < 2: + continue + + main_r = by_cmd['main'] + branch_r = next(r for cmd, r in by_cmd.items() if cmd != 'main') + + # hyperfine stores times in seconds; convert to ms + main_mean = main_r['mean'] * 1000 + main_pm = main_r['stddev'] * 1000 + br_mean = branch_r['mean'] * 1000 + br_pm = branch_r['stddev'] * 1000 + + speedup = main_mean / br_mean + # error propagation for f = a/b: σ_f/f = sqrt((σ_a/a)² + (σ_b/b)²) + speedup_pm = speedup * math.sqrt((main_pm / main_mean) ** 2 + (br_pm / br_mean) ** 2) + + results.append((name, speedup, speedup_pm, br_mean, br_pm, main_mean, main_pm)) + +# Natural sort: split name into text/number chunks so e.g. _2 < _11 +def natural_key(row): + return [int(c) if c.isdigit() else c for c in re.split(r'(\d+)', row[0])] + +results.sort(key=natural_key) + +header = ['benchmark', 'speedup', 'speedup_pm', 'ar_mean_ms', 'ar_pm_ms', 'main_mean_ms', 'main_pm_ms'] + +def fmt(v, decimals=2): + return f"{v:.{decimals}f}" + +fh = open(output, 'w', newline='') if output else sys.stdout + +writer = csv.writer(fh) +writer.writerow(header) +for name, speedup, speedup_pm, ar_mean, ar_pm, main_mean, main_pm in results: + writer.writerow([ + name, + fmt(speedup), + fmt(speedup_pm) if speedup_pm is not None else '', + fmt(ar_mean, 1), + fmt(ar_pm, 1), + fmt(main_mean, 1), + fmt(main_pm, 1), + ]) + +if output: + fh.close() + print(f"Written to {output}", file=sys.stderr) diff --git a/python_benchmark/create.sh b/python_benchmark/create.sh index 772b06978f..25f52a0b9e 100755 --- a/python_benchmark/create.sh +++ b/python_benchmark/create.sh @@ -1,18 +1,28 @@ #!/bin/bash +NESTED_OUT="../examples/benchmarks/nested_record" +LARGE_OUT="../examples/benchmarks/large_record" + +mkdir -p "$NESTED_OUT" "$LARGE_OUT" + MAX_NESTED_RECORD_SIZE=1000 for i in $(seq 1 $MAX_NESTED_RECORD_SIZE); do - python create_nested_record.py $i > ../examples/benchmarks/nested_records/nested_records_$i.effekt - python create_nested_record_no_rec.py $i > ../examples/benchmarks/nested_records/nested_records_no_rec_$i.effekt + python nested_record/create_return_int_recreate.py $i > "$NESTED_OUT/return_int_recreate_$i.effekt" + python nested_record/create_return_int_reuse.py $i > "$NESTED_OUT/return_int_reuse_$i.effekt" + python nested_record/create_return_record_recreate.py $i > "$NESTED_OUT/return_record_recreate_$i.effekt" + python nested_record/create_return_record_reuse.py $i > "$NESTED_OUT/return_record_reuse_$i.effekt" done echo "Generated files from 1 to $MAX_NESTED_RECORD_SIZE for nested records" MAX_LARGE_RECORD_SIZE=100 + for i in $(seq 1 $MAX_LARGE_RECORD_SIZE); do - python create_large_record.py $i > ../examples/benchmarks/large_records/large_records_$i.effekt - python create_large_record_no_rec.py $i > ../examples/benchmarks/large_records/large_records_no_rec_$i.effekt + python large_record/create_return_int_recreate.py $i > "$LARGE_OUT/return_int_recreate_$i.effekt" + python large_record/create_return_int_reuse.py $i > "$LARGE_OUT/return_int_reuse_$i.effekt" + python large_record/create_return_record_recreate.py $i > "$LARGE_OUT/return_record_recreate_$i.effekt" + python large_record/create_return_record_reuse.py $i > "$LARGE_OUT/return_record_reuse_$i.effekt" done echo "Generated files from 1 to $MAX_LARGE_RECORD_SIZE for large records" diff --git a/python_benchmark/create_large_record.py b/python_benchmark/large_record/create_return_int_recreate.py similarity index 100% rename from python_benchmark/create_large_record.py rename to python_benchmark/large_record/create_return_int_recreate.py diff --git a/python_benchmark/create_large_record_no_rec.py b/python_benchmark/large_record/create_return_int_reuse.py similarity index 100% rename from python_benchmark/create_large_record_no_rec.py rename to python_benchmark/large_record/create_return_int_reuse.py diff --git a/python_benchmark/large_record/create_return_record_recreate.py b/python_benchmark/large_record/create_return_record_recreate.py new file mode 100644 index 0000000000..ff6e8996db --- /dev/null +++ b/python_benchmark/large_record/create_return_record_recreate.py @@ -0,0 +1,35 @@ +import sys + +length = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +fields = [str(i) for i in range(length)] +field_types = ", ".join([f"x{i}: Int" for i in fields]) +result_field_sum = " + ".join([f"result.x{i}" for i in fields]) +field_values = ", ".join([f"i + {i}" for i in fields]) +shifted_fields = ", ".join([f"m.x{i}" for i in (fields[-1:] + fields[:-1])]) + +print(f"record Rec({field_types})") +print(f""" +def recfunc(m: Rec, depth: Int): Rec = {{ + if (depth <= 0) {{ m }} + else {{recfunc(Rec({shifted_fields}), depth - 1)}} +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + val rec = Rec({field_values}) + val result = recfunc(rec, 2) + loop(i - 1, acc + {result_field_sum}) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") diff --git a/python_benchmark/large_record/create_return_record_reuse.py b/python_benchmark/large_record/create_return_record_reuse.py new file mode 100644 index 0000000000..e27784c47a --- /dev/null +++ b/python_benchmark/large_record/create_return_record_reuse.py @@ -0,0 +1,34 @@ +import sys + +length = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +fields = [str(i) for i in range(length)] +field_types = ", ".join([f"x{i}: Int" for i in fields]) +result_field_sum = " + ".join([f"result.x{i}" for i in fields]) +field_values = ", ".join([f"i + {i}" for i in fields]) + +print(f"record Rec({field_types})") +print(f""" +def recfunc(m: Rec, depth: Int): Rec = {{ + if (depth <= 0) {{ m }} + else {{recfunc(m, depth - 1)}} +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + val rec = Rec({field_values}) + val result = recfunc(rec, 2) + loop(i - 1, acc + {result_field_sum}) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") diff --git a/python_benchmark/create_nested_record.py b/python_benchmark/nested_record/create_return_int_recreate.py similarity index 100% rename from python_benchmark/create_nested_record.py rename to python_benchmark/nested_record/create_return_int_recreate.py diff --git a/python_benchmark/create_nested_record_no_rec.py b/python_benchmark/nested_record/create_return_int_reuse.py similarity index 100% rename from python_benchmark/create_nested_record_no_rec.py rename to python_benchmark/nested_record/create_return_int_reuse.py diff --git a/python_benchmark/nested_record/create_return_record_recreate.py b/python_benchmark/nested_record/create_return_record_recreate.py new file mode 100644 index 0000000000..e8355fae1f --- /dev/null +++ b/python_benchmark/nested_record/create_return_record_recreate.py @@ -0,0 +1,43 @@ +import sys + +nesting = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +rec_constructor = "Rec0(1, 1)" + +for i in range(nesting): + if i == 0: + print("record Rec0(a: Int, b: Int)") + print(""" +def recfunc0(m: Rec0, depth: Int): Rec0 = { + m +} +""") + else: + rec_constructor = f"Rec{i}({rec_constructor}, {i} - i)" + print(f"record Rec{i}(a: Rec{i-1}, b: Int)") + print(f""" +def recfunc{i}(m: Rec{i}, depth: Int): Rec{i} = {{ + + if (depth <= 0) {{ Rec{i}(recfunc{i-1}(m.a, 2), m.b) }} + else {{ recfunc{i}(Rec{i}(m.a, m.b + 1), depth - 1) }} + +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + val rec = {rec_constructor} + val result = recfunc{nesting - 1}(rec, 2) + loop(i - 1, acc + result.b) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }") diff --git a/python_benchmark/nested_record/create_return_record_reuse.py b/python_benchmark/nested_record/create_return_record_reuse.py new file mode 100644 index 0000000000..6cebc3605c --- /dev/null +++ b/python_benchmark/nested_record/create_return_record_reuse.py @@ -0,0 +1,43 @@ +import sys + +nesting = int(sys.argv[1]) + +print("import examples/benchmarks/runner") + +rec_constructor = "Rec0(1, 1)" + +for i in range(nesting): + if i == 0: + print("record Rec0(a: Int, b: Int)") + print(""" +def recfunc0(m: Rec0, depth: Int): Rec0 = { + m +} +""") + else: + rec_constructor = f"Rec{i}({rec_constructor}, {i} - i)" + print(f"record Rec{i}(a: Rec{i-1}, b: Int)") + print(f""" +def recfunc{i}(m: Rec{i}, depth: Int): Rec{i} = {{ + + if (depth <= 0) {{ Rec{i}(recfunc{i-1}(m.a, 2), m.b) }} + else {{ recfunc{i}(m, depth - 1) }} + +}} +""") + +print(f""" +def runBenchmark(n: Int): Int = {{ + def loop(i: Int, acc: Int): Int = {{ + if (i <= 0) {{ acc }} + else {{ + val rec = {rec_constructor} + val result = recfunc{nesting - 1}(rec, 2) + loop(i - 1, acc + result.b) + }} + }} + loop(n, 0) +}} +""") + +print("def main() = benchmark(1000000){ n => runBenchmark(n) }")