translator: add cast extensions, add float, long types, add support test order in tests, add Primitives in kotlib, fix extension function resolving
This commit is contained in:
@@ -7,7 +7,7 @@ fi
|
||||
|
||||
DIRECTORY="src/test/kotlin/tests"
|
||||
MAIN="$DIRECTORY/linked/main.c"
|
||||
for i in $( ls "$DIRECTORY/input"); do
|
||||
for i in $( ls "$DIRECTORY/input" $1); do
|
||||
rm -f $DIRECTORY/linked/*
|
||||
TEST=`basename $i ".txt"`
|
||||
echo test: $TEST
|
||||
@@ -40,7 +40,7 @@ for i in $( ls "$DIRECTORY/input"); do
|
||||
java -jar build/libs/ast-kotlin-1.0-SNAPSHOT.jar $DIRECTORY/kotlin/$TEST.kt > $DIRECTORY/linked/$TEST.ll
|
||||
llvm-link-3.6 $DIRECTORY/linked/* > $DIRECTORY/linked/run.ll
|
||||
lli-3.6 $DIRECTORY/linked/run.ll
|
||||
|
||||
exit
|
||||
done
|
||||
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class FunctionCodegen(override val state: TranslationState,
|
||||
val receiverType = receiverParameter.type
|
||||
val translatorType = LLVMMapStandardType(receiverType)
|
||||
|
||||
val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType, HashMap())
|
||||
val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType.toString(), HashMap())
|
||||
extensionFunctionsOfThisType.put(name, this)
|
||||
state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType)
|
||||
|
||||
|
||||
@@ -14,11 +14,14 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnTy
|
||||
|
||||
fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope()): LLVMVariable = when {
|
||||
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), name, scope, pointer = 1)
|
||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope)
|
||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope)
|
||||
type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope)
|
||||
type.toString() == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope)
|
||||
type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope)
|
||||
type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope)
|
||||
type.toString() == "Short" -> LLVMVariable(name, LLVMShortType(), name, scope)
|
||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope)
|
||||
type.toString() == "Long" -> LLVMVariable(name, LLVMLongType(), name, scope)
|
||||
type.toString() == "Float" -> LLVMVariable(name, LLVMFloatType(), name, scope)
|
||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope)
|
||||
type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope)
|
||||
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(type.toString().dropLast(1)), name, scope, pointer = 1)
|
||||
else -> LLVMVariable(name, LLVMReferenceType(type.toString()), name, scope, pointer = 1)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
|
||||
class LLVMFloatType() : LLVMType() {
|
||||
|
||||
//TODO switch by types: int + double = int
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMFloatType(), "fsub float i32 $firstOp, $secondOp")
|
||||
|
||||
//TODO switch by types: int + double = int
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMFloatType(), "fmul float i32 $firstOp, $secondOp")
|
||||
|
||||
//TODO switch by types: int + double = int
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMFloatType(), "fadd float $firstOp, $secondOp")
|
||||
|
||||
override val align = 4
|
||||
override var size: Int = 4
|
||||
override fun toString() = "float"
|
||||
override val defaultValue = "0.0"
|
||||
override fun isPrimitive() = true
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
|
||||
class LLVMLongType() : LLVMType() {
|
||||
|
||||
override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "or i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "and i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "xor i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "shl i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "ashr i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "lshr i64 $firstOp, $secondOp")
|
||||
|
||||
//TODO switch by types: int + double = int
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "sub nsw i64 $firstOp, $secondOp")
|
||||
|
||||
//TODO switch by types: int + double = int
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "mul nsw i64 $firstOp, $secondOp")
|
||||
|
||||
//TODO switch by types: int + double = int
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMLongType(), "add nsw i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression {
|
||||
return LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp")
|
||||
}
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i64 $firstOp, $secondOp")
|
||||
|
||||
override val align = 4
|
||||
override var size: Int = 8
|
||||
override val defaultValue = "0"
|
||||
|
||||
override fun toString() = "i64"
|
||||
override fun isPrimitive() = true
|
||||
}
|
||||
@@ -32,11 +32,13 @@ abstract class LLVMType() : Cloneable {
|
||||
}
|
||||
|
||||
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||
"i64" -> LLVMLongType()
|
||||
"i32" -> LLVMIntType()
|
||||
"i16" -> LLVMShortType()
|
||||
"i8" -> LLVMCharType()
|
||||
"i1" -> LLVMBooleanType()
|
||||
"double" -> LLVMDoubleType()
|
||||
"float" -> LLVMFloatType()
|
||||
"Unit" -> LLVMVoidType()
|
||||
else -> LLVMReferenceType(type)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
external fun kotlinclib_intToByte(value: Int): Byte
|
||||
external fun kotlinclib_intToChar(value: Int): Char
|
||||
external fun kotlinclib_intToShort(value: Int): Short
|
||||
external fun kotlinclib_intToLong(value: Int): Long
|
||||
external fun kotlinclib_intToFloat(value: Int): Float
|
||||
external fun kotlinclib_intToDouble(value: Int): Double
|
||||
|
||||
fun Int.toByte(): Byte {
|
||||
return kotlinclib_intToByte(this)
|
||||
}
|
||||
|
||||
fun Int.toInt(): Int {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Int.toChar(): Char {
|
||||
return kotlinclib_intToChar(this)
|
||||
}
|
||||
|
||||
fun Int.toShort(): Short {
|
||||
return kotlinclib_intToShort(this)
|
||||
}
|
||||
|
||||
fun Int.toLong(): Long {
|
||||
return kotlinclib_intToLong(this)
|
||||
}
|
||||
|
||||
fun Int.toFloat(): Float {
|
||||
return kotlinclib_intToFloat(this)
|
||||
}
|
||||
|
||||
fun Int.toDouble(): Double {
|
||||
return kotlinclib_intToDouble(this)
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
; ModuleID = 'primitives.c'
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-pc-linux-gnu"
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define signext i8 @kotlinclib_intToByte(i32 %value) #0 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %value, i32* %1, align 4
|
||||
%2 = load i32* %1, align 4
|
||||
%3 = trunc i32 %2 to i8
|
||||
ret i8 %3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define signext i8 @kotlinclib_intToChar(i32 %value) #0 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %value, i32* %1, align 4
|
||||
%2 = load i32* %1, align 4
|
||||
%3 = trunc i32 %2 to i8
|
||||
ret i8 %3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define signext i16 @kotlinclib_intToShort(i32 %value) #0 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %value, i32* %1, align 4
|
||||
%2 = load i32* %1, align 4
|
||||
%3 = trunc i32 %2 to i16
|
||||
ret i16 %3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define i64 @kotlinclib_intToLong(i32 %value) #0 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %value, i32* %1, align 4
|
||||
%2 = load i32* %1, align 4
|
||||
%3 = sext i32 %2 to i64
|
||||
ret i64 %3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define float @kotlinclib_intToFloat(i32 %value) #0 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %value, i32* %1, align 4
|
||||
%2 = load i32* %1, align 4
|
||||
%3 = sitofp i32 %2 to float
|
||||
ret float %3
|
||||
}
|
||||
|
||||
; Function Attrs: nounwind uwtable
|
||||
define double @kotlinclib_intToDouble(i32 %value) #0 {
|
||||
%1 = alloca i32, align 4
|
||||
store i32 %value, i32* %1, align 4
|
||||
%2 = load i32* %1, align 4
|
||||
%3 = sitofp i32 %2 to double
|
||||
ret double %3
|
||||
}
|
||||
|
||||
attributes #0 = { nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
||||
@@ -0,0 +1,4 @@
|
||||
testCastToInt(32) == 0
|
||||
testCastToInt(34) == 1
|
||||
testCastToByte(32) == 0
|
||||
testCastToByte(34) == 1
|
||||
@@ -0,0 +1,7 @@
|
||||
fun testCastToByte(X : Byte): Boolean{
|
||||
return 34.toByte() == X
|
||||
}
|
||||
|
||||
fun testCastToInt(X : Int): Boolean{
|
||||
return 34.toInt() == X
|
||||
}
|
||||
Reference in New Issue
Block a user