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 void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)
|
||||||
declare i8* @malloc(i32)
|
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 }
|
%class.ByteArray = type { i32, i32 }
|
||||||
define void @ByteArray(%class.ByteArray* %classvariable.this, i32 %size)
|
define void @ByteArray(%class.ByteArray* %classvariable.this, i32 %size)
|
||||||
{
|
{
|
||||||
%classvariable.this.addr = alloca %class.ByteArray, align 4
|
%classvariable.this.addr = alloca %class.ByteArray, align 4
|
||||||
%size.addr = alloca i32, align 4
|
%size.addr = alloca i32, align 4
|
||||||
store i32 %size, i32* %size.addr, align 4
|
store i32 %size, i32* %size.addr, align 4
|
||||||
%var5 = load i32* %size.addr, align 4
|
%var1 = load i32* %size.addr, align 4
|
||||||
%var6 = getelementptr inbounds %class.ByteArray* %classvariable.this.addr, i32 0, i32 0
|
%var2 = getelementptr inbounds %class.ByteArray* %classvariable.this.addr, i32 0, i32 0
|
||||||
store i32 %var5, i32* %var6, align 4
|
store i32 %var1, i32* %var2, align 4
|
||||||
%var7 = bitcast %class.ByteArray* %classvariable.this to i8*
|
%var3 = bitcast %class.ByteArray* %classvariable.this to i8*
|
||||||
%var8 = bitcast %class.ByteArray* %classvariable.this.addr to i8*
|
%var4 = 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)
|
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %var3, i8* %var4, i64 8, i32 4, i1 false)
|
||||||
%var9 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
%var5 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||||
%var10 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
%var6 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||||
%var11 = load i32* %var10, align 4
|
%var7 = load i32* %var6, align 4
|
||||||
%var12 = call i32 @malloc_array(i32 %var11)
|
%var8 = call i32 @malloc_array(i32 %var7)
|
||||||
%var13 = alloca i32, align 4
|
%var9 = alloca i32, align 4
|
||||||
store i32 %var12, i32* %var13, align 4
|
store i32 %var8, i32* %var9, align 4
|
||||||
%var14 = load i32* %var9, align 4
|
%var10 = load i32* %var5, align 4
|
||||||
%var15 = load i32* %var13, align 4
|
%var11 = load i32* %var9, align 4
|
||||||
store i32 %var15, i32* %var9, align 4
|
store i32 %var11, i32* %var5, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
define i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %index)
|
define i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %index)
|
||||||
{
|
{
|
||||||
%index.addr = alloca i32, align 4
|
%index.addr = alloca i32, align 4
|
||||||
store i32 %index, i32* %index.addr, align 4
|
store i32 %index, i32* %index.addr, align 4
|
||||||
%var16 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
%var12 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||||
%var17 = load i32* %var16, align 4
|
%var13 = load i32* %var12, align 4
|
||||||
%var18 = load i32* %index.addr, align 4
|
%var14 = load i32* %index.addr, align 4
|
||||||
%var19 = call i8 @kotlinclib_get_byte(i32 %var17, i32 %var18)
|
%var15 = call i8 @kotlinclib_get_byte(i32 %var13, i32 %var14)
|
||||||
%var20 = alloca i8, align 1
|
%var16 = alloca i8, align 1
|
||||||
store i8 %var19, i8* %var20, align 1
|
store i8 %var15, i8* %var16, align 1
|
||||||
%var21 = load i8* %var20, align 1
|
%var17 = load i8* %var16, align 1
|
||||||
ret i8 %var21
|
ret i8 %var17
|
||||||
}
|
}
|
||||||
define void @ByteArray.clone(%class.ByteArray** %instance, %class.ByteArray* %classvariable.this)
|
define void @ByteArray.clone(%class.ByteArray** %instance, %class.ByteArray* %classvariable.this)
|
||||||
{
|
{
|
||||||
%var22 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
%var18 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||||
%var23 = load i32* %var22, align 4
|
%var19 = load i32* %var18, align 4
|
||||||
%var25 = call i8* @malloc(i32 8)
|
%var21 = call i8* @malloc(i32 8)
|
||||||
%var24 = bitcast i8* %var25 to %class.ByteArray*
|
%var20 = bitcast i8* %var21 to %class.ByteArray*
|
||||||
call void @ByteArray(%class.ByteArray* %var24, i32 %var23)
|
call void @ByteArray(%class.ByteArray* %var20, i32 %var19)
|
||||||
%managed.index.1 = alloca i32, align 4
|
%managed.index.1 = alloca i32, align 4
|
||||||
store i32 0, i32* %managed.index.1, align 4
|
store i32 0, i32* %managed.index.1, align 4
|
||||||
br label %label.while.1
|
br label %label.while.1
|
||||||
label.while.1:
|
label.while.1:
|
||||||
%var26 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
%var22 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 0
|
||||||
%var27 = load i32* %managed.index.1, align 4
|
%var23 = load i32* %managed.index.1, align 4
|
||||||
%var28 = load i32* %var26, align 4
|
%var24 = load i32* %var22, align 4
|
||||||
%var29 = icmp slt i32 %var27, %var28
|
%var25 = icmp slt i32 %var23, %var24
|
||||||
br i1 %var29, label %label.while.2, label %label.while.3
|
br i1 %var25, label %label.while.2, label %label.while.3
|
||||||
label.while.2:
|
label.while.2:
|
||||||
%var30 = load i32* %managed.index.1, align 4
|
%var26 = load i32* %managed.index.1, align 4
|
||||||
%var31 = call i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %var30)
|
%var27 = call i8 @ByteArray.get(%class.ByteArray* %classvariable.this, i32 %var26)
|
||||||
%var32 = alloca i8, align 1
|
%var28 = alloca i8, align 1
|
||||||
store i8 %var31, i8* %var32, 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
|
%var33 = load i32* %managed.index.1, align 4
|
||||||
%var34 = load i8* %var32, align 1
|
store i32 %var32, i32* %managed.index.1, align 4
|
||||||
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
|
|
||||||
br label %label.while.1
|
br label %label.while.1
|
||||||
label.while.3:
|
label.while.3:
|
||||||
store %class.ByteArray* %var24, %class.ByteArray** %instance, align 4
|
store %class.ByteArray* %var20, %class.ByteArray** %instance, align 4
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
define void @ByteArray.set(%class.ByteArray* %classvariable.this, i32 %index, i8 %value)
|
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
|
store i32 %index, i32* %index.addr, align 4
|
||||||
%value.addr = alloca i8, align 1
|
%value.addr = alloca i8, align 1
|
||||||
store i8 %value, i8* %value.addr, align 1
|
store i8 %value, i8* %value.addr, align 1
|
||||||
%var38 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
%var34 = getelementptr inbounds %class.ByteArray* %classvariable.this, i32 0, i32 1
|
||||||
%var39 = load i32* %var38, align 4
|
%var35 = load i32* %var34, align 4
|
||||||
%var40 = load i32* %index.addr, align 4
|
%var36 = load i32* %index.addr, align 4
|
||||||
%var41 = load i8* %value.addr, align 1
|
%var37 = load i8* %value.addr, align 1
|
||||||
call void @kotlinclib_set_byte(i32 %var39, i32 %var40, i8 %var41)
|
call void @kotlinclib_set_byte(i32 %var35, i32 %var36, i8 %var37)
|
||||||
ret void
|
ret void
|
||||||
}
|
}
|
||||||
declare i8 @kotlinclib_get_byte(i32 %src, i32 %index)
|
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 i32 @malloc_array(i32 %size)
|
||||||
declare void @kotlinclib_set_byte(i32 %src, i32 %index, i8 %value)
|
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>
|
</content>
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<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-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: org.jetbrains.kotlin:kotlin-compiler:1.0.3" level="project" />
|
||||||
<orderEntry type="library" name="Gradle: junit:junit:4.11" 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'
|
version '1.0-SNAPSHOT'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
|
ext.kotlin_version = '1.0.3'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
}
|
}
|
||||||
dependencies {
|
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: 'java'
|
||||||
apply plugin: 'kotlin'
|
apply plugin: 'kotlin'
|
||||||
|
apply plugin: 'application'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@@ -19,7 +22,16 @@ repositories {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.1"
|
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'
|
compile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler', version: '1.0.3'
|
||||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
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
|
#!/bin/bash
|
||||||
|
|
||||||
|
java -jar build/libs/ast-kotlin-1.0-SNAPSHOT.jar $1 > $2
|
||||||
/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
|
|
||||||
|
|||||||
@@ -14,11 +14,9 @@ fun main(args: Array<String>) {
|
|||||||
|
|
||||||
val analyzedFiles = ArrayList<String>()
|
val analyzedFiles = ArrayList<String>()
|
||||||
|
|
||||||
val kotlib = ClassLoader.getSystemClassLoader().getResources("kotlib/kotlin")
|
val kotlib = File("build/resources/main/kotlib/kotlin").listFiles()
|
||||||
for (resource in kotlib) {
|
for (resourse in kotlib) {
|
||||||
for (app in File(resource.toURI()).listFiles()) {
|
analyzedFiles.add(resourse.absolutePath)
|
||||||
analyzedFiles.add(app.absoluteFile.toString())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
analyzedFiles.addAll(args.toList())
|
analyzedFiles.addAll(args.toList())
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|||||||
is KtReferenceExpression -> evaluateReferenceExpression(expr, scopeDepth)
|
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 KtStringTemplateExpression -> evaluateStringTemplateExpression(expr)
|
is KtStringTemplateExpression -> evaluateStringTemplateExpression(expr)
|
||||||
|
is KtReturnExpression -> evaluateReturnInstruction(expr.firstChild, scopeDepth)
|
||||||
is PsiWhiteSpace -> null
|
is PsiWhiteSpace -> null
|
||||||
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
|
is PsiElement -> evaluatePsiElement(expr, scopeDepth)
|
||||||
null -> null
|
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) {
|
private fun evaluateReferenceExpression(expr: KtReferenceExpression, scopeDepth: Int, classScope: ClassCodegen? = null): LLVMSingleValue? = when (expr) {
|
||||||
is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
is KtArrayAccessExpression -> evaluateArrayAccessExpression(expr, scopeDepth + 1)
|
||||||
else -> if ((expr is KtNameReferenceExpression) && (classScope != null)) evaluatenameReferenceExpression(expr, scopeDepth + 1, classScope)
|
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? {
|
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)
|
callArgs.addAll(loadedArgs)
|
||||||
|
|
||||||
return evaluateFunctionCallExpression(LLVMVariable(methodFullName, returnType, scope = LLVMVariableScope()), callArgs)
|
return evaluateFunctionCallExpression(LLVMVariable(methodFullName, returnType, scope = LLVMVariableScope()), callArgs)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val nestedConstructor = classScope?.nestedClasses?.get(expr.calleeExpression!!.text)
|
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 {
|
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 left = evaluateExpression(expr.firstChild, scopeDepth) ?: throw UnsupportedOperationException("Wrong binary exception")
|
||||||
val right = evaluateExpression(expr.lastChild, 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)
|
return executeBinaryExpression(operator, expr.operationReference, left, right, scopeDepth)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun executeBinaryExpression(operator: IElementType, referenceName: KtSimpleNameExpression?, left: LLVMSingleValue, right: LLVMSingleValue, scopeDepth: Int): LLVMVariable {
|
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) {
|
if (left.type is LLVMReferenceType && left.pointer > 0 && right.pointer > 0) {
|
||||||
variableManager.addVariable((left as LLVMVariable).kotlinName!!, result, scopeDepth)
|
variableManager.addVariable((left as LLVMVariable).kotlinName!!, result, scopeDepth)
|
||||||
@@ -323,6 +326,80 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|||||||
return result
|
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 {
|
private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMConstant {
|
||||||
val node = expr.node
|
val node = expr.node
|
||||||
|
|
||||||
@@ -535,17 +612,21 @@ abstract class BlockCodegen(open val state: TranslationState, open val variableM
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateReturnInstruction(element: LeafPsiElement, scopeDepth: Int): LLVMVariable? {
|
private fun evaluateReturnInstruction(element: PsiElement, scopeDepth: Int): LLVMVariable? {
|
||||||
val next = element.getNextSiblingIgnoringWhitespaceAndComments()
|
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 -> {
|
is LLVMReferenceType -> {
|
||||||
codeBuilder.storeVariable(returnType!!, retVar)
|
codeBuilder.storeVariable(returnType!!, retVar!!)
|
||||||
|
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||||
|
}
|
||||||
|
is LLVMVoidType -> {
|
||||||
codeBuilder.addAnyReturn(LLVMVoidType())
|
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val retNativeValue = codeBuilder.receiveNativeValue(retVar)
|
val retNativeValue = codeBuilder.receiveNativeValue(retVar!!)
|
||||||
codeBuilder.addReturnOperator(retNativeValue)
|
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() {
|
fun clean() {
|
||||||
localCode = StringBuilder()
|
localCode = StringBuilder()
|
||||||
globalCode = StringBuilder()
|
globalCode = StringBuilder()
|
||||||
initBuilder()
|
initBuilder()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addAssignment(llvmVariable: LLVMVariable, rhs: LLVMNode) {
|
fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) {
|
||||||
localCode.appendln("$llvmVariable = $rhs")
|
localCode.appendln("$lhs = $rhs")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addReturnOperator(llvmVariable: LLVMSingleValue) {
|
fun addReturnOperator(llvmVariable: LLVMSingleValue) {
|
||||||
|
|||||||
@@ -8,11 +8,11 @@ fun if_test_1(x: Int): Int {
|
|||||||
return a
|
return a
|
||||||
}
|
}
|
||||||
|
|
||||||
class MyClass(i: Int)
|
class MyClass2(i: Int)
|
||||||
|
|
||||||
fun if_test_null(x: Int): Int {
|
fun if_test_null(x: Int): Int {
|
||||||
|
|
||||||
val y: MyClass? = null
|
val y: MyClass2? = null
|
||||||
if (y == null) {
|
if (y == null) {
|
||||||
return 1
|
return 1
|
||||||
} else {
|
} else {
|
||||||
@@ -21,7 +21,7 @@ fun if_test_null(x: Int): Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun if_test_null_2(x: Int): Int {
|
fun if_test_null_2(x: Int): Int {
|
||||||
val y: MyClass? = MyClass(1)
|
val y: MyClass2? = MyClass2(1)
|
||||||
|
|
||||||
if (y == null) {
|
if (y == null) {
|
||||||
return 1
|
return 1
|
||||||
|
|||||||
Reference in New Issue
Block a user