diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt index 4ad543cd1cd..d3a0fc5b0c6 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FileTranslator.kt @@ -2,22 +2,15 @@ package org.kotlinnative.translator import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtNamedFunction -import org.jetbrains.kotlin.resolve.BindingContext -import org.kotlin.native.translator.llvm.LLVMBuilder -import org.kotlinnative.translator.llvm.LLVMDescriptorGenearte -import org.kotlinnative.translator.llvm.LLVMMapStandardType +import org.kotlinnative.translator.llvm.LLVMBuilder class FileTranslator(val state: TranslationState, val file: KtFile) { private var codeBuilder = LLVMBuilder() - private var compiled = false; fun generateCode(): String { - if (!compiled) { - generateFileBody() - } - - compiled = true + codeBuilder.clean() + generateFileBody() return codeBuilder.toString() } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt index 356ef86a0f7..6c4dfc0b9e8 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/FunctionCodegen.kt @@ -10,21 +10,19 @@ import org.jetbrains.kotlin.psi.KtConstantExpression import org.jetbrains.kotlin.psi.KtNamedFunction import org.jetbrains.kotlin.psi.psiUtil.getNextSiblingIgnoringWhitespaceAndComments import org.jetbrains.kotlin.resolve.BindingContext -import org.kotlin.native.translator.llvm.LLVMBuilder -import org.kotlin.native.translator.llvm.LLVMVariable -import org.kotlinnative.translator.llvm.LLVMDescriptorGenearte +import org.kotlinnative.translator.llvm.LLVMBuilder +import org.kotlinnative.translator.llvm.LLVMVariable +import org.kotlinnative.translator.llvm.LLVMDescriptorGenerate import org.kotlinnative.translator.llvm.LLVMMapStandardType class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction, val codeBuilder: LLVMBuilder) { - private var variableCount = 0 - fun generate() { generateDeclaration(function) - codeBuilder.addLlvmCode("{") + codeBuilder.addStartExpression() expressionWalker(function.bodyExpression) - codeBuilder.addLlvmCode("}") + codeBuilder.addEndExpression() } private fun generateDeclaration(function: KtNamedFunction) { @@ -34,8 +32,7 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } val returnType = LLVMMapStandardType(descriptor?.returnType.toString()) - - codeBuilder.addLlvmCode(LLVMDescriptorGenearte(function.fqName.toString(), args, returnType)) + codeBuilder.addLLVMCode(LLVMDescriptorGenerate(function.fqName.toString(), args, returnType)) } private fun expressionWalker(expr: Any?) { @@ -48,17 +45,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } private fun evaluateBlockExpression(expr: KtBlockExpression) { - var element = expr - expressionWalker(element.firstChild) - - expressionWalker(element.getNextSiblingIgnoringWhitespaceAndComments()) + expressionWalker(expr.firstChild) + expressionWalker(expr.getNextSiblingIgnoringWhitespaceAndComments()) } private fun evaluatePsiExpression(expr: PsiElement) { - var element = expr - evaluateExpression(element.firstChild) - - evaluatePsiExpression(element.getNextSiblingIgnoringWhitespaceAndComments() ?: return) + evaluateExpression(expr.firstChild) + evaluatePsiExpression(expr.getNextSiblingIgnoringWhitespaceAndComments() ?: return) } private fun evaluateExpression(expr: Any?): LLVMVariable? { @@ -73,21 +66,11 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction } private fun evaluateBinaryExpression(expr: KtBinaryExpression): LLVMVariable { - val left = evaluateExpression(expr.firstChild) - val right = evaluateExpression(expr.lastChild) + val left = evaluateExpression(expr.firstChild) ?: throw UnsupportedOperationException("Wrong binary exception") + val right = evaluateExpression(expr.lastChild) ?: throw UnsupportedOperationException("Wrong binary exception") val operator = expr.operationToken - - val llvmOperator = when (operator) { - KtTokens.PLUS -> "add nsw i32" - KtTokens.MINUS -> "sub nsw i32" - KtTokens.MUL -> "mul nsw i32" - else -> throw UnsupportedOperationException("Unkbown binary operator") - } - - variableCount++ - codeBuilder.addLlvmCode("%var$variableCount = $llvmOperator ${left?.label}, ${right?.label}") - return LLVMVariable("%var$variableCount") + return codeBuilder.addPrimitiveBinaryOperation(operator, left, right) } private fun evaluateConstantExpression(expr: KtConstantExpression): LLVMVariable { @@ -109,14 +92,13 @@ class FunctionCodegen(val state: TranslationState, val function: KtNamedFunction KtTokens.RETURN_KEYWORD -> evaluateReturnInstruction(element) else -> LLVMVariable("") } - } private fun evaluateReturnInstruction(element: LeafPsiElement): LLVMVariable? { var next = element.getNextSiblingIgnoringWhitespaceAndComments(); val retVar = evaluateExpression(next) - codeBuilder.addLlvmCode("ret i32 ${retVar?.label}") + codeBuilder.addLLVMCode("ret i32 ${retVar?.label}") return null } } \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/KotlinScriptParser.kt b/translator/src/main/kotlin/org/kotlinnative/translator/KotlinScriptParser.kt deleted file mode 100644 index c8ff7fd4c5c..00000000000 --- a/translator/src/main/kotlin/org/kotlinnative/translator/KotlinScriptParser.kt +++ /dev/null @@ -1,117 +0,0 @@ -package hello - -import com.intellij.openapi.util.Disposer -import com.intellij.psi.search.GlobalSearchScope -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation -import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity -import org.jetbrains.kotlin.cli.common.messages.GroupingMessageCollector -import org.jetbrains.kotlin.cli.common.messages.MessageCollector -import org.jetbrains.kotlin.cli.jvm.compiler.CliLightClassGenerationSupport -import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles -import org.jetbrains.kotlin.cli.jvm.compiler.JvmPackagePartProvider -import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment -import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots -import org.jetbrains.kotlin.cli.jvm.config.getModuleName -import org.jetbrains.kotlin.config.CompilerConfiguration -import org.jetbrains.kotlin.config.JVMConfigurationKeys -import org.jetbrains.kotlin.config.LanguageVersion -import org.jetbrains.kotlin.config.addKotlinSourceRoot -import org.jetbrains.kotlin.descriptors.PackageFragmentProvider -import org.jetbrains.kotlin.frontend.java.di.createContainerForTopDownAnalyzerForJvm -import org.jetbrains.kotlin.incremental.components.LookupTracker -import org.jetbrains.kotlin.load.java.JvmAbi -import org.jetbrains.kotlin.resolve.TopDownAnalysisContext -import org.jetbrains.kotlin.resolve.TopDownAnalysisMode -import org.jetbrains.kotlin.resolve.jvm.JvmAnalyzerFacade -import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM -import org.jetbrains.kotlin.resolve.lazy.declarations.FileBasedDeclarationProviderFactory -import org.jetbrains.kotlin.utils.PathUtil -import java.io.File -import java.util.* -import java.util.logging.Logger - -class KotlinScriptParser { - companion object { - private val LOG = Logger.getLogger(KotlinScriptParser.javaClass.name) - private val messageCollector = object : MessageCollector { - override fun hasErrors(): Boolean { - throw UnsupportedOperationException() - } - - override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) { - val path = location.path - val position = if (path == null) "" else "$path: (${location.line}, ${location.column}) " - - val text = position + message - - if (CompilerMessageSeverity.VERBOSE.contains(severity)) { - LOG.finest(text) - } else if (CompilerMessageSeverity.ERRORS.contains(severity)) { - LOG.severe(text) - } else if (severity == CompilerMessageSeverity.INFO) { - LOG.info(text) - } else { - LOG.warning(text) - } - } - } - - private val classPath: ArrayList by lazy { - val classpath = arrayListOf() - classpath += PathUtil.getResourcePathForClass(AnnotationTarget.CLASS.javaClass) - classpath - } - } - - fun parse(vararg files: String): TopDownAnalysisContext { - // The Kotlin compiler configuration - val configuration = CompilerConfiguration() - - val groupingCollector = GroupingMessageCollector(messageCollector) - //val severityCollector = MessageSeverityCollector(groupingCollector) - //configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, severityCollector) - - - configuration.addJvmClasspathRoots(PathUtil.getJdkClassesRoots()) - // The path to .kt files sources - files.forEach { configuration.addKotlinSourceRoot(it) } - // Configuring Kotlin class path - configuration.addJvmClasspathRoots(classPath) - configuration.put(JVMConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME) - //configuration.put>(JVMConfigurationKeys.SCRIPT_PARAMETERS, CommandLineScriptUtils.scriptParameters()) - - val rootDisposable = Disposer.newDisposable() - try { - val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES) - val ktFiles = environment.getSourceFiles() - //printFile(ktFiles.first()) - val sharedTrace = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace() - val moduleContext = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(environment.project, - environment.getModuleName()) - - val project = moduleContext.project - val allFiles = JvmAnalyzerFacade.getAllFilesToAnalyze(project, null, ktFiles) - val providerFactory = FileBasedDeclarationProviderFactory(moduleContext.storageManager, allFiles) - val lookupTracker = LookupTracker.DO_NOTHING - val packagePartProvider = JvmPackagePartProvider(environment) - val container = createContainerForTopDownAnalyzerForJvm( - moduleContext, - sharedTrace, - providerFactory, - GlobalSearchScope.allScope(project), - lookupTracker, - packagePartProvider, LanguageVersion.LATEST) - - val additionalProviders = ArrayList() - - additionalProviders.add(container.javaDescriptorResolver.packageFragmentProvider) - - return container.lazyTopDownAnalyzerForTopLevel.analyzeFiles(TopDownAnalysisMode.LocalDeclarations, allFiles, additionalProviders) - } finally { - rootDisposable.dispose() - //if (severityCollector.anyReported(CompilerMessageSeverity.ERROR)) { - // throw RuntimeException("Compilation error") - //} - } - } -} \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt index bf18de7e8e1..961abc58dfd 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/TranslationState.kt @@ -1,4 +1,5 @@ package org.kotlinnative.translator + import com.intellij.openapi.Disposable import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt index 6ee8edd05fe..a363acaa1b1 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMBuilder.kt @@ -1,12 +1,47 @@ -package org.kotlin.native.translator.llvm +package org.kotlinnative.translator.llvm + +import com.intellij.psi.tree.IElementType +import org.jetbrains.kotlin.lexer.KtTokens class LLVMBuilder { - private val llvmCode: StringBuilder = StringBuilder() + private var llvmCode: StringBuilder = StringBuilder() + private var variableCount = 0 - fun addLlvmCode(code: String) { + private fun getNewVariable(): LLVMVariable { + variableCount++ + return LLVMVariable("%var$variableCount") + } + + fun addLLVMCode(code: String) { llvmCode.appendln(code) } + fun addStartExpression() { + llvmCode.appendln("{") + } + + fun addEndExpression() { + llvmCode.appendln("}") + } + + fun addPrimitiveBinaryOperation(operation: IElementType, firstOp: LLVMVariable, secondOp: LLVMVariable): LLVMVariable { + val newVar = getNewVariable() + val llvmOperator = when (operation) { + KtTokens.PLUS -> "add nsw i32" + KtTokens.MINUS -> "sub nsw i32" + KtTokens.MUL -> "mul nsw i32" + else -> throw UnsupportedOperationException("Unkbown binary operator") + } + + llvmCode.appendln("$newVar = $llvmOperator $firstOp, $secondOp") + return newVar + } + + + fun clean() { + llvmCode = StringBuilder() + } + override fun toString(): String { return llvmCode.toString() } diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt index 9ee935d9088..d0e0c0f72ae 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/LLVMVariable.kt @@ -1,3 +1,7 @@ -package org.kotlin.native.translator.llvm +package org.kotlinnative.translator.llvm -data class LLVMVariable(val label: String) \ No newline at end of file +data class LLVMVariable(val label: String){ + override fun toString(): String { + return label + } +} \ No newline at end of file diff --git a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt index 28b0d7a3626..dc846f44a2d 100644 --- a/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt +++ b/translator/src/main/kotlin/org/kotlinnative/translator/llvm/generators.kt @@ -1,6 +1,6 @@ package org.kotlinnative.translator.llvm -fun LLVMDescriptorGenearte(name: String, argTypes: List>?, returnType: String) = +fun LLVMDescriptorGenerate(name: String, argTypes: List>?, returnType: String) = "define $returnType @$name(${argTypes?.mapIndexed { i: Int, s: Pair -> "${s.second} %${s.first}" }?.joinToString() ?: "" })" fun LLVMMapStandardType(type: String) = when(type) {