translator: add LLVMArray, access to string by index, basic type for string
This commit is contained in:
@@ -136,22 +136,24 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
is KtConstantExpression -> evaluateConstantExpression(expr)
|
is KtConstantExpression -> evaluateConstantExpression(expr)
|
||||||
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
||||||
is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr)
|
is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr)
|
||||||
is KtReferenceExpression -> evaluateReferenceExpression(expr)
|
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
|
||||||
is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true)
|
is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true)
|
||||||
is KtDotQualifiedExpression -> evaluateDotExpression(expr)
|
is KtDotQualifiedExpression -> evaluateDotExpression(expr)
|
||||||
is PsiWhiteSpace -> null
|
|
||||||
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr, scopeDepth + 1)
|
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr, scopeDepth + 1)
|
||||||
|
is PsiWhiteSpace -> null
|
||||||
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
|
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
|
||||||
null -> null
|
null -> null
|
||||||
else -> throw UnsupportedOperationException()
|
else -> throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun evaluateStringTemplateExpression(expr: KtStringTemplateExpression, scope: Int): LLVMSingleValue? {
|
fun evaluateStringTemplateExpression(expr: KtStringTemplateExpression, scope: Int): LLVMSingleValue? {
|
||||||
val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr)
|
val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr)
|
||||||
val type = (receiveValue as TypedCompileTimeConstant).type
|
val type = (receiveValue as TypedCompileTimeConstant).type
|
||||||
val value = receiveValue.getValue(type) ?: return null
|
val value = receiveValue.getValue(type) ?: return null
|
||||||
val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMGlobalScope(), pointer = false)
|
val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMGlobalScope(), pointer = false)
|
||||||
|
|
||||||
codeBuilder.addStringConstant(variable, value.toString())
|
codeBuilder.addStringConstant(variable, value.toString())
|
||||||
return variable
|
return variable
|
||||||
}
|
}
|
||||||
@@ -175,9 +177,19 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateReferenceExpression(expr: KtReferenceExpression): LLVMSingleValue? {
|
fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
|
||||||
val variableName = expr.firstChild.text
|
val arrayNameVariable = evaluateReferenceExpression(expr.arrayExpression as KtReferenceExpression, scope) as LLVMVariable
|
||||||
return variableManager.getLLVMvalue(variableName)
|
val arrayIndex = evaluateConstantExpression(expr.indexExpressions.first() as KtConstantExpression)
|
||||||
|
val arrayReceivedVariable = codeBuilder.loadAndGetVariable(arrayNameVariable)
|
||||||
|
val arrayElementType = (arrayNameVariable.type as LLVMArray).basicType()
|
||||||
|
val indexVariable = codeBuilder.getNewVariable(arrayElementType, pointer = true)
|
||||||
|
codeBuilder.loadVariableOffset(indexVariable, arrayReceivedVariable, arrayIndex);
|
||||||
|
return indexVariable
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int): LLVMSingleValue? = when (expr) {
|
||||||
|
is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
||||||
|
else -> variableManager.getLLVMvalue(expr.firstChild.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int): LLVMSingleValue? {
|
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int): LLVMSingleValue? {
|
||||||
@@ -286,8 +298,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
|||||||
val result = ArrayList<LLVMSingleValue>()
|
val result = ArrayList<LLVMSingleValue>()
|
||||||
|
|
||||||
for (arg in args) {
|
for (arg in args) {
|
||||||
val expr = evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
|
val currentExpression = evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
|
||||||
result.add(expr)
|
result.add(currentExpression)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -131,6 +131,11 @@ class LLVMBuilder(val arm: Boolean) {
|
|||||||
llvmLocalCode.appendln(code)
|
llvmLocalCode.appendln(code)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) {
|
||||||
|
val code = "$target = getelementptr inbounds ${target.type}, ${source.type} $source, ${index.type} ${index.value}"
|
||||||
|
llvmLocalCode.appendln(code)
|
||||||
|
}
|
||||||
|
|
||||||
fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) {
|
fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) {
|
||||||
val tmp = getNewVariable(source.type, source.pointer)
|
val tmp = getNewVariable(source.type, source.pointer)
|
||||||
llvmLocalCode.appendln("$tmp = load ${tmp.type}, ${source.getType()} $source, align ${tmp.type.align}")
|
llvmLocalCode.appendln("$tmp = load ${tmp.type}, ${source.getType()} $source, align ${tmp.type.align}")
|
||||||
|
|||||||
@@ -10,12 +10,13 @@ fun LLVMFunctionDescriptor(name: String, argTypes: List<LLVMVariable>?, returnTy
|
|||||||
"${if (declare) "declare" else "define"} $returnType @$name(${
|
"${if (declare) "declare" else "define"} $returnType @$name(${
|
||||||
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
|
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
|
||||||
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).isReturn) "byval" else ""} %${s.label}"
|
"${s.getType()} ${if (s.type is LLVMReferenceType && !(s.type as LLVMReferenceType).isReturn) "byval" else ""} %${s.label}"
|
||||||
}?.joinToString() }) ${ if (arm) "#0" else ""}"
|
}?.joinToString()}) ${if (arm) "#0" else ""}"
|
||||||
|
|
||||||
fun LLVMMapStandardType(name: String, type: KotlinType): LLVMVariable = when {
|
fun LLVMMapStandardType(name: String, type: KotlinType): LLVMVariable = when {
|
||||||
type.isFunctionType -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), pointer = true)
|
type.isFunctionType -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), pointer = true)
|
||||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString())
|
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString())
|
||||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString())
|
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString())
|
||||||
|
type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), type.toString())
|
||||||
type.isUnit() -> LLVMVariable("", LLVMVoidType())
|
type.isUnit() -> LLVMVariable("", LLVMVoidType())
|
||||||
else -> LLVMVariable(name, LLVMReferenceType("$type"), name, pointer = true)
|
else -> LLVMVariable(name, LLVMReferenceType("$type"), name, pointer = true)
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package org.kotlinnative.translator.llvm.types
|
||||||
|
|
||||||
|
interface LLVMArray {
|
||||||
|
|
||||||
|
fun basicType(): LLVMType
|
||||||
|
fun fullType(): String
|
||||||
|
|
||||||
|
val length: Int
|
||||||
|
}
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
package org.kotlinnative.translator.llvm.types
|
package org.kotlinnative.translator.llvm.types
|
||||||
|
|
||||||
class LLVMStringType(val length : Int) : LLVMType() {
|
class LLVMStringType(override val length: Int) : LLVMArray, LLVMType() {
|
||||||
|
|
||||||
override val size: Byte = 1
|
override val size: Byte = 1
|
||||||
override val align = 8
|
override val align = 8
|
||||||
override val defaultValue = ""
|
override val defaultValue = ""
|
||||||
|
|
||||||
|
override fun basicType() = LLVMCharType()
|
||||||
override fun toString(): String = "i8*"
|
override fun toString(): String = "i8*"
|
||||||
fun fullType() = "[${length+1} x i8]"
|
override fun fullType() = "[${length + 1} x i8]"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user