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"
|
DIRECTORY="src/test/kotlin/tests"
|
||||||
MAIN="$DIRECTORY/linked/main.c"
|
MAIN="$DIRECTORY/linked/main.c"
|
||||||
for i in $( ls "$DIRECTORY/input"); do
|
for i in $( ls "$DIRECTORY/input" $1); do
|
||||||
rm -f $DIRECTORY/linked/*
|
rm -f $DIRECTORY/linked/*
|
||||||
TEST=`basename $i ".txt"`
|
TEST=`basename $i ".txt"`
|
||||||
echo test: $TEST
|
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
|
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
|
llvm-link-3.6 $DIRECTORY/linked/* > $DIRECTORY/linked/run.ll
|
||||||
lli-3.6 $DIRECTORY/linked/run.ll
|
lli-3.6 $DIRECTORY/linked/run.ll
|
||||||
|
exit
|
||||||
done
|
done
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class FunctionCodegen(override val state: TranslationState,
|
|||||||
val receiverType = receiverParameter.type
|
val receiverType = receiverParameter.type
|
||||||
val translatorType = LLVMMapStandardType(receiverType)
|
val translatorType = LLVMMapStandardType(receiverType)
|
||||||
|
|
||||||
val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType, HashMap())
|
val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType.toString(), HashMap())
|
||||||
extensionFunctionsOfThisType.put(name, this)
|
extensionFunctionsOfThisType.put(name, this)
|
||||||
state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType)
|
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 {
|
fun LLVMInstanceOfStandardType(name: String, type: KotlinType, scope: LLVMScope = LLVMRegisterScope()): LLVMVariable = when {
|
||||||
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), name, scope, pointer = 1)
|
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type), name, scope, pointer = 1)
|
||||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope)
|
type.toString() == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope)
|
||||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope)
|
|
||||||
type.toString() == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope)
|
type.toString() == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope)
|
||||||
type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), 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.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope)
|
||||||
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(type.toString().dropLast(1)), name, scope, pointer = 1)
|
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(type.toString().dropLast(1)), name, scope, pointer = 1)
|
||||||
else -> LLVMVariable(name, LLVMReferenceType(type.toString()), 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) {
|
fun parseLLVMType(type: String): LLVMType = when (type) {
|
||||||
|
"i64" -> LLVMLongType()
|
||||||
"i32" -> LLVMIntType()
|
"i32" -> LLVMIntType()
|
||||||
"i16" -> LLVMShortType()
|
"i16" -> LLVMShortType()
|
||||||
"i8" -> LLVMCharType()
|
"i8" -> LLVMCharType()
|
||||||
"i1" -> LLVMBooleanType()
|
"i1" -> LLVMBooleanType()
|
||||||
"double" -> LLVMDoubleType()
|
"double" -> LLVMDoubleType()
|
||||||
|
"float" -> LLVMFloatType()
|
||||||
"Unit" -> LLVMVoidType()
|
"Unit" -> LLVMVoidType()
|
||||||
else -> LLVMReferenceType(type)
|
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