This commit is contained in:
e5l
2016-07-11 16:12:37 +03:00
5 changed files with 55 additions and 17 deletions
@@ -4,15 +4,14 @@ import com.intellij.psi.tree.IElementType
import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.lexer.KtTokens
import org.kotlinnative.translator.llvm.types.LLVMIntType import org.kotlinnative.translator.llvm.types.LLVMIntType
import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMType
import kotlin.reflect.KFunction0
class LLVMBuilder { class LLVMBuilder {
private var llvmCode: StringBuilder = StringBuilder() private var llvmCode: StringBuilder = StringBuilder()
private var variableCount = 0 private var variableCount = 0
fun getNewVariable(type: KFunction0<LLVMType>?): LLVMVariable { fun getNewVariable(type: LLVMType?): LLVMVariable {
variableCount++ variableCount++
return LLVMVariable("%var$variableCount", type?.invoke()) return LLVMVariable("%var$variableCount", type)
} }
fun addLLVMCode(code: String) { fun addLLVMCode(code: String) {
@@ -28,18 +27,23 @@ class LLVMBuilder {
} }
fun addPrimitiveBinaryOperation(operation: IElementType, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMVariable { fun addPrimitiveBinaryOperation(operation: IElementType, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMVariable {
val newVar = getNewVariable(::LLVMIntType) val newVar = getNewVariable(LLVMIntType())
val llvmOperator = when (operation) { val llvmExpression = when (operation) {
KtTokens.PLUS -> "add nsw i32" KtTokens.PLUS -> firstOp.type!!.operatorPlus(newVar, firstOp, secondOp)
KtTokens.MINUS -> "sub nsw i32" KtTokens.MINUS -> firstOp.type!!.operatorMinus(newVar, firstOp, secondOp)
KtTokens.MUL -> "mul nsw i32" KtTokens.MUL -> firstOp.type!!.operatorTimes(newVar, firstOp, secondOp)
else -> throw UnsupportedOperationException("Unknown binary operator") else -> throw UnsupportedOperationException("Unkbown binary operator")
} }
llvmCode.appendln("$newVar = $llvmOperator $firstOp, $secondOp") addAssignment(newVar, llvmExpression)
return newVar return newVar
} }
fun addAssignment(llvmVariable: LLVMNode, assignExpression: LLVMNode) {
llvmCode.appendln("$llvmVariable = $assignExpression")
}
fun clean() { fun clean() {
llvmCode = StringBuilder() llvmCode = StringBuilder()
} }
@@ -1,14 +1,11 @@
package org.kotlinnative.translator.llvm package org.kotlinnative.translator.llvm
import org.kotlinnative.translator.llvm.types.LLVMType import org.kotlinnative.translator.llvm.types.LLVMType
import kotlin.reflect.KFunction0
open class LLVMExpression(val variableType: KFunction0<LLVMType>, val llvmCode: String) : LLVMNode() { class LLVMExpression(val variableType: LLVMType, val llvmCode: String) : LLVMNode() {
fun generateExpression(builder: LLVMBuilder): LLVMVariable { override fun toString(): String {
val newVar = builder.getNewVariable(variableType) return llvmCode
builder.addLLVMCode("%$newVar = $llvmCode")
return newVar
} }
} }
@@ -0,0 +1,24 @@
package org.kotlinnative.translator.llvm.types
import org.kotlinnative.translator.llvm.LLVMExpression
import org.kotlinnative.translator.llvm.LLVMVariable
class LLVMDoubleType() : LLVMType() {
override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
//TODO switch by types: int + double = int
return LLVMExpression(LLVMDoubleType(), "fsub double i32 $firstOp, $secondOp")
}
override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
//TODO switch by types: int + double = int
return LLVMExpression(LLVMDoubleType(), "fmul double i32 $firstOp, $secondOp")
}
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
//TODO switch by types: int + double = int
return LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp")
}
}
@@ -6,9 +6,19 @@ import org.kotlinnative.translator.llvm.LLVMVariable
class LLVMIntType() : LLVMType() { class LLVMIntType() : LLVMType() {
override fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
//TODO switch by types: int + double = int
return LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp")
}
override fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
//TODO switch by types: int + double = int
return LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp")
}
override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression { override fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression {
//TODO switch by types: int + double = int //TODO switch by types: int + double = int
return LLVMExpression(::LLVMIntType, "add nsw i32 $firstOp, $secondOp") return LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp")
} }
override fun toString(): String { override fun toString(): String {
@@ -5,7 +5,10 @@ import org.kotlinnative.translator.llvm.LLVMExpression
import org.kotlinnative.translator.llvm.LLVMVariable import org.kotlinnative.translator.llvm.LLVMVariable
abstract class LLVMType() { abstract class LLVMType() {
abstract fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression; abstract fun operatorPlus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression;
abstract fun operatorTimes(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression;
abstract fun operatorMinus(result: LLVMVariable, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMExpression;
} }
fun parseLLVMType(type: String): LLVMType = when(type) { fun parseLLVMType(type: String): LLVMType = when(type) {