Remove some oldish experiments.
This commit is contained in:
-22
@@ -1,22 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="CompilerConfiguration">
|
||||
<resourceExtensions />
|
||||
<wildcardResourcePatterns>
|
||||
<entry name="!?*.java" />
|
||||
<entry name="!?*.form" />
|
||||
<entry name="!?*.class" />
|
||||
<entry name="!?*.groovy" />
|
||||
<entry name="!?*.scala" />
|
||||
<entry name="!?*.flex" />
|
||||
<entry name="!?*.kt" />
|
||||
<entry name="!?*.clj" />
|
||||
<entry name="!?*.aj" />
|
||||
</wildcardResourcePatterns>
|
||||
<annotationProcessing>
|
||||
<profile default="true" name="Default" enabled="false">
|
||||
<processorPath useClasspath="true" />
|
||||
</profile>
|
||||
</annotationProcessing>
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,3 +0,0 @@
|
||||
<component name="CopyrightManager">
|
||||
<settings default="" />
|
||||
</component>
|
||||
@@ -1,9 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="builtins">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/dist/builtins" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,11 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="cli-parser">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/cli-parser-1.1.2.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/cli-parser-1.1.2-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,18 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="intellij-core">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/sources/sources.jar!/" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/ideaSDK/core" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/guava-17.0-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/asm5-src.zip!/" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/sources/sources.jar!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/../kotlin-ir/ideaSDK/core" recursive="false" />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,11 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jansi">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/dependencies/jansi.jar" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/dependencies/jansi-sources.jar" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,11 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="javax.inject">
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/lib/javax.inject.jar" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/lib/javax.inject-src.zip" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,14 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jline">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/jline.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/jline-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
-15
@@ -1,15 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jps">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/ideaSDK/jps" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/sources/sources.jar!/" />
|
||||
</SOURCES>
|
||||
<jarDirectory url="file://$PROJECT_DIR$/../kotlin-ir/ideaSDK/jps" recursive="false" />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,14 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="jps-model">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/jps/jps-model.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/sources/sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,16 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="junit-4.12">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/hamcrest-core-1.3.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/junit-4.12.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/hamcrest-core-1.3-sources.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/junit-4.12-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,9 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-reflect">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,12 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-runtime">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime.jar!/" />
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-reflect.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-runtime-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,13 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="kotlin-test">
|
||||
<CLASSES>
|
||||
<root url="jar://$KOTLIN_BUNDLED$/lib/kotlin-test.jar!/"/>
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/libraries/kotlin.test/shared/src/main/kotlin" />
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/libraries/kotlin.test/shared/src/main/kotlin.jvm" />
|
||||
<root url="file://$PROJECT_DIR$/../kotlin-ir/libraries/kotlin.test/junit/src/main/kotlin" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,11 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="protobuf-java">
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/protobuf-2.6.1.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/dependencies/protobuf-2.6.1-sources.jar!/" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
@@ -1,17 +0,0 @@
|
||||
<component name="libraryTable">
|
||||
<library name="trove4j">
|
||||
<ANNOTATIONS>
|
||||
<root url="file://$PROJECT_DIR$/annotations" />
|
||||
</ANNOTATIONS>
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/trove4j.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/src/trove4j_src.jar!/core/src" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/src/trove4j_src.jar!/generated/src" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/src/trove4j_src.jar!/test/src" />
|
||||
<root url="jar://$PROJECT_DIR$/../kotlin-ir/ideaSDK/lib/src/trove4j_src.jar!/util/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</component>
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="EntryPointsManager">
|
||||
<entry_points version="2.0" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" default="true" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
||||
-36
@@ -1,36 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/Kotlin.iml" filepath="$PROJECT_DIR$/../kotlin-ir/Kotlin.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/plugins/annotation-collector/annotation-collector.iml" filepath="$PROJECT_DIR$/../kotlin-ir/plugins/annotation-collector/annotation-collector.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/backend/backend.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/backend/backend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/backend-common/backend-common.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/backend-common/backend-common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/ir/backend.common/backend.common.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/ir/backend.common/backend.common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/ir/backend.jvm/backend.jvm.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/ir/backend.jvm/backend.jvm.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/cli/cli.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/cli/cli.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/cli/cli-common/cli-common.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/cli/cli-common/cli-common.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/container/container.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/container/container.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/core/descriptor.loader.java/descriptor.loader.java.iml" filepath="$PROJECT_DIR$/../kotlin-ir/core/descriptor.loader.java/descriptor.loader.java.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/core/descriptors/descriptors.iml" filepath="$PROJECT_DIR$/../kotlin-ir/core/descriptors/descriptors.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/core/deserialization/deserialization.iml" filepath="$PROJECT_DIR$/../kotlin-ir/core/deserialization/deserialization.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/frontend/frontend.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/frontend/frontend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/frontend.java/frontend.java.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/frontend.java/frontend.java.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/ir/ir.psi2ir/ir.psi2ir.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/ir/ir.psi2ir/ir.psi2ir.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/ir/ir.tree/ir.tree.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/ir/ir.tree/ir.tree.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/js/js.dart-ast/js.dart-ast.iml" filepath="$PROJECT_DIR$/../kotlin-ir/js/js.dart-ast/js.dart-ast.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/js/js.frontend/js.frontend.iml" filepath="$PROJECT_DIR$/../kotlin-ir/js/js.frontend/js.frontend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/js/js.inliner/js.inliner.iml" filepath="$PROJECT_DIR$/../kotlin-ir/js/js.inliner/js.inliner.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/js/js.parser/js.parser.iml" filepath="$PROJECT_DIR$/../kotlin-ir/js/js.parser/js.parser.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/js/js.serializer/js.serializer.iml" filepath="$PROJECT_DIR$/../kotlin-ir/js/js.serializer/js.serializer.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/js/js.translator/js.translator.iml" filepath="$PROJECT_DIR$/../kotlin-ir/js/js.translator/js.translator.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/light-classes/light-classes.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/light-classes/light-classes.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/plugin-api/plugin-api.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/plugin-api/plugin-api.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/resolution/resolution.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/resolution/resolution.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/serialization/serialization.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/serialization/serialization.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/student-backend.iml" filepath="$PROJECT_DIR$/student-backend.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/compiler/util/util.iml" filepath="$PROJECT_DIR$/../kotlin-ir/compiler/util/util.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/../kotlin-ir/core/util.runtime/util.runtime.iml" filepath="$PROJECT_DIR$/../kotlin-ir/core/util.runtime/util.runtime.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
@@ -1,81 +0,0 @@
|
||||
package org.jetbrains.kotlin.cli.student
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.cli.common.CLICompiler
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
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.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.Services
|
||||
import org.jetbrains.kotlin.config.addKotlinSourceRoot
|
||||
import org.jetbrains.kotlin.ir.util.DumpIrTreeVisitor
|
||||
import org.jetbrains.kotlin.ir.util.RenderIrElementVisitor
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import java.lang.System.out
|
||||
|
||||
/**
|
||||
* Created by minamoto on 14/09/16.
|
||||
*/
|
||||
|
||||
class K2StudentLlvm : CLICompiler<K2StudentLlvmArguments>() {
|
||||
override fun setupPlatformSpecificArgumentsAndServices(configuration: CompilerConfiguration, arguments: K2StudentLlvmArguments, services: Services) {}
|
||||
|
||||
override fun doExecute(arguments: K2StudentLlvmArguments, configuration: CompilerConfiguration, rootDisposable: Disposable): ExitCode {
|
||||
configuration.put(CommonConfigurationKeys.MODULE_NAME, /*arguments.moduleName ?: */ JvmAbi.DEFAULT_MODULE_NAME)
|
||||
configuration.addKotlinSourceRoot(arguments.freeArgs.get(0))
|
||||
val environment = KotlinCoreEnvironment.createForProduction(rootDisposable, configuration, emptyList())
|
||||
val collector = configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
val analyzerWithCompilerReport = AnalyzerWithCompilerReport(collector)
|
||||
analyzerWithCompilerReport.analyzeAndReport(
|
||||
environment.getSourceFiles(), object : AnalyzerWithCompilerReport.Analyzer {
|
||||
override fun analyze(): AnalysisResult {
|
||||
val sharedTrace = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace()
|
||||
val moduleContext =
|
||||
TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(environment.project, environment.configuration)
|
||||
|
||||
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
moduleContext,
|
||||
environment.getSourceFiles(),
|
||||
sharedTrace,
|
||||
environment.configuration,
|
||||
JvmPackagePartProvider(environment)
|
||||
)
|
||||
}
|
||||
override fun reportEnvironmentErrors() {
|
||||
TODO(/* implement me*/)
|
||||
//KotlinToJVMBytecodeCompiler.reportRuntimeConflicts(collector, environment.configuration.jvmClasspathRoots)
|
||||
}
|
||||
})
|
||||
|
||||
val translator = Psi2IrTranslator(Psi2IrConfiguration(false))
|
||||
val module = translator.generateModule(analyzerWithCompilerReport.analysisResult.moduleDescriptor,
|
||||
environment.getSourceFiles(),
|
||||
analyzerWithCompilerReport.analysisResult.bindingContext)
|
||||
|
||||
module.accept(DumpIrTreeVisitor(out), "")
|
||||
return ExitCode.OK
|
||||
}
|
||||
|
||||
override fun createArguments(): K2StudentLlvmArguments {
|
||||
return K2StudentLlvmArguments()
|
||||
}
|
||||
|
||||
companion object {
|
||||
@JvmStatic fun main(args: Array<String>) {
|
||||
CLICompiler.doMain(K2StudentLlvm(), args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) = K2StudentLlvm.main(args)
|
||||
-9
@@ -1,9 +0,0 @@
|
||||
package org.jetbrains.kotlin.cli.student;
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments;
|
||||
|
||||
/**
|
||||
* Created by minamoto on 14/09/16.
|
||||
*/
|
||||
public class K2StudentLlvmArguments extends CommonCompilerArguments {
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
package org.jetbrains.kotlin.student.descriptorUtils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
/**
|
||||
* Created by minamoto on 17/09/2016.
|
||||
* this code is copied from org.jetbrains.kotlin.js.descriptorUtils
|
||||
*/
|
||||
val KotlinType.nameIfStandardType: Name?
|
||||
get() {
|
||||
return constructor.declarationDescriptor
|
||||
?.check { descriptor ->
|
||||
descriptor.builtIns.isBuiltInPackageFragment(descriptor.containingDeclaration as? PackageFragmentDescriptor)
|
||||
}
|
||||
?.name
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.kotlinnative.translator.codegens.ClassCodegen
|
||||
import org.kotlinnative.translator.codegens.FunctionCodegen
|
||||
import org.kotlinnative.translator.codegens.ObjectCodegen
|
||||
import org.kotlinnative.translator.codegens.PropertyCodegen
|
||||
|
||||
class ProjectTranslator(val files: List<KtFile>,
|
||||
val state: TranslationState) {
|
||||
private var codeBuilder = state.codeBuilder
|
||||
|
||||
fun generateCode(): String {
|
||||
with(files) {
|
||||
map { addClassDeclarations(it) }
|
||||
map { addObjectDeclarations(it) }
|
||||
map { addFunctionDeclarations(it) }
|
||||
map { addPropertyDeclarations(it) }
|
||||
}
|
||||
generateProjectBody()
|
||||
return codeBuilder.toString()
|
||||
}
|
||||
|
||||
fun addFunctionDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtNamedFunction>()) {
|
||||
val function = FunctionCodegen(state, variableManager, declaration, codeBuilder)
|
||||
if (function.external) {
|
||||
state.externalFunctions.put(function.fullName, function)
|
||||
} else {
|
||||
state.functions.put(function.fullName, function)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addClassDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtClass>()) {
|
||||
val codegen = ClassCodegen(state, variableManager, declaration, codeBuilder)
|
||||
state.classes.put(codegen.structName, codegen)
|
||||
}
|
||||
}
|
||||
|
||||
fun addPropertyDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtProperty>()) {
|
||||
val property = PropertyCodegen(state, variableManager, declaration, codeBuilder)
|
||||
state.properties.put(declaration.name!!, property)
|
||||
}
|
||||
}
|
||||
|
||||
fun addObjectDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtObjectDeclaration>()) {
|
||||
val codegen = ObjectCodegen(state, variableManager, declaration, codeBuilder)
|
||||
state.objects.put(codegen.structName, codegen)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateProjectBody() {
|
||||
with(state) {
|
||||
properties.values.map { it.generate() }
|
||||
objects.values.map { it.prepareForGenerate() }
|
||||
classes.values.map { it.prepareForGenerate() }
|
||||
objects.values.map { it.generate() }
|
||||
classes.values.map { it.generate() }
|
||||
externalFunctions.values.map { it.generate() }
|
||||
functions.values.filter { it.isExtensionDeclaration }.map { it.generate() }
|
||||
functions.values.filter { !it.isExtensionDeclaration }.map { it.generate() }
|
||||
}
|
||||
|
||||
if (state.mainFunction != "main") {
|
||||
codeBuilder.declareEntryPoint(state.mainFunction)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.kotlinnative.translator.codegens.ClassCodegen
|
||||
import org.kotlinnative.translator.codegens.FunctionCodegen
|
||||
import org.kotlinnative.translator.codegens.ObjectCodegen
|
||||
import org.kotlinnative.translator.codegens.PropertyCodegen
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import java.util.*
|
||||
|
||||
|
||||
class TranslationState
|
||||
private constructor
|
||||
(
|
||||
val bindingContext: BindingContext,
|
||||
val mainFunction: String,
|
||||
arm: Boolean
|
||||
) {
|
||||
var externalFunctions = HashMap<String, FunctionCodegen>()
|
||||
var functions = HashMap<String, FunctionCodegen>()
|
||||
var classes = HashMap<String, ClassCodegen>()
|
||||
var objects = HashMap<String, ObjectCodegen>()
|
||||
var properties = HashMap<String, PropertyCodegen>()
|
||||
val codeBuilder = LLVMBuilder(arm)
|
||||
val extensionFunctions = HashMap<String, HashMap<String, FunctionCodegen>>()
|
||||
val globalVariableCollection = HashMap<String, LLVMVariable>()
|
||||
|
||||
init {
|
||||
POINTER_ALIGN = if (arm) 4 else 8
|
||||
POINTER_SIZE = if (arm) 4 else 8
|
||||
}
|
||||
|
||||
companion object {
|
||||
var POINTER_ALIGN = 4
|
||||
var POINTER_SIZE = 4
|
||||
|
||||
fun createTranslationState(bindingContext:BindingContext, mainFunction: String, arm: Boolean = false): TranslationState {
|
||||
return TranslationState(bindingContext, mainFunction, arm)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMScope
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import java.util.*
|
||||
|
||||
class VariableManager(val globalVariableCollection: HashMap<String, LLVMVariable>) {
|
||||
|
||||
private var fileVariableCollectionTree = HashMap<String, Stack<Pair<LLVMVariable, Int>>>()
|
||||
|
||||
private companion object UniqueGenerator {
|
||||
private var unique = 0
|
||||
fun generateUniqueString() =
|
||||
".unique." + unique++
|
||||
}
|
||||
|
||||
operator fun get(variableName: String): LLVMVariable? {
|
||||
return fileVariableCollectionTree[variableName]?.peek()?.first ?: globalVariableCollection[variableName]
|
||||
}
|
||||
|
||||
operator fun contains(variableName: String): Boolean {
|
||||
return (fileVariableCollectionTree.contains(variableName) && !fileVariableCollectionTree[variableName]!!.empty()) || globalVariableCollection.containsKey(variableName)
|
||||
}
|
||||
|
||||
fun pullOneUpwardLevelVariable(variableName: String) {
|
||||
fileVariableCollectionTree[variableName]?.pop()
|
||||
}
|
||||
|
||||
fun pullUpwardsLevel(level: Int) {
|
||||
fileVariableCollectionTree.forEach { s, stack -> while (!stack.empty() && stack.peek().second >= level) stack.pop() }
|
||||
}
|
||||
|
||||
fun addVariable(name: String, variable: LLVMVariable, level: Int) {
|
||||
val stack = fileVariableCollectionTree.getOrDefault(name, Stack<Pair<LLVMVariable, Int>>())
|
||||
stack.push(Pair(variable, level))
|
||||
fileVariableCollectionTree.put(name, stack)
|
||||
}
|
||||
|
||||
fun addGlobalVariable(name: String, variable: LLVMVariable) {
|
||||
globalVariableCollection.put(name, variable)
|
||||
}
|
||||
|
||||
fun receiveVariable(name: String, type: LLVMType, scope: LLVMScope, pointer: Int): LLVMVariable {
|
||||
return LLVMVariable("managed${generateUniqueString()}.$name", type, name, scope, pointer)
|
||||
}
|
||||
|
||||
}
|
||||
-1121
File diff suppressed because it is too large
Load Diff
@@ -1,84 +0,0 @@
|
||||
package org.kotlinnative.translator.codegens
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.VariableManager
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class ClassCodegen(state: TranslationState,
|
||||
variableManager: VariableManager,
|
||||
val clazz: KtClass,
|
||||
codeBuilder: LLVMBuilder,
|
||||
parentCodegen: StructCodegen? = null) :
|
||||
StructCodegen(state, variableManager, clazz, codeBuilder, parentCodegen) {
|
||||
|
||||
val annotation: Boolean
|
||||
val enum: Boolean
|
||||
var companionObjectCodegen: ObjectCodegen? = null
|
||||
val descriptor: ClassDescriptor
|
||||
|
||||
override var size: Int = 0
|
||||
override val structName: String = clazz.fqName?.asString()!!
|
||||
override val type: LLVMReferenceType
|
||||
|
||||
init {
|
||||
type = LLVMReferenceType(structName, "class", align = TranslationState.POINTER_ALIGN, size = TranslationState.POINTER_SIZE, byRef = true)
|
||||
descriptor = state.bindingContext.get(BindingContext.CLASS, clazz) ?: throw TranslationException("Can't receive descriptor of class " + clazz.name)
|
||||
|
||||
annotation = descriptor.kind == ClassKind.ANNOTATION_CLASS
|
||||
enum = descriptor.kind == ClassKind.ENUM_CLASS
|
||||
|
||||
type.align = TranslationState.POINTER_ALIGN
|
||||
}
|
||||
|
||||
override fun prepareForGenerate() {
|
||||
val parameterList = clazz.getPrimaryConstructorParameterList()?.parameters ?: listOf()
|
||||
indexFields(parameterList)
|
||||
generateInnerFields(clazz.declarations)
|
||||
|
||||
type.size = calculateTypeSize()
|
||||
|
||||
if (annotation) {
|
||||
return
|
||||
}
|
||||
|
||||
super.prepareForGenerate()
|
||||
nestedClasses.forEach { x, classCodegen -> classCodegen.prepareForGenerate() }
|
||||
|
||||
if (descriptor.companionObjectDescriptor != null) {
|
||||
val companionObject = clazz.getCompanionObjects().first()
|
||||
companionObjectCodegen = ObjectCodegen(state, variableManager, companionObject, codeBuilder, this)
|
||||
companionObjectCodegen!!.prepareForGenerate()
|
||||
}
|
||||
}
|
||||
|
||||
override fun generate() {
|
||||
if (annotation) {
|
||||
return
|
||||
}
|
||||
|
||||
super.generate()
|
||||
nestedClasses.forEach { x, classCodegen -> classCodegen.generate() }
|
||||
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)
|
||||
}
|
||||
|
||||
}
|
||||
-138
@@ -1,138 +0,0 @@
|
||||
package org.kotlinnative.translator.codegens
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.VariableManager
|
||||
import org.kotlinnative.translator.llvm.*
|
||||
import org.kotlinnative.translator.llvm.types.LLVMFunctionType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
||||
import java.util.*
|
||||
|
||||
|
||||
class FunctionCodegen(state: TranslationState,
|
||||
variableManager: VariableManager,
|
||||
val function: KtNamedFunction,
|
||||
codeBuilder: LLVMBuilder) :
|
||||
BlockCodegen(state, variableManager, codeBuilder) {
|
||||
|
||||
var name: String
|
||||
var args = LinkedList<LLVMVariable>()
|
||||
val isExtensionDeclaration = function.isExtensionDeclaration()
|
||||
var functionNamePrefix = ""
|
||||
val external: Boolean
|
||||
val defaultValues: List<KtExpression?>
|
||||
val fullName: String
|
||||
get() = functionNamePrefix + name
|
||||
|
||||
init {
|
||||
val descriptor = state.bindingContext.get(BindingContext.FUNCTION, function)!!
|
||||
args.addAll(descriptor.valueParameters.map {
|
||||
LLVMInstanceOfStandardType(it?.fqNameSafe?.asString() ?: it.name.toString(), it.type, state = state)
|
||||
})
|
||||
|
||||
returnType = LLVMInstanceOfStandardType("instance", descriptor.returnType!!, state = state)
|
||||
if (returnType!!.type is LLVMReferenceType) {
|
||||
returnType!!.pointer = 2
|
||||
}
|
||||
external = descriptor.isExternal
|
||||
name = if (external) function.name!! else function.fqName!!.convertToNativeName() + LLVMType.mangleFunctionArguments(args)
|
||||
|
||||
if (isExtensionDeclaration) {
|
||||
name = "${function.name}${if (!external) LLVMType.mangleFunctionArguments(args) else ""}"
|
||||
val receiverType = descriptor.extensionReceiverParameter!!.type
|
||||
val translatorType = LLVMMapStandardType(receiverType, state)
|
||||
val packageName = (function.containingFile as KtFile).packageFqName.asString()
|
||||
functionNamePrefix = packageName.addAfterIfNotEmpty(".") + translatorType.mangle + "."
|
||||
|
||||
val extensionFunctionsOfThisType = state.extensionFunctions.getOrDefault(translatorType.toString(), HashMap())
|
||||
extensionFunctionsOfThisType.put(fullName, this)
|
||||
state.extensionFunctions.put(translatorType.toString(), extensionFunctionsOfThisType)
|
||||
}
|
||||
|
||||
defaultValues = descriptor.valueParameters.indices.map {
|
||||
val parameterDescriptor = descriptor.valueParameters[it]
|
||||
if (parameterDescriptor.declaresDefaultValue()) {
|
||||
val initializer = (parameterDescriptor.source as KotlinSourceElement).psi as KtParameter
|
||||
initializer.defaultValue
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generate(this_type: LLVMVariable? = null) {
|
||||
generateDeclaration(this_type)
|
||||
|
||||
if (external) {
|
||||
return
|
||||
}
|
||||
|
||||
codeBuilder.addStartExpression()
|
||||
generateLoadArguments()
|
||||
evaluateCodeBlock(function.bodyExpression, scopeDepth = topLevelScopeDepth, isBlock = function.hasBlockBody())
|
||||
|
||||
if (returnType?.type is LLVMVoidType){
|
||||
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||
}
|
||||
codeBuilder.addEndExpression()
|
||||
}
|
||||
|
||||
private fun generateDeclaration(this_type: LLVMVariable? = null) {
|
||||
var actualReturnType: LLVMType = returnType!!.type
|
||||
val actualArgs = ArrayList<LLVMVariable>()
|
||||
|
||||
if (returnType!!.pointer > 0) {
|
||||
actualReturnType = LLVMVoidType()
|
||||
actualArgs.add(returnType!!)
|
||||
}
|
||||
|
||||
if (isExtensionDeclaration) {
|
||||
val receiverParameter = state.bindingContext.get(BindingContext.FUNCTION, function)!!.extensionReceiverParameter!!
|
||||
val receiverType = receiverParameter.type
|
||||
val translatorType = LLVMMapStandardType(receiverType, state)
|
||||
|
||||
val classVal = when (translatorType) {
|
||||
is LLVMReferenceType -> LLVMVariable("classvariable.this", translatorType, pointer = 1)
|
||||
else -> LLVMVariable("type", translatorType, pointer = 0)
|
||||
}
|
||||
|
||||
variableManager.addVariable("this", classVal, level = 0)
|
||||
actualArgs.add(classVal)
|
||||
}
|
||||
|
||||
if (this_type != null) {
|
||||
actualArgs.add(this_type)
|
||||
}
|
||||
|
||||
actualArgs.addAll(args)
|
||||
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(fullName, actualArgs, actualReturnType, external))
|
||||
}
|
||||
|
||||
private fun generateLoadArguments() {
|
||||
args.forEach(fun(it: LLVMVariable) {
|
||||
if (it.type is LLVMFunctionType || (it.type is LLVMReferenceType && it.type.byRef)) {
|
||||
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 1), topLevelScopeDepth)
|
||||
return
|
||||
}
|
||||
|
||||
if (it.type !is LLVMReferenceType || it.type.byRef) {
|
||||
val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = it.pointer)
|
||||
val allocVar = codeBuilder.loadArgument(loadVariable)
|
||||
variableManager.addVariable(it.label, allocVar, topLevelScopeDepth)
|
||||
} else {
|
||||
variableManager.addVariable(it.label, LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope(), pointer = 0), topLevelScopeDepth)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
package org.kotlinnative.translator.codegens
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtObjectDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.VariableManager
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.LLVMVariableScope
|
||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class ObjectCodegen(state: TranslationState,
|
||||
variableManager: VariableManager,
|
||||
val objectDeclaration: KtObjectDeclaration,
|
||||
codeBuilder: LLVMBuilder,
|
||||
parentCodegen: StructCodegen? = null) :
|
||||
StructCodegen(state, variableManager, objectDeclaration, codeBuilder, parentCodegen) {
|
||||
|
||||
override var size: Int = 0
|
||||
override val structName: String = objectDeclaration.fqName?.asString()!!
|
||||
override val type = LLVMReferenceType(structName, "class")
|
||||
|
||||
init {
|
||||
primaryConstructorIndex = LLVMType.mangleFunctionArguments(emptyList())
|
||||
constructorFields.put(primaryConstructorIndex!!, arrayListOf())
|
||||
}
|
||||
|
||||
override fun prepareForGenerate() {
|
||||
generateInnerFields(objectDeclaration.declarations)
|
||||
type.size = calculateTypeSize()
|
||||
|
||||
super.prepareForGenerate()
|
||||
|
||||
val classInstance = LLVMVariable("object.instance.$structName", type, objectDeclaration.name, LLVMVariableScope(), pointer = 1)
|
||||
codeBuilder.addGlobalInitialize(classInstance, fields, initializedFields.map {
|
||||
val type = state.bindingContext.get(BindingContext.EXPRESSION_TYPE_INFO, it.value)!!.type!!
|
||||
Pair(it.key, state.bindingContext.get(BindingContext.COMPILE_TIME_VALUE, it.value)!!.getValue(type).toString())
|
||||
}.toMap(), type)
|
||||
variableManager.addGlobalVariable(structName, classInstance)
|
||||
}
|
||||
|
||||
}
|
||||
-33
@@ -1,33 +0,0 @@
|
||||
package org.kotlinnative.translator.codegens
|
||||
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.student.descriptorUtils.nameIfStandardType
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.VariableManager
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMInstanceOfStandardType
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.LLVMVariableScope
|
||||
|
||||
|
||||
class PropertyCodegen(val state: TranslationState,
|
||||
val variableManager: VariableManager,
|
||||
val property: KtProperty,
|
||||
val codeBuilder: LLVMBuilder) {
|
||||
|
||||
fun generate() {
|
||||
val varInfo = state.bindingContext.get(BindingContext.VARIABLE, property)?.compileTimeInitializer ?: return
|
||||
|
||||
val kotlinType = varInfo.type
|
||||
val value = varInfo.value
|
||||
if (kotlinType.nameIfStandardType != null) {
|
||||
val variableType = LLVMInstanceOfStandardType(property.name ?: return, kotlinType, state = state).type
|
||||
val variable = LLVMVariable(property.name.toString(), variableType, property.name.toString(), LLVMVariableScope())
|
||||
variableManager.addGlobalVariable(property.name.toString(), variable)
|
||||
codeBuilder.defineGlobalVariable(variable, variableType.parseArg(value.toString()))
|
||||
variable.pointer++
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-252
@@ -1,252 +0,0 @@
|
||||
package org.kotlinnative.translator.codegens
|
||||
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.VariableManager
|
||||
import org.kotlinnative.translator.llvm.*
|
||||
import org.kotlinnative.translator.llvm.types.LLVMCharType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMReferenceType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import org.kotlinnative.translator.llvm.types.LLVMVoidType
|
||||
import java.util.*
|
||||
|
||||
/*
|
||||
* TODO make high level description of code generation process
|
||||
* and structure of generated code.
|
||||
*/
|
||||
abstract class StructCodegen(val state: TranslationState,
|
||||
val variableManager: VariableManager,
|
||||
val classOrObject: KtClassOrObject,
|
||||
val codeBuilder: LLVMBuilder,
|
||||
val parentCodegen: StructCodegen? = null) {
|
||||
|
||||
val fields = ArrayList<LLVMClassVariable>()
|
||||
val fieldsIndex = HashMap<String, LLVMClassVariable>()
|
||||
val nestedClasses = HashMap<String, ClassCodegen>()
|
||||
val enumFields = HashMap<String, LLVMVariable>()
|
||||
val constructorFields = HashMap<String, List<LLVMVariable>>()
|
||||
var primaryConstructorIndex: String? = null
|
||||
val initializedFields = HashMap<LLVMVariable, KtExpression>()
|
||||
var methods = HashMap<String, FunctionCodegen>()
|
||||
|
||||
abstract val type: LLVMReferenceType
|
||||
abstract var size: Int
|
||||
abstract val structName: String
|
||||
|
||||
open fun prepareForGenerate() {
|
||||
generateStruct()
|
||||
classOrObject.declarations.filterIsInstance<KtNamedFunction>().map {
|
||||
val function = FunctionCodegen(state, variableManager, it, codeBuilder)
|
||||
methods.put(function.name, function)
|
||||
}
|
||||
}
|
||||
|
||||
fun calculateTypeSize(): Int {
|
||||
val classAlignment = fields.map { it.type.align }.max()?.toInt() ?: 0
|
||||
var alignmentRemainder = 0
|
||||
size = 0
|
||||
|
||||
for (item in fields) {
|
||||
val currentFieldSize = if (item.pointer > 0) TranslationState.POINTER_ALIGN else item.type.align
|
||||
alignmentRemainder -= (alignmentRemainder % currentFieldSize)
|
||||
if (alignmentRemainder < currentFieldSize) {
|
||||
size += classAlignment
|
||||
alignmentRemainder = classAlignment - currentFieldSize
|
||||
} else {
|
||||
alignmentRemainder -= currentFieldSize
|
||||
}
|
||||
}
|
||||
return size
|
||||
}
|
||||
|
||||
open fun generate() {
|
||||
generateEnumFields()
|
||||
generatePrimaryConstructor()
|
||||
classOrObject.getSecondaryConstructors().map { generateSecondaryConstructor(it) }
|
||||
|
||||
val classVal = LLVMVariable("classvariable.this", type, pointer = if (type.isPrimitive) 0 else 1)
|
||||
variableManager.addVariable("this", classVal, level = 0)
|
||||
|
||||
methods.values.map { it.generate(classVal) }
|
||||
}
|
||||
|
||||
fun generateInnerFields(declarations: List<KtDeclaration>) {
|
||||
for (declaration in declarations) {
|
||||
when (declaration) {
|
||||
is KtProperty -> {
|
||||
val ktType = state.bindingContext.get(BindingContext.TYPE, declaration.typeReference)
|
||||
?: state.bindingContext.get(BindingContext.VARIABLE, declaration)!!.type
|
||||
val field = resolveType(declaration, ktType, fields.size)
|
||||
|
||||
if (declaration.initializer != null) {
|
||||
initializedFields.put(field, declaration.initializer!!)
|
||||
}
|
||||
|
||||
fields.add(field)
|
||||
fieldsIndex[field.label] = field
|
||||
}
|
||||
is KtEnumEntry -> {
|
||||
val name = declaration.name!!
|
||||
val field = LLVMVariable("class.$structName.$name", type, scope = LLVMVariableScope(), pointer = 2)
|
||||
enumFields.put(name, field)
|
||||
}
|
||||
is KtClass ->
|
||||
nestedClasses.put(declaration.fqName!!.asString(),
|
||||
ClassCodegen(state,
|
||||
VariableManager(state.globalVariableCollection),
|
||||
declaration, codeBuilder, this))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateEnumFields() {
|
||||
val enumEntries = classOrObject.declarations.filterIsInstance<KtEnumEntry>()
|
||||
|
||||
for (declaration in enumEntries) {
|
||||
val name = declaration.name!!
|
||||
val initializer = declaration.initializerList!!.initializers[0]
|
||||
val arguments = (initializer as KtSuperTypeCallEntry).valueArguments.map { it.getArgumentExpression()!!.text }
|
||||
|
||||
val field = codeBuilder.getNewVariable(type, scope = LLVMVariableScope())
|
||||
val enumField = enumFields[name]!!
|
||||
|
||||
codeBuilder.defineGlobalVariable(field, codeBuilder.makeStructInitializer(constructorFields[primaryConstructorIndex]!!, arguments))
|
||||
codeBuilder.defineGlobalVariable(LLVMVariable(enumField.label, enumField.type, enumField.kotlinName, enumField.scope, enumField.pointer - 1), field.toString())
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateStruct() =
|
||||
codeBuilder.createClass(structName, fields)
|
||||
|
||||
private fun generateSecondaryConstructor(secondaryConstructor: KtSecondaryConstructor) {
|
||||
val thisCall = secondaryConstructor.getDelegationCall().calleeExpression
|
||||
val descriptor = state.bindingContext.get(BindingContext.CONSTRUCTOR, secondaryConstructor)
|
||||
|
||||
val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
|
||||
variableManager.addVariable("this", classVal, level = 0)
|
||||
|
||||
val secondaryConstructorArguments = descriptor!!.valueParameters.map {
|
||||
LLVMInstanceOfStandardType(it.fqNameSafe.convertToNativeName(), it.type, state = state)
|
||||
}
|
||||
|
||||
val argFields = mutableListOf(classVal)
|
||||
argFields.addAll(secondaryConstructorArguments)
|
||||
val currentConstructorIndex = LLVMType.mangleFunctionArguments(secondaryConstructorArguments)
|
||||
constructorFields.put(currentConstructorIndex, argFields)
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(structName + currentConstructorIndex, argFields, LLVMVoidType()))
|
||||
|
||||
codeBuilder.addStartExpression()
|
||||
|
||||
secondaryConstructorArguments.map { variableManager.addVariable(it.label, it, level = 2) }
|
||||
|
||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
||||
val mainConstructorThis = blockCodegen.evaluateConstructorDelegationReferenceExpression(thisCall!!, this, secondaryConstructorArguments, 1) as LLVMVariable
|
||||
variableManager.addVariable("this", mainConstructorThis, level = 0)
|
||||
|
||||
blockCodegen.evaluateCodeBlock(secondaryConstructor.bodyExpression, scopeDepth = 1)
|
||||
generateReturn(codeBuilder.receivePointedArgument(variableManager["this"]!!, requirePointer = 1) as LLVMVariable)
|
||||
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||
codeBuilder.addEndExpression()
|
||||
}
|
||||
|
||||
private fun generatePrimaryConstructor() {
|
||||
val classVal = LLVMVariable("classvariable.this", type, pointer = 1)
|
||||
variableManager.addVariable("this", classVal, level = 0)
|
||||
|
||||
val argFields = mutableListOf(classVal)
|
||||
argFields.addAll(constructorFields[primaryConstructorIndex]!!)
|
||||
|
||||
codeBuilder.addLLVMCodeToLocalPlace(LLVMFunctionDescriptor(structName + primaryConstructorIndex, argFields, LLVMVoidType()))
|
||||
|
||||
codeBuilder.addStartExpression()
|
||||
generateLoadArguments(classVal)
|
||||
generateAssignments()
|
||||
generateReturn(LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1))
|
||||
genClassInitializers()
|
||||
codeBuilder.addAnyReturn(LLVMVoidType())
|
||||
codeBuilder.addEndExpression()
|
||||
}
|
||||
|
||||
private fun generateLoadArguments(thisField: LLVMVariable) {
|
||||
val thisVariable = LLVMVariable(thisField.label, thisField.type, thisField.label, LLVMRegisterScope(), pointer = 0)
|
||||
codeBuilder.loadArgument(thisVariable, false)
|
||||
|
||||
constructorFields[primaryConstructorIndex]!!.filter { it.type !is LLVMReferenceType }.forEach {
|
||||
val loadVariable = LLVMVariable(it.label, it.type, it.label, LLVMRegisterScope())
|
||||
codeBuilder.loadArgument(loadVariable)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateAssignments() {
|
||||
constructorFields[primaryConstructorIndex]!!.forEach {
|
||||
when (it.type) {
|
||||
is LLVMReferenceType -> {
|
||||
val classField = codeBuilder.getNewVariable(it.type, pointer = it.pointer + 1)
|
||||
codeBuilder.loadClassField(classField, LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1), (it as LLVMClassVariable).offset)
|
||||
codeBuilder.storeVariable(classField, it)
|
||||
}
|
||||
else -> {
|
||||
val argument = codeBuilder.loadAndGetVariable(LLVMVariable("${it.label}.addr", it.type, scope = LLVMRegisterScope(), pointer = it.pointer + 1))
|
||||
val classField = codeBuilder.getNewVariable(it.type, pointer = 1)
|
||||
codeBuilder.loadClassField(classField, LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1), (it as LLVMClassVariable).offset)
|
||||
codeBuilder.storeVariable(classField, argument)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val blockCodegen = object : BlockCodegen(state, variableManager, codeBuilder) {}
|
||||
val receiverThis = LLVMVariable("classvariable.this.addr", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||
variableManager.addVariable("this", receiverThis, level = 2)
|
||||
|
||||
for ((variable, initializer) in initializedFields) {
|
||||
val left = blockCodegen.evaluateMemberMethodOrField(receiverThis, variable.label, blockCodegen.topLevelScopeDepth, call = null)!!
|
||||
val right = blockCodegen.evaluateExpression(initializer, scopeDepth = blockCodegen.topLevelScopeDepth)!!
|
||||
blockCodegen.addPrimitiveBinaryOperation(KtTokens.EQ, left, right)
|
||||
}
|
||||
|
||||
variableManager.pullOneUpwardLevelVariable("this")
|
||||
}
|
||||
|
||||
private fun generateReturn(src: LLVMVariable) {
|
||||
val dst = LLVMVariable("classvariable.this", type, scope = LLVMRegisterScope(), pointer = 1)
|
||||
|
||||
val castedDst = codeBuilder.bitcast(dst, LLVMCharType(), pointer = 1)
|
||||
val castedSrc = codeBuilder.bitcast(src, LLVMCharType(), pointer = 1)
|
||||
|
||||
codeBuilder.memcpy(castedDst, castedSrc, size)
|
||||
}
|
||||
|
||||
protected fun resolveType(field: KtNamedDeclaration, ktType: KotlinType, offset: Int): LLVMClassVariable {
|
||||
val annotations = parseFieldAnnotations(field)
|
||||
val fieldName = state.bindingContext.get(BindingContext.VALUE_PARAMETER, field as?KtParameter)?.fqNameSafe?.convertToNativeName()
|
||||
?: field.fqName?.asString()
|
||||
?: field.name!!
|
||||
|
||||
val result = LLVMInstanceOfStandardType(fieldName, ktType, LLVMRegisterScope(), state = state)
|
||||
|
||||
if (state.classes.containsKey(field.name!!)) {
|
||||
return LLVMClassVariable(result.label, state.classes[fieldName]!!.type, result.pointer)
|
||||
}
|
||||
|
||||
if (annotations.contains("Plain")) {
|
||||
result.pointer = 0
|
||||
}
|
||||
|
||||
return LLVMClassVariable(result.label, result.type, result.pointer, offset)
|
||||
}
|
||||
|
||||
private fun parseFieldAnnotations(field: KtNamedDeclaration): Set<String> =
|
||||
field.annotationEntries.map { state.bindingContext.get(BindingContext.ANNOTATION, it)?.type.toString() }.toHashSet()
|
||||
|
||||
protected fun genClassInitializers() =
|
||||
classOrObject.getAnonymousInitializers().map {
|
||||
object : BlockCodegen(state, variableManager, codeBuilder) {
|
||||
fun generate() = evaluateCodeBlock(it.body, scopeDepth = topLevelScopeDepth)
|
||||
}
|
||||
}.map { it.generate() }
|
||||
|
||||
}
|
||||
@@ -1,59 +0,0 @@
|
||||
package org.kotlinnative.translator.debug
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import com.intellij.psi.impl.source.tree.CompositeElement
|
||||
import org.jetbrains.kotlin.psi.KtClass
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
|
||||
fun debugPrintNode(node: Any?, indent: Int = 0): Unit {
|
||||
if (node == null) {
|
||||
return
|
||||
}
|
||||
|
||||
for (i in 0..indent) {
|
||||
print(" ")
|
||||
}
|
||||
|
||||
println(node.toString())
|
||||
|
||||
when (node) {
|
||||
is CompositeElement -> {
|
||||
debugPrintNode(node.firstChildNode, indent + 2)
|
||||
debugPrintNode(node.treeNext, indent)
|
||||
}
|
||||
is PsiElement -> {
|
||||
debugPrintNode(node.firstChild, indent + 2)
|
||||
debugPrintNode(node.nextSibling, indent)
|
||||
}
|
||||
is PsiWhiteSpace -> {
|
||||
debugPrintNode(node.firstChild, indent + 2)
|
||||
debugPrintNode(node.nextSibling, indent)
|
||||
}
|
||||
else -> {
|
||||
print(" not supported: " + node.javaClass.canonicalName)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun printFunction(function: KtNamedFunction) {
|
||||
debugPrintNode(function.node)
|
||||
}
|
||||
|
||||
fun printClass(function: KtClass) {
|
||||
debugPrintNode(function.node)
|
||||
}
|
||||
|
||||
fun printFile(file: KtFile) {
|
||||
|
||||
for (declaration in file.declarations) {
|
||||
|
||||
when (declaration) {
|
||||
is KtNamedFunction -> printFunction(declaration)
|
||||
is KtClass -> printClass(declaration)
|
||||
else -> println(declaration.toString())
|
||||
}
|
||||
}
|
||||
}
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
package org.kotlinnative.translator.exceptions
|
||||
|
||||
import java.lang.Exception
|
||||
|
||||
class TranslationException(message: String) : Exception(message)
|
||||
-5
@@ -1,5 +0,0 @@
|
||||
package org.kotlinnative.translator.exceptions
|
||||
|
||||
import java.lang.Exception
|
||||
|
||||
class UnimplementedException() : Exception()
|
||||
@@ -1,252 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.llvm.types.*
|
||||
import java.rmi.UnexpectedException
|
||||
import java.util.*
|
||||
|
||||
class LLVMBuilder(arm: Boolean = false) {
|
||||
|
||||
private val localCode: StringBuilder = StringBuilder()
|
||||
private val globalCode: StringBuilder = StringBuilder()
|
||||
private var variableCount = 0
|
||||
private var labelCount = 0
|
||||
private val exceptions = mapOf(
|
||||
Pair("KotlinNullPointerException", initializeExceptionString("Exception in thread main kotlin.KotlinNullPointerException")))
|
||||
|
||||
|
||||
init {
|
||||
val declares = arrayOf(
|
||||
"declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture readonly, i64, i32, i1)",
|
||||
"declare i8* @malloc_heap(i32)",
|
||||
"declare i32 @printf(i8*, ...)",
|
||||
"declare void @abort()",
|
||||
"%class.Nothing = type { }")
|
||||
|
||||
declares.forEach { addLLVMCodeToGlobalPlace(it) }
|
||||
|
||||
if (arm) {
|
||||
val functionAttributes = """attributes #0 = { nounwind "stack-protector-buffer-size"="8" "target-cpu"="cortex-m3" "target-features"="+hwdiv,+strict-align" }"""
|
||||
addLLVMCodeToGlobalPlace(functionAttributes)
|
||||
}
|
||||
}
|
||||
|
||||
fun addLLVMCodeToLocalPlace(code: String) =
|
||||
localCode.appendln(code)
|
||||
|
||||
fun addLLVMCodeToGlobalPlace(code: String) =
|
||||
globalCode.appendln(code)
|
||||
|
||||
fun addComment(comment: String) =
|
||||
addLLVMCodeToLocalPlace("; " + comment)
|
||||
|
||||
fun addStartExpression() =
|
||||
addLLVMCodeToLocalPlace("{")
|
||||
|
||||
fun addEndExpression() =
|
||||
addLLVMCodeToLocalPlace("unreachable\n}")
|
||||
|
||||
fun addAssignment(lhs: LLVMVariable, rhs: LLVMNode) =
|
||||
addLLVMCodeToLocalPlace("$lhs = $rhs")
|
||||
|
||||
fun addReturnOperator(llvmVariable: LLVMSingleValue) =
|
||||
addLLVMCodeToLocalPlace("ret ${llvmVariable.type} $llvmVariable")
|
||||
|
||||
fun addAnyReturn(type: LLVMType, value: String = type.defaultValue, pointer: Int = 0) =
|
||||
addLLVMCodeToLocalPlace("ret $type${"*".repeat(pointer)} $value")
|
||||
|
||||
fun addStringConstant(variable: LLVMVariable, value: String) =
|
||||
addLLVMCodeToGlobalPlace("$variable = private unnamed_addr constant ${(variable.type as LLVMStringType).fullArrayType} c\"${value.replace("\"", "\\\"")}\\00\", align 1")
|
||||
|
||||
fun addCondition(condition: LLVMSingleValue, thenLabel: LLVMLabel, elseLabel: LLVMLabel) =
|
||||
addLLVMCodeToLocalPlace("br ${condition.pointedType} $condition, label $thenLabel, label $elseLabel")
|
||||
|
||||
fun addUnconditionalJump(label: LLVMLabel) =
|
||||
addLLVMCodeToLocalPlace("br label $label")
|
||||
|
||||
fun addExceptionCall(exceptionName: String) {
|
||||
val exception = exceptions[exceptionName]
|
||||
val printResult = getNewVariable(LLVMIntType(), pointer = 0)
|
||||
addLLVMCodeToLocalPlace("$printResult = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds (${(exception!!.type as LLVMStringType).fullArrayType}* $exception, i32 0, i32 0))")
|
||||
addFunctionCall(LLVMVariable("abort", LLVMVoidType(), scope = LLVMVariableScope()), emptyList())
|
||||
}
|
||||
|
||||
fun addFunctionCall(functionName: LLVMVariable, arguments: List<LLVMVariable>) =
|
||||
addLLVMCodeToLocalPlace("call ${functionName.type} $functionName(${arguments.joinToString { it -> "${it.type} $it" }})")
|
||||
|
||||
fun allocStackVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
|
||||
val type = if (asValue) target.type.toString() else target.pointedType
|
||||
addLLVMCodeToLocalPlace("$target = alloca ${if (pointer) type.removeSuffix("*") else type}, align ${target.type.align}")
|
||||
}
|
||||
|
||||
fun allocStaticVar(target: LLVMVariable, asValue: Boolean = false, pointer: Boolean = false) {
|
||||
val allocated = getNewVariable(LLVMCharType(), pointer = 1)
|
||||
val size = if ((target.pointer >= 2) || (target.pointer >= 1 && !pointer)) TranslationState.POINTER_SIZE else target.type.size
|
||||
|
||||
addLLVMCodeToLocalPlace("$allocated = call i8* @malloc_heap(i32 $size)")
|
||||
addLLVMCodeToLocalPlace("$target = bitcast ${allocated.pointedType} $allocated to ${if (asValue) target.type.toString() else target.pointedType}" + if (pointer) "" else "*")
|
||||
}
|
||||
|
||||
fun addGlobalInitialize(target: LLVMVariable, fields: ArrayList<LLVMClassVariable>, initializers: Map<LLVMVariable, String>, classType: LLVMType) {
|
||||
val code = "$target = internal global $classType { ${
|
||||
fields.map { it.pointedType + " " + if (initializers.containsKey(it)) initializers[it] else "0" }.joinToString()
|
||||
} }, align ${classType.align}"
|
||||
addLLVMCodeToGlobalPlace(code)
|
||||
}
|
||||
|
||||
fun bitcast(src: LLVMVariable, llvmType: LLVMType, pointer: Int): LLVMVariable {
|
||||
val empty = getNewVariable(llvmType, pointer = pointer)
|
||||
addLLVMCodeToLocalPlace("$empty = bitcast ${src.pointedType} $src to ${llvmType.toString() + "*".repeat(pointer)}")
|
||||
return empty
|
||||
}
|
||||
|
||||
fun convertVariableToType(variable: LLVMSingleValue, targetType: LLVMType): LLVMSingleValue {
|
||||
var resultVariable = variable
|
||||
if (variable.type != targetType) {
|
||||
val convertedExpression = targetType.convertFrom(variable)
|
||||
resultVariable = saveExpression(convertedExpression)
|
||||
}
|
||||
return resultVariable
|
||||
}
|
||||
|
||||
fun copyVariable(from: LLVMVariable, to: LLVMVariable) =
|
||||
when {
|
||||
from.type is LLVMStringType && !from.type.isLoaded -> storeString(to, from, 0)
|
||||
else -> copyVariableValue(to, from)
|
||||
}
|
||||
|
||||
fun createClass(name: String, fields: List<LLVMVariable>) =
|
||||
addLLVMCodeToGlobalPlace("%class.$name = type { ${fields.map { it.pointedType }.joinToString()} }")
|
||||
|
||||
fun declareEntryPoint(name: String) {
|
||||
addLLVMCodeToLocalPlace("define weak void @main()")
|
||||
addStartExpression()
|
||||
addFunctionCall(LLVMVariable(name, LLVMVoidType(), scope = LLVMVariableScope()), listOf())
|
||||
addAnyReturn(LLVMVoidType())
|
||||
addEndExpression()
|
||||
}
|
||||
|
||||
fun defineGlobalVariable(variable: LLVMVariable, defaultValue: String = variable.type.defaultValue) =
|
||||
addLLVMCodeToLocalPlace("$variable = global ${variable.pointedType} $defaultValue, align ${variable.type.align}")
|
||||
|
||||
fun getNewVariable(type: LLVMType, pointer: Int = 0, kotlinName: String? = null, scope: LLVMScope = LLVMRegisterScope(), prefix: String = "var"): LLVMVariable {
|
||||
variableCount++
|
||||
return LLVMVariable("$prefix$variableCount", type, kotlinName, scope, pointer)
|
||||
}
|
||||
|
||||
fun getNewLabel(scope: LLVMScope = LLVMRegisterScope(), prefix: String): LLVMLabel {
|
||||
labelCount++
|
||||
return LLVMLabel("label.$prefix.$labelCount", scope)
|
||||
}
|
||||
|
||||
fun loadArgsIfRequired(names: List<LLVMSingleValue>, args: List<LLVMVariable>) =
|
||||
names.mapIndexed(fun(i: Int, value: LLVMSingleValue): LLVMSingleValue {
|
||||
return receivePointedArgument(value, args[i].pointer)
|
||||
}).toList()
|
||||
|
||||
fun loadArgument(llvmVariable: LLVMVariable, store: Boolean = true): LLVMVariable {
|
||||
val allocVar = LLVMVariable("${llvmVariable.label}.addr", llvmVariable.type, llvmVariable.kotlinName, LLVMRegisterScope(), pointer = llvmVariable.pointer + 1)
|
||||
allocStackVar(allocVar, asValue = false, pointer = true)
|
||||
if (store) {
|
||||
storeVariable(allocVar, llvmVariable)
|
||||
}
|
||||
return allocVar
|
||||
}
|
||||
|
||||
fun loadClassField(target: LLVMVariable, source: LLVMVariable, offset: Int) =
|
||||
addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.pointedType} $source, i32 0, i32 $offset")
|
||||
|
||||
fun loadVariableOffset(target: LLVMVariable, source: LLVMVariable, index: LLVMConstant) =
|
||||
addLLVMCodeToLocalPlace("$target = getelementptr inbounds ${source.type} $source, ${index.type} ${index.value}")
|
||||
|
||||
fun loadAndGetVariable(source: LLVMVariable): LLVMVariable {
|
||||
assert(source.pointer > 0)
|
||||
val target = getNewVariable(source.type, source.pointer - 1, source.kotlinName)
|
||||
addLLVMCodeToLocalPlace("$target = load ${source.pointedType} $source, align ${target.type.align}")
|
||||
return target
|
||||
}
|
||||
|
||||
fun makeStructInitializer(args: List<LLVMVariable>, values: List<String>)
|
||||
= "{ ${args.mapIndexed { i: Int, variable: LLVMVariable -> "${variable.type} ${values[i]}" }.joinToString()} }"
|
||||
|
||||
fun markWithLabel(label: LLVMLabel?) {
|
||||
if (label != null)
|
||||
addLLVMCodeToLocalPlace("${label.label}:")
|
||||
}
|
||||
|
||||
fun memcpy(castedDst: LLVMVariable, castedSrc: LLVMVariable, size: Int, align: Int = 4, volatile: Boolean = false) =
|
||||
addLLVMCodeToLocalPlace("call void @llvm.memcpy.p0i8.p0i8.i64(i8* $castedDst, i8* $castedSrc, i64 $size, i32 $align, i1 $volatile)")
|
||||
|
||||
fun nullCheck(variable: LLVMVariable): LLVMVariable {
|
||||
val result = getNewVariable(LLVMBooleanType(), pointer = 0)
|
||||
val loaded = loadAndGetVariable(variable)
|
||||
addLLVMCodeToLocalPlace("$result = icmp eq ${loaded.pointedType} null, $loaded")
|
||||
return result
|
||||
}
|
||||
|
||||
fun receiveNativeValue(firstOp: LLVMSingleValue): LLVMSingleValue =
|
||||
when {
|
||||
firstOp is LLVMConstant || firstOp.pointer == 0 -> firstOp
|
||||
firstOp is LLVMVariable -> loadAndGetVariable(firstOp)
|
||||
else -> throw UnexpectedException("Unknown inheritor of LLVMSingleValue")
|
||||
}
|
||||
|
||||
fun receivePointedArgument(value: LLVMSingleValue, requirePointer: Int): LLVMSingleValue {
|
||||
var result = value
|
||||
|
||||
while (result.pointer > requirePointer) {
|
||||
result = receiveNativeValue(result)
|
||||
}
|
||||
|
||||
if ((value.type is LLVMStringType) && !(value.type.isLoaded)) {
|
||||
val newVariable = getNewVariable(value.type, pointer = result.pointer + 1)
|
||||
allocStackVar(newVariable, asValue = true)
|
||||
copyVariable(result as LLVMVariable, newVariable)
|
||||
result = loadAndGetVariable(newVariable)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun storeString(target: LLVMVariable, source: LLVMVariable, offset: Int) {
|
||||
val code = "store ${target.type} getelementptr inbounds (" +
|
||||
"${(source.type as LLVMStringType).fullArrayType}* $source, i32 0, i32 $offset), ${target.pointedType} $target, align ${source.type.align}"
|
||||
(target.type as LLVMStringType).isLoaded = true
|
||||
addLLVMCodeToLocalPlace(code)
|
||||
}
|
||||
|
||||
fun storeVariable(target: LLVMSingleValue, source: LLVMSingleValue) {
|
||||
if ((source.type is LLVMStringType) && !(source.type.isLoaded)) {
|
||||
storeString(target as LLVMVariable, source as LLVMVariable, 0)
|
||||
} else {
|
||||
addLLVMCodeToLocalPlace("store ${source.pointedType} $source, ${target.pointedType} $target, align ${source.type.align}")
|
||||
}
|
||||
}
|
||||
|
||||
fun saveExpression(expression: LLVMSingleValue): LLVMVariable {
|
||||
val resultOp = getNewVariable(expression.type, pointer = expression.pointer)
|
||||
addAssignment(resultOp, expression)
|
||||
return resultOp
|
||||
}
|
||||
|
||||
fun storeNull(result: LLVMVariable) =
|
||||
addLLVMCodeToLocalPlace("store ${result.pointedType.dropLast(1)} null, ${result.pointedType} $result, align ${TranslationState.POINTER_ALIGN}")
|
||||
|
||||
override fun toString() = globalCode.toString() + localCode.toString()
|
||||
|
||||
private fun copyVariableValue(target: LLVMVariable, source: LLVMVariable) {
|
||||
var from = source
|
||||
if (source.pointer > 0) {
|
||||
from = getNewVariable(source.type, source.pointer)
|
||||
addLLVMCodeToLocalPlace("$from = load ${source.pointedType} $source, align ${from.type.align}")
|
||||
}
|
||||
addLLVMCodeToLocalPlace("store ${target.type} $from, ${target.pointedType} $target, align ${from.type.align}")
|
||||
}
|
||||
|
||||
private fun initializeExceptionString(string: String): LLVMVariable {
|
||||
val result = getNewVariable(LLVMStringType(string.length), pointer = 0, scope = LLVMVariableScope(), prefix = "exceptions.str.")
|
||||
addStringConstant(result, string)
|
||||
return result
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class LLVMCall(val returnType: LLVMType,
|
||||
val name: String,
|
||||
val arguments: Collection<LLVMSingleValue>) : LLVMSingleValue(returnType) {
|
||||
|
||||
override fun toString() = "call $returnType $name(${arguments.joinToString { "${it.pointedType} ${it.toString()}" }})"
|
||||
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class LLVMClassVariable(label: String,
|
||||
type: LLVMType,
|
||||
pointer: Int = 0,
|
||||
var offset: Int = 0) : LLVMVariable(label, type, pointer = pointer)
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
open class LLVMConstant(value: String,
|
||||
type: LLVMType,
|
||||
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
||||
|
||||
val value = type.parseArg(value)
|
||||
|
||||
override fun toString() = value
|
||||
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
class LLVMExpression(type: LLVMType, val llvmCode: String, pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
||||
|
||||
override fun toString() = llvmCode
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
class LLVMLabel(val label: String, val scope: LLVMScope) : LLVMNode() {
|
||||
|
||||
override fun toString() = "$scope$label"
|
||||
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
abstract class LLVMNode
|
||||
@@ -1,11 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
abstract class LLVMScope
|
||||
|
||||
class LLVMVariableScope : LLVMScope() {
|
||||
override fun toString() = "@"
|
||||
}
|
||||
|
||||
class LLVMRegisterScope : LLVMScope() {
|
||||
override fun toString() = "%"
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
open class LLVMSingleValue(val type: LLVMType, var pointer: Int = 0) : LLVMNode() {
|
||||
|
||||
open val pointedType: String
|
||||
get() = type.toString() + "*".repeat(pointer)
|
||||
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
|
||||
open class LLVMVariable(val label: String,
|
||||
type: LLVMType,
|
||||
var kotlinName: String? = null,
|
||||
val scope: LLVMScope = LLVMRegisterScope(),
|
||||
pointer: Int = 0) : LLVMSingleValue(type, pointer) {
|
||||
|
||||
override fun toString() = "$scope$label"
|
||||
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm
|
||||
|
||||
import org.jetbrains.kotlin.builtins.isFunctionTypeOrSubtype
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.student.descriptorUtils.nameIfStandardType
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.llvm.types.*
|
||||
|
||||
|
||||
fun LLVMFunctionDescriptor(name: String,
|
||||
argTypes: List<LLVMVariable>?,
|
||||
returnType: LLVMType,
|
||||
declare: Boolean = false) =
|
||||
"${if (declare) "declare" else "define weak"} $returnType @$name(${
|
||||
argTypes?.mapIndexed { i: Int, s: LLVMVariable ->
|
||||
"${s.pointedType} ${if (s.type is LLVMReferenceType && !s.type.byRef) "byval" else ""} %${s.label}"
|
||||
}?.joinToString()}) #0"
|
||||
|
||||
fun LLVMInstanceOfStandardType(name: String,
|
||||
type: KotlinType,
|
||||
scope: LLVMScope = LLVMRegisterScope(),
|
||||
state: TranslationState): LLVMVariable {
|
||||
val typeName = type.toString().dropLastWhile { it == '?' }
|
||||
val pointerMark = if (type.isMarkedNullable) 1 else 0
|
||||
return when {
|
||||
type.isFunctionTypeOrSubtype -> LLVMVariable(name, LLVMFunctionType(type, state), name, scope, pointer = 1)
|
||||
typeName == "Boolean" -> LLVMVariable(name, LLVMBooleanType(), name, scope, pointerMark)
|
||||
typeName == "Byte" -> LLVMVariable(name, LLVMByteType(), name, scope, pointerMark)
|
||||
typeName == "Char" -> LLVMVariable(name, LLVMCharType(), name, scope, pointerMark)
|
||||
typeName == "Short" -> LLVMVariable(name, LLVMShortType(), name, scope, pointerMark)
|
||||
typeName == "Int" -> LLVMVariable(name, LLVMIntType(), name, scope, pointerMark)
|
||||
typeName == "Long" -> LLVMVariable(name, LLVMLongType(), name, scope, pointerMark)
|
||||
typeName == "Float" -> LLVMVariable(name, LLVMFloatType(), name, scope, pointerMark)
|
||||
typeName == "Double" -> LLVMVariable(name, LLVMDoubleType(), name, scope, pointerMark)
|
||||
typeName == "String" -> LLVMVariable(name, LLVMStringType(0), name, scope, pointerMark)
|
||||
type.nameIfStandardType.toString() == "Nothing" -> LLVMVariable(name, LLVMNullType(), name, scope)
|
||||
type.isUnit() -> LLVMVariable("", LLVMVoidType(), name, scope)
|
||||
type.isMarkedNullable -> LLVMVariable(name, LLVMReferenceType(typeName, prefix = "class"), name, scope, pointer = pointerMark)
|
||||
else -> {
|
||||
val declarationDescriptor = type.constructor.declarationDescriptor!!
|
||||
val refName = declarationDescriptor.fqNameSafe.asString()
|
||||
val refType = state.classes[type.toString()]?.type ?: LLVMReferenceType(refName, align = TranslationState.POINTER_ALIGN, prefix = "class")
|
||||
|
||||
LLVMVariable(name, refType, name, scope, pointer = 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun LLVMMapStandardType(type: KotlinType,
|
||||
state: TranslationState) =
|
||||
LLVMInstanceOfStandardType("type", type, LLVMRegisterScope(), state).type
|
||||
|
||||
fun String.addBeforeIfNotEmpty(add: String): String =
|
||||
if (this.length > 0) add + this else this
|
||||
|
||||
fun String.addAfterIfNotEmpty(add: String): String =
|
||||
if (this.length > 0) this + add else this
|
||||
|
||||
fun FqName.convertToNativeName(): String =
|
||||
this.asString().replace(".<init>", "")
|
||||
@@ -1,9 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
interface LLVMArray {
|
||||
|
||||
val arrayElementType: LLVMType
|
||||
val fullArrayType: String
|
||||
val length: Int
|
||||
|
||||
}
|
||||
-69
@@ -1,69 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
|
||||
class LLVMBooleanType() : LLVMType() {
|
||||
|
||||
override val align = 4
|
||||
override var size: Int = 1
|
||||
override val defaultValue = "0"
|
||||
override val mangle = "Boolean"
|
||||
override val isPrimitive = true
|
||||
override val typename = "i1"
|
||||
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "sub nsw i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "mul nsw i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "add nsw i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "sdiv i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sgt i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i1" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "or i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "and i1 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "xor i1 $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMBooleanType
|
||||
|
||||
override fun parseArg(inputArg: String) =
|
||||
when (inputArg.toLowerCase()) {
|
||||
"true" -> "1"
|
||||
"false" -> "0"
|
||||
else -> throw IllegalArgumentException("Failed to parse boolean type")
|
||||
}
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
class LLVMByteType() : LLVMType() {
|
||||
|
||||
override val align = 1
|
||||
override var size: Int = 1
|
||||
override val mangle = "Byte"
|
||||
override val typename = "i8"
|
||||
override val defaultValue = "0"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sgt i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMByteType(), "srem i8 $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMByteType
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-41
@@ -1,41 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
class LLVMCharType() : LLVMType() {
|
||||
|
||||
override val align = 1
|
||||
override var size: Int = 1
|
||||
override val mangle = "Char"
|
||||
override val typename = "i8"
|
||||
override val defaultValue = "0"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun parseArg(inputArg: String) = inputArg.first().toInt().toString()
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sgt i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i8 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i8" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMCharType
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
|
||||
class LLVMDoubleType() : LLVMType() {
|
||||
|
||||
override val align = 8
|
||||
override var size: Int = 8
|
||||
override val mangle = "Double"
|
||||
override val typename = "double"
|
||||
override val defaultValue = "0.0"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fmul double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorInc(firstOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fadd double $firstOp, 1.0")
|
||||
|
||||
override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fdiv double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorDec(firstOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fsub double $firstOp, 1.0")
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp olt double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp ogt double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp ole double i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp oge double i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp oeq double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp one double $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "frem double $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMDoubleType
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-61
@@ -1,61 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
|
||||
class LLVMFloatType() : LLVMType() {
|
||||
|
||||
override val align = 4
|
||||
override var size: Int = 4
|
||||
override val mangle = "Float"
|
||||
override val typename = "float"
|
||||
override val defaultValue = "0.0"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMFloatType(), "fsub float $firstOp, $secondOp")
|
||||
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMFloatType(), "fmul float $firstOp, $secondOp")
|
||||
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMFloatType(), "fadd float $firstOp, $secondOp")
|
||||
|
||||
override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMFloatType(), "fdiv float $firstOp, $secondOp")
|
||||
|
||||
override fun operatorInc(firstOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fadd float $firstOp, 1.0")
|
||||
|
||||
override fun operatorDec(firstOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMDoubleType(), "fsub float $firstOp, 1.0")
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp olt float $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp ogt float $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp ole float i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp oge float i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp oeq float" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "fcmp one float" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMFloatType(), "frem float $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMFloatType
|
||||
|
||||
override fun hashCode() =
|
||||
typename.hashCode()
|
||||
|
||||
}
|
||||
-37
@@ -1,37 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.llvm.LLVMInstanceOfStandardType
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
|
||||
class LLVMFunctionType(type: KotlinType, state: TranslationState) : LLVMType() {
|
||||
|
||||
override val defaultValue = ""
|
||||
override val align: Int = 4
|
||||
override var size: Int = 4
|
||||
override val mangle: String
|
||||
override val typename = "FunctionType"
|
||||
|
||||
val arguments: List<LLVMVariable>
|
||||
val returnType: LLVMVariable
|
||||
|
||||
init {
|
||||
val types = type.arguments.map { LLVMInstanceOfStandardType("", it.type, state = state) }.toList()
|
||||
returnType = types.last()
|
||||
arguments = types.dropLast(1)
|
||||
mangle = "F.${LLVMType.mangleFunctionArguments(arguments)}.EF"
|
||||
}
|
||||
|
||||
fun mangleArgs() = LLVMType.mangleFunctionArguments(arguments)
|
||||
|
||||
override fun toString() =
|
||||
"${returnType.type} (${arguments.map { it.pointedType }.joinToString()})"
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
(other is LLVMFunctionType) && (mangle == other.mangle)
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.exceptions.UnimplementedException
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
|
||||
class LLVMIntType() : LLVMType() {
|
||||
|
||||
override val align = 4
|
||||
override var size: Int = 4
|
||||
override val defaultValue = "0"
|
||||
override val mangle = "Int"
|
||||
override val typename = "i32"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun convertFrom(source: LLVMSingleValue) =
|
||||
when (source.type) {
|
||||
is LLVMBooleanType,
|
||||
is LLVMByteType,
|
||||
is LLVMCharType,
|
||||
is LLVMShortType -> LLVMExpression(LLVMIntType(), " sext ${source.type} $source to i32")
|
||||
else -> throw UnimplementedException()
|
||||
}
|
||||
|
||||
override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "or i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "and i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "xor i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "shl i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "ashr i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "lshr i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "mul nsw i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "sdiv i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorInc(firstOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "add nsw i32 $firstOp, 1")
|
||||
|
||||
override fun operatorDec(firstOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "sub nsw i32 $firstOp, 1")
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sgt i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i32 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i32" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMIntType(), "srem i32 $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMIntType
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-84
@@ -1,84 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.exceptions.UnimplementedException
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
|
||||
class LLVMLongType() : LLVMType() {
|
||||
|
||||
override val align = 8
|
||||
override var size = 8
|
||||
override val defaultValue = "0"
|
||||
override val typename = "i64"
|
||||
override val mangle = "Long"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun convertFrom(source: LLVMSingleValue) =
|
||||
when (source.type) {
|
||||
is LLVMBooleanType,
|
||||
is LLVMByteType,
|
||||
is LLVMCharType,
|
||||
is LLVMShortType,
|
||||
is LLVMIntType -> LLVMExpression(LLVMLongType(), " sext ${source.type} $source to i64")
|
||||
else -> throw UnimplementedException()
|
||||
}
|
||||
|
||||
override fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "or i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "and i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "xor i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "shl i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "ashr i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "lshr i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "sub nsw i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "mul nsw i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "add nsw i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "sdiv i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sgt i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i64 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i64" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i64" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMLongType(), "srem i64 $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMLongType
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-20
@@ -1,20 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMNullType(var baseType: LLVMType? = null) : LLVMType() {
|
||||
|
||||
override val align = 1
|
||||
override var size = 0
|
||||
override val defaultValue = "null"
|
||||
override val mangle = ""
|
||||
override val typename = baseType?.typename.orEmpty()
|
||||
|
||||
override fun parseArg(inputArg: String) = "null"
|
||||
override fun toString() = baseType?.toString().orEmpty()
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMNullType
|
||||
|
||||
override fun hashCode() =
|
||||
"null".hashCode()
|
||||
|
||||
}
|
||||
-32
@@ -1,32 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
import org.kotlinnative.translator.llvm.addAfterIfNotEmpty
|
||||
|
||||
|
||||
class LLVMReferenceType(val type: String,
|
||||
var prefix: String = "",
|
||||
override var align: Int = TranslationState.POINTER_ALIGN,
|
||||
override var size: Int = TranslationState.POINTER_SIZE,
|
||||
var byRef: Boolean = true) : LLVMType() {
|
||||
|
||||
override val defaultValue: String = "null"
|
||||
override val mangle = "Ref_$type"
|
||||
override val typename = prefix.addAfterIfNotEmpty(".") + type
|
||||
|
||||
override fun toString() = "%$typename"
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq ${firstOp.pointedType} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne ${firstOp.pointedType} $firstOp, ${if (secondOp.type is LLVMNullType) "null" else "$secondOp"}")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
(other is LLVMReferenceType) and (typename.equals((other as LLVMReferenceType).typename))
|
||||
|
||||
override fun hashCode() =
|
||||
typename.hashCode()
|
||||
}
|
||||
-45
@@ -1,45 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
class LLVMShortType() : LLVMType() {
|
||||
|
||||
override val align = 2
|
||||
override var size: Int = 2
|
||||
override val defaultValue = "0"
|
||||
override val typename = "i16"
|
||||
override val mangle = "Short"
|
||||
override val isPrimitive = true
|
||||
|
||||
override fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp slt i16 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sgt i16 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sle i16 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp sge i16 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp eq i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMBooleanType(), "icmp ne i16" + (if ((firstOp.pointer > 0) || (secondOp.pointer > 0)) "*" else "") + " $firstOp, $secondOp")
|
||||
|
||||
override fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMShortType(), "srem i16 $firstOp, $secondOp")
|
||||
|
||||
override fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue) =
|
||||
LLVMExpression(LLVMShortType(), "sdiv i16 $firstOp, $secondOp")
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMShortType
|
||||
|
||||
override fun hashCode() =
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
-23
@@ -1,23 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMStringType(override val length: Int, var isLoaded: Boolean = true) : LLVMArray, LLVMType() {
|
||||
|
||||
override val align = 8
|
||||
override var size: Int = 1
|
||||
override val defaultValue = ""
|
||||
override val typename = "i8*"
|
||||
override val mangle = "String"
|
||||
override val arrayElementType = LLVMCharType()
|
||||
override val fullArrayType = "[${length + 1} x i8]"
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
when (other) {
|
||||
is LLVMStringType -> this.length == other.length
|
||||
else -> false
|
||||
}
|
||||
|
||||
override fun hashCode() =
|
||||
length * 31 + if (isLoaded) 1 else 0 +
|
||||
mangle.hashCode()
|
||||
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
import org.kotlinnative.translator.exceptions.UnimplementedException
|
||||
import org.kotlinnative.translator.llvm.LLVMExpression
|
||||
import org.kotlinnative.translator.llvm.LLVMSingleValue
|
||||
|
||||
abstract class LLVMType() {
|
||||
|
||||
companion object {
|
||||
fun mangleFunctionArguments(names: List<LLVMSingleValue>) =
|
||||
mangleFunctionTypes(names.map { it.type })
|
||||
|
||||
fun mangleFunctionTypes(names: List<LLVMType>) =
|
||||
if (names.size > 0) "_${names.joinToString(separator = "_", transform = { it.mangle })}" else ""
|
||||
|
||||
fun nullOrVoidType(type: LLVMType): Boolean =
|
||||
(type is LLVMNullType) or (type is LLVMVoidType)
|
||||
|
||||
fun isReferredType(type: LLVMType?): Boolean =
|
||||
(type is LLVMNullType) or (type is LLVMReferenceType)
|
||||
|
||||
}
|
||||
|
||||
abstract val align: Int
|
||||
abstract val typename: String
|
||||
abstract var size: Int
|
||||
abstract val defaultValue: String
|
||||
abstract val mangle: String
|
||||
open val isPrimitive: Boolean = false
|
||||
|
||||
open fun parseArg(inputArg: String) = inputArg
|
||||
open fun convertFrom(source: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
override fun toString() = typename
|
||||
|
||||
open fun operatorPlus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorTimes(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorMinus(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorDiv(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorLt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorGt(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorLeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorGeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorEq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorNeq(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorOr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorAnd(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorXor(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorShl(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorShr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorUshr(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorMod(firstOp: LLVMSingleValue, secondOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorInc(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
open fun operatorDec(firstOp: LLVMSingleValue): LLVMExpression = throw UnimplementedException()
|
||||
|
||||
}
|
||||
-17
@@ -1,17 +0,0 @@
|
||||
package org.kotlinnative.translator.llvm.types
|
||||
|
||||
class LLVMVoidType() : LLVMType() {
|
||||
|
||||
override val align = 0
|
||||
override var size = 0
|
||||
override val defaultValue = ""
|
||||
override val typename = "void"
|
||||
override val mangle = ""
|
||||
|
||||
override fun equals(other: Any?) =
|
||||
other is LLVMVoidType
|
||||
|
||||
override fun hashCode() =
|
||||
typename.hashCode()
|
||||
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
<orderEntry type="module" module-name="cli" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="module" module-name="util" />
|
||||
<orderEntry type="module" module-name="ir.psi2ir" />
|
||||
<orderEntry type="module" module-name="frontend.java" />
|
||||
<orderEntry type="module" module-name="ir.tree" />
|
||||
<orderEntry type="module" module-name="descriptor.loader.java" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Nikolay Igotti
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,46 +0,0 @@
|
||||
DIRECTORY = "src/test/kotlin/tests"
|
||||
OUTPUT = $(shell ls ${DIRECTORY}/*/*.txt)
|
||||
OBJECTS = $(OUTPUT:.txt=.out)
|
||||
green = '\033[0;32m'
|
||||
red = '\033[0;31m'
|
||||
lightRed = '\033[1;31m'
|
||||
orange = '\033[0;33m'
|
||||
nc = '\033[0m'
|
||||
KOTSTD='../kotstd'
|
||||
SOURCELIB=build/sources
|
||||
|
||||
#
|
||||
# ! Disabled stdlib/test compilation (because we've imported only translator)
|
||||
#
|
||||
|
||||
#stdlib:
|
||||
# cd $(KOTSTD) && make clean && make
|
||||
#
|
||||
#%.out: stdlib %.txt
|
||||
# @./run_one_test.sh $(@:.out=.txt)
|
||||
#
|
||||
#tests: stdlib $(OBJECTS)
|
||||
# @date
|
||||
|
||||
|
||||
build:
|
||||
./gradlew jar
|
||||
|
||||
all: build #tests;
|
||||
|
||||
clean:
|
||||
./gradlew clean
|
||||
|
||||
#compile: build
|
||||
# mkdir -p $(SOURCELIB)
|
||||
# rm -f $(SOURCELIB)/linked.ll
|
||||
# rm -f $(SOURCELIB)/linked.ll
|
||||
# java -jar build/libs/translator-1.0.jar -I $(KOTSTD)/kt $(files) -o $(SOURCELIB)/build.ll
|
||||
# llvm-link-3.6 -S $(KOTSTD)/build/stdlib_x86.ll $(SOURCELIB)/build.ll >> $(SOURCELIB)/linked.ll
|
||||
# clang-3.6 $(SOURCELIB)/linked.ll -o $(output)
|
||||
# rm $(SOURCELIB)/linked.ll
|
||||
# rm $(SOURCELIB)/build.ll
|
||||
|
||||
.DEFAULT_GOAL := all
|
||||
.FORCE: build, all
|
||||
.PHONY: tests, stdlib, build, all, compile
|
||||
@@ -1,64 +0,0 @@
|
||||
# Translator from Kotlin to LLVM
|
||||
|
||||
## Fast build
|
||||
If you want to use the translator without going into any technical details, this section is for you. Using following commands you will be able to compile your Kotlin files, the resulting executable file
|
||||
|
||||
$ make compile files=$(KTFILES) output=$(OUTPUT)
|
||||
|
||||
where
|
||||
- $(KTFILES) - list of your Kotlin files separated by spaces
|
||||
- $(OUTPUT) - the resulting file
|
||||
|
||||
**NOTE:** when you use a fast build, the name of your your entry point function must be **main** and it should not receive arguments
|
||||
|
||||
## Building
|
||||
|
||||
For build translator into jar, you must run gradle target
|
||||
|
||||
$ ./gradlew jar
|
||||
|
||||
**NOTE:** make sure you have jdk version 1.8 or higher
|
||||
|
||||
|
||||
Assembled the translator can be found in the following folder
|
||||
|
||||
$ cd build/libs/translator
|
||||
|
||||
## Using compiler
|
||||
$ java -jar $(PATH_TO_TRANSLATOR_JAR) -I $(PATH_TO_KOTLIB) $(KOTLIN_SOURCES)
|
||||
where
|
||||
- $(PATH_TO_TRANSLATOR_JAR) - path to jar, which you got in building step, by default it `build/libs/translator-1.0.jar`
|
||||
- $(PATH_TO_KOTLIB) - path to standard kotlin lib, by default it `./kotstd/include`
|
||||
- $(KOTLIN_SOURCES) - the different files that you want to compile
|
||||
|
||||
### Optional arguments
|
||||
- -M - specified entry point of your project, by default it is main
|
||||
|
||||
**NOTE:** your entry point function should not receive arguments
|
||||
|
||||
- -o - file to redirect output of the generated code
|
||||
|
||||
|
||||
## Using generated code
|
||||
|
||||
To execute the generated code you should use should link your code with kotlin native runtime. By default, you can find the appropriate library at
|
||||
`../kotstd/build/stdlib_x86.ll`
|
||||
|
||||
If this file is missing you can assemble it yourself
|
||||
|
||||
$ cd ../kotstd && make clean && make
|
||||
|
||||
For linking, run the following command
|
||||
|
||||
$ llvm-link-3.6 -S $(KOTLIN_NATIVE_RUNTIME) $(COMPILED_LLVM_CODE)
|
||||
|
||||
where $(COMPILED_LLVM_CODE) - code obtained in the step compiler
|
||||
|
||||
**NOTE:** The translator supports the llvm version number 3.6. Please make sure you have the correct version of llvm.
|
||||
|
||||
## Run
|
||||
|
||||
$ lli-3.6 $(LINKED_CODE)
|
||||
|
||||
where $(LINKED_CODE) - code obtained in the previous step
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
group 'translator-bc'
|
||||
version '1.0'
|
||||
|
||||
buildscript {
|
||||
ext.kotlin_version = '1.0.3'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
apply plugin: 'kotlin'
|
||||
apply plugin: 'application'
|
||||
apply plugin: org.jetbrains.kotlin.NativeInteropPlugin
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven { url "https://jitpack.io" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.1"
|
||||
compile group: 'org.jetbrains.kotlin', name: 'kotlin-compiler', version: '1.0.3'
|
||||
compile 'com.github.jshmrsn:karg:a636b3e'
|
||||
testCompile group: 'junit', name: 'junit', version: '4.11'
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3"
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
}
|
||||
|
||||
jar {
|
||||
manifest {
|
||||
attributes 'Main-Class': 'MainKt'
|
||||
}
|
||||
|
||||
from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } }
|
||||
}
|
||||
sourceSets {
|
||||
main.java.srcDirs += 'src/main/kotlin'
|
||||
}
|
||||
|
||||
genInteropStubs {
|
||||
environment 'CPATH' : "$llvmInstallPath/include"
|
||||
environment 'LIBRARY_PATH' : "$llvmInstallPath/lib"
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -1,6 +0,0 @@
|
||||
#Thu Jul 07 16:27:28 MSK 2016
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-2.9-all.zip
|
||||
Vendored
-160
@@ -1,160 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS=""
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn ( ) {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die ( ) {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
esac
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:function=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
|
||||
function splitJvmOpts() {
|
||||
JVM_OPTS=("$@")
|
||||
}
|
||||
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
|
||||
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
|
||||
|
||||
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
|
||||
-90
@@ -1,90 +0,0 @@
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS=
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windowz variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
if "%@eval[2+2]" == "4" goto 4NT_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
goto execute
|
||||
|
||||
:4NT_args
|
||||
@rem Get arguments from the 4NT Shell from JP Software
|
||||
set CMD_LINE_ARGS=%$
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
@@ -1,49 +0,0 @@
|
||||
|
||||
BUILD_DIR=$(PWD)/build
|
||||
INCLUDE_DIR=$(PWD)/include
|
||||
LIB_ARM_DIR=$(PWD)/lib/arm
|
||||
LIB_X86_DIR=$(PWD)/lib/x86
|
||||
LIBC=$(PWD)/libc
|
||||
|
||||
KT=$(PWD)/../translator/build/libs/translator-1.0.jar
|
||||
LLINK=llvm-link-3.6
|
||||
CC=clang-3.6
|
||||
|
||||
CCFLAGS_ARM=-g -S -Wall -m32 -emit-llvm -nostdlib -ffreestanding -march=armv7-m -mthumb -flto -O0 -target arm-none-eabi -DARM
|
||||
CCFLAGS=-g -O0 -S -Wall -emit-llvm -nostdlib -ffreestanding
|
||||
CCFLAGS_DEBUG=-g -O0 -S -Wall -emit-llvm -nostdlib -ffreestanding -DDBG
|
||||
LLINK_FLAGS=-S
|
||||
|
||||
KT_ALL_DEPS=java -jar $(KT)
|
||||
LLINK_ALL_DEPS=$(LLINK) $(LLINK_FLAGS) $(filter %.ll,$^) > $@
|
||||
|
||||
all: memory $(BUILD_DIR) $(BUILD_DIR)/stdlib_arm.ll $(BUILD_DIR)/stdlib_x86.ll
|
||||
debug: memory_debug $(BUILD_DIR) $(BUILD_DIR)/stdlib_arm.ll $(BUILD_DIR)/stdlib_x86.ll
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir -p $(BUILD_DIR)
|
||||
|
||||
$(BUILD_DIR)/stdlib_x86.ll: $(LIB_X86_DIR)/*.ll
|
||||
$(LLINK_ALL_DEPS)
|
||||
|
||||
$(BUILD_DIR)/stdlib_arm.ll: $(LIB_ARM_DIR)/*.ll
|
||||
$(LLINK_ALL_DEPS)
|
||||
|
||||
$(BUILD_DIR)/classes_x86.ll: $(INCLUDE_DIR)/*.kt
|
||||
$(KT_ALL_DEPS) -o $@ $(filter %.kt,$^)
|
||||
|
||||
$(BUILD_DIR)/classes_arm.ll: $(INCLUDE_DIR)/*.kt
|
||||
$(KT_ALL_DEPS) --arm -o $@ $(filter %.kt,$^)
|
||||
|
||||
memory:
|
||||
$(CC) $(CCFLAGS) $(LIBC)/memory.c -o $(LIB_X86_DIR)/memory.ll
|
||||
$(CC) $(CCFLAGS_ARM) $(LIBC)/memory.c -o $(LIB_ARM_DIR)/memory.ll
|
||||
|
||||
memory_debug:
|
||||
$(CC) $(CCFLAGS_DEBUG) $(LIBC)/memory.c -o $(LIB_X86_DIR)/memory.ll
|
||||
|
||||
clean:
|
||||
rm -rf $(BUILD_DIR)
|
||||
|
||||
.PHONY: all clean
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun assert_c(value: Boolean)
|
||||
|
||||
fun assert(value: Boolean) {
|
||||
println(value)
|
||||
assert_c(value)
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun kotlinclib_boolean_size(): Int
|
||||
|
||||
class BooleanArray(var size: Int) {
|
||||
val data: Int
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
//size: Int
|
||||
|
||||
init {
|
||||
this.data = malloc_array(kotlinclib_boolean_size() * this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
set(index, false)
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the array element at the given [index]. This method can be called using the index operator. */
|
||||
operator fun get(index: Int): Boolean {
|
||||
val res = kotlinclib_get_byte(this.data, index) == 1.toByte()
|
||||
return res
|
||||
}
|
||||
|
||||
|
||||
/** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */
|
||||
operator fun set(index: Int, value: Boolean) {
|
||||
if (value == true) {
|
||||
kotlinclib_set_byte(this.data, index, 1.toByte())
|
||||
} else {
|
||||
kotlinclib_set_byte(this.data, index, 0.toByte())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun clone(): BooleanArray {
|
||||
val newInstance = BooleanArray(this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
}
|
||||
|
||||
fun BooleanArray.print() {
|
||||
var index = 0
|
||||
print('[')
|
||||
while (index < size) {
|
||||
print(get(index))
|
||||
index++
|
||||
if (index < size){
|
||||
print(';')
|
||||
print(' ')
|
||||
}
|
||||
}
|
||||
print(']')
|
||||
}
|
||||
|
||||
fun BooleanArray.println() {
|
||||
this.print()
|
||||
//println()
|
||||
}
|
||||
|
||||
|
||||
fun BooleanArray.copyOf(newSize: Int): BooleanArray {
|
||||
val newInstance = BooleanArray(newSize)
|
||||
var index = 0
|
||||
val end = if (newSize > this.size) this.size else newSize
|
||||
while (index < end) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
while (index < newSize) {
|
||||
newInstance.set(index, false)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
fun BooleanArray.copyOfRange(fromIndex: Int, toIndex: Int): BooleanArray {
|
||||
val newInstance = BooleanArray(toIndex - fromIndex)
|
||||
var index = fromIndex
|
||||
while (index < toIndex) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index - fromIndex, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
operator fun BooleanArray.plus(element: Boolean): BooleanArray {
|
||||
val index = size
|
||||
val result = this.copyOf(index + 1)
|
||||
result[index] = element
|
||||
return result
|
||||
}
|
||||
|
||||
operator fun BooleanArray.plus(elements: BooleanArray): BooleanArray {
|
||||
val thisSize = size
|
||||
val arraySize = elements.size
|
||||
val resultSize = thisSize + arraySize
|
||||
val newInstance = this.copyOf(resultSize)
|
||||
var index = thisSize
|
||||
|
||||
while (index < resultSize) {
|
||||
val value = elements.get(index - thisSize)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun malloc_array(size: Int): Int
|
||||
external fun kotlinclib_get_byte(src: Int, index: Int): Byte
|
||||
external fun kotlinclib_set_byte(src: Int, index: Int, value: Byte)
|
||||
external fun kotlinclib_byte_size(): Int
|
||||
|
||||
|
||||
class ByteArray(var size: Int) {
|
||||
val data: Int
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
//size: Int
|
||||
|
||||
init {
|
||||
this.data = malloc_array(kotlinclib_byte_size() * this.size)
|
||||
var index = 0
|
||||
|
||||
while (index < this.size) {
|
||||
set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the array element at the given [index]. This method can be called using the index operator. */
|
||||
operator fun get(index: Int): Byte {
|
||||
return kotlinclib_get_byte(this.data, index)
|
||||
}
|
||||
|
||||
|
||||
/** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */
|
||||
operator fun set(index: Int, value: Byte) {
|
||||
kotlinclib_set_byte(this.data, index, value)
|
||||
}
|
||||
|
||||
|
||||
fun clone(): ByteArray {
|
||||
val newInstance = ByteArray(this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun ByteArray.print() {
|
||||
var index = 0
|
||||
print('[')
|
||||
while (index < size) {
|
||||
print(get(index))
|
||||
index++
|
||||
if (index < size){
|
||||
print(';')
|
||||
print(' ')
|
||||
}
|
||||
}
|
||||
print(']')
|
||||
}
|
||||
|
||||
fun ByteArray.println() {
|
||||
this.print()
|
||||
//println()
|
||||
}
|
||||
|
||||
fun ByteArray.copyOf(newSize: Int): ByteArray {
|
||||
val newInstance = ByteArray(newSize)
|
||||
var index = 0
|
||||
val end = if (newSize > this.size) this.size else newSize
|
||||
while (index < end) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
while (index < newSize) {
|
||||
newInstance.set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
fun ByteArray.copyOfRange(fromIndex: Int, toIndex: Int): ByteArray {
|
||||
val newInstance = ByteArray(toIndex - fromIndex)
|
||||
var index = fromIndex
|
||||
while (index < toIndex) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index - fromIndex, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
operator fun ByteArray.plus(element: Byte): ByteArray {
|
||||
val index = size
|
||||
val result = this.copyOf(index + 1)
|
||||
result[index] = element
|
||||
return result
|
||||
}
|
||||
|
||||
operator fun ByteArray.plus(elements: ByteArray): ByteArray {
|
||||
val thisSize = size
|
||||
val arraySize = elements.size
|
||||
val resultSize = thisSize + arraySize
|
||||
val newInstance = this.copyOf(resultSize)
|
||||
var index = thisSize
|
||||
|
||||
while (index < resultSize) {
|
||||
val value = elements.get(index - thisSize)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
@@ -1,216 +0,0 @@
|
||||
/**
|
||||
* Created by Dmitry Savvinov on 7/6/16.
|
||||
*
|
||||
* Hides details of work with Protobuf encoding
|
||||
*
|
||||
* Note that CodedInputStream reads protobuf-defined types from stream (such as int32, sint32, etc),
|
||||
* while CodedOutputStream has methods for writing Kotlin-types (such as Boolean, Int, Long, Short, etc)
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO: refactor correctness checks into readTag
|
||||
class CodedInputStream(val buffer: ByteArray) {
|
||||
val inputStream: KotlinInputStream
|
||||
init {
|
||||
inputStream = KotlinInputStream(buffer)
|
||||
}
|
||||
|
||||
fun mark() {
|
||||
inputStream.mark()
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
inputStream.reset()
|
||||
}
|
||||
|
||||
fun readInt32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
val actualFieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val actualWireType = WireFormat.getTagWireType(tag)
|
||||
checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, WireType.VARINT, actualWireType)
|
||||
return readInt32NoTag()
|
||||
}
|
||||
|
||||
// Note that unsigned integer types are stored as their signed counterparts with top bit
|
||||
// simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all
|
||||
// methods reading unsigned ints simply redirect call to corresponding signed-reading method
|
||||
fun readUInt32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readUInt32NoTag()
|
||||
}
|
||||
|
||||
fun readUInt32NoTag(): Int {
|
||||
return readInt32NoTag()
|
||||
}
|
||||
|
||||
fun readInt64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readInt64NoTag()
|
||||
}
|
||||
|
||||
// See note on unsigned integers implementations above
|
||||
fun readUInt64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readUInt64NoTag()
|
||||
}
|
||||
|
||||
fun readUInt64NoTag(): Long {
|
||||
return readInt64NoTag()
|
||||
}
|
||||
|
||||
fun readBool(expectedFieldNumber: Int): Boolean {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readBoolNoTag()
|
||||
}
|
||||
|
||||
fun readBoolNoTag(): Boolean {
|
||||
val readValue = readInt32NoTag()
|
||||
val boolValue = when (readValue) {
|
||||
0 -> false
|
||||
1 -> true
|
||||
else -> false
|
||||
}
|
||||
return boolValue
|
||||
}
|
||||
|
||||
// Reading enums is like reading one int32 number. Caller is responsible for converting this ordinal to enum-object
|
||||
fun readEnum(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readEnumNoTag()
|
||||
}
|
||||
|
||||
fun readEnumNoTag(): Int {
|
||||
return readUInt32NoTag()
|
||||
}
|
||||
|
||||
fun readSInt32(expectedFieldNumber: Int): Int {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readSInt32NoTag()
|
||||
}
|
||||
|
||||
fun readSInt32NoTag(): Int {
|
||||
return readZigZag32NoTag()
|
||||
}
|
||||
|
||||
fun readSInt64(expectedFieldNumber: Int): Long {
|
||||
val tag = readTag(expectedFieldNumber, WireType.VARINT)
|
||||
return readSInt64NoTag()
|
||||
}
|
||||
|
||||
fun readSInt64NoTag(): Long {
|
||||
return readZigZag64NoTag()
|
||||
}
|
||||
fun readBytes(expectedFieldNumber: Int): ByteArray {
|
||||
val tag = readTag(expectedFieldNumber, WireType.LENGTH_DELIMITED)
|
||||
return readBytesNoTag()
|
||||
}
|
||||
|
||||
fun readBytesNoTag(): ByteArray {
|
||||
val length = readInt32NoTag()
|
||||
return readRawBytes(length)
|
||||
}
|
||||
|
||||
/** ============ Utility methods ==================
|
||||
* They are left non-private for cases when one wants to implement her/his own protocol format.
|
||||
* Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags.
|
||||
*/
|
||||
|
||||
fun checkFieldCorrectness(
|
||||
expectedFieldNumber: Int,
|
||||
actualFieldNumber: Int,
|
||||
expectedWireType: WireType,
|
||||
actualWireType: WireType) {
|
||||
if (expectedFieldNumber != actualFieldNumber) {
|
||||
return
|
||||
}
|
||||
|
||||
if (expectedWireType.id != actualWireType.id) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
fun readRawBytes(count: Int): ByteArray {
|
||||
val ba = ByteArray(count)
|
||||
var i = 0
|
||||
while (i < count) {
|
||||
ba[i] = inputStream.read().toByte()
|
||||
i++
|
||||
}
|
||||
return ba
|
||||
}
|
||||
|
||||
// reads tag. Note that it returns 0 for the end of message!
|
||||
fun readTag(expectedFieldNumber: Int, expectedWireType: WireType): Int {
|
||||
if (isAtEnd()) {
|
||||
return 0 // we can safely return 0 as sign of end of message, because 0-tags are illegal
|
||||
}
|
||||
val tag = readInt32NoTag()
|
||||
if (tag == 0) { // if we somehow had read 0-tag, then message is corrupted
|
||||
return 0
|
||||
}
|
||||
|
||||
val actualFieldNumber = WireFormat.getTagFieldNumber(tag)
|
||||
val actualWireType = WireFormat.getTagWireType(tag)
|
||||
checkFieldCorrectness(expectedFieldNumber, actualFieldNumber, expectedWireType, actualWireType)
|
||||
return tag
|
||||
}
|
||||
|
||||
// reads varint not larger than 32-bit integer according to protobuf varint-encoding
|
||||
fun readInt32NoTag(): Int {
|
||||
var done: Boolean = false
|
||||
var result: Long = 0
|
||||
var step: Int = 0
|
||||
while (!done) {
|
||||
val byte: Int = inputStream.read().toInt()
|
||||
result = result or
|
||||
(
|
||||
(byte and WireFormat.VARINT_INFO_BITS_MASK).toLong()
|
||||
shl
|
||||
(WireFormat.VARINT_INFO_BITS_COUNT * step)
|
||||
).toLong()
|
||||
step++
|
||||
if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0) {
|
||||
done = true
|
||||
}
|
||||
}
|
||||
return result.toInt()
|
||||
}
|
||||
|
||||
// reads varint not larger than 64-bit integer according to protobuf varint-encoding
|
||||
fun readInt64NoTag(): Long {
|
||||
var done: Boolean = false
|
||||
var result: Long = 0
|
||||
var step: Int = 0
|
||||
while (!done) {
|
||||
val byte: Int = inputStream.read().toInt()
|
||||
result = result or
|
||||
(
|
||||
(byte and WireFormat.VARINT_INFO_BITS_MASK).toLong()
|
||||
shl
|
||||
(WireFormat.VARINT_INFO_BITS_COUNT * step)
|
||||
)
|
||||
step++
|
||||
if ((byte and WireFormat.VARINT_UTIL_BIT_MASK) == 0 /* || byte == -1 ???? */) {
|
||||
done = true
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// reads zig-zag encoded integer not larger than 32-bit long
|
||||
fun readZigZag32NoTag(): Int {
|
||||
val value = readInt32NoTag()
|
||||
return (value ushr 1) xor (-(value and 1)) // bit magic for decoding zig-zag number
|
||||
}
|
||||
|
||||
// reads zig-zag encoded integer not larger than 64-bit long
|
||||
fun readZigZag64NoTag(): Long {
|
||||
val value = readInt64NoTag()
|
||||
return (value ushr 1) xor (-(value and 1L)) // bit magic for decoding zig-zag number
|
||||
}
|
||||
|
||||
// checks if at least one more byte can be read from underlying input stream
|
||||
fun isAtEnd(): Boolean {
|
||||
return inputStream.isAtEnd()
|
||||
}
|
||||
}
|
||||
@@ -1,167 +0,0 @@
|
||||
/**
|
||||
* Created by user on 7/6/16.
|
||||
*/
|
||||
|
||||
class CodedOutputStream(val buffer: ByteArray) {
|
||||
val output = KotlinOutputStream(buffer)
|
||||
|
||||
fun toByteArray(): ByteArray {
|
||||
return buffer
|
||||
}
|
||||
|
||||
fun writeTag(fieldNumber: Int, type: WireType) {
|
||||
val tag = (fieldNumber shl 3) or type.id
|
||||
writeRawVarint32(tag)
|
||||
}
|
||||
|
||||
fun writeInt32(fieldNumber: Int, value: Int) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeInt32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeInt32NoTag(value: Int) {
|
||||
if (value < 0) { // sign-extend negative values
|
||||
writeRawVarint64(value.toLong())
|
||||
return
|
||||
}
|
||||
writeRawVarint32(value)
|
||||
}
|
||||
|
||||
// Note that unsigned integer types are stored as their signed counterparts with top bit
|
||||
// simply stored in the sign bit - similar to Java's protobuf implementation. Hence, all
|
||||
// methods, writing unsigned ints simply redirect call to corresponding signed-writing method
|
||||
fun writeUInt32(fieldNumber: Int, value: Int) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeUInt32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeUInt32NoTag(value: Int) {
|
||||
writeRawVarint32(value)
|
||||
}
|
||||
|
||||
fun writeInt64(fieldNumber: Int, value: Long) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeInt64NoTag(value)
|
||||
}
|
||||
|
||||
fun writeInt64NoTag(value: Long) {
|
||||
writeRawVarint64(value)
|
||||
}
|
||||
|
||||
// See notes on unsigned integers implementation above
|
||||
fun writeUInt64(fieldNumber: Int, value: Long) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeUInt64NoTag(value)
|
||||
}
|
||||
|
||||
fun writeUInt64NoTag(value: Long) {
|
||||
writeRawVarint64(value)
|
||||
}
|
||||
|
||||
fun writeBool(fieldNumber: Int, value: Boolean) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeBoolNoTag(value)
|
||||
}
|
||||
|
||||
fun writeBoolNoTag(value: Boolean) {
|
||||
writeRawVarint32(if (value) 1 else 0)
|
||||
}
|
||||
|
||||
// Writing enums is like writing one int32 number. Caller is responsible for converting enum-object to ordinal
|
||||
fun writeEnum(fieldNumber: Int, value: Int) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeEnumNoTag(value)
|
||||
}
|
||||
|
||||
fun writeEnumNoTag(value: Int) {
|
||||
writeRawVarint32(value)
|
||||
}
|
||||
|
||||
fun writeSInt32(fieldNumber: Int, value: Int) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeSInt32NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSInt32NoTag(value: Int) {
|
||||
writeUInt32NoTag((value shl 1) xor (value shr 31))
|
||||
}
|
||||
|
||||
fun writeSInt64(fieldNumber: Int, value: Long) {
|
||||
writeTag(fieldNumber, WireType.VARINT)
|
||||
writeSInt64NoTag(value)
|
||||
}
|
||||
|
||||
fun writeSInt64NoTag(value: Long) {
|
||||
writeUInt64NoTag((value shl 1) xor (value shr 63))
|
||||
}
|
||||
|
||||
fun writeBytes(fieldNumber: Int, value: ByteArray) {
|
||||
if (value.size == 0) {
|
||||
return
|
||||
}
|
||||
writeTag(fieldNumber, WireType.LENGTH_DELIMITED)
|
||||
writeBytesNoTag(value)
|
||||
}
|
||||
|
||||
fun writeBytesNoTag(value: ByteArray) {
|
||||
writeRawVarint32(value.size)
|
||||
output.write(value)
|
||||
}
|
||||
|
||||
/** ============ Utility methods ==================
|
||||
* They are left non-private for cases when one wants to implement her/his own protocol format.
|
||||
* Then she/he can re-use low-level methods for operating with raw values, that are not annotated with Protobuf tags.
|
||||
*/
|
||||
|
||||
fun writeRawVarint32(value: Int) {
|
||||
var curValue: Int = value
|
||||
|
||||
// we have at most 32 information bits. With overhead of 1 bit per 7 bits we need at most 5 bytes for encoding
|
||||
val res = ByteArray(5)
|
||||
|
||||
var resSize = 0
|
||||
do {
|
||||
// encode current 7 bits
|
||||
var curByte = (curValue and WireFormat.VARINT_INFO_BITS_MASK)
|
||||
|
||||
// discard encoded bits. Note that unsigned shift is needed for cases with negative numbers
|
||||
curValue = curValue ushr WireFormat.VARINT_INFO_BITS_COUNT
|
||||
|
||||
// check if there will be next byte in encoding and set util bit if needed
|
||||
if (curValue != 0) {
|
||||
curByte = curByte or WireFormat.VARINT_UTIL_BIT_MASK
|
||||
}
|
||||
|
||||
res[resSize] = curByte.toByte()
|
||||
resSize++
|
||||
} while (curValue != 0)
|
||||
output.write(res, 0, resSize)
|
||||
}
|
||||
|
||||
fun writeRawVarint64(value: Long) {
|
||||
var curValue: Long = value
|
||||
|
||||
// we have at most 64 information bits. With overhead of 1 bit per 7 bits we need at most 10 bytes for encoding
|
||||
val res = ByteArray(10)
|
||||
|
||||
var resSize = 0
|
||||
do {
|
||||
// encode current 7 bits
|
||||
var curByte = (curValue and WireFormat.VARINT_INFO_BITS_MASK.toLong())
|
||||
|
||||
// discard encoded bits. Note that unsigned shift is needed for cases with negative numbers
|
||||
curValue = curValue ushr WireFormat.VARINT_INFO_BITS_COUNT
|
||||
|
||||
// check if there will be next byte and set util bit if needed
|
||||
if (curValue != 0L) {
|
||||
curByte = curByte or WireFormat.VARINT_UTIL_BIT_MASK.toLong()
|
||||
}
|
||||
|
||||
res[resSize] = curByte.toByte()
|
||||
resSize++
|
||||
} while(curValue != 0L)
|
||||
output.write(res, 0, resSize)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
/*
|
||||
* Library for console interaction
|
||||
*/
|
||||
|
||||
external fun kotlinclib_print_int(message: Int)
|
||||
external fun kotlinclib_print_long(message: Long)
|
||||
external fun kotlinclib_print_byte(message: Byte)
|
||||
external fun kotlinclib_print_short(message: Short)
|
||||
external fun kotlinclib_print_char(message: Char)
|
||||
external fun kotlinclib_print_boolean(message: Boolean)
|
||||
external fun kotlinclib_print_float(message: Float)
|
||||
external fun kotlinclib_print_double(message: Double)
|
||||
external fun kotlinclib_print_string(message: String)
|
||||
external fun kotlinclib_println_int(message: Int)
|
||||
external fun kotlinclib_println_long(message: Long)
|
||||
external fun kotlinclib_println_byte(message: Byte)
|
||||
external fun kotlinclib_println_short(message: Short)
|
||||
external fun kotlinclib_println_char(message: Char)
|
||||
external fun kotlinclib_println_boolean(message: Boolean)
|
||||
external fun kotlinclib_println_float(message: Float)
|
||||
external fun kotlinclib_println_double(message: Double)
|
||||
external fun kotlinclib_println_string(message: String)
|
||||
external fun kotlinclib_println()
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Int) {
|
||||
kotlinclib_print_int(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Long) {
|
||||
kotlinclib_print_long(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Byte) {
|
||||
kotlinclib_print_byte(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Short) {
|
||||
kotlinclib_print_short(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Char) {
|
||||
kotlinclib_print_char(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Boolean) {
|
||||
kotlinclib_print_boolean(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Float) {
|
||||
kotlinclib_print_float(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: Double) {
|
||||
kotlinclib_print_double(message)
|
||||
}
|
||||
|
||||
/** Prints the given message to the standard output stream. */
|
||||
fun print(message: String) {
|
||||
kotlinclib_print_string(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun print(message: ByteArray) {
|
||||
message.print()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun print(message: BooleanArray) {
|
||||
message.print()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun print(message: IntArray) {
|
||||
message.print()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun print(message: LongArray) {
|
||||
message.print()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun print(message: ShortArray) {
|
||||
message.print()
|
||||
}
|
||||
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Int) {
|
||||
kotlinclib_println_int(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Long) {
|
||||
kotlinclib_println_long(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Byte) {
|
||||
kotlinclib_println_byte(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Short) {
|
||||
kotlinclib_println_short(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Char) {
|
||||
kotlinclib_println_char(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Boolean) {
|
||||
kotlinclib_println_boolean(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Float) {
|
||||
kotlinclib_println_float(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: Double) {
|
||||
kotlinclib_println_double(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: String) {
|
||||
kotlinclib_println_string(message)
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: ByteArray) {
|
||||
message.println()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: BooleanArray) {
|
||||
message.println()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: IntArray) {
|
||||
message.println()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: LongArray) {
|
||||
message.println()
|
||||
}
|
||||
|
||||
/** Prints the given message and newline to the standard output stream. */
|
||||
fun println(message: ShortArray) {
|
||||
message.println()
|
||||
}
|
||||
|
||||
/** Prints newline to the standard output stream. */
|
||||
fun println() {
|
||||
kotlinclib_println()
|
||||
}
|
||||
@@ -1,195 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun kotlinclib_get_int(src: Int, index: Int): Int
|
||||
external fun kotlinclib_set_int(src: Int, index: Int, value: Int)
|
||||
external fun kotlinclib_int_size(): Int
|
||||
|
||||
|
||||
class IntArray(var size: Int) {
|
||||
val data: Int
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
//size: Int
|
||||
|
||||
init {
|
||||
this.data = malloc_array(kotlinclib_int_size() * this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the array element at the given [index]. This method can be called using the index operator. */
|
||||
operator fun get(index: Int): Int {
|
||||
return kotlinclib_get_int(this.data, index)
|
||||
}
|
||||
|
||||
|
||||
/** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */
|
||||
operator fun set(index: Int, value: Int) {
|
||||
kotlinclib_set_int(this.data, index, value)
|
||||
}
|
||||
|
||||
|
||||
fun clone(): IntArray {
|
||||
val newInstance = IntArray(this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun IntArray.print() {
|
||||
var index = 0
|
||||
print('[')
|
||||
while (index < size) {
|
||||
print(get(index))
|
||||
index++
|
||||
if (index < size) {
|
||||
print(';')
|
||||
print(' ')
|
||||
}
|
||||
}
|
||||
print(']')
|
||||
}
|
||||
|
||||
fun IntArray.println() {
|
||||
this.print()
|
||||
//println()
|
||||
}
|
||||
|
||||
fun IntArray.copyOf(newSize: Int): IntArray {
|
||||
val newInstance = IntArray(newSize)
|
||||
var index = 0
|
||||
val end = if (newSize > this.size) this.size else newSize
|
||||
while (index < end) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
while (index < newSize) {
|
||||
newInstance.set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
fun IntArray.copyOfRange(fromIndex: Int, toIndex: Int): IntArray {
|
||||
val newInstance = IntArray(toIndex - fromIndex)
|
||||
var index = fromIndex
|
||||
while (index < toIndex) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index - fromIndex, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
operator fun IntArray.plus(element: Int): IntArray {
|
||||
val index = size
|
||||
val result = this.copyOf(index + 1)
|
||||
result[index] = element
|
||||
return result
|
||||
}
|
||||
|
||||
operator fun IntArray.plus(elements: IntArray): IntArray {
|
||||
val thisSize = size
|
||||
val arraySize = elements.size
|
||||
val resultSize = thisSize + arraySize
|
||||
val newInstance = this.copyOf(resultSize)
|
||||
var index = thisSize
|
||||
|
||||
while (index < resultSize) {
|
||||
val value = elements.get(index - thisSize)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
fun IntArray.max(from: Int = 0): Int {
|
||||
var result = from
|
||||
var i = from
|
||||
while (i < size - 1) {
|
||||
result = if (get(i) > get(result)) i else result
|
||||
i++
|
||||
}
|
||||
|
||||
return get(result)
|
||||
}
|
||||
|
||||
fun IntArray.min(from: Int = 0): Int {
|
||||
var result = from
|
||||
var i = from
|
||||
while (i < size - 1) {
|
||||
result = if (this.get(i) < this.get(result)) i else result
|
||||
i++
|
||||
}
|
||||
|
||||
return this.get(result)
|
||||
}
|
||||
|
||||
fun IntArray.sum(): Int {
|
||||
var result = 0
|
||||
var i = 0
|
||||
while (i < size - 1) {
|
||||
result += this.get(i)
|
||||
i++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun IntArray.sort(): IntArray {
|
||||
val result = this.clone()
|
||||
var i = 0
|
||||
while (i < size - 1) {
|
||||
result[i] = this.max(i)
|
||||
i++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
fun IntArray.mean(): Int =
|
||||
this.sum() / this.size
|
||||
|
||||
fun IntArray.median(): Int =
|
||||
this.sort()[this.size / 2]
|
||||
|
||||
fun IntArray.filter(predicate: (Int) -> Boolean): IntArray {
|
||||
var resultSize = 0
|
||||
var i = 0
|
||||
while (i < size - 1) {
|
||||
if (predicate(get(i))) {
|
||||
resultSize++
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
|
||||
val result = IntArray(resultSize)
|
||||
var j = 0
|
||||
i = 0
|
||||
while (i < size - 1) {
|
||||
if (predicate(get(i))) {
|
||||
result[j] = get(i)
|
||||
j++
|
||||
}
|
||||
|
||||
i++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
package kotlin.collections
|
||||
|
||||
/** An iterator over a sequence of values of type `Byte`. */
|
||||
public abstract class ByteIterator {
|
||||
final fun next() = nextByte()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextByte(): Byte
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
|
||||
/** An iterator over a sequence of values of type `Char`. */
|
||||
public abstract class CharIterator {
|
||||
final fun next() = nextChar()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextChar(): Char
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
|
||||
/** An iterator over a sequence of values of type `Short`. */
|
||||
public abstract class ShortIterator {
|
||||
final fun next() = nextShort()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextShort(): Short
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
|
||||
/** An iterator over a sequence of values of type `Int`. */
|
||||
class IntIterator(first: Int, last: Int, val step: Int) {
|
||||
private var next = first
|
||||
private val finalElement = last
|
||||
private var hasNext: Boolean = if (step > 0) first <= last else first >= last
|
||||
|
||||
final fun next() = nextInt ()
|
||||
|
||||
fun hasNext(): Boolean = hasNext
|
||||
|
||||
fun nextInt(): Int {
|
||||
val value = next
|
||||
if (value == finalElement) {
|
||||
hasNext = false
|
||||
}
|
||||
else {
|
||||
next += step
|
||||
}
|
||||
return value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** An iterator over a sequence of values of type `Long`. */
|
||||
public abstract class LongIterator {
|
||||
final fun next() = nextLong()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextLong(): Long
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
|
||||
/** An iterator over a sequence of values of type `Float`. */
|
||||
public abstract class FloatIterator {
|
||||
final fun next() = nextFloat()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextFloat(): Float
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
|
||||
/** An iterator over a sequence of values of type `Double`. */
|
||||
public abstract class DoubleIterator {
|
||||
final fun next() = nextDouble()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextDouble(): Double
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
|
||||
/** An iterator over a sequence of values of type `Boolean`. */
|
||||
public abstract class BooleanIterator {
|
||||
final fun next() = nextBoolean()
|
||||
|
||||
/** Returns the next value in the sequence without boxing. */
|
||||
public abstract fun nextBoolean(): Boolean
|
||||
|
||||
public abstract fun hasNext(): Boolean
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
/**
|
||||
* Created by user on 8/8/16.
|
||||
*/
|
||||
|
||||
class KotlinInputStream(val buffer: ByteArray) {
|
||||
var pos = 0
|
||||
var mark_ = 0
|
||||
|
||||
fun read(): Byte {
|
||||
pos += 1
|
||||
return buffer[pos - 1]
|
||||
}
|
||||
|
||||
fun isAtEnd(): Boolean {
|
||||
return pos >= buffer.size
|
||||
}
|
||||
|
||||
fun mark() {
|
||||
mark_ = pos
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
pos = mark_
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
/**
|
||||
* Created by user on 8/8/16.
|
||||
*/
|
||||
|
||||
class KotlinOutputStream(val buffer: ByteArray) {
|
||||
var pos = 0
|
||||
|
||||
fun write (data: ByteArray) {
|
||||
write(data, 0, data.size)
|
||||
}
|
||||
|
||||
fun write (data: ByteArray, begin: Int, size: Int) {
|
||||
var i = begin
|
||||
while (i < begin + size) {
|
||||
buffer[pos] = data[i]
|
||||
pos += 1
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun kotlinclib_get_long(src: Int, index: Int): Long
|
||||
external fun kotlinclib_set_long(src: Int, index: Int, value: Long)
|
||||
external fun kotlinclib_long_size(): Int
|
||||
|
||||
|
||||
class LongArray(var size: Int) {
|
||||
val data: Int
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
//size: Int
|
||||
|
||||
init {
|
||||
this.data = malloc_array(kotlinclib_long_size() * this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the array element at the given [index]. This method can be called using the index operator. */
|
||||
operator fun get(index: Int): Long {
|
||||
return kotlinclib_get_long(this.data, index)
|
||||
}
|
||||
|
||||
|
||||
/** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */
|
||||
operator fun set(index: Int, value: Long) {
|
||||
kotlinclib_set_long(this.data, index, value)
|
||||
}
|
||||
|
||||
|
||||
fun clone(): LongArray {
|
||||
val newInstance = LongArray(this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
}
|
||||
|
||||
fun LongArray.print() {
|
||||
var index = 0
|
||||
print('[')
|
||||
while (index < size) {
|
||||
print(get(index))
|
||||
index++
|
||||
if (index < size) {
|
||||
print(';')
|
||||
print(' ')
|
||||
}
|
||||
}
|
||||
print(']')
|
||||
}
|
||||
|
||||
fun LongArray.println() {
|
||||
this.print()
|
||||
//println()
|
||||
}
|
||||
|
||||
fun LongArray.copyOf(newSize: Int): LongArray {
|
||||
val newInstance = LongArray(newSize)
|
||||
var index = 0
|
||||
val end = if (newSize > this.size) this.size else newSize
|
||||
while (index < end) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
while (index < newSize) {
|
||||
newInstance.set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
fun LongArray.copyOfRange(fromIndex: Int, toIndex: Int): LongArray {
|
||||
val newInstance = LongArray(toIndex - fromIndex)
|
||||
var index = fromIndex
|
||||
while (index < toIndex) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index - fromIndex, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
operator fun LongArray.plus(element: Long): LongArray {
|
||||
val index = size
|
||||
val result = this.copyOf(index + 1)
|
||||
result[index] = element
|
||||
return result
|
||||
}
|
||||
|
||||
operator fun LongArray.plus(elements: LongArray): LongArray {
|
||||
val thisSize = size
|
||||
val arraySize = elements.size
|
||||
val resultSize = thisSize + arraySize
|
||||
val newInstance = this.copyOf(resultSize)
|
||||
var index = thisSize
|
||||
|
||||
while (index < resultSize) {
|
||||
val value = elements.get(index - thisSize)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
@@ -1,251 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun kotlinclib_byteToChar(value: Byte): Char
|
||||
external fun kotlinclib_byteToShort(value: Byte): Short
|
||||
external fun kotlinclib_byteToInt(value: Byte): Int
|
||||
external fun kotlinclib_byteToLong(value: Byte): Long
|
||||
external fun kotlinclib_byteToFloat(value: Byte): Float
|
||||
external fun kotlinclib_byteToDouble(value: Byte): Double
|
||||
|
||||
|
||||
fun Byte.toByte(): Byte {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Byte.toInt(): Int {
|
||||
return kotlinclib_byteToInt(this)
|
||||
}
|
||||
|
||||
fun Byte.toChar(): Char {
|
||||
return kotlinclib_byteToChar(this)
|
||||
}
|
||||
|
||||
fun Byte.toShort(): Short {
|
||||
return kotlinclib_byteToShort(this)
|
||||
}
|
||||
|
||||
fun Byte.toLong(): Long {
|
||||
return kotlinclib_byteToLong(this)
|
||||
}
|
||||
|
||||
fun Byte.toFloat(): Float {
|
||||
return kotlinclib_byteToFloat(this)
|
||||
}
|
||||
|
||||
fun Byte.toDouble(): Double {
|
||||
return kotlinclib_byteToDouble(this)
|
||||
}
|
||||
|
||||
external fun kotlinclib_charToByte(value: Char): Byte
|
||||
external fun kotlinclib_charToShort(value: Char): Short
|
||||
external fun kotlinclib_charToInt(value: Char): Int
|
||||
external fun kotlinclib_charToLong(value: Char): Long
|
||||
external fun kotlinclib_charToFloat(value: Char): Float
|
||||
external fun kotlinclib_charToDouble(value: Char): Double
|
||||
|
||||
|
||||
fun Char.toByte(): Byte {
|
||||
return kotlinclib_charToByte(this)
|
||||
}
|
||||
|
||||
fun Char.toInt(): Int {
|
||||
return kotlinclib_charToInt(this)
|
||||
}
|
||||
|
||||
fun Char.toChar(): Char {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Char.toShort(): Short {
|
||||
return kotlinclib_charToShort(this)
|
||||
}
|
||||
|
||||
fun Char.toLong(): Long {
|
||||
return kotlinclib_charToLong(this)
|
||||
}
|
||||
|
||||
fun Char.toFloat(): Float {
|
||||
return kotlinclib_charToFloat(this)
|
||||
}
|
||||
|
||||
fun Char.toDouble(): Double {
|
||||
return kotlinclib_charToDouble(this)
|
||||
}
|
||||
|
||||
external fun kotlinclib_doubleToByte(value: Double): Byte
|
||||
external fun kotlinclib_doubleToChar(value: Double): Char
|
||||
external fun kotlinclib_doubleToShort(value: Double): Short
|
||||
external fun kotlinclib_doubleToInt(value: Double): Int
|
||||
external fun kotlinclib_doubleToLong(value: Double): Long
|
||||
external fun kotlinclib_doubleToFloat(value: Double): Float
|
||||
|
||||
fun Double.toByte(): Byte {
|
||||
return kotlinclib_doubleToByte(this)
|
||||
}
|
||||
|
||||
fun Double.toChar(): Char {
|
||||
return kotlinclib_doubleToChar(this)
|
||||
}
|
||||
|
||||
fun Double.toShort(): Short {
|
||||
return kotlinclib_doubleToShort(this)
|
||||
}
|
||||
|
||||
fun Double.toInt(): Int {
|
||||
return kotlinclib_doubleToInt(this)
|
||||
}
|
||||
|
||||
fun Double.toLong(): Long {
|
||||
return kotlinclib_doubleToLong(this)
|
||||
}
|
||||
|
||||
fun Double.toFloat(): Float {
|
||||
return kotlinclib_doubleToFloat(this)
|
||||
}
|
||||
|
||||
fun Double.toDouble(): Double {
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
external fun kotlinclib_floatToByte(value: Float): Byte
|
||||
external fun kotlinclib_floatToChar(value: Float): Char
|
||||
external fun kotlinclib_floatToShort(value: Float): Short
|
||||
external fun kotlinclib_floatToInt(value: Float): Int
|
||||
external fun kotlinclib_floatToLong(value: Float): Long
|
||||
external fun kotlinclib_floatToDouble(value: Float): Double
|
||||
|
||||
fun Float.toByte(): Byte {
|
||||
return kotlinclib_floatToByte(this)
|
||||
}
|
||||
|
||||
fun Float.toChar(): Char {
|
||||
return kotlinclib_floatToChar(this)
|
||||
}
|
||||
|
||||
fun Float.toShort(): Short {
|
||||
return kotlinclib_floatToShort(this)
|
||||
}
|
||||
|
||||
fun Float.toInt(): Int {
|
||||
return kotlinclib_floatToInt(this)
|
||||
}
|
||||
|
||||
fun Float.toLong(): Long {
|
||||
return kotlinclib_floatToLong(this)
|
||||
}
|
||||
|
||||
fun Float.toFloat(): Float {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Float.toDouble(): Double {
|
||||
return kotlinclib_floatToDouble(this)
|
||||
}
|
||||
|
||||
|
||||
external fun kotlinclib_intToByte(value: Int): Byte
|
||||
external fun kotlinclib_intToChar(value: Int): Char
|
||||
external fun kotlinclib_intToShort(value: Int): Short
|
||||
external fun kotlinclib_intToLong(value: Int): Long
|
||||
external fun kotlinclib_intToFloat(value: Int): Float
|
||||
external fun kotlinclib_intToDouble(value: Int): Double
|
||||
|
||||
fun Int.toByte(): Byte {
|
||||
return kotlinclib_intToByte(this)
|
||||
}
|
||||
|
||||
fun Int.toInt(): Int {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Int.toChar(): Char {
|
||||
return kotlinclib_intToChar(this)
|
||||
}
|
||||
|
||||
fun Int.toShort(): Short {
|
||||
return kotlinclib_intToShort(this)
|
||||
}
|
||||
|
||||
fun Int.toLong(): Long {
|
||||
return kotlinclib_intToLong(this)
|
||||
}
|
||||
|
||||
fun Int.toFloat(): Float {
|
||||
return kotlinclib_intToFloat(this)
|
||||
}
|
||||
|
||||
fun Int.toDouble(): Double {
|
||||
return kotlinclib_intToDouble(this)
|
||||
}
|
||||
|
||||
external fun kotlinclib_longToByte(value: Long): Byte
|
||||
external fun kotlinclib_longToChar(value: Long): Char
|
||||
external fun kotlinclib_longToShort(value: Long): Short
|
||||
external fun kotlinclib_longToInt(value: Long): Int
|
||||
external fun kotlinclib_longToFloat(value: Long): Float
|
||||
external fun kotlinclib_longToDouble(value: Long): Double
|
||||
|
||||
fun Long.toByte(): Byte {
|
||||
return kotlinclib_longToByte(this)
|
||||
}
|
||||
|
||||
fun Long.toLong(): Long {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Long.toChar(): Char {
|
||||
return kotlinclib_longToChar(this)
|
||||
}
|
||||
|
||||
fun Long.toShort(): Short {
|
||||
return kotlinclib_longToShort(this)
|
||||
}
|
||||
|
||||
fun Long.toInt(): Int {
|
||||
return kotlinclib_longToInt(this)
|
||||
}
|
||||
|
||||
fun Long.toFloat(): Float {
|
||||
return kotlinclib_longToFloat(this)
|
||||
}
|
||||
|
||||
fun Long.toDouble(): Double {
|
||||
return kotlinclib_longToDouble(this)
|
||||
}
|
||||
|
||||
external fun kotlinclib_shortToByte(value: Short): Byte
|
||||
external fun kotlinclib_shortToChar(value: Short): Char
|
||||
external fun kotlinclib_shortToInt(value: Short): Int
|
||||
external fun kotlinclib_shortToLong(value: Short): Long
|
||||
external fun kotlinclib_shortToFloat(value: Short): Float
|
||||
external fun kotlinclib_shortToDouble(value: Short): Double
|
||||
|
||||
|
||||
fun Short.toByte(): Byte {
|
||||
return kotlinclib_shortToByte(this)
|
||||
}
|
||||
|
||||
fun Short.toInt(): Int {
|
||||
return kotlinclib_shortToInt(this)
|
||||
}
|
||||
|
||||
fun Short.toChar(): Char {
|
||||
return kotlinclib_shortToChar(this)
|
||||
}
|
||||
|
||||
fun Short.toShort(): Short {
|
||||
return this
|
||||
}
|
||||
|
||||
fun Short.toLong(): Long {
|
||||
return kotlinclib_shortToLong(this)
|
||||
}
|
||||
|
||||
fun Short.toFloat(): Float {
|
||||
return kotlinclib_shortToFloat(this)
|
||||
}
|
||||
|
||||
fun Short.toDouble(): Double {
|
||||
return kotlinclib_shortToDouble(this)
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
/**
|
||||
* A progression of values of type `Int`.
|
||||
*/
|
||||
public open class IntProgression
|
||||
constructor
|
||||
(
|
||||
start: Int,
|
||||
endInclusive: Int,
|
||||
val step: Int
|
||||
) {
|
||||
init {
|
||||
if (step == 0) {
|
||||
println("Step must be non-zero.")
|
||||
assert(false)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The first element in the progression.
|
||||
*/
|
||||
public val first: Int = start
|
||||
|
||||
/**
|
||||
* The last element in the progression.
|
||||
*/
|
||||
public val last: Int = getProgressionLastElement(start.toInt(), endInclusive.toInt(), step).toInt()
|
||||
|
||||
|
||||
fun iterator(): IntIterator = IntIterator(first, last, step)
|
||||
|
||||
/** Checks if the progression is empty. */
|
||||
public open fun isEmpty(): Boolean = if (step > 0) first > last else first < last
|
||||
|
||||
//[TODO] equals
|
||||
|
||||
override fun hashCode(): Int =
|
||||
if (isEmpty()) -1 else (31 * (31 * first + last) + step)
|
||||
|
||||
companion object {
|
||||
/**
|
||||
* Creates IntProgression within the specified bounds of a closed range.
|
||||
|
||||
* The progression starts with the [rangeStart] value and goes toward the [rangeEnd] value not excluding it, with the specified [step].
|
||||
* In order to go backwards the [step] must be negative.
|
||||
*/
|
||||
public fun fromClosedRange(rangeStart: Int, rangeEnd: Int, step: Int): IntProgression = IntProgression(rangeStart, rangeEnd, step)
|
||||
}
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
package kotlin.ranges
|
||||
|
||||
import kotlin.IntProgression
|
||||
import kotlin.collections.IntIterator
|
||||
|
||||
public class IntRange(val start: Int, val endInclusive: Int) {
|
||||
val progression = IntProgression(start, endInclusive, 1)
|
||||
val first: Int
|
||||
val last: Int
|
||||
|
||||
init {
|
||||
this.first = progression.first
|
||||
this.last = progression.last
|
||||
}
|
||||
|
||||
fun contains(value: Int): Boolean = first <= value && value <= last
|
||||
|
||||
fun isEmpty(): Boolean = first > last
|
||||
|
||||
fun iterator(): IntIterator = progression.iterator()
|
||||
|
||||
override fun hashCode(): Int =
|
||||
if (isEmpty()) -1 else (31 * first + last)
|
||||
|
||||
}
|
||||
@@ -1,120 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
external fun kotlinclib_get_short(src: Int, index: Int): Short
|
||||
external fun kotlinclib_set_short(src: Int, index: Int, value: Short)
|
||||
external fun kotlinclib_short_size(): Int
|
||||
|
||||
|
||||
class ShortArray(var size: Int) {
|
||||
val data: Int
|
||||
|
||||
/** Returns the number of elements in the array. */
|
||||
//size: Int
|
||||
|
||||
init {
|
||||
this.data = malloc_array(kotlinclib_short_size() * this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns the array element at the given [index]. This method can be called using the index operator. */
|
||||
operator fun get(index: Int): Short {
|
||||
return kotlinclib_get_short(this.data, index)
|
||||
}
|
||||
|
||||
|
||||
/** Sets the element at the given [index] to the given [value]. This method can be called using the index operator. */
|
||||
operator fun set(index: Int, value: Short) {
|
||||
kotlinclib_set_short(this.data, index, value)
|
||||
}
|
||||
|
||||
|
||||
fun clone(): ShortArray {
|
||||
val newInstance = ShortArray(this.size)
|
||||
var index = 0
|
||||
while (index < this.size) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun ShortArray.print() {
|
||||
var index = 0
|
||||
print('[')
|
||||
while (index < size) {
|
||||
print(get(index))
|
||||
index++
|
||||
if (index < size) {
|
||||
print(';')
|
||||
print(' ')
|
||||
}
|
||||
}
|
||||
print(']')
|
||||
}
|
||||
|
||||
fun ShortArray.println() {
|
||||
this.print()
|
||||
//println()
|
||||
}
|
||||
|
||||
|
||||
fun ShortArray.copyOf(newSize: Int): ShortArray {
|
||||
val newInstance = ShortArray(newSize)
|
||||
var index = 0
|
||||
val end = if (newSize > this.size) this.size else newSize
|
||||
while (index < end) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
while (index < newSize) {
|
||||
newInstance.set(index, 0)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
fun ShortArray.copyOfRange(fromIndex: Int, toIndex: Int): ShortArray {
|
||||
val newInstance = ShortArray(toIndex - fromIndex)
|
||||
var index = fromIndex
|
||||
while (index < toIndex) {
|
||||
val value = this.get(index)
|
||||
newInstance.set(index - fromIndex, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
|
||||
operator fun ShortArray.plus(element: Short): ShortArray {
|
||||
val index = size
|
||||
val result = this.copyOf(index + 1)
|
||||
result[index] = element
|
||||
return result
|
||||
}
|
||||
|
||||
operator fun ShortArray.plus(elements: ShortArray): ShortArray {
|
||||
val thisSize = size
|
||||
val arraySize = elements.size
|
||||
val resultSize = thisSize + arraySize
|
||||
val newInstance = this.copyOf(resultSize)
|
||||
var index = thisSize
|
||||
|
||||
while (index < resultSize) {
|
||||
val value = elements.get(index - thisSize)
|
||||
newInstance.set(index, value)
|
||||
index = index + 1
|
||||
}
|
||||
|
||||
return newInstance
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
|
||||
object WireFormat {
|
||||
// couple of constants for magic numbers
|
||||
val TAG_TYPE_BITS: Int = 3
|
||||
val TAG_TYPE_MASK: Int = (1 shl TAG_TYPE_BITS) - 1
|
||||
val VARINT_INFO_BITS_COUNT: Int = 7
|
||||
val VARINT_INFO_BITS_MASK: Int = 0b01111111 // mask for separating lowest 7 bits, where actual information stored
|
||||
val VARINT_UTIL_BIT_MASK: Int = 0b10000000 // mask for separating highest bit, that indicates next byte presence
|
||||
val FIXED_32_BYTE_SIZE: Int = 4
|
||||
val FIXED_64_BYTE_SIZE: Int = 8
|
||||
|
||||
fun getTagWireType(tag: Int): WireType {
|
||||
return WireType.from((tag and TAG_TYPE_MASK).toByte())
|
||||
}
|
||||
|
||||
fun getTagFieldNumber(tag: Int): Int {
|
||||
return tag ushr TAG_TYPE_BITS
|
||||
}
|
||||
|
||||
// TODO: refactor casts into function overloading as soon as translator will support it
|
||||
fun getTagSize(fieldNumber: Int, wireType: WireType): Int {
|
||||
return getVarint32Size((fieldNumber shl 3) or wireType.id)
|
||||
}
|
||||
|
||||
fun getVarint32Size(value: Int): Int {
|
||||
var curValue = value
|
||||
var size = 0
|
||||
do {
|
||||
size += 1
|
||||
curValue = curValue ushr VARINT_INFO_BITS_COUNT
|
||||
} while (curValue != 0)
|
||||
return size
|
||||
}
|
||||
|
||||
fun getVarint64Size(value: Long): Int {
|
||||
var curValue = value
|
||||
var size = 0
|
||||
do {
|
||||
size += 1
|
||||
curValue = curValue ushr VARINT_INFO_BITS_COUNT
|
||||
}while (curValue != 0L)
|
||||
return size
|
||||
}
|
||||
|
||||
fun getZigZag32Size(value: Int): Int {
|
||||
return getVarint32Size((value shl 1) xor (value shr 31))
|
||||
}
|
||||
|
||||
fun getZigZag64Size(value: Long): Int {
|
||||
return getVarint64Size((value shl 1) xor (value shr 63))
|
||||
}
|
||||
|
||||
fun getInt32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getInt32SizeNoTag(value)
|
||||
}
|
||||
|
||||
fun getInt32SizeNoTag(value: Int): Int {
|
||||
if (value < 0) {
|
||||
return getVarint64Size(value.toLong())
|
||||
}
|
||||
return getVarint32Size(value)
|
||||
}
|
||||
|
||||
fun getUInt32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getUInt32SizeNoTag(value)
|
||||
}
|
||||
|
||||
fun getUInt32SizeNoTag(value: Int): Int {
|
||||
return getVarint32Size(value)
|
||||
}
|
||||
|
||||
fun getInt64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getUInt64SizeNoTag(value)
|
||||
}
|
||||
|
||||
fun getInt64SizeNoTag(value: Long): Int {
|
||||
return getVarint64Size(value)
|
||||
}
|
||||
|
||||
fun getUInt64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getInt64Size(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun getUInt64SizeNoTag(value: Long): Int {
|
||||
return getVarint64Size(value)
|
||||
}
|
||||
|
||||
fun getBoolSize(fieldNumber: Int, value: Boolean): Int {
|
||||
val intValue = if (value) 1 else 0
|
||||
return getInt32Size(fieldNumber, intValue)
|
||||
}
|
||||
|
||||
fun getBoolSizeNoTag(value: Boolean): Int {
|
||||
val intValue = if (value) 1 else 0
|
||||
return getInt32SizeNoTag(intValue)
|
||||
}
|
||||
|
||||
fun getEnumSize(fieldNumber: Int, value: Int): Int {
|
||||
return getInt32Size(fieldNumber, value)
|
||||
}
|
||||
|
||||
fun getEnumSizeNoTag(value: Int): Int {
|
||||
return getInt32SizeNoTag(value)
|
||||
}
|
||||
|
||||
fun getSInt32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getZigZag32Size(value)
|
||||
}
|
||||
|
||||
fun getSInt32SizeNoTag(value: Int): Int {
|
||||
return getZigZag32Size(value)
|
||||
}
|
||||
|
||||
fun getSInt64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.VARINT) + getZigZag64Size(value)
|
||||
}
|
||||
|
||||
fun getSInt64SizeNoTag(value: Long): Int {
|
||||
return getZigZag64Size(value)
|
||||
}
|
||||
|
||||
fun getFixed32Size(fieldNumber: Int, value: Int): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_32) + FIXED_32_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFixed32SizeNoTag(value: Int): Int {
|
||||
return FIXED_32_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFixed64Size(fieldNumber: Int, value: Long): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_64) + FIXED_64_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFixed64SizeNoTag(value: Long): Int {
|
||||
return FIXED_64_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getDoubleSize(fieldNumber: Int, value: Double): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_64) + FIXED_64_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getDoubleSizeNoTag(value: Double): Int {
|
||||
return FIXED_64_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFloatSize(fieldNumber: Int, value: Float): Int {
|
||||
return getTagSize(fieldNumber, WireType.FIX_32) + FIXED_32_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getFloatSizeNoTag(value: Float): Int {
|
||||
return FIXED_32_BYTE_SIZE
|
||||
}
|
||||
|
||||
fun getBytesSize(fieldNumber: Int, value: ByteArray): Int {
|
||||
if (value.size == 0)
|
||||
return 0
|
||||
var size = 0
|
||||
return value.size + getTagSize(fieldNumber, WireType.LENGTH_DELIMITED) + getVarint32Size(value.size)
|
||||
}
|
||||
|
||||
fun getBytesSizeNoTag(value: ByteArray): Int {
|
||||
return value.size + getVarint32Size(value.size)
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
/**
|
||||
* Created by Dmitry Savvinov on 7/6/16.
|
||||
* Enum for possible WireTypes.
|
||||
* See details at [official Google reference](https://developers.google.com/protocol-buffers/docs/encoding#structure)
|
||||
*/
|
||||
|
||||
enum class WireType(val id: Int) {
|
||||
VARINT(0), // int32, int64, uint32, uint64, sint32, sint64, bool, enum
|
||||
FIX_64(1), // fixed64, sfixed64, double
|
||||
LENGTH_DELIMITED(2), // string, bytes, embedded messages, packed repeated fields
|
||||
START_GROUP(3), // groups (deprecated)
|
||||
END_GROUP(4), // groups (deprecated)
|
||||
FIX_32(5), // fixed32, sfixed32, float
|
||||
UNDEFINED(6); // indicates error when parsing from Int
|
||||
|
||||
companion object {
|
||||
fun from (value: Byte): WireType {
|
||||
return when (value) {
|
||||
0.toByte() -> VARINT
|
||||
1.toByte() -> FIX_64
|
||||
2.toByte() -> LENGTH_DELIMITED
|
||||
3.toByte() -> START_GROUP
|
||||
4.toByte() -> END_GROUP
|
||||
5.toByte() -> FIX_32
|
||||
else -> UNDEFINED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,71 +0,0 @@
|
||||
package kotlin
|
||||
|
||||
// a mod b (in arithmetical sense)
|
||||
private fun mod(a: Int, b: Int): Int {
|
||||
val mod = a % b
|
||||
return if (mod >= 0) mod else mod + b
|
||||
}
|
||||
|
||||
private fun mod(a: Long, b: Long): Long {
|
||||
val mod = a % b
|
||||
return if (mod >= 0) mod else mod + b
|
||||
}
|
||||
|
||||
// (a - b) mod c
|
||||
private fun differenceModulo(a: Int, b: Int, c: Int): Int {
|
||||
return mod(mod(a, c) - mod(b, c), c)
|
||||
}
|
||||
|
||||
private fun differenceModulo(a: Long, b: Long, c: Long): Long {
|
||||
return mod(mod(a, c) - mod(b, c), c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range
|
||||
* from [start] to [end] in case of a positive [step], or from [end] to [start] in case of a negative
|
||||
* [step].
|
||||
*
|
||||
* No validation on passed parameters is performed. The given parameters should satisfy the condition: either
|
||||
* `step > 0` and `start >= end`, or `step < 0` and`start >= end`.
|
||||
* @param start first element of the progression
|
||||
* @param end ending bound for the progression
|
||||
* @param step increment, or difference of successive elements in the progression
|
||||
* @return the final element of the progression
|
||||
* @suppress
|
||||
*/
|
||||
fun getProgressionLastElement(start: Int, end: Int, step: Int): Int {
|
||||
if (step > 0) {
|
||||
return end - differenceModulo(end, start, step)
|
||||
} else if (step < 0) {
|
||||
return end + differenceModulo(start, end, -step)
|
||||
} else {
|
||||
println("Step is zero.")
|
||||
assert(false)
|
||||
return -1
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range
|
||||
* from [start] to [end] in case of a positive [step], or from [end] to [start] in case of a negative
|
||||
* [step].
|
||||
*
|
||||
* No validation on passed parameters is performed. The given parameters should satisfy the condition: either
|
||||
* `step > 0` and `start >= end`, or `step < 0` and`start >= end`.
|
||||
* @param start first element of the progression
|
||||
* @param end ending bound for the progression
|
||||
* @param step increment, or difference of successive elements in the progression
|
||||
* @return the final element of the progression
|
||||
* @suppress
|
||||
*/
|
||||
internal fun getProgressionLastElement(start: Long, end: Long, step: Long): Long {
|
||||
if (step > 0) {
|
||||
return end - differenceModulo(end, start, step)
|
||||
} else if (step < 0) {
|
||||
return end + differenceModulo(start, end, -step)
|
||||
} else {
|
||||
println("Step is zero.")
|
||||
assert(false)
|
||||
return -1L
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
extern char *malloc(int size);
|
||||
|
||||
int malloc_array(int x) {
|
||||
return (int) malloc(x);
|
||||
}
|
||||
|
||||
char kotlinclib_get_byte(int data, int index) {
|
||||
return *((char *) data + index);
|
||||
}
|
||||
|
||||
void kotlinclib_set_byte(int data, int index, char value) {
|
||||
char *ptr = (char *) data;
|
||||
*(ptr + index) = value;
|
||||
}
|
||||
|
||||
int kotlinclib_get_int(int data, int index) {
|
||||
return *((int *) data + index);
|
||||
}
|
||||
|
||||
void kotlinclib_set_int(int data, int index, int value) {
|
||||
int *ptr = (int *) data;
|
||||
*(ptr + index) = value;
|
||||
}
|
||||
|
||||
short kotlinclib_get_short(int data, int index) {
|
||||
return *((short *) data + index);
|
||||
}
|
||||
|
||||
void kotlinclib_set_short(int data, int index, short value) {
|
||||
short *ptr = (short *) data;
|
||||
*(ptr + index) = value;
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
void assert_c(int value) {
|
||||
if (!value) {
|
||||
printf("Exception in thread \"main\" java.lang.AssertionError: Assertion failed\n");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
|
||||
#define STATIC_AREA_SIZE 30000
|
||||
#define DYNAMIC_AREA_SIZE 30000
|
||||
|
||||
#define STATIC_HEAP 0
|
||||
#define DYNAMIC_HEAP 1
|
||||
|
||||
#ifdef ARM
|
||||
|
||||
char static_area[STATIC_AREA_SIZE];
|
||||
char dynamic_area[DYNAMIC_AREA_SIZE];
|
||||
|
||||
char* heaps[2] = {
|
||||
(char*) static_area,
|
||||
(char*) dynamic_area
|
||||
};
|
||||
|
||||
int heap_tails[2] = {0, 0};
|
||||
int active_heap = STATIC_HEAP;
|
||||
|
||||
int dynamic_heap_consume = 0;
|
||||
int dynamic_heap_max = 0;
|
||||
|
||||
#else
|
||||
char* malloc(int);
|
||||
#endif
|
||||
|
||||
#ifdef DBG
|
||||
static int total = 0;
|
||||
int printf(const char * restrict format, ... );
|
||||
#endif
|
||||
|
||||
char* malloc_heap(int size) {
|
||||
#ifdef ARM
|
||||
char* ptr = heaps[active_heap] + heap_tails[active_heap];
|
||||
heap_tails[active_heap] += size;
|
||||
|
||||
return ptr;
|
||||
|
||||
#else
|
||||
#ifdef DBG
|
||||
total = total + size;
|
||||
printf("Alloc [%d] TOTAL: [%d]\n", size, total);
|
||||
#endif
|
||||
return malloc(size);
|
||||
#endif
|
||||
}
|
||||
|
||||
void set_active_heap(int heap) {
|
||||
#ifdef ARM
|
||||
active_heap = heap;
|
||||
#endif
|
||||
}
|
||||
|
||||
void clean_dynamic_heap() {
|
||||
#ifdef ARM
|
||||
dynamic_heap_consume += heap_tails[DYNAMIC_HEAP];
|
||||
if (heap_tails[DYNAMIC_HEAP] > dynamic_heap_max) {
|
||||
dynamic_heap_max = heap_tails[DYNAMIC_HEAP];
|
||||
}
|
||||
|
||||
heap_tails[DYNAMIC_HEAP] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef ARM
|
||||
int dynamic_heap_tail() {
|
||||
return heap_tails[DYNAMIC_HEAP];
|
||||
}
|
||||
|
||||
int static_heap_tail() {
|
||||
return heap_tails[STATIC_HEAP];
|
||||
}
|
||||
|
||||
int dynamic_heap_max_bytes() {
|
||||
return dynamic_heap_max;
|
||||
}
|
||||
|
||||
int dynamic_heap_total() {
|
||||
return dynamic_heap_consume;
|
||||
}
|
||||
#endif
|
||||
@@ -1,57 +0,0 @@
|
||||
#define MAKE_CONVERT(from, from_type, to, to_type) to_type kotlinclib_ ## from ## To ## to ( from_type value ) { return (to_type) value;}
|
||||
|
||||
|
||||
MAKE_CONVERT(int, int, Byte, char)
|
||||
MAKE_CONVERT(int, int, Char, char)
|
||||
MAKE_CONVERT(int, int, Short, short)
|
||||
MAKE_CONVERT(int, int, Long, long)
|
||||
MAKE_CONVERT(int, int, Float, float)
|
||||
MAKE_CONVERT(int, int, Double, double)
|
||||
|
||||
|
||||
MAKE_CONVERT(byte, char, Char, char)
|
||||
MAKE_CONVERT(byte, char, Short, short)
|
||||
MAKE_CONVERT(byte, char, Int, int)
|
||||
MAKE_CONVERT(byte, char, Long, long)
|
||||
MAKE_CONVERT(byte, char, Float, float)
|
||||
MAKE_CONVERT(byte, char, Double, double)
|
||||
|
||||
|
||||
MAKE_CONVERT(char, char, Byte, char)
|
||||
MAKE_CONVERT(char, char, Short, short)
|
||||
MAKE_CONVERT(char, char, Int, int)
|
||||
MAKE_CONVERT(char, char, Long, long)
|
||||
MAKE_CONVERT(char, char, Float, float)
|
||||
MAKE_CONVERT(char, char, Double, double)
|
||||
|
||||
|
||||
MAKE_CONVERT(short, short, Byte, char)
|
||||
MAKE_CONVERT(short, short, Char, char)
|
||||
MAKE_CONVERT(short, short, Int, int)
|
||||
MAKE_CONVERT(short, short, Long, long)
|
||||
MAKE_CONVERT(short, short, Float, float)
|
||||
MAKE_CONVERT(short, short, Double, double)
|
||||
|
||||
|
||||
MAKE_CONVERT(long, long, Byte, char)
|
||||
MAKE_CONVERT(long, long, Char, char)
|
||||
MAKE_CONVERT(long, long, Short, short)
|
||||
MAKE_CONVERT(long, long, Int, int)
|
||||
MAKE_CONVERT(long, long, Float, float)
|
||||
MAKE_CONVERT(long, long, Double, double)
|
||||
|
||||
|
||||
MAKE_CONVERT(float, float, Byte, char)
|
||||
MAKE_CONVERT(float, float, Char, char)
|
||||
MAKE_CONVERT(float, float, Short, short)
|
||||
MAKE_CONVERT(float, float, Int, int)
|
||||
MAKE_CONVERT(float, float, Long, long)
|
||||
MAKE_CONVERT(float, float, Double, double)
|
||||
|
||||
|
||||
MAKE_CONVERT(double, double, Byte, char)
|
||||
MAKE_CONVERT(double, double, Char, char)
|
||||
MAKE_CONVERT(double, double, Short, short)
|
||||
MAKE_CONVERT(double, double, Int, int)
|
||||
MAKE_CONVERT(double, double, Long, long)
|
||||
MAKE_CONVERT(double, double, Float, float)
|
||||
@@ -1,78 +0,0 @@
|
||||
#!/bin/bash
|
||||
green='\033[0;32m'
|
||||
red='\033[0;31m'
|
||||
lightRed='\033[1;31m'
|
||||
orange='\033[0;33m'
|
||||
KOTSTD='../kotstd/kt'
|
||||
|
||||
cd ../translator
|
||||
|
||||
i=$1
|
||||
TEST=`basename $i ".txt"`
|
||||
DIRECTORY="src/test/kotlin/tests"
|
||||
MAIN="$DIRECTORY/$TEST/linked/main.c"
|
||||
rm -f $DIRECTORY/$TEST/linked/*
|
||||
mkdir -p $DIRECTORY/$TEST/linked
|
||||
|
||||
echo "#include <stdlib.h>" >> $MAIN
|
||||
echo "#include <stdio.h>" >> $MAIN
|
||||
echo "#include <assert.h>" >> $MAIN
|
||||
|
||||
echo "int main(){" >> $MAIN
|
||||
echo "printf(\"%stest: $TEST%s\n\", \"\x1B[33m\", \"\x1B[0m\");" >> $MAIN
|
||||
cat "$i" | while read LINE
|
||||
do
|
||||
echo " assert($LINE);" >> $MAIN
|
||||
echo " printf(\"%s[OK]:%s $LINE\n\", \"\x1B[32m\", \"\x1B[0m\");" >> $MAIN
|
||||
done
|
||||
|
||||
echo "printf(\"TEST RESULT: OK\n\");" >> $MAIN
|
||||
echo "return 0;}" >> $MAIN
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${red}Error somewhere in main.c generation${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
clang-3.6 -S -emit-llvm $DIRECTORY/$TEST/linked/main.c -o $DIRECTORY/$TEST/linked/main.ll -Wno-implicit-function-declaration
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${red}Error building main.c${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp ../kotstd/build/stdlib_x86.ll $DIRECTORY/$TEST/linked/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${red}Error copying ../kotstd/build/stdlib_x86.ll to ${DIRECTORY}/${TEST}/linked/${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$DIRECTORY/$TEST/$TEST.c" ]
|
||||
then
|
||||
clang-3.6 -S -emit-llvm "$DIRECTORY/$TEST/$TEST.c" -o $DIRECTORY/$TEST/linked/$TEST"_c.ll" -Wno-implicit-function-declaration
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${red}Error building: ${DIRECTORY}/${TEST}/linked/${TEST}_c.ll${nc}"
|
||||
fi
|
||||
fi
|
||||
|
||||
java -jar build/libs/translator-1.0.jar -I $KOTSTD $DIRECTORY/$TEST/$TEST.kt > $DIRECTORY/$TEST/linked/$TEST.ll
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${red}Translation error: ${DIRECTORY}/$TEST/${TEST}.kt${nc}"
|
||||
fi
|
||||
|
||||
llvm-link-3.6 -S $DIRECTORY/$TEST/linked/*.ll > $DIRECTORY/$TEST/linked/run.ll
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${red}Error linking with llvm${nc}"
|
||||
fi
|
||||
|
||||
lli-3.6 $DIRECTORY/$TEST/linked/run.ll
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo -e "${lightRed}Error running test${nc}"
|
||||
fi
|
||||
@@ -1,104 +0,0 @@
|
||||
#!/bin/bash
|
||||
green='\033[0;32m'
|
||||
red='\033[0;31m'
|
||||
lightRed='\033[1;31m'
|
||||
orange='\033[0;33m'
|
||||
nc='\033[0m'
|
||||
KOTSTD='../kotstd/kt'
|
||||
|
||||
if [ "$3" == "--debug" ]; then
|
||||
cd ../kotstd && make clean && make debug
|
||||
else
|
||||
cd ../kotstd && make clean && make
|
||||
fi
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error building kotstd lib${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd ../translator
|
||||
|
||||
DIRECTORY="src/test/kotlin/tests"
|
||||
TESTS=$( ls $DIRECTORY/*/*.txt $1) # Note that "ls $DIRECTORY/input $1" is wrong. Why? Because it's bash.
|
||||
|
||||
if [ "$2" == "--proto" ]; then
|
||||
TESTS=$( ls $DIRECTORY/*/proto*.txt $1)
|
||||
fi
|
||||
total_scripts=0
|
||||
successful_scripts=0
|
||||
|
||||
for i in $TESTS; do
|
||||
TEST=`basename $i ".txt"`
|
||||
MAIN="$DIRECTORY/$TEST/linked/main.c"
|
||||
rm -f $DIRECTORY/$TEST/linked/*
|
||||
mkdir -p $DIRECTORY/$TEST/linked
|
||||
successful=1
|
||||
echo -e "${orange}test: ${TEST}${nc}"
|
||||
echo "#include <stdlib.h>" >> $MAIN
|
||||
echo "#include <stdio.h>" >> $MAIN
|
||||
echo "#include <assert.h>" >> $MAIN
|
||||
|
||||
echo "int main(){" >> $MAIN
|
||||
cat "$i" | while read LINE
|
||||
do
|
||||
echo " assert($LINE);" >> $MAIN
|
||||
echo " printf(\"%s[OK]:%s $LINE\n\", \"\x1B[32m\", \"\x1B[0m\");" >> $MAIN
|
||||
done
|
||||
|
||||
echo "printf(\"TEST RESULT: OK\n\");" >> $MAIN
|
||||
echo "return 0;}" >> $MAIN
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error somewhere in main.c generation${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
clang-3.6 -S -emit-llvm $DIRECTORY/$TEST/linked/main.c -o $DIRECTORY/$TEST/linked/main.ll -Wno-implicit-function-declaration
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error building main.c${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
||||
cp ../kotstd/build/stdlib_x86.ll $DIRECTORY/$TEST/linked/
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error copying ../kotstd/build/stdlib_x86.ll to ${DIRECTORY}/${TEST}/linked/${nc}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "$DIRECTORY/$TEST/$TEST.c" ]
|
||||
then
|
||||
clang-3.6 -S -emit-llvm "$DIRECTORY/$TEST/$TEST.c" -o $DIRECTORY/$TEST/linked/$TEST"_c.ll" -Wno-implicit-function-declaration
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error building: ${DIRECTORY}/${TEST}/linked/${TEST}_c.ll${nc}"
|
||||
fi
|
||||
fi
|
||||
|
||||
java -jar build/libs/translator-1.0.jar -I $KOTSTD $DIRECTORY/$TEST/$TEST.kt > $DIRECTORY/$TEST/linked/$TEST.ll
|
||||
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Translation error: ${DIRECTORY}/$TEST/${TEST}.kt${nc}"
|
||||
successful=0
|
||||
fi
|
||||
|
||||
llvm-link-3.6 -S $DIRECTORY/$TEST/linked/*.ll > $DIRECTORY/$TEST/linked/run.ll
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${red}Error linking with llvm${nc}"
|
||||
successful=0
|
||||
fi
|
||||
|
||||
lli-3.6 $DIRECTORY/$TEST/linked/run.ll
|
||||
if [ $? -ne 0 ]; then
|
||||
echo -e "${lightRed}Error running test${nc}"
|
||||
successful=0
|
||||
fi
|
||||
|
||||
if [ "$2" == "--once" ]; then
|
||||
exit
|
||||
fi
|
||||
successful_scripts=$((successful_scripts+successful))
|
||||
total_scripts=$((total_scripts+1))
|
||||
done
|
||||
|
||||
echo -e "Result: ${orange} [${successful_scripts}]/[${total_scripts}]"
|
||||
@@ -1,2 +0,0 @@
|
||||
rootProject.name = 'translator-bc'
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
import com.jshmrsn.karg.Arguments
|
||||
import com.jshmrsn.karg.RawArguments
|
||||
|
||||
class DefaultArguments(raw: RawArguments) : Arguments(raw, name = "default") {
|
||||
|
||||
val includeDir = optionalParameter(
|
||||
name = "include directory",
|
||||
aliasNames = listOf("include"),
|
||||
shortNames = listOf('I')
|
||||
)
|
||||
|
||||
val arm = optionalFlag(
|
||||
name = "arm",
|
||||
description = "enable arm build",
|
||||
aliasNames = listOf("arm"),
|
||||
default = false
|
||||
)
|
||||
|
||||
val output = optionalParameter(
|
||||
name = "output",
|
||||
description = "output file path",
|
||||
shortNames = listOf('o')
|
||||
)
|
||||
|
||||
val mainClass = optionalParameter(
|
||||
name = "main class",
|
||||
aliasNames = listOf("main"),
|
||||
default = "main",
|
||||
shortNames = listOf('M')
|
||||
)
|
||||
|
||||
//[TODO] files with [] or another marking
|
||||
val sources = positionalArguments(
|
||||
name = "sources",
|
||||
description = "source files",
|
||||
minCount = 1
|
||||
)
|
||||
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.jshmrsn.karg.parseArguments
|
||||
import org.kotlinnative.translator.ProjectTranslator
|
||||
import org.kotlinnative.translator.TranslationState
|
||||
import java.io.*
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
// TODO make good help message (ex. is rm --help)
|
||||
val arguments = parseArguments(args, ::DefaultArguments)
|
||||
val disposer = Disposer.newDisposable()
|
||||
val analyzedFiles = arguments.sources.toMutableList()
|
||||
|
||||
if (arguments.includeDir != null) {
|
||||
val libraryFiles = File(arguments.includeDir).walk().filter { !it.isDirectory }.map { it.absolutePath }
|
||||
analyzedFiles.addAll(libraryFiles)
|
||||
}
|
||||
|
||||
val translationState = TranslationState.createTranslationState(analyzedFiles, disposer, arguments.mainClass, arguments.arm)
|
||||
val code:String = ProjectTranslator(
|
||||
translationState.environment.getSourceFiles(),
|
||||
translationState
|
||||
).generateCode()
|
||||
|
||||
if (arguments.output == null) {
|
||||
println(code)
|
||||
} else {
|
||||
val output = File(arguments.output)
|
||||
output.writeText(code)
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
libName = llvmbridge
|
||||
|
||||
headers = llvm-c/Core.h llvm-c/ExecutionEngine.h llvm-c/Target.h llvm-c/Analysis.h llvm-c/BitWriter.h
|
||||
|
||||
|
||||
compiler = clang
|
||||
|
||||
compilerOpts = -std=c99 -fPIC \
|
||||
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \
|
||||
-pedantic -Wno-long-long -Wcovered-switch-default -Wdelete-non-virtual-dtor \
|
||||
-DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
|
||||
|
||||
|
||||
linker = clang++
|
||||
|
||||
linkerOpts = -stdlib=libc++ -fPIC -fvisibility-inlines-hidden \
|
||||
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wcast-qual -Wmissing-field-initializers \
|
||||
-pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor \
|
||||
-std=c++11 \
|
||||
-DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \
|
||||
-Wl,-search_paths_first -Wl,-headerpad_max_install_names \
|
||||
-lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter \
|
||||
-lLLVMX86Desc -lLLVMMCDisassembler -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMInterpreter \
|
||||
-lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMInstrumentation -lLLVMProfileData -lLLVMTransformUtils \
|
||||
-lLLVMBitWriter -lLLVMExecutionEngine -lLLVMTarget -lLLVMAnalysis -lLLVMRuntimeDyld -lLLVMObject -lLLVMMCParser \
|
||||
-lLLVMBitReader -lLLVMMC -lLLVMCore -lLLVMSupport -lcurses -lpthread -lz -lm \
|
||||
-lffi
|
||||
|
||||
excludedFunctions =
|
||||
-77
@@ -1,77 +0,0 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.kotlinnative.translator.codegens.ClassCodegen
|
||||
import org.kotlinnative.translator.codegens.FunctionCodegen
|
||||
import org.kotlinnative.translator.codegens.ObjectCodegen
|
||||
import org.kotlinnative.translator.codegens.PropertyCodegen
|
||||
|
||||
class ProjectTranslator(val files: List<KtFile>,
|
||||
val state: TranslationState) {
|
||||
private var codeBuilder = state.codeBuilder
|
||||
|
||||
fun generateCode(): String {
|
||||
with(files) {
|
||||
map { addClassDeclarations(it) }
|
||||
map { addObjectDeclarations(it) }
|
||||
map { addFunctionDeclarations(it) }
|
||||
map { addPropertyDeclarations(it) }
|
||||
}
|
||||
generateProjectBody()
|
||||
return codeBuilder.toString()
|
||||
}
|
||||
|
||||
fun addFunctionDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtNamedFunction>()) {
|
||||
val function = FunctionCodegen(state, variableManager, declaration, codeBuilder)
|
||||
if (function.external) {
|
||||
state.externalFunctions.put(function.fullName, function)
|
||||
} else {
|
||||
state.functions.put(function.fullName, function)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun addClassDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtClass>()) {
|
||||
val codegen = ClassCodegen(state, variableManager, declaration, codeBuilder)
|
||||
state.classes.put(codegen.structName, codegen)
|
||||
}
|
||||
}
|
||||
|
||||
fun addPropertyDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtProperty>()) {
|
||||
val property = PropertyCodegen(state, variableManager, declaration, codeBuilder)
|
||||
state.properties.put(declaration.name!!, property)
|
||||
}
|
||||
}
|
||||
|
||||
fun addObjectDeclarations(file: KtFile) {
|
||||
val variableManager = VariableManager(state.globalVariableCollection)
|
||||
for (declaration in file.declarations.filterIsInstance<KtObjectDeclaration>()) {
|
||||
val codegen = ObjectCodegen(state, variableManager, declaration, codeBuilder)
|
||||
state.objects.put(codegen.structName, codegen)
|
||||
}
|
||||
}
|
||||
|
||||
private fun generateProjectBody() {
|
||||
with(state) {
|
||||
properties.values.map { it.generate() }
|
||||
objects.values.map { it.prepareForGenerate() }
|
||||
classes.values.map { it.prepareForGenerate() }
|
||||
objects.values.map { it.generate() }
|
||||
classes.values.map { it.generate() }
|
||||
externalFunctions.values.map { it.generate() }
|
||||
functions.values.filter { it.isExtensionDeclaration }.map { it.generate() }
|
||||
functions.values.filter { !it.isExtensionDeclaration }.map { it.generate() }
|
||||
}
|
||||
|
||||
if (state.mainFunction != "main") {
|
||||
codeBuilder.declareEntryPoint(state.mainFunction)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
-118
@@ -1,118 +0,0 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import com.intellij.openapi.Disposable
|
||||
import org.jetbrains.kotlin.analyzer.AnalysisResult
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
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.getModuleName
|
||||
import org.jetbrains.kotlin.cli.jvm.config.jvmClasspathRoots
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.addKotlinSourceRoots
|
||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||
import org.jetbrains.kotlin.native.llvm.LLVMModuleCreateWithName
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.jvm.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.kotlin.utils.PathUtil
|
||||
import org.kotlinnative.translator.codegens.ClassCodegen
|
||||
import org.kotlinnative.translator.codegens.FunctionCodegen
|
||||
import org.kotlinnative.translator.codegens.ObjectCodegen
|
||||
import org.kotlinnative.translator.codegens.PropertyCodegen
|
||||
import org.kotlinnative.translator.exceptions.TranslationException
|
||||
import org.kotlinnative.translator.llvm.LLVMBuilder
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import java.util.*
|
||||
|
||||
|
||||
class TranslationState
|
||||
private constructor
|
||||
(
|
||||
val environment: KotlinCoreEnvironment,
|
||||
val bindingContext: BindingContext,
|
||||
val mainFunction: String, arm: Boolean
|
||||
) {
|
||||
var externalFunctions = HashMap<String, FunctionCodegen>()
|
||||
var functions = HashMap<String, FunctionCodegen>()
|
||||
var classes = HashMap<String, ClassCodegen>()
|
||||
var objects = HashMap<String, ObjectCodegen>()
|
||||
var properties = HashMap<String, PropertyCodegen>()
|
||||
val codeBuilder = LLVMBuilder(arm)
|
||||
val extensionFunctions = HashMap<String, HashMap<String, FunctionCodegen>>()
|
||||
val globalVariableCollection = HashMap<String, LLVMVariable>()
|
||||
val llvmModule = LLVMModuleCreateWithName("main")
|
||||
|
||||
init {
|
||||
POINTER_ALIGN = if (arm) 4 else 8
|
||||
POINTER_SIZE = if (arm) 4 else 8
|
||||
}
|
||||
|
||||
companion object {
|
||||
var POINTER_ALIGN = 4
|
||||
var POINTER_SIZE = 4
|
||||
|
||||
fun createTranslationState(sources: List<String>, disposer: Disposable, mainFunction: String, arm: Boolean = false): TranslationState {
|
||||
|
||||
val configuration = CompilerConfiguration()
|
||||
val messageCollector = object : MessageCollector {
|
||||
private var hasError = false
|
||||
|
||||
override fun hasErrors(): Boolean = hasError
|
||||
|
||||
override fun report(severity: CompilerMessageSeverity, message: String, location: CompilerMessageLocation) {
|
||||
if (severity.isError) {
|
||||
System.err.println("[${severity.toString()}]${location.path} ${location.line}:${location.column} $message")
|
||||
hasError = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configuration.put(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY, messageCollector)
|
||||
configuration.put(JVMConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME)
|
||||
|
||||
configuration.addKotlinSourceRoots(sources)
|
||||
|
||||
val environment = KotlinCoreEnvironment.createForProduction(disposer, configuration, EnvironmentConfigFiles.JVM_CONFIG_FILES)
|
||||
val bindingContext = analyze(environment)?.bindingContext ?: throw TranslationException("Can't initialize binding context for project")
|
||||
|
||||
return TranslationState(environment, bindingContext, mainFunction, arm)
|
||||
}
|
||||
|
||||
private fun analyze(environment: KotlinCoreEnvironment): AnalysisResult? {
|
||||
val collector = environment.configuration.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
|
||||
val analyzer = AnalyzerWithCompilerReport(collector)
|
||||
analyzer.analyzeAndReport(environment.getSourceFiles(), object : AnalyzerWithCompilerReport.Analyzer {
|
||||
override fun analyze(): AnalysisResult {
|
||||
val sharedTrace = CliLightClassGenerationSupport.NoScopeRecordCliBindingTrace()
|
||||
val moduleContext = TopDownAnalyzerFacadeForJVM.createContextWithSealedModule(environment.project, environment.getModuleName())
|
||||
|
||||
return TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegrationWithCustomContext(
|
||||
moduleContext,
|
||||
environment.getSourceFiles(),
|
||||
sharedTrace,
|
||||
environment.configuration.get(JVMConfigurationKeys.MODULES),
|
||||
environment.configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS),
|
||||
JvmPackagePartProvider(environment))
|
||||
}
|
||||
|
||||
override fun reportEnvironmentErrors() {
|
||||
val files = environment.configuration.jvmClasspathRoots
|
||||
val runtimes = files.map { it.canonicalFile }.filter { it.name == PathUtil.KOTLIN_JAVA_RUNTIME_JAR && it.exists() }
|
||||
collector.report(CompilerMessageSeverity.ERROR, runtimes.joinToString { it.path }, CompilerMessageLocation.NO_LOCATION)
|
||||
System.err.println(runtimes.joinToString { it.toString() })
|
||||
}
|
||||
})
|
||||
|
||||
return if (analyzer.hasErrors()) null else analyzer.analysisResult
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-48
@@ -1,48 +0,0 @@
|
||||
package org.kotlinnative.translator
|
||||
|
||||
import org.kotlinnative.translator.llvm.LLVMScope
|
||||
import org.kotlinnative.translator.llvm.LLVMVariable
|
||||
import org.kotlinnative.translator.llvm.types.LLVMType
|
||||
import java.util.*
|
||||
|
||||
class VariableManager(val globalVariableCollection: HashMap<String, LLVMVariable>) {
|
||||
|
||||
private var fileVariableCollectionTree = HashMap<String, Stack<Pair<LLVMVariable, Int>>>()
|
||||
|
||||
private companion object UniqueGenerator {
|
||||
private var unique = 0
|
||||
fun generateUniqueString() =
|
||||
".unique." + unique++
|
||||
}
|
||||
|
||||
operator fun get(variableName: String): LLVMVariable? {
|
||||
return fileVariableCollectionTree[variableName]?.peek()?.first ?: globalVariableCollection[variableName]
|
||||
}
|
||||
|
||||
operator fun contains(variableName: String): Boolean {
|
||||
return (fileVariableCollectionTree.contains(variableName) && !fileVariableCollectionTree[variableName]!!.empty()) || globalVariableCollection.containsKey(variableName)
|
||||
}
|
||||
|
||||
fun pullOneUpwardLevelVariable(variableName: String) {
|
||||
fileVariableCollectionTree[variableName]?.pop()
|
||||
}
|
||||
|
||||
fun pullUpwardsLevel(level: Int) {
|
||||
fileVariableCollectionTree.forEach { s, stack -> while (!stack.empty() && stack.peek().second >= level) stack.pop() }
|
||||
}
|
||||
|
||||
fun addVariable(name: String, variable: LLVMVariable, level: Int) {
|
||||
val stack = fileVariableCollectionTree.getOrDefault(name, Stack<Pair<LLVMVariable, Int>>())
|
||||
stack.push(Pair(variable, level))
|
||||
fileVariableCollectionTree.put(name, stack)
|
||||
}
|
||||
|
||||
fun addGlobalVariable(name: String, variable: LLVMVariable) {
|
||||
globalVariableCollection.put(name, variable)
|
||||
}
|
||||
|
||||
fun receiveVariable(name: String, type: LLVMType, scope: LLVMScope, pointer: Int): LLVMVariable {
|
||||
return LLVMVariable("managed${generateUniqueString()}.$name", type, name, scope, pointer)
|
||||
}
|
||||
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user