translator: rearrange private functions

This commit is contained in:
Alexey Stepanov
2016-08-31 18:23:51 +03:00
parent 13ddf0ebf5
commit 15edcff509
3 changed files with 125 additions and 132 deletions
@@ -53,6 +53,114 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
codeBuilder.addUnconditionalJump(nextIterationLabel ?: return)
}
fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? =
when (expr) {
is KtBlockExpression -> {
expressionWalker(expr.lBrace, breakLabel = null, scopeDepth = scopeDepth + 1)
null
}
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
is KtPrefixExpression -> evaluatePrefixExpression(expr, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(expr)
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
is KtWhenExpression -> evaluateWhenExpression(expr, scopeDepth)
is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr)
is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth)
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
is KtIfExpression -> evaluateIfOperator(expr, scopeDepth + 1)
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr)
is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth)
is KtThisExpression -> evaluateThisExpression()
is KtSafeQualifiedExpression -> evaluateSafeAccessExpression(expr, scopeDepth)
is KtParenthesizedExpression -> evaluateExpression(expr.expression, scopeDepth)
null,
is PsiWhiteSpace -> null
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
else -> throw UnsupportedOperationException()
}
fun evaluateConstructorDelegationReferenceExpression(expr: KtConstructorDelegationReferenceExpression, structCodegen: StructCodegen, constructorArguments: List<LLVMVariable>, scopeDepth: Int): LLVMSingleValue? {
val targetCall = state.bindingContext.get(BindingContext.CALL, expr)
val names = parseValueArguments(targetCall!!.valueArguments, scopeDepth)
val args = codeBuilder.loadArgsIfRequired(names, constructorArguments)
return evaluateConstructorCallExpression(LLVMVariable(structCodegen.structName + LLVMType.mangleFunctionArguments(names), structCodegen.type, scope = LLVMVariableScope()), args)
}
fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement? = null): LLVMSingleValue? {
val type = receiver.type as LLVMReferenceType
val clazz = resolveClassOrObjectLocation(type) ?: throw UnexpectedException(type.toString() + receiver.toString())
val field = clazz.fieldsIndex[selectorName]
if (field != null) {
return evaluateClassField(receiver, field)
} else {
return evaluateMemberMethod(receiver, clazz, scopeDepth, call as? KtCallExpression ?: throw UnexpectedException("$receiver:$selectorName"))
}
}
fun addPrimitiveBinaryOperation(operator: IElementType, firstOp: LLVMSingleValue, secondOp: LLVMSingleValue, referenceName: KtSimpleNameExpression? = null): LLVMVariable {
val firstNativeOp = codeBuilder.receiveNativeValue(firstOp)
val secondNativeOp = codeBuilder.receiveNativeValue(secondOp)
val llvmExpression = when (operator) {
KtTokens.PLUS -> firstOp.type.operatorPlus(firstNativeOp, secondNativeOp)
KtTokens.MINUS -> firstOp.type.operatorMinus(firstNativeOp, secondNativeOp)
KtTokens.MUL -> firstOp.type.operatorTimes(firstNativeOp, secondNativeOp)
KtTokens.DIV -> firstOp.type.operatorDiv(firstNativeOp, secondNativeOp)
KtTokens.LT -> firstOp.type.operatorLt(firstNativeOp, secondNativeOp)
KtTokens.GT -> firstOp.type.operatorGt(firstNativeOp, secondNativeOp)
KtTokens.LTEQ -> firstOp.type.operatorLeq(firstNativeOp, secondNativeOp)
KtTokens.GTEQ -> firstOp.type.operatorGeq(firstNativeOp, secondNativeOp)
KtTokens.EQEQ ->
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type.operatorEq(firstNativeOp, secondNativeOp)
KtTokens.EQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EXCLEQ -> {
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type.operatorNeq(firstNativeOp, secondNativeOp)
}
KtTokens.EXCLEQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EQ -> {
if (secondOp.type is LLVMNullType) {
codeBuilder.storeNull(firstOp as LLVMVariable)
return firstOp
}
val result = firstOp as LLVMVariable
val sourceArgument: LLVMSingleValue
if ((firstOp.pointer == 2) && secondOp.type.isPrimitive && (secondOp.pointer == 0)) {
sourceArgument = codeBuilder.getNewVariable(secondOp.type, 1)
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
codeBuilder.storeVariable(sourceArgument, secondOp)
} else {
sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp
}
codeBuilder.storeVariable(result, sourceArgument)
return result
}
else -> addPrimitiveReferenceOperationByName(referenceName!!.getReferencedName(), firstOp, secondNativeOp)
}
return codeBuilder.storeExpression(llvmExpression)
}
private fun expressionWalker(expr: PsiElement?, breakLabel: LLVMLabel?, scopeDepth: Int) {
when (expr) {
is KtBlockExpression -> expressionWalker(expr.lBrace, breakLabel, scopeDepth + 1)
@@ -81,42 +189,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
private fun evaluateDoWhileExpression(expr: KtDoWhileExpression, scopeDepth: Int) =
executeWhileBlock(expr.condition!!, expr.body!!, scopeDepth, checkConditionBeforeExecute = false)
fun evaluateExpression(expr: PsiElement?, scopeDepth: Int): LLVMSingleValue? {
return when (expr) {
is KtBlockExpression -> {
expressionWalker(expr.lBrace, breakLabel = null, scopeDepth = scopeDepth + 1)
return null
}
is KtBinaryExpression -> evaluateBinaryExpression(expr, scopeDepth)
is KtPostfixExpression -> evaluatePostfixExpression(expr, scopeDepth)
is KtPrefixExpression -> evaluatePrefixExpression(expr, scopeDepth)
is KtConstantExpression -> evaluateConstantExpression(expr)
is KtCallExpression -> evaluateCallExpression(expr, scopeDepth)
is KtWhenExpression -> evaluateWhenExpression(expr, scopeDepth)
is KtCallableReferenceExpression -> evaluateCallableReferenceExpression(expr)
is KtDotQualifiedExpression -> evaluateDotExpression(expr, scopeDepth)
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
is KtIfExpression -> evaluateIfOperator(expr, scopeDepth + 1)
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr)
is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth)
is KtThisExpression -> evaluateThisExpression()
is KtSafeQualifiedExpression -> evaluateSafeAccessExpression(expr, scopeDepth)
is KtParenthesizedExpression -> evaluateExpression(expr.expression, scopeDepth)
null,
is PsiWhiteSpace -> null
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
else -> throw UnsupportedOperationException()
}
}
fun evaluateConstructorDelegationReferenceExpression(expr: KtConstructorDelegationReferenceExpression, structCodegen: StructCodegen, constructorArguments: List<LLVMVariable>, scopeDepth: Int): LLVMSingleValue? {
val targetCall = state.bindingContext.get(BindingContext.CALL, expr)
val names = parseValueArguments(targetCall!!.valueArguments, scopeDepth)
val args = codeBuilder.loadArgsIfRequired(names, constructorArguments)
return evaluateConstructorCallExpression(LLVMVariable(structCodegen.structName + LLVMType.mangleFunctionArguments(names), structCodegen.type, scope = LLVMVariableScope()), args)
}
private fun evaluateThisExpression(): LLVMSingleValue? =
variableManager["this"]
@@ -263,25 +335,13 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
else -> throw UnsupportedOperationException()
}
fun evaluateMemberMethodOrField(receiver: LLVMVariable, selectorName: String, scopeDepth: Int, call: PsiElement? = null): LLVMSingleValue? {
val type = receiver.type as LLVMReferenceType
val clazz = resolveClassOrObjectLocation(type) ?: throw UnexpectedException(type.toString() + receiver.toString())
val field = clazz.fieldsIndex[selectorName]
if (field != null) {
return evaluateClassField(receiver, field)
} else {
return evaluateMemberMethod(receiver, clazz, scopeDepth, call as? KtCallExpression ?: throw UnexpectedException("$receiver:$selectorName"))
}
}
fun evaluateClassField(receiver: LLVMVariable, field: LLVMClassVariable): LLVMVariable {
private fun evaluateClassField(receiver: LLVMVariable, field: LLVMClassVariable): LLVMVariable {
val result = codeBuilder.getNewVariable(field.type, pointer = field.pointer + 1)
codeBuilder.loadClassField(result, receiver, field.offset)
return result
}
fun evaluateMemberMethod(receiver: LLVMVariable, clazz: StructCodegen, scopeDepth: Int, call: KtCallExpression): LLVMSingleValue? {
private fun evaluateMemberMethod(receiver: LLVMVariable, clazz: StructCodegen, scopeDepth: Int, call: KtCallExpression): LLVMSingleValue? {
val resolvedCall = call.getCall(state.bindingContext)!!.getResolvedCallWithAssert(state.bindingContext)
val functionDescriptor = resolvedCall.candidateDescriptor
val functionArguments = functionDescriptor.valueParameters.map { it -> it.type }.map { LLVMMapStandardType(it, state) }
@@ -329,7 +389,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
return if (codegen?.structName == type.type) codegen else codegen?.nestedClasses?.get(type.type)
}
fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
private fun evaluateArrayAccessExpression(expr: KtArrayAccessExpression, scope: Int): LLVMSingleValue? {
val arrayNameVariable = evaluateExpression(expr.arrayExpression, scope) as LLVMVariable
return when (arrayNameVariable.type) {
is LLVMReferenceType -> {
@@ -536,10 +596,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
parseValueArguments(expr.getValueArgumentsInParentheses(), scopeDepth)
private fun parseValueArguments(args: List<ValueArgument>, scopeDepth: Int): List<LLVMSingleValue> =
args.map { parseOneValueArgument(it, scopeDepth) }
fun parseOneValueArgument(arg: ValueArgument, scopeDepth: Int): LLVMSingleValue =
evaluateExpression(arg.getArgumentExpression(), scopeDepth) as LLVMSingleValue
args.map { evaluateExpression(it.getArgumentExpression(), scopeDepth) as LLVMSingleValue }
private fun parseArgumentsWithDefaultValues(args: MutableCollection<ResolvedValueArgument>, defaultValues: List<KtExpression?>, scopeDepth: Int): List<LLVMSingleValue> =
args.mapIndexed(fun(i: Int, value: ResolvedValueArgument): LLVMSingleValue {
@@ -550,7 +607,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
}
}).toList()
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable? {
val operator = expr.operationToken
@@ -667,7 +723,7 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
return left
}
fun addPrimitiveReferenceOperationByName(operator: String, firstOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression {
private fun addPrimitiveReferenceOperationByName(operator: String, firstOp: LLVMSingleValue, secondNativeOp: LLVMSingleValue): LLVMExpression {
val firstNativeOp = codeBuilder.receiveNativeValue(firstOp)
return when (operator) {
@@ -711,68 +767,6 @@ abstract class BlockCodegen(val state: TranslationState, val variableManager: Va
}
}
fun addPrimitiveBinaryOperation(operator: IElementType, firstOp: LLVMSingleValue, secondOp: LLVMSingleValue, referenceName: KtSimpleNameExpression? = null): LLVMVariable {
val firstNativeOp = codeBuilder.receiveNativeValue(firstOp)
val secondNativeOp = codeBuilder.receiveNativeValue(secondOp)
val llvmExpression = when (operator) {
KtTokens.PLUS -> firstOp.type.operatorPlus(firstNativeOp, secondNativeOp)
KtTokens.MINUS -> firstOp.type.operatorMinus(firstNativeOp, secondNativeOp)
KtTokens.MUL -> firstOp.type.operatorTimes(firstNativeOp, secondNativeOp)
KtTokens.DIV -> firstOp.type.operatorDiv(firstNativeOp, secondNativeOp)
KtTokens.LT -> firstOp.type.operatorLt(firstNativeOp, secondNativeOp)
KtTokens.GT -> firstOp.type.operatorGt(firstNativeOp, secondNativeOp)
KtTokens.LTEQ -> firstOp.type.operatorLeq(firstNativeOp, secondNativeOp)
KtTokens.GTEQ -> firstOp.type.operatorGeq(firstNativeOp, secondNativeOp)
KtTokens.EQEQ ->
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type.operatorEq(firstNativeOp, secondNativeOp)
KtTokens.EQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorEq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EXCLEQ -> {
if (LLVMType.isReferredType(firstOp.type) && LLVMType.isReferredType(secondOp.type)) {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
} else
firstOp.type.operatorNeq(firstNativeOp, secondNativeOp)
}
KtTokens.EXCLEQEQEQ -> {
val firstPointedArgument = codeBuilder.receivePointedArgument(firstOp, 1)
val secondPointedArgument = codeBuilder.receivePointedArgument(secondOp, 1)
firstOp.type.operatorNeq(firstPointedArgument, secondPointedArgument)
}
KtTokens.EQ -> {
if (secondOp.type is LLVMNullType) {
codeBuilder.storeNull(firstOp as LLVMVariable)
return firstOp
}
val result = firstOp as LLVMVariable
val sourceArgument: LLVMSingleValue
if ((firstOp.pointer == 2) && secondOp.type.isPrimitive && (secondOp.pointer == 0)) {
sourceArgument = codeBuilder.getNewVariable(secondOp.type, 1)
codeBuilder.allocStaticVar(sourceArgument, asValue = true)
codeBuilder.storeVariable(sourceArgument, secondOp)
} else {
sourceArgument = if (result.pointer == secondOp.pointer + 1) secondOp else secondNativeOp
}
codeBuilder.storeVariable(result, sourceArgument)
return result
}
else -> addPrimitiveReferenceOperationByName(referenceName!!.getReferencedName(), firstOp, secondNativeOp)
}
return codeBuilder.storeExpression(llvmExpression)
}
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMConstant {
val expressionKotlinType = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, expr)!!.type!!
val expressionValue = state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr)?.getValue(expressionKotlinType)
@@ -36,18 +36,6 @@ class ClassCodegen(state: TranslationState,
type.align = TranslationState.POINTER_ALIGN
}
private fun indexFields(parameters: MutableList<KtParameter>) {
if (annotation) {
return
}
val currentConstructorFields = parameters.mapIndexed { i, it -> resolveType(it, state.bindingContext.get(BindingContext.TYPE, it.typeReference)!!, fields.size + i) }
fields.addAll(currentConstructorFields)
fieldsIndex.putAll(currentConstructorFields.map { Pair(it.label, it) })
primaryConstructorIndex = LLVMType.mangleFunctionArguments(currentConstructorFields)
constructorFields.put(primaryConstructorIndex!!, currentConstructorFields)
}
override fun prepareForGenerate() {
val parameterList = clazz.getPrimaryConstructorParameterList()?.parameters ?: listOf()
indexFields(parameterList)
@@ -79,4 +67,16 @@ class ClassCodegen(state: TranslationState,
companionObjectCodegen?.generate()
}
private fun indexFields(parameters: MutableList<KtParameter>) {
if (annotation) {
return
}
val currentConstructorFields = parameters.mapIndexed { i, it -> resolveType(it, state.bindingContext.get(BindingContext.TYPE, it.typeReference)!!, fields.size + i) }
fields.addAll(currentConstructorFields)
fieldsIndex.putAll(currentConstructorFields.map { Pair(it.label, it) })
primaryConstructorIndex = LLVMType.mangleFunctionArguments(currentConstructorFields)
constructorFields.put(primaryConstructorIndex!!, currentConstructorFields)
}
}
@@ -97,7 +97,6 @@ abstract class StructCodegen(val state: TranslationState,
}
}
private fun generateEnumFields() {
val enumEntries = classOrObject.declarations.filter { it is KtEnumEntry }