From c41b1ee200ffb51b566f0151c02e1c5237f0ed1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Brachtha=CC=88user?= Date: Thu, 18 Jan 2024 18:37:19 +0100 Subject: [PATCH] Partially use templates for LLVM --- .../effekt/generator/llvm/Transformer.scala | 7 ++++++- .../scala/effekt/machine/Transformer.scala | 12 +++++------- .../src/main/scala/effekt/machine/Tree.scala | 2 +- libraries/llvm/effekt.effekt | 18 +++++++++--------- 4 files changed, 21 insertions(+), 18 deletions(-) diff --git a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala index c5bdd2611..c413aab7c 100644 --- a/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/generator/llvm/Transformer.scala @@ -3,6 +3,7 @@ package generator package llvm import effekt.machine +import effekt.util.intercalate import effekt.machine.analysis.* import scala.collection.mutable @@ -42,11 +43,15 @@ object Transformer { case machine.Extern(functionName, parameters, returnType, body) => VerbatimFunction(transform(returnType), functionName, parameters.map { case machine.Variable(name, tpe) => Parameter(transform(tpe), name) - }, body) + }, transform(body)) case machine.Include(content) => Verbatim(content) } + def transform(t: Template[machine.Variable]): String = intercalate(t.strings, t.args.map { + case machine.Variable(name, tpe) => PrettyPrinter.localName(name) + }).mkString + def transform(statement: machine.Statement)(using ModuleContext, FunctionContext, BlockContext): Terminator = statement match { diff --git a/effekt/shared/src/main/scala/effekt/machine/Transformer.scala b/effekt/shared/src/main/scala/effekt/machine/Transformer.scala index c8dad97f7..1ec400a3c 100644 --- a/effekt/shared/src/main/scala/effekt/machine/Transformer.scala +++ b/effekt/shared/src/main/scala/effekt/machine/Transformer.scala @@ -47,7 +47,7 @@ object Transformer { } def transform(extern: lifted.Extern)(using BlocksParamsContext, ErrorReporter): Declaration = extern match { - case lifted.Extern.Def(name, tps, params, ret, body) => + case lifted.Extern.Def(name, tps, params, ret, Template(strings, args)) => val transformedParams = params.flatMap { case lifted.ValueParam(id, tpe) => Some(Variable(id.name.name, transform(tpe))) case lifted.BlockParam(id, tpe) => ErrorReporter.abort("Foreign functions currently cannot take block arguments.") @@ -55,17 +55,15 @@ object Transformer { case lifted.EvidenceParam(id) => None // Variable(id.name.name, builtins.Evidence) } noteBlockParams(name, params map transform, List.empty) - Extern(transform(name), transformedParams, transform(ret), transform(body)) + Extern(transform(name), transformedParams, transform(ret), Template(strings, args map { + case lifted.ValueVar(id, tpe) => Variable(id.name.name, transform(tpe)) + case _ => ErrorReporter.abort("In the LLVM backend, only variables are allowed in templates") + })) case lifted.Extern.Include(contents) => Include(contents) } - def transform(t: Template[lifted.Expr]): String = t match { - case Template(List(string), Nil) => string - case _ => sys error "Splices not yet supported in backends based on Machine IR" - } - def transform(stmt: lifted.Stmt)(using BPC: BlocksParamsContext, DC: DeclarationContext, E: ErrorReporter): Statement = stmt match { case lifted.Scope(definitions, rest) => diff --git a/effekt/shared/src/main/scala/effekt/machine/Tree.scala b/effekt/shared/src/main/scala/effekt/machine/Tree.scala index a51081fd6..587582ef8 100644 --- a/effekt/shared/src/main/scala/effekt/machine/Tree.scala +++ b/effekt/shared/src/main/scala/effekt/machine/Tree.scala @@ -45,7 +45,7 @@ case class Program(declarations: List[Declaration], program: Statement) * Toplevel declarations for FFI */ enum Declaration { - case Extern(name: String, parameters: Environment, returnType: Type, body: String) + case Extern(name: String, parameters: Environment, returnType: Type, body: Template[Variable]) case Include(contents: String) } export Declaration.* diff --git a/libraries/llvm/effekt.effekt b/libraries/llvm/effekt.effekt index 4cf69eaa1..ecb3046a5 100644 --- a/libraries/llvm/effekt.effekt +++ b/libraries/llvm/effekt.effekt @@ -62,20 +62,20 @@ extern pure def infixConcat(s: String, z: String): String = """ // integer arithmetic -extern pure def infixAdd(x: Int, y: Int): Int = "%z = add %Int %x, %y ret %Int %z" -extern pure def infixSub(x: Int, y: Int): Int = "%z = sub %Int %x, %y ret %Int %z" -extern pure def infixMul(x: Int, y: Int): Int = "%z = mul %Int %x, %y ret %Int %z" -extern pure def infixDiv(x: Int, y: Int): Int = "%z = sdiv %Int %x, %y ret %Int %z" +extern pure def infixAdd(x: Int, y: Int): Int = "%z = add %Int ${x}, ${y} ret %Int %z" +extern pure def infixSub(x: Int, y: Int): Int = "%z = sub %Int ${x}, ${y} ret %Int %z" +extern pure def infixMul(x: Int, y: Int): Int = "%z = mul %Int ${x}, ${y} ret %Int %z" +extern pure def infixDiv(x: Int, y: Int): Int = "%z = sdiv %Int ${x}, ${y} ret %Int %z" -extern pure def mod (x: Int, y: Int): Int = "%z = srem %Int %x, %y ret %Int %z" +extern pure def mod (x: Int, y: Int): Int = "%z = srem %Int ${x}, ${y} ret %Int %z" // floating-point arithmetic -extern pure def infixAdd(x: Double, y: Double): Double = "%z = fadd %Double %x, %y ret %Double %z" -extern pure def infixSub(x: Double, y: Double): Double = "%z = fsub %Double %x, %y ret %Double %z" -extern pure def infixMul(x: Double, y: Double): Double = "%z = fmul %Double %x, %y ret %Double %z" -extern pure def infixDiv(x: Double, y: Double): Double = "%z = fdiv %Double %x, %y ret %Double %z" +extern pure def infixAdd(x: Double, y: Double): Double = "%z = fadd %Double ${x}, ${y} ret %Double %z" +extern pure def infixSub(x: Double, y: Double): Double = "%z = fsub %Double ${x}, ${y} ret %Double %z" +extern pure def infixMul(x: Double, y: Double): Double = "%z = fmul %Double ${x}, ${y} ret %Double %z" +extern pure def infixDiv(x: Double, y: Double): Double = "%z = fdiv %Double ${x}, ${y} ret %Double %z" // ordering on signed integers