translator: elvis operator, fix includes in build system, gradle jar build
This commit is contained in:
@@ -1,86 +1,72 @@
|
||||
declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
|
||||
declare i8* @malloc(i32)
|
||||
%class.MyClass = type { i32 }
|
||||
define void @MyClass(%class.MyClass* %classvariable.this, i32 %i)
|
||||
{
|
||||
%classvariable.this.addr = alloca %class.MyClass, align 4
|
||||
%i.addr = alloca i32, align 4
|
||||
store i32 %i, i32* %i.addr, align 4
|
||||
%var1 = load i32* %i.addr, align 4
|
||||
%var2 = getelementptr inbounds %class.MyClass* %classvariable.this.addr, i32 0, i32 0
|
||||
store i32 %var1, i32* %var2, align 4
|
||||
%var3 = bitcast %class.MyClass* %classvariable.this to i8*
|
||||
%var4 = bitcast %class.MyClass* %classvariable.this.addr to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var3, i8* %var4, i64 4, i32 4, i1 false)
|
||||
ret void
|
||||
}
|
||||
%class.ByteArray = type { i32, i32 }
|
||||
define void @ByteArray(%class.ByteArray* %classvariable.this, i32 %size)
|
||||
{
|
||||
%classvariable.this.addr = alloca %class.ByteArray, align 4
|
||||
%size.addr = alloca i32, align 4
|
||||
store i32 %size, i32* %size.addr, align 4
|
||||
%var5 = load i32* %size.addr, align 4
|
||||
%var6 = getelementptr inbounds %class.ByteArray* %classvariable.this.addr, i32 0, i32 0
|
||||
store i32 %var5, i32* %var6, align 4
|
||||
%var7 = bitcast %class.ByteArray* %classvariable.this to i8*
|
||||
%var8 = bitcast %class.ByteArray* %classvariable.this.addr to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var7, i8* %var8, i64 8, i32 4, i1 false)
|
||||
%var9 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||
%var10 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||
%var11 = load i32* %var10, align 4
|
||||
%var12 = call i32 @malloc_array(i32 %var11)
|
||||
%var13 = alloca i32, align 4
|
||||
store i32 %var12, i32* %var13, align 4
|
||||
%var14 = load i32* %var9, align 4
|
||||
%var15 = load i32* %var13, align 4
|
||||
store i32 %var15, i32* %var9, align 4
|
||||
%var1 = load i32* %size.addr, align 4
|
||||
%var2 = getelementptr inbounds %class.ByteArray* %classvariable.this.addr, i32 0, i32 0
|
||||
store i32 %var1, i32* %var2, align 4
|
||||
%var3 = bitcast %class.ByteArray* %classvariable.this to i8*
|
||||
%var4 = bitcast %class.ByteArray* %classvariable.this.addr to i8*
|
||||
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var3, i8* %var4, i64 8, i32 4, i1 false)
|
||||
%var5 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||
%var6 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||
%var7 = load i32* %var6, align 4
|
||||
%var8 = call i32 @malloc_array(i32 %var7)
|
||||
%var9 = alloca i32, align 4
|
||||
store i32 %var8, i32* %var9, align 4
|
||||
%var10 = load i32* %var5, align 4
|
||||
%var11 = load i32* %var9, align 4
|
||||
store i32 %var11, i32* %var5, align 4
|
||||
ret void
|
||||
}
|
||||
define i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %index)
|
||||
{
|
||||
%index.addr = alloca i32, align 4
|
||||
store i32 %index, i32* %index.addr, align 4
|
||||
%var16 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||
%var17 = load i32* %var16, align 4
|
||||
%var18 = load i32* %index.addr, align 4
|
||||
%var19 = call i8 @kotlinclib_get_byte(i32 %var17, i32 %var18)
|
||||
%var20 = alloca i8, align 1
|
||||
store i8 %var19, i8* %var20, align 1
|
||||
%var21 = load i8* %var20, align 1
|
||||
ret i8 %var21
|
||||
%var12 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||
%var13 = load i32* %var12, align 4
|
||||
%var14 = load i32* %index.addr, align 4
|
||||
%var15 = call i8 @kotlinclib_get_byte(i32 %var13, i32 %var14)
|
||||
%var16 = alloca i8, align 1
|
||||
store i8 %var15, i8* %var16, align 1
|
||||
%var17 = load i8* %var16, align 1
|
||||
ret i8 %var17
|
||||
}
|
||||
define void @ByteArray.clone(%class.ByteArray** %instance, %class.ByteArray* %classvariable.this)
|
||||
{
|
||||
%var22 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||
%var23 = load i32* %var22, align 4
|
||||
%var25 = call i8* @malloc(i32 8)
|
||||
%var24 = bitcast i8* %var25 to %class.ByteArray*
|
||||
call void @ByteArray(%class.ByteArray* %var24, i32 %var23)
|
||||
%var18 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||
%var19 = load i32* %var18, align 4
|
||||
%var21 = call i8* @malloc(i32 8)
|
||||
%var20 = bitcast i8* %var21 to %class.ByteArray*
|
||||
call void @ByteArray(%class.ByteArray* %var20, i32 %var19)
|
||||
%managed.index.1 = alloca i32, align 4
|
||||
store i32 0, i32* %managed.index.1, align 4
|
||||
br label %label.while.1
|
||||
label.while.1:
|
||||
%var26 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||
%var27 = load i32* %managed.index.1, align 4
|
||||
%var28 = load i32* %var26, align 4
|
||||
%var29 = icmp slt i32 %var27, %var28
|
||||
br i1 %var29, label %label.while.2, label %label.while.3
|
||||
%var22 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||
%var23 = load i32* %managed.index.1, align 4
|
||||
%var24 = load i32* %var22, align 4
|
||||
%var25 = icmp slt i32 %var23, %var24
|
||||
br i1 %var25, label %label.while.2, label %label.while.3
|
||||
label.while.2:
|
||||
%var30 = load i32* %managed.index.1, align 4
|
||||
%var31 = call i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %var30)
|
||||
%var32 = alloca i8, align 1
|
||||
store i8 %var31, i8* %var32, align 1
|
||||
%var26 = load i32* %managed.index.1, align 4
|
||||
%var27 = call i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %var26)
|
||||
%var28 = alloca i8, align 1
|
||||
store i8 %var27, i8* %var28, align 1
|
||||
%var29 = load i32* %managed.index.1, align 4
|
||||
%var30 = load i8* %var28, align 1
|
||||
call void @ByteArray.set(%class.ByteArray* %var20, i32 %var29, i8 %var30)
|
||||
%var31 = load i32* %managed.index.1, align 4
|
||||
%var32 = add nsw i32 %var31, 1
|
||||
%var33 = load i32* %managed.index.1, align 4
|
||||
%var34 = load i8* %var32, align 1
|
||||
call void @ByteArray.set(%class.ByteArray* %var24, i32 %var33, i8 %var34)
|
||||
%var35 = load i32* %managed.index.1, align 4
|
||||
%var36 = add nsw i32 %var35, 1
|
||||
%var37 = load i32* %managed.index.1, align 4
|
||||
store i32 %var36, i32* %managed.index.1, align 4
|
||||
store i32 %var32, i32* %managed.index.1, align 4
|
||||
br label %label.while.1
|
||||
label.while.3:
|
||||
store %class.ByteArray* %var24, %class.ByteArray** %instance, align 4
|
||||
store %class.ByteArray* %var20, %class.ByteArray** %instance, align 4
|
||||
ret void
|
||||
}
|
||||
define void @ByteArray.set(%class.ByteArray* %classvariable.this, i32 %index, i8 %value)
|
||||
@@ -89,22 +75,29 @@ define void @ByteArray.set(%class.ByteArray* %classvariable.this, i32 %index,
|
||||
store i32 %index, i32* %index.addr, align 4
|
||||
%value.addr = alloca i8, align 1
|
||||
store i8 %value, i8* %value.addr, align 1
|
||||
%var38 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||
%var39 = load i32* %var38, align 4
|
||||
%var40 = load i32* %index.addr, align 4
|
||||
%var41 = load i8* %value.addr, align 1
|
||||
call void @kotlinclib_set_byte(i32 %var39, i32 %var40, i8 %var41)
|
||||
%var34 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||
%var35 = load i32* %var34, align 4
|
||||
%var36 = load i32* %index.addr, align 4
|
||||
%var37 = load i8* %value.addr, align 1
|
||||
call void @kotlinclib_set_byte(i32 %var35, i32 %var36, i8 %var37)
|
||||
ret void
|
||||
}
|
||||
declare i8 @kotlinclib_get_byte(i32 %src, i32 %index)
|
||||
define i8 @bytearray_1(i8 %x)
|
||||
{
|
||||
%x.addr = alloca i8, align 1
|
||||
store i8 %x, i8* %x.addr, align 1
|
||||
%var39 = call i8* @malloc(i32 8)
|
||||
%var38 = bitcast i8* %var39 to %class.ByteArray*
|
||||
call void @ByteArray(%class.ByteArray* %var38, i32 10)
|
||||
%var40 = load i8* %x.addr, align 1
|
||||
call void @ByteArray.set(%class.ByteArray* %var38, i32 1, i8 %var40)
|
||||
%var41 = call i8 @ByteArray.get(%class.ByteArray* %var38, i32 1)
|
||||
%var42 = alloca i8, align 1
|
||||
store i8 %var41, i8* %var42, align 1
|
||||
%var43 = load i8* %var42, align 1
|
||||
ret i8 %var43
|
||||
}
|
||||
declare i32 @malloc_array(i32 %size)
|
||||
declare void @kotlinclib_set_byte(i32 %src, i32 %index, i8 %value)
|
||||
define void @createMyClass(%class.MyClass** %instance)
|
||||
{
|
||||
%var43 = call i8* @malloc(i32 4)
|
||||
%var42 = bitcast i8* %var43 to %class.MyClass*
|
||||
call void @MyClass(%class.MyClass* %var42, i32 1)
|
||||
store %class.MyClass* %var42, %class.MyClass** %instance, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1
@@ -10,6 +10,7 @@
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="ast-kotlin_main" />
|
||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-stdlib:1.0.1" level="project" />
|
||||
<orderEntry type="library" name="Gradle: org.jetbrains.kotlin:kotlin-compiler:1.0.3" level="project" />
|
||||
<orderEntry type="library" name="Gradle: junit:junit:4.11" level="project" />
|
||||
|
||||
+14
-2
@@ -2,16 +2,19 @@ group 'ast-kotlin'
|
||||
version '1.0-SNAPSHOT'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.0.3'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.1"
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.0.2"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'application'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
@@ -19,7 +22,16 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.1"
|
||||
// https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-compiler
|
||||
compile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler', version: '1.0.3'
|
||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes 'Main-Class': 'MainKt'
|
||||
}
|
||||
|
||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
}
|
||||
|
||||
mainClassName = 'MainKt'
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
/usr/lib/jvm/default-java/bin/java -Didea.launcher.port=7533 -Didea.launcher.bin.path=/opt/idea-IU-145.1617.8/bin -Dfile.encoding=UTF-8 -classpath /usr/lib/jvm/default-java/jre/lib/charsets.jar:/usr/lib/jvm/default-java/jre/lib/ext/cldrdata.jar:/usr/lib/jvm/default-java/jre/lib/ext/dnsns.jar:/usr/lib/jvm/default-java/jre/lib/ext/icedtea-sound.jar:/usr/lib/jvm/default-java/jre/lib/ext/jaccess.jar:/usr/lib/jvm/default-java/jre/lib/ext/localedata.jar:/usr/lib/jvm/default-java/jre/lib/ext/nashorn.jar:/usr/lib/jvm/default-java/jre/lib/ext/sunec.jar:/usr/lib/jvm/default-java/jre/lib/ext/sunjce_provider.jar:/usr/lib/jvm/default-java/jre/lib/ext/sunpkcs11.jar:/usr/lib/jvm/default-java/jre/lib/ext/zipfs.jar:/usr/lib/jvm/default-java/jre/lib/jce.jar:/usr/lib/jvm/default-java/jre/lib/jsse.jar:/usr/lib/jvm/default-java/jre/lib/management-agent.jar:/usr/lib/jvm/default-java/jre/lib/resources.jar:/usr/lib/jvm/default-java/jre/lib/rt.jar:/home/user/Kotlin/carkot/translator/build/classes/main:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-stdlib/1.0.1/68cddd9aec83d23f789f72bfdc933db245c4a635/kotlin-stdlib-1.0.1.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-compiler/1.0.3/5dbeb14062996a5c2208861d6364cc97a21b06b8/kotlin-compiler-1.0.3.jar:/home/user/.gradle/caches/modules-2/files-2.1/org.jetbrains.kotlin/kotlin-runtime/1.0.1/124852ea8cdd3d89827923b5e79627e8a7c314b2/kotlin-runtime-1.0.1.jar:/opt/idea-IU-145.1617.8/lib/idea_rt.jar com.intellij.rt.execution.application.AppMain MainKt $1 > $2
|
||||
java -jar build/libs/ast-kotlin-1.0-SNAPSHOT.jar $1 > $2
|
||||
|
||||
@@ -14,11 +14,9 @@ fun main(args: Array<String>) {
|
||||
|
||||
val analyzedFiles = ArrayList<String>()
|
||||
|
||||
val kotlib = ClassLoader.getSystemClassLoader().getResources("kotlib/kotlin")
|
||||
for (resource in kotlib) {
|
||||
for (app in File(resource.toURI()).listFiles()) {
|
||||
analyzedFiles.add(app.absoluteFile.toString())
|
||||
}
|
||||
val kotlib = File("build/resources/main/kotlib/kotlin").listFiles()
|
||||
for (resourse in kotlib) {
|
||||
analyzedFiles.add(resourse.absolutePath)
|
||||
}
|
||||
|
||||
analyzedFiles.addAll(args.toList())
|
||||
|
||||
@@ -67,6 +67,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
|
||||
is KtIfExpression -> evaluateIfOperator(expr.firstChild as LeafPsiElement, scopeDepth + 1, true)
|
||||
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr)
|
||||
is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth)
|
||||
is PsiWhiteSpace -> null
|
||||
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
|
||||
null -> null
|
||||
@@ -175,7 +176,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? = when (expr) {
|
||||
is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
||||
else -> if ((expr is KtNameReferenceExpression) && (classScope != null)) evaluatenameReferenceExpression(expr, scopeDepth + 1, classScope)
|
||||
else variableManager.getLLVMvalue(expr.firstChild.text)
|
||||
else variableManager.getLLVMvalue(expr.firstChild.text)
|
||||
}
|
||||
|
||||
private fun evaluateCallExpression(expr: KtCallExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? {
|
||||
@@ -217,9 +218,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
callArgs.addAll(loadedArgs)
|
||||
|
||||
return evaluateFunctionCallExpression(LLVMVariable(methodFullName, returnType, scope = LLVMVariableScope()), callArgs)
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
val nestedConstructor = classScope?.nestedClasses?.get(expr.calleeExpression!!.text)
|
||||
@@ -306,15 +305,19 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
}
|
||||
|
||||
private fun evaluateBinaryExpression(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
||||
val operator = expr.operationToken
|
||||
if (operator == KtTokens.ELVIS) {
|
||||
return evaluateElvisOperator(expr, scopeDepth)
|
||||
}
|
||||
|
||||
val left = evaluateExpression(expr.firstChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
||||
val right = evaluateExpression(expr.lastChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
||||
val operator = expr.operationToken
|
||||
|
||||
return executeBinaryExpression(operator, expr.operationReference, left, right, scopeDepth)
|
||||
}
|
||||
|
||||
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue, scopeDepth: Int): LLVMVariable {
|
||||
val result = codeBuilder.addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
||||
val result = addPrimitiveBinaryOperation(operator, referenceName, left, right)
|
||||
|
||||
if (left.type is LLVMReferenceType && left.pointer > 0 && right.pointer > 0) {
|
||||
variableManager.addVariable((left as LLVMVariable).kotlinName!!, result, scopeDepth)
|
||||
@@ -323,6 +326,80 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
return result
|
||||
}
|
||||
|
||||
private fun evaluateElvisOperator(expr: KtBinaryExpression, scopeDepth: Int): LLVMVariable {
|
||||
val left = evaluateExpression(expr.firstChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
||||
val condition = left.type!!.operatorEq(left, LLVMVariable("", LLVMNullType()))
|
||||
|
||||
val conditionResult = codeBuilder.getNewVariable(condition.variableType)
|
||||
codeBuilder.addAssignment(conditionResult, condition)
|
||||
|
||||
val elvisResult = codeBuilder.getNewVariable(left.type!!, pointer = left.pointer)
|
||||
codeBuilder.allocStackVar(elvisResult)
|
||||
elvisResult.pointer++
|
||||
|
||||
val thenLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
||||
val elseLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
||||
val endLabel = codeBuilder.getNewLabel(prefix = "elvis")
|
||||
|
||||
codeBuilder.addCondition(conditionResult, thenLabel, elseLabel)
|
||||
|
||||
codeBuilder.markWithLabel(thenLabel)
|
||||
codeBuilder.storeVariable(elvisResult, left)
|
||||
codeBuilder.addUnconditionalJump(endLabel)
|
||||
|
||||
codeBuilder.markWithLabel(elseLabel)
|
||||
val right = evaluateExpression(expr.lastChild, scopeDepth + 1)
|
||||
if (right != null) {
|
||||
codeBuilder.storeVariable(elvisResult, right)
|
||||
}
|
||||
|
||||
codeBuilder.addUnconditionalJump(endLabel)
|
||||
codeBuilder.markWithLabel(endLabel)
|
||||
return elvisResult
|
||||
}
|
||||
|
||||
private fun addPrimitiveBinaryOperation(operator: IElementType, referenceName: KtSimpleNameExpression?, firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): 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.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 (firstOp.type is LLVMReferenceType)
|
||||
firstOp.type!!.operatorEq(firstOp, secondOp)
|
||||
else
|
||||
firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
|
||||
KtTokens.EXCLEQ -> firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
|
||||
KtTokens.EQ -> {
|
||||
if (secondOp.type is LLVMNullType) {
|
||||
val result = codeBuilder.getNewVariable(firstOp.type!!, firstOp.pointer)
|
||||
codeBuilder.allocStackVar(result)
|
||||
result.pointer++
|
||||
|
||||
codeBuilder.storeNull(result)
|
||||
return result
|
||||
}
|
||||
|
||||
if (firstOp.type is LLVMReferenceType && firstOp.pointer > 0 && secondOp.pointer > 0) {
|
||||
return secondOp as LLVMVariable
|
||||
}
|
||||
|
||||
val result = firstOp as LLVMVariable
|
||||
codeBuilder.storeVariable(result, secondNativeOp)
|
||||
return result
|
||||
}
|
||||
else -> codeBuilder.addPrimitiveReferenceOperation(referenceName!!, firstNativeOp, secondNativeOp)
|
||||
}
|
||||
val resultOp = codeBuilder.getNewVariable(llvmExpression.variableType)
|
||||
codeBuilder.addAssignment(resultOp, llvmExpression)
|
||||
return resultOp
|
||||
}
|
||||
|
||||
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMConstant {
|
||||
val node = expr.node
|
||||
|
||||
@@ -535,17 +612,21 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
||||
return null
|
||||
}
|
||||
|
||||
private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
private fun evaluateReturnInstruction(element: PsiElement, scopeDepth: Int): LLVMVariable? {
|
||||
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
||||
val retVar = evaluateExpression(next, scopeDepth) as LLVMSingleValue
|
||||
val retVar = evaluateExpression(next, scopeDepth)
|
||||
val type = retVar?.type ?: LLVMVoidType()
|
||||
|
||||
when (returnType!!.type) {
|
||||
when (type) {
|
||||
is LLVMReferenceType -> {
|
||||
codeBuilder.storeVariable(returnType!!, retVar)
|
||||
codeBuilder.storeVariable(returnType!!, retVar!!)
|
||||
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||
}
|
||||
is LLVMVoidType -> {
|
||||
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||
}
|
||||
else -> {
|
||||
val retNativeValue = codeBuilder.receiveNativeValue(retVar)
|
||||
val retNativeValue = codeBuilder.receiveNativeValue(retVar!!)
|
||||
codeBuilder.addReturnOperator(retNativeValue)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,57 +70,14 @@ class LLVMBuilder(val arm: Boolean) {
|
||||
}
|
||||
}
|
||||
|
||||
fun addPrimitiveBinaryOperation(operation: IElementType, referenceName: KtSimpleNameExpression?, firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMVariable {
|
||||
val firstNativeOp = receiveNativeValue(firstOp)
|
||||
val secondNativeOp = receiveNativeValue(secondOp)
|
||||
val llvmExpression = when (operation) {
|
||||
KtTokens.PLUS -> firstOp.type!!.operatorPlus(firstNativeOp, secondNativeOp)
|
||||
KtTokens.MINUS -> firstOp.type!!.operatorMinus(firstNativeOp, secondNativeOp)
|
||||
KtTokens.MUL -> firstOp.type!!.operatorTimes(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 (firstOp.type is LLVMReferenceType)
|
||||
firstOp.type!!.operatorEq(firstOp, secondOp)
|
||||
else
|
||||
firstOp.type!!.operatorEq(firstNativeOp, secondNativeOp)
|
||||
KtTokens.EXCLEQ -> firstOp.type!!.operatorNeq(firstNativeOp, secondNativeOp)
|
||||
KtTokens.EQ -> {
|
||||
if (secondOp.type is LLVMNullType) {
|
||||
val result = getNewVariable(firstOp.type!!, firstOp.pointer)
|
||||
allocStackVar(result)
|
||||
result.pointer++
|
||||
|
||||
storeNull(result)
|
||||
return result
|
||||
}
|
||||
|
||||
if (firstOp.type is LLVMReferenceType && firstOp.pointer > 0 && secondOp.pointer > 0) {
|
||||
return secondOp as LLVMVariable
|
||||
}
|
||||
|
||||
val result = firstOp as LLVMVariable
|
||||
storeVariable(result, secondNativeOp)
|
||||
return result
|
||||
}
|
||||
else -> addPrimitiveReferenceOperation(referenceName!!, firstNativeOp, secondNativeOp)
|
||||
}
|
||||
val resultOp = getNewVariable(llvmExpression.variableType)
|
||||
addAssignment(resultOp, llvmExpression)
|
||||
|
||||
return resultOp
|
||||
}
|
||||
|
||||
fun clean() {
|
||||
localCode = StringBuilder()
|
||||
globalCode = StringBuilder()
|
||||
initBuilder()
|
||||
}
|
||||
|
||||
fun addAssignment(llvmVariable: LLVMVariable, rhs: LLVMNode) {
|
||||
localCode.appendln("$llvmVariable = $rhs")
|
||||
fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) {
|
||||
localCode.appendln("$lhs = $rhs")
|
||||
}
|
||||
|
||||
fun addReturnOperator(llvmVariable: LLVMSingleValue) {
|
||||
|
||||
@@ -8,11 +8,11 @@ fun if_test_1(x: Int): Int {
|
||||
return a
|
||||
}
|
||||
|
||||
class MyClass(i: Int)
|
||||
class MyClass2(i: Int)
|
||||
|
||||
fun if_test_null(x: Int): Int {
|
||||
|
||||
val y: MyClass? = null
|
||||
val y: MyClass2? = null
|
||||
if (y == null) {
|
||||
return 1
|
||||
} else {
|
||||
@@ -21,7 +21,7 @@ fun if_test_null(x: Int): Int {
|
||||
}
|
||||
|
||||
fun if_test_null_2(x: Int): Int {
|
||||
val y: MyClass? = MyClass(1)
|
||||
val y: MyClass2? = MyClass2(1)
|
||||
|
||||
if (y == null) {
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user