Skip to content

Commit

Permalink
Partially use templates for LLVM
Browse files Browse the repository at this point in the history
  • Loading branch information
b-studios committed Jan 18, 2024
1 parent 1c809d9 commit c41b1ee
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package generator
package llvm

import effekt.machine
import effekt.util.intercalate
import effekt.machine.analysis.*

import scala.collection.mutable
Expand Down Expand Up @@ -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 {

Expand Down
12 changes: 5 additions & 7 deletions effekt/shared/src/main/scala/effekt/machine/Transformer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,23 @@ 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.")
// for now, in machine we do not pass evidence to externs
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) =>
Expand Down
2 changes: 1 addition & 1 deletion effekt/shared/src/main/scala/effekt/machine/Tree.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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.*
Expand Down
18 changes: 9 additions & 9 deletions libraries/llvm/effekt.effekt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit c41b1ee

Please sign in to comment.