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 KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
|
||||
is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr)
|
||||
is KtReferenceExpression -> evaluateReferenceExpression(expr)
|
||||
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
|
||||
is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true)
|
||||
is KtDotQualifiedExpression -> evaluateDotExpression(expr)
|
||||
is PsiWhiteSpace -> null
|
||||
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr, scopeDepth + 1)
|
||||
is PsiWhiteSpace -> null
|
||||
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
|
||||
null -> null
|
||||
else -> throw UnsupportedOperationException()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun evaluateStringTemplateExpression(expr: KtStringTemplateExpression, scope: Int): LLVMSingleValue? {
|
||||
val receiveValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr)
|
||||
val type = (receiveValue as TypedCompileTimeConstant).type
|
||||
val value = receiveValue.getValue(type) ?: return null
|
||||
val variable = variableManager.receiveVariable(".str", LLVMStringType(value.toString().length), LLVMGlobalScope(), pointer = false)
|
||||
|
||||
codeBuilder.addStringConstant(variable, value.toString())
|
||||
return variable
|
||||
}
|
||||
@@ -175,9 +177,19 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
return result
|
||||
}
|
||||
|
||||
private fun evaluateReferenceExpression(expr: KtReferenceExpression): LLVMSingleValue? {
|
||||
val variableName = expr.firstChild.text
|
||||
return variableManager.getLLVMvalue(variableName)
|
||||
fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
|
||||
val arrayNameVariable = evaluateReferenceExpression(expr.arrayExpression as KtReferenceExpression, scope) as LLVMVariable
|
||||
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? {
|
||||
@@ -286,8 +298,8 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction
|
||||
val result = ArrayList<LLVMSingleValue>()
|
||||
|
||||
for (arg in args) {
|
||||
val expr = evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
|
||||
result.add(expr)
|
||||
val currentExpression = evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
|
||||
result.add(currentExpression)
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -131,6 +131,11 @@ class LLVMBuilder(val arm: Boolean) {
|
||||
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) {
|
||||
val tmp = getNewVariable(source.type, source.pointer)
|
||||
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(${
|
||||
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
|
||||
"${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 {
|
||||
type.isFunctionType -> LLVMVariable(name, LLVMFunctionType(type), type.toString(), pointer = true)
|
||||
type.toString() == "Int" -> LLVMVariable(name, LLVMIntType(), type.toString())
|
||||
type.toString() == "Double" -> LLVMVariable(name, LLVMDoubleType(), type.toString())
|
||||
type.toString() == "Char" -> LLVMVariable(name, LLVMCharType(), type.toString())
|
||||
type.isUnit() -> LLVMVariable("", LLVMVoidType())
|
||||
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
|
||||
|
||||
class LLVMStringType(val length : Int) : LLVMType() {
|
||||
class LLVMStringType(override val length: Int) : LLVMArray, LLVMType() {
|
||||
|
||||
override val size: Byte = 1
|
||||
override val align = 8
|
||||
override val defaultValue = ""
|
||||
|
||||
override fun basicType() = LLVMCharType()
|
||||
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