mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
split out the code generator into own project submodule
This commit is contained in:
parent
82da8f4946
commit
0b5ddcdc9b
1
.idea/modules.xml
generated
1
.idea/modules.xml
generated
@ -2,6 +2,7 @@
|
|||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<modules>
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/codeGeneration/codeGeneration.iml" filepath="$PROJECT_DIR$/codeGeneration/codeGeneration.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/codeOptimizers/codeOptimizers.iml" filepath="$PROJECT_DIR$/codeOptimizers/codeOptimizers.iml" />
|
<module fileurl="file://$PROJECT_DIR$/codeOptimizers/codeOptimizers.iml" filepath="$PROJECT_DIR$/codeOptimizers/codeOptimizers.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/compiler/compiler.iml" filepath="$PROJECT_DIR$/compiler/compiler.iml" />
|
<module fileurl="file://$PROJECT_DIR$/compiler/compiler.iml" filepath="$PROJECT_DIR$/compiler/compiler.iml" />
|
||||||
<module fileurl="file://$PROJECT_DIR$/compilerAst/compilerAst.iml" filepath="$PROJECT_DIR$/compilerAst/compilerAst.iml" />
|
<module fileurl="file://$PROJECT_DIR$/compilerAst/compilerAst.iml" filepath="$PROJECT_DIR$/compilerAst/compilerAst.iml" />
|
||||||
|
73
codeGeneration/build.gradle
Normal file
73
codeGeneration/build.gradle
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
|
||||||
|
plugins {
|
||||||
|
id 'java'
|
||||||
|
id 'application'
|
||||||
|
id "org.jetbrains.kotlin.jvm"
|
||||||
|
}
|
||||||
|
|
||||||
|
targetCompatibility = 11
|
||||||
|
sourceCompatibility = 11
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
|
mavenCentral()
|
||||||
|
maven { url "https://kotlin.bintray.com/kotlinx" }
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation project(':compilerInterfaces')
|
||||||
|
implementation project(':compilerAst')
|
||||||
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||||
|
// implementation "org.jetbrains.kotlin:kotlin-reflect"
|
||||||
|
implementation "com.michael-bull.kotlin-result:kotlin-result-jvm:1.1.12"
|
||||||
|
|
||||||
|
testImplementation "org.jetbrains.kotlin:kotlin-test-junit5"
|
||||||
|
testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.2'
|
||||||
|
testImplementation 'org.hamcrest:hamcrest:2.2'
|
||||||
|
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.2'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
compileKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
// verbose = true
|
||||||
|
// freeCompilerArgs += "-XXLanguage:+NewInference"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
compileTestKotlin {
|
||||||
|
kotlinOptions {
|
||||||
|
jvmTarget = "11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceSets {
|
||||||
|
main {
|
||||||
|
java {
|
||||||
|
srcDirs = ["${project.projectDir}/src"]
|
||||||
|
}
|
||||||
|
resources {
|
||||||
|
srcDirs = ["${project.projectDir}/res"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
test {
|
||||||
|
java {
|
||||||
|
srcDirs = ["${project.projectDir}/test"]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
test {
|
||||||
|
// Enable JUnit 5 (Gradle 4.6+).
|
||||||
|
useJUnitPlatform()
|
||||||
|
|
||||||
|
// Always run tests, even when nothing changed.
|
||||||
|
dependsOn 'cleanTest'
|
||||||
|
|
||||||
|
// Show test results.
|
||||||
|
testLogging {
|
||||||
|
events "skipped", "failed"
|
||||||
|
}
|
||||||
|
}
|
18
codeGeneration/codeGeneration.iml
Normal file
18
codeGeneration/codeGeneration.iml
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?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" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/test" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="jdk" jdkName="openjdk-11" jdkType="JavaSDK" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="KotlinJavaRuntime" level="project" />
|
||||||
|
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
|
||||||
|
<orderEntry type="module" module-name="compilerInterfaces" />
|
||||||
|
<orderEntry type="module" module-name="compilerAst" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="hamcrest" level="project" />
|
||||||
|
<orderEntry type="library" name="junit.jupiter" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
@ -0,0 +1,3 @@
|
|||||||
|
package prog8.compiler.target
|
||||||
|
|
||||||
|
class AssemblyError(msg: String) : RuntimeException(msg)
|
@ -10,7 +10,7 @@ import prog8.compiler.target.cbm.Petscii
|
|||||||
import prog8.compilerinterface.*
|
import prog8.compilerinterface.*
|
||||||
|
|
||||||
|
|
||||||
internal object C64Target: ICompilationTarget {
|
object C64Target: ICompilationTarget {
|
||||||
override val name = "c64"
|
override val name = "c64"
|
||||||
override val machine = C64MachineDefinition
|
override val machine = C64MachineDefinition
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
@ -10,7 +10,7 @@ import prog8.compiler.target.cx16.CX16MachineDefinition
|
|||||||
import prog8.compilerinterface.*
|
import prog8.compilerinterface.*
|
||||||
|
|
||||||
|
|
||||||
internal object Cx16Target: ICompilationTarget {
|
object Cx16Target: ICompilationTarget {
|
||||||
override val name = "cx16"
|
override val name = "cx16"
|
||||||
override val machine = CX16MachineDefinition
|
override val machine = CX16MachineDefinition
|
||||||
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
override fun encodeString(str: String, altEncoding: Boolean): List<Short> {
|
@ -1,6 +1,5 @@
|
|||||||
package prog8.compiler.target.c64
|
package prog8.compiler.target.c64
|
||||||
|
|
||||||
import prog8.compiler.*
|
|
||||||
import prog8.compiler.target.cbm.viceMonListPostfix
|
import prog8.compiler.target.cbm.viceMonListPostfix
|
||||||
import prog8.compilerinterface.*
|
import prog8.compilerinterface.*
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
@ -8,7 +7,7 @@ import java.nio.file.Path
|
|||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
internal object C64MachineDefinition: IMachineDefinition {
|
object C64MachineDefinition: IMachineDefinition {
|
||||||
|
|
||||||
override val cpu = CpuType.CPU6502
|
override val cpu = CpuType.CPU6502
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ internal object C64MachineDefinition: IMachineDefinition {
|
|||||||
"sta", "stx", "sty", "tas", "tax", "tay", "tsx", "txa", "txs", "tya", "xaa")
|
"sta", "stx", "sty", "tas", "tax", "tay", "tsx", "txa", "txs", "tya", "xaa")
|
||||||
|
|
||||||
|
|
||||||
internal class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
class C64Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||||
|
|
||||||
override val SCRATCH_B1 = 0x02 // temp storage for a single byte
|
override val SCRATCH_B1 = 0x02 // temp storage for a single byte
|
||||||
override val SCRATCH_REG = 0x03 // temp storage for a register, must be B1+1
|
override val SCRATCH_REG = 0x03 // temp storage for a register, must be B1+1
|
||||||
@ -144,7 +143,7 @@ internal object C64MachineDefinition: IMachineDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, val b4: Short):
|
data class Mflpt5(val b0: Short, val b1: Short, val b2: Short, val b3: Short, val b4: Short):
|
||||||
IMachineFloat {
|
IMachineFloat {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
@ -1,10 +1,17 @@
|
|||||||
package prog8.compiler.target.cbm
|
package prog8.compiler.target.cbm
|
||||||
|
|
||||||
|
import com.github.michaelbull.result.Ok
|
||||||
|
import com.github.michaelbull.result.Result
|
||||||
|
import com.github.michaelbull.result.mapError
|
||||||
import prog8.compilerinterface.CompilationOptions
|
import prog8.compilerinterface.CompilationOptions
|
||||||
import prog8.compilerinterface.IAssemblyProgram
|
import prog8.compilerinterface.IAssemblyProgram
|
||||||
import prog8.compilerinterface.OutputType
|
import prog8.compilerinterface.OutputType
|
||||||
import prog8.compilerinterface.generatedLabelPrefix
|
import prog8.compilerinterface.generatedLabelPrefix
|
||||||
|
import prog8.parser.SourceCode
|
||||||
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.Path
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
|
||||||
|
|
||||||
internal const val viceMonListPostfix = "vice-mon-list"
|
internal const val viceMonListPostfix = "vice-mon-list"
|
||||||
@ -76,3 +83,18 @@ class AssemblyProgram(
|
|||||||
viceMonListFile.toFile().appendText(breakpoints.joinToString("\n") + "\n")
|
viceMonListFile.toFile().appendText(breakpoints.joinToString("\n") + "\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
internal fun loadAsmIncludeFile(filename: String, source: SourceCode): Result<String, NoSuchFileException> {
|
||||||
|
return if (filename.startsWith(SourceCode.libraryFilePrefix)) {
|
||||||
|
return com.github.michaelbull.result.runCatching {
|
||||||
|
SourceCode.Resource("/prog8lib/${filename.substring(SourceCode.libraryFilePrefix.length)}").readText()
|
||||||
|
}.mapError { NoSuchFileException(File(filename)) }
|
||||||
|
} else {
|
||||||
|
val sib = Path(source.origin).resolveSibling(filename)
|
||||||
|
if (sib.isRegularFile())
|
||||||
|
Ok(SourceCode.File(sib).readText())
|
||||||
|
else
|
||||||
|
Ok(SourceCode.File(Path(filename)).readText())
|
||||||
|
}
|
||||||
|
}
|
@ -1098,7 +1098,7 @@ object Petscii {
|
|||||||
fun decodePetscii(petscii: Iterable<Short>, lowercase: Boolean = false): String {
|
fun decodePetscii(petscii: Iterable<Short>, lowercase: Boolean = false): String {
|
||||||
return petscii.map {
|
return petscii.map {
|
||||||
val code = it.toInt()
|
val code = it.toInt()
|
||||||
if(code<0 || code>=decodingPetsciiLowercase.size)
|
if(code<0 || code>= decodingPetsciiLowercase.size)
|
||||||
throw CharConversionException("petscii $code out of range 0..${decodingPetsciiLowercase.size-1}")
|
throw CharConversionException("petscii $code out of range 0..${decodingPetsciiLowercase.size-1}")
|
||||||
if(lowercase) decodingPetsciiLowercase[code] else decodingPetsciiUppercase[code]
|
if(lowercase) decodingPetsciiLowercase[code] else decodingPetsciiUppercase[code]
|
||||||
}.joinToString("")
|
}.joinToString("")
|
||||||
@ -1137,7 +1137,7 @@ object Petscii {
|
|||||||
fun decodeScreencode(screencode: Iterable<Short>, lowercase: Boolean = false): String {
|
fun decodeScreencode(screencode: Iterable<Short>, lowercase: Boolean = false): String {
|
||||||
return screencode.map {
|
return screencode.map {
|
||||||
val code = it.toInt()
|
val code = it.toInt()
|
||||||
if(code<0 || code>=decodingScreencodeLowercase.size)
|
if(code<0 || code>= decodingScreencodeLowercase.size)
|
||||||
throw CharConversionException("screencode $code out of range 0..${decodingScreencodeLowercase.size-1}")
|
throw CharConversionException("screencode $code out of range 0..${decodingScreencodeLowercase.size-1}")
|
||||||
if (lowercase) decodingScreencodeLowercase[code] else decodingScreencodeUppercase[code]
|
if (lowercase) decodingScreencodeLowercase[code] else decodingScreencodeUppercase[code]
|
||||||
}.joinToString("")
|
}.joinToString("")
|
@ -7,14 +7,12 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.*
|
import prog8.compiler.*
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
import prog8.compiler.functions.FSignature
|
|
||||||
import prog8.compiler.target.*
|
import prog8.compiler.target.*
|
||||||
import prog8.compiler.target.cbm.AssemblyProgram
|
import prog8.compiler.target.cbm.AssemblyProgram
|
||||||
|
import prog8.compiler.target.cbm.loadAsmIncludeFile
|
||||||
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignment
|
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignment
|
||||||
import prog8.compiler.target.cpu6502.codegen.assignment.AssignmentAsmGen
|
import prog8.compiler.target.cpu6502.codegen.assignment.AssignmentAsmGen
|
||||||
import prog8.compilerinterface.*
|
import prog8.compilerinterface.*
|
||||||
import prog8.optimizer.CallGraph
|
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
@ -24,7 +22,7 @@ import kotlin.io.path.Path
|
|||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
|
|
||||||
internal class AsmGen(private val program: Program,
|
class AsmGen(private val program: Program,
|
||||||
val errors: IErrorReporter,
|
val errors: IErrorReporter,
|
||||||
val zeropage: Zeropage,
|
val zeropage: Zeropage,
|
||||||
val options: CompilationOptions,
|
val options: CompilationOptions,
|
||||||
@ -275,7 +273,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
&& variable.datatype != DataType.FLOAT
|
&& variable.datatype != DataType.FLOAT
|
||||||
&& options.zeropage != ZeropageType.DONTUSE) {
|
&& options.zeropage != ZeropageType.DONTUSE) {
|
||||||
try {
|
try {
|
||||||
val errors = ErrorReporter()
|
val errors = ErrorReporter() // TODO why not just use this.errors? then we can clean up the visibility of ErrorReporter class again too
|
||||||
val address = zeropage.allocate(fullName, variable.datatype, null, errors)
|
val address = zeropage.allocate(fullName, variable.datatype, null, errors)
|
||||||
errors.report()
|
errors.report()
|
||||||
out("${variable.name} = $address\t; auto zp ${variable.datatype}")
|
out("${variable.name} = $address\t; auto zp ${variable.datatype}")
|
||||||
@ -500,7 +498,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
return newName
|
return newName
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun asmSymbolName(identifier: IdentifierReference): String {
|
fun asmSymbolName(identifier: IdentifierReference): String {
|
||||||
if(identifier.nameInSource.size==2 && identifier.nameInSource[0]=="prog8_slabs")
|
if(identifier.nameInSource.size==2 && identifier.nameInSource[0]=="prog8_slabs")
|
||||||
return identifier.nameInSource.joinToString(".")
|
return identifier.nameInSource.joinToString(".")
|
||||||
|
|
||||||
@ -531,7 +529,7 @@ internal class AsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun asmVariableName(identifier: IdentifierReference) =
|
fun asmVariableName(identifier: IdentifierReference) =
|
||||||
fixNameSymbols(identifier.nameInSource.joinToString("."))
|
fixNameSymbols(identifier.nameInSource.joinToString("."))
|
||||||
|
|
||||||
private fun getScopedSymbolNameForTarget(actualName: String, target: Statement): MutableList<String> {
|
private fun getScopedSymbolNameForTarget(actualName: String, target: Statement): MutableList<String> {
|
||||||
@ -546,16 +544,16 @@ internal class AsmGen(private val program: Program,
|
|||||||
return scopedName
|
return scopedName
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun asmSymbolName(regs: RegisterOrPair): String =
|
fun asmSymbolName(regs: RegisterOrPair): String =
|
||||||
if (regs in Cx16VirtualRegisters)
|
if (regs in Cx16VirtualRegisters)
|
||||||
"cx16." + regs.toString().lowercase()
|
"cx16." + regs.toString().lowercase()
|
||||||
else
|
else
|
||||||
throw AssemblyError("no symbol name for register $regs")
|
throw AssemblyError("no symbol name for register $regs")
|
||||||
|
|
||||||
internal fun asmSymbolName(name: String) = fixNameSymbols(name)
|
fun asmSymbolName(name: String) = fixNameSymbols(name)
|
||||||
internal fun asmVariableName(name: String) = fixNameSymbols(name)
|
fun asmVariableName(name: String) = fixNameSymbols(name)
|
||||||
internal fun asmSymbolName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
fun asmSymbolName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
||||||
internal fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
fun asmVariableName(name: Iterable<String>) = fixNameSymbols(name.joinToString("."))
|
||||||
|
|
||||||
|
|
||||||
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): String {
|
internal fun loadByteFromPointerIntoA(pointervar: IdentifierReference): String {
|
@ -10,11 +10,11 @@ import prog8.ast.statements.DirectMemoryWrite
|
|||||||
import prog8.ast.statements.FunctionCallStatement
|
import prog8.ast.statements.FunctionCallStatement
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.toHex
|
import prog8.ast.toHex
|
||||||
import prog8.compiler.AssemblyError
|
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compiler.functions.FSignature
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
import prog8.compiler.target.cpu6502.codegen.assignment.*
|
import prog8.compiler.target.cpu6502.codegen.assignment.*
|
||||||
|
import prog8.compilerinterface.FSignature
|
||||||
import prog8.compilerinterface.subroutineFloatEvalResultVar2
|
import prog8.compilerinterface.subroutineFloatEvalResultVar2
|
||||||
|
|
||||||
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
|
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
|
||||||
@ -1532,7 +1532,7 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
AsmAssignSource.fromAstSource(value, program, asmgen)
|
AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
val tgt = AsmAssignTarget.fromRegisters(conv.reg!!, null, program, asmgen)
|
||||||
val assign = AsmAssignment(src, tgt, false, program.memsizer, value.position)
|
val assign = AsmAssignment(src, tgt, false, program.memsizer, value.position)
|
||||||
asmgen.translateNormalAssignment(assign)
|
asmgen.translateNormalAssignment(assign)
|
||||||
}
|
}
|
@ -7,9 +7,9 @@ import prog8.ast.statements.ArrayIndex
|
|||||||
import prog8.ast.statements.BuiltinFunctionStatementPlaceholder
|
import prog8.ast.statements.BuiltinFunctionStatementPlaceholder
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.toHex
|
import prog8.ast.toHex
|
||||||
import prog8.compiler.AssemblyError
|
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
import prog8.compiler.target.AssemblyError
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.subroutineFloatEvalResultVar1
|
import prog8.compilerinterface.subroutineFloatEvalResultVar1
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
@ -8,7 +8,7 @@ import prog8.ast.expressions.IdentifierReference
|
|||||||
import prog8.ast.expressions.RangeExpr
|
import prog8.ast.expressions.RangeExpr
|
||||||
import prog8.ast.statements.ForLoop
|
import prog8.ast.statements.ForLoop
|
||||||
import prog8.ast.toHex
|
import prog8.ast.toHex
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compilerinterface.toConstantIntegerRange
|
import prog8.compilerinterface.toConstantIntegerRange
|
||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
@ -9,7 +9,7 @@ import prog8.ast.statements.InlineAssembly
|
|||||||
import prog8.ast.statements.RegisterOrStatusflag
|
import prog8.ast.statements.RegisterOrStatusflag
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.statements.SubroutineParameter
|
import prog8.ast.statements.SubroutineParameter
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignSource
|
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignSource
|
||||||
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignTarget
|
import prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignTarget
|
@ -6,7 +6,7 @@ import prog8.ast.expressions.IdentifierReference
|
|||||||
import prog8.ast.expressions.NumericLiteralValue
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.PostIncrDecr
|
import prog8.ast.statements.PostIncrDecr
|
||||||
import prog8.ast.toHex
|
import prog8.ast.toHex
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.target.AssemblyError
|
||||||
|
|
||||||
|
|
||||||
internal class PostIncrDecrAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
internal class PostIncrDecrAsmGen(private val program: Program, private val asmgen: AsmGen) {
|
@ -4,8 +4,8 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.AssemblyError
|
|
||||||
import prog8.compiler.IMemSizer
|
import prog8.compiler.IMemSizer
|
||||||
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
||||||
|
|
||||||
|
|
||||||
@ -61,9 +61,9 @@ internal class AsmAssignTarget(val kind: TargetStorageKind,
|
|||||||
throw AssemblyError("unknown dt")
|
throw AssemblyError("unknown dt")
|
||||||
val dt = idt.getOr(DataType.UNDEFINED)
|
val dt = idt.getOr(DataType.UNDEFINED)
|
||||||
when {
|
when {
|
||||||
identifier != null -> AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, assign.definingSubroutine, variableAsmName = asmgen.asmVariableName(identifier!!), origAstTarget = this)
|
identifier != null -> AsmAssignTarget(prog8.compiler.target.cpu6502.codegen.assignment.TargetStorageKind.VARIABLE, program, asmgen, dt, assign.definingSubroutine, variableAsmName = asmgen.asmVariableName(identifier!!), origAstTarget = this)
|
||||||
arrayindexed != null -> AsmAssignTarget(TargetStorageKind.ARRAY, program, asmgen, dt, assign.definingSubroutine, array = arrayindexed, origAstTarget = this)
|
arrayindexed != null -> AsmAssignTarget(prog8.compiler.target.cpu6502.codegen.assignment.TargetStorageKind.ARRAY, program, asmgen, dt, assign.definingSubroutine, array = arrayindexed, origAstTarget = this)
|
||||||
memoryAddress != null -> AsmAssignTarget(TargetStorageKind.MEMORY, program, asmgen, dt, assign.definingSubroutine, memory = memoryAddress, origAstTarget = this)
|
memoryAddress != null -> AsmAssignTarget(prog8.compiler.target.cpu6502.codegen.assignment.TargetStorageKind.MEMORY, program, asmgen, dt, assign.definingSubroutine, memory = memoryAddress, origAstTarget = this)
|
||||||
else -> throw AssemblyError("weird target")
|
else -> throw AssemblyError("weird target")
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,12 +5,12 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.toHex
|
import prog8.ast.toHex
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
import prog8.compiler.functions.builtinFunctionReturnType
|
|
||||||
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
||||||
import prog8.compiler.target.cpu6502.codegen.ExpressionsAsmGen
|
import prog8.compiler.target.cpu6502.codegen.ExpressionsAsmGen
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
|
import prog8.compilerinterface.builtinFunctionReturnType
|
||||||
|
|
||||||
|
|
||||||
internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen,
|
internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen,
|
||||||
@ -21,7 +21,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
|
|
||||||
fun translate(assignment: Assignment) {
|
fun translate(assignment: Assignment) {
|
||||||
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
val target = AsmAssignTarget.fromAstAssignment(assignment, program, asmgen)
|
||||||
val source = AsmAssignSource.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
|
val source = AsmAssignSource.Companion.fromAstSource(assignment.value, program, asmgen).adjustSignedUnsigned(target)
|
||||||
|
|
||||||
val assign = AsmAssignment(source, target, assignment.isAugmentable, program.memsizer, assignment.position)
|
val assign = AsmAssignment(source, target, assignment.isAugmentable, program.memsizer, assignment.position)
|
||||||
target.origAssign = assign
|
target.origAssign = assign
|
||||||
@ -1363,7 +1363,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
// these will be correctly typecasted from a byte to a word value
|
// these will be correctly typecasted from a byte to a word value
|
||||||
if(target.register !in Cx16VirtualRegisters &&
|
if(target.register !in Cx16VirtualRegisters &&
|
||||||
target.register!=RegisterOrPair.AX && target.register!=RegisterOrPair.AY && target.register!=RegisterOrPair.XY) {
|
target.register!=RegisterOrPair.AX && target.register!=RegisterOrPair.AY && target.register!=RegisterOrPair.XY) {
|
||||||
if(target.kind==TargetStorageKind.VARIABLE) {
|
if(target.kind== TargetStorageKind.VARIABLE) {
|
||||||
val parts = target.asmVarname.split('.')
|
val parts = target.asmVarname.split('.')
|
||||||
if (parts.size != 2 || parts[0] != "cx16")
|
if (parts.size != 2 || parts[0] != "cx16")
|
||||||
require(target.datatype in ByteDatatypes)
|
require(target.datatype in ByteDatatypes)
|
||||||
@ -2158,14 +2158,14 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun assignExpressionToRegister(expr: Expression, register: RegisterOrPair) {
|
internal fun assignExpressionToRegister(expr: Expression, register: RegisterOrPair) {
|
||||||
val src = AsmAssignSource.fromAstSource(expr, program, asmgen)
|
val src = AsmAssignSource.Companion.fromAstSource(expr, program, asmgen)
|
||||||
val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen)
|
val tgt = AsmAssignTarget.fromRegisters(register, null, program, asmgen)
|
||||||
val assign = AsmAssignment(src, tgt, false, program.memsizer, expr.position)
|
val assign = AsmAssignment(src, tgt, false, program.memsizer, expr.position)
|
||||||
translateNormalAssignment(assign)
|
translateNormalAssignment(assign)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) {
|
internal fun assignExpressionToVariable(expr: Expression, asmVarName: String, dt: DataType, scope: Subroutine?) {
|
||||||
val src = AsmAssignSource.fromAstSource(expr, program, asmgen)
|
val src = AsmAssignSource.Companion.fromAstSource(expr, program, asmgen)
|
||||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName)
|
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, dt, scope, variableAsmName = asmVarName)
|
||||||
val assign = AsmAssignment(src, tgt, false, program.memsizer, expr.position)
|
val assign = AsmAssignment(src, tgt, false, program.memsizer, expr.position)
|
||||||
translateNormalAssignment(assign)
|
translateNormalAssignment(assign)
|
@ -5,7 +5,7 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.ast.toHex
|
import prog8.ast.toHex
|
||||||
import prog8.compiler.AssemblyError
|
import prog8.compiler.target.AssemblyError
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
||||||
import prog8.compiler.target.cpu6502.codegen.ExpressionsAsmGen
|
import prog8.compiler.target.cpu6502.codegen.ExpressionsAsmGen
|
||||||
@ -246,19 +246,37 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
indexVar!=null -> {
|
indexVar!=null -> {
|
||||||
when (target.datatype) {
|
when (target.datatype) {
|
||||||
in ByteDatatypes -> {
|
in ByteDatatypes -> {
|
||||||
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.A, null, program, asmgen)
|
val tgt =
|
||||||
|
prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignTarget.fromRegisters(
|
||||||
|
RegisterOrPair.A,
|
||||||
|
null,
|
||||||
|
program,
|
||||||
|
asmgen
|
||||||
|
)
|
||||||
val assign = AsmAssignment(target.origAssign.source, tgt, false, program.memsizer, value.position)
|
val assign = AsmAssignment(target.origAssign.source, tgt, false, program.memsizer, value.position)
|
||||||
assignmentAsmGen.translateNormalAssignment(assign)
|
assignmentAsmGen.translateNormalAssignment(assign)
|
||||||
assignmentAsmGen.assignRegisterByte(target, CpuRegister.A)
|
assignmentAsmGen.assignRegisterByte(target, CpuRegister.A)
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
in WordDatatypes -> {
|
||||||
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.AY, null, program, asmgen)
|
val tgt =
|
||||||
|
prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignTarget.fromRegisters(
|
||||||
|
RegisterOrPair.AY,
|
||||||
|
null,
|
||||||
|
program,
|
||||||
|
asmgen
|
||||||
|
)
|
||||||
val assign = AsmAssignment(target.origAssign.source, tgt, false, program.memsizer, value.position)
|
val assign = AsmAssignment(target.origAssign.source, tgt, false, program.memsizer, value.position)
|
||||||
assignmentAsmGen.translateNormalAssignment(assign)
|
assignmentAsmGen.translateNormalAssignment(assign)
|
||||||
assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY)
|
assignmentAsmGen.assignRegisterpairWord(target, RegisterOrPair.AY)
|
||||||
}
|
}
|
||||||
DataType.FLOAT -> {
|
DataType.FLOAT -> {
|
||||||
val tgt = AsmAssignTarget.fromRegisters(RegisterOrPair.FAC1, null, program, asmgen)
|
val tgt =
|
||||||
|
prog8.compiler.target.cpu6502.codegen.assignment.AsmAssignTarget.fromRegisters(
|
||||||
|
RegisterOrPair.FAC1,
|
||||||
|
null,
|
||||||
|
program,
|
||||||
|
asmgen
|
||||||
|
)
|
||||||
val assign = AsmAssignment(target.origAssign.source, tgt, false, program.memsizer, value.position)
|
val assign = AsmAssignment(target.origAssign.source, tgt, false, program.memsizer, value.position)
|
||||||
assignmentAsmGen.translateNormalAssignment(assign)
|
assignmentAsmGen.translateNormalAssignment(assign)
|
||||||
assignmentAsmGen.assignFAC1float(target)
|
assignmentAsmGen.assignFAC1float(target)
|
@ -8,7 +8,7 @@ import java.io.IOException
|
|||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
|
||||||
internal object CX16MachineDefinition: IMachineDefinition {
|
object CX16MachineDefinition: IMachineDefinition {
|
||||||
|
|
||||||
override val cpu = CpuType.CPU65c02
|
override val cpu = CpuType.CPU65c02
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ internal object CX16MachineDefinition: IMachineDefinition {
|
|||||||
"rmb", "smb", "stp", "wai")
|
"rmb", "smb", "stp", "wai")
|
||||||
|
|
||||||
|
|
||||||
internal class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
|
class CX16Zeropage(options: CompilationOptions) : Zeropage(options) {
|
||||||
|
|
||||||
override val SCRATCH_B1 = 0x7a // temp storage for a single byte
|
override val SCRATCH_B1 = 0x7a // temp storage for a single byte
|
||||||
override val SCRATCH_REG = 0x7b // temp storage for a register, must be B1+1
|
override val SCRATCH_REG = 0x7b // temp storage for a register, must be B1+1
|
21
codeGeneration/test/TestCodeGeneration.kt
Normal file
21
codeGeneration/test/TestCodeGeneration.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package prog8tests
|
||||||
|
|
||||||
|
import org.junit.jupiter.api.Disabled
|
||||||
|
import org.junit.jupiter.api.Test
|
||||||
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
import kotlin.test.assertEquals
|
||||||
|
import kotlin.test.assertFalse
|
||||||
|
import kotlin.test.assertTrue
|
||||||
|
import kotlin.test.fail
|
||||||
|
|
||||||
|
|
||||||
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
|
class TestCodeGeneration {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Disabled("for future implementation")
|
||||||
|
fun dummy() {
|
||||||
|
fail("dummy")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -9,6 +9,7 @@ import prog8.ast.expressions.TypecastExpression
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
|
import prog8.compilerinterface.CallGraph
|
||||||
import prog8.compilerinterface.ICompilationTarget
|
import prog8.compilerinterface.ICompilationTarget
|
||||||
import prog8.compilerinterface.IErrorReporter
|
import prog8.compilerinterface.IErrorReporter
|
||||||
import prog8.compilerinterface.isInRegularRAMof
|
import prog8.compilerinterface.isInRegularRAMof
|
||||||
|
@ -21,6 +21,7 @@ dependencies {
|
|||||||
implementation project(':compilerInterfaces')
|
implementation project(':compilerInterfaces')
|
||||||
implementation project(':codeOptimizers')
|
implementation project(':codeOptimizers')
|
||||||
implementation project(':compilerAst')
|
implementation project(':compilerAst')
|
||||||
|
implementation project(':codeGeneration')
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
|
||||||
// implementation "org.jetbrains.kotlin:kotlin-reflect"
|
// implementation "org.jetbrains.kotlin:kotlin-reflect"
|
||||||
implementation 'org.jetbrains.kotlinx:kotlinx-cli:0.3.3'
|
implementation 'org.jetbrains.kotlinx:kotlinx-cli:0.3.3'
|
||||||
|
@ -24,5 +24,6 @@
|
|||||||
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
|
<orderEntry type="library" name="michael.bull.kotlin.result.jvm" level="project" />
|
||||||
<orderEntry type="module" module-name="codeOptimizers" />
|
<orderEntry type="module" module-name="codeOptimizers" />
|
||||||
<orderEntry type="module" module-name="compilerInterfaces" />
|
<orderEntry type="module" module-name="compilerInterfaces" />
|
||||||
|
<orderEntry type="module" module-name="codeGeneration" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
@ -1,3 +0,0 @@
|
|||||||
package prog8.compiler
|
|
||||||
|
|
||||||
internal class AssemblyError(msg: String) : RuntimeException(msg)
|
|
@ -10,7 +10,6 @@ import prog8.ast.expressions.Expression
|
|||||||
import prog8.ast.expressions.NumericLiteralValue
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.Directive
|
import prog8.ast.statements.Directive
|
||||||
import prog8.compiler.astprocessing.*
|
import prog8.compiler.astprocessing.*
|
||||||
import prog8.compiler.functions.*
|
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
||||||
@ -18,12 +17,8 @@ import prog8.compilerinterface.*
|
|||||||
import prog8.optimizer.*
|
import prog8.optimizer.*
|
||||||
import prog8.parser.ParseError
|
import prog8.parser.ParseError
|
||||||
import prog8.parser.ParsingFailedError
|
import prog8.parser.ParsingFailedError
|
||||||
import prog8.parser.SourceCode
|
|
||||||
import prog8.parser.SourceCode.Companion.libraryFilePrefix
|
|
||||||
import java.io.File
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
import kotlin.io.path.isRegularFile
|
|
||||||
import kotlin.io.path.nameWithoutExtension
|
import kotlin.io.path.nameWithoutExtension
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
@ -351,20 +346,6 @@ fun printAst(programAst: Program) {
|
|||||||
println()
|
println()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun loadAsmIncludeFile(filename: String, source: SourceCode): Result<String, NoSuchFileException> {
|
|
||||||
return if (filename.startsWith(libraryFilePrefix)) {
|
|
||||||
return runCatching {
|
|
||||||
SourceCode.Resource("/prog8lib/${filename.substring(libraryFilePrefix.length)}").readText()
|
|
||||||
}.mapError { NoSuchFileException(File(filename)) }
|
|
||||||
} else {
|
|
||||||
val sib = Path(source.origin).resolveSibling(filename)
|
|
||||||
if (sib.isRegularFile())
|
|
||||||
Ok(SourceCode.File(sib).readText())
|
|
||||||
else
|
|
||||||
Ok(SourceCode.File(Path(filename)).readText())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal fun asmGeneratorFor(
|
internal fun asmGeneratorFor(
|
||||||
compTarget: ICompilationTarget,
|
compTarget: ICompilationTarget,
|
||||||
program: Program,
|
program: Program,
|
||||||
|
@ -1,48 +0,0 @@
|
|||||||
package prog8.compiler
|
|
||||||
|
|
||||||
import prog8.ast.base.Position
|
|
||||||
import prog8.compilerinterface.IErrorReporter
|
|
||||||
|
|
||||||
|
|
||||||
internal class ErrorReporter: IErrorReporter {
|
|
||||||
private enum class MessageSeverity {
|
|
||||||
WARNING,
|
|
||||||
ERROR
|
|
||||||
}
|
|
||||||
private class CompilerMessage(val severity: MessageSeverity, val message: String, val position: Position)
|
|
||||||
|
|
||||||
private val messages = mutableListOf<CompilerMessage>()
|
|
||||||
private val alreadyReportedMessages = mutableSetOf<String>()
|
|
||||||
|
|
||||||
override fun err(msg: String, position: Position) {
|
|
||||||
messages.add(CompilerMessage(MessageSeverity.ERROR, msg, position))
|
|
||||||
}
|
|
||||||
override fun warn(msg: String, position: Position) {
|
|
||||||
messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position))
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun report() {
|
|
||||||
var numErrors = 0
|
|
||||||
var numWarnings = 0
|
|
||||||
messages.forEach {
|
|
||||||
when(it.severity) {
|
|
||||||
MessageSeverity.ERROR -> System.err.print("\u001b[91m") // bright red
|
|
||||||
MessageSeverity.WARNING -> System.err.print("\u001b[93m") // bright yellow
|
|
||||||
}
|
|
||||||
val msg = "${it.position.toClickableStr()} ${it.severity} ${it.message}".trim()
|
|
||||||
if(msg !in alreadyReportedMessages) {
|
|
||||||
System.err.println(msg)
|
|
||||||
alreadyReportedMessages.add(msg)
|
|
||||||
when(it.severity) {
|
|
||||||
MessageSeverity.WARNING -> numWarnings++
|
|
||||||
MessageSeverity.ERROR -> numErrors++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
System.err.print("\u001b[0m") // reset color
|
|
||||||
}
|
|
||||||
messages.clear()
|
|
||||||
finalizeNumErrors(numErrors, numWarnings)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun noErrors() = messages.none { it.severity==MessageSeverity.ERROR }
|
|
||||||
}
|
|
@ -8,12 +8,7 @@ import prog8.ast.base.*
|
|||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compilerinterface.CompilationOptions
|
import prog8.compilerinterface.*
|
||||||
import prog8.compilerinterface.ICompilationTarget
|
|
||||||
import prog8.compilerinterface.IErrorReporter
|
|
||||||
import prog8.compilerinterface.ZeropageType
|
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
import prog8.compiler.functions.builtinFunctionReturnType
|
|
||||||
import java.io.CharConversionException
|
import java.io.CharConversionException
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -4,9 +4,9 @@ import prog8.ast.base.Position
|
|||||||
import prog8.ast.expressions.StringLiteralValue
|
import prog8.ast.expressions.StringLiteralValue
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.ICompilationTarget
|
import prog8.compilerinterface.ICompilationTarget
|
||||||
import prog8.compilerinterface.IErrorReporter
|
import prog8.compilerinterface.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
|
|
||||||
internal class AstIdentifiersChecker(private val errors: IErrorReporter, private val compTarget: ICompilationTarget) : IAstVisitor {
|
internal class AstIdentifiersChecker(private val errors: IErrorReporter, private val compTarget: ICompilationTarget) : IAstVisitor {
|
||||||
private var blocks = mutableMapOf<String, Block>()
|
private var blocks = mutableMapOf<String, Block>()
|
||||||
|
@ -10,8 +10,8 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.IErrorReporter
|
import prog8.compilerinterface.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
|
|
||||||
|
|
||||||
internal class StatementReorderer(val program: Program, val errors: IErrorReporter) : AstWalker() {
|
internal class StatementReorderer(val program: Program, val errors: IErrorReporter) : AstWalker() {
|
||||||
|
@ -8,8 +8,8 @@ import prog8.ast.expressions.*
|
|||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.IErrorReporter
|
import prog8.compilerinterface.IErrorReporter
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
|
|
||||||
|
|
||||||
class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalker() {
|
class TypecastsAdder(val program: Program, val errors: IErrorReporter) : AstWalker() {
|
||||||
|
@ -8,8 +8,8 @@ import prog8.ast.expressions.FunctionCall
|
|||||||
import prog8.ast.expressions.TypecastExpression
|
import prog8.ast.expressions.TypecastExpression
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.CompilerException
|
import prog8.compilerinterface.CompilerException
|
||||||
import prog8.compiler.functions.BuiltinFunctions
|
|
||||||
|
|
||||||
class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
|
class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
|
||||||
|
|
||||||
|
@ -14,19 +14,17 @@ import prog8.ast.expressions.AddressOf
|
|||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.expressions.NumericLiteralValue
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.compiler.*
|
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition
|
import prog8.compiler.target.c64.C64MachineDefinition
|
||||||
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
import prog8.compiler.target.cpu6502.codegen.AsmGen
|
||||||
import prog8.compilerinterface.CompilationOptions
|
import prog8.compilerinterface.*
|
||||||
import prog8.compilerinterface.LauncherType
|
|
||||||
import prog8.compilerinterface.OutputType
|
|
||||||
import prog8.compilerinterface.ZeropageType
|
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import prog8tests.helpers.DummyFunctions
|
import prog8tests.ast.helpers.DummyFunctions
|
||||||
import prog8tests.helpers.DummyMemsizer
|
import prog8tests.ast.helpers.DummyMemsizer
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
// TODO move to codegen project, readjust symbol protection levels
|
||||||
|
|
||||||
|
|
||||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||||
class TestAsmGen6502 {
|
class TestAsmGen6502 {
|
||||||
|
@ -13,6 +13,7 @@ import prog8.compilerinterface.IErrorReporter
|
|||||||
import prog8.compiler.ModuleImporter
|
import prog8.compiler.ModuleImporter
|
||||||
import prog8.parser.ParseError
|
import prog8.parser.ParseError
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
|
import prog8tests.ast.helpers.*
|
||||||
import prog8tests.helpers.*
|
import prog8tests.helpers.*
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.*
|
||||||
import kotlin.test.assertContains
|
import kotlin.test.assertContains
|
||||||
|
@ -5,7 +5,7 @@ import org.junit.jupiter.api.TestInstance
|
|||||||
import prog8.ast.statements.Block
|
import prog8.ast.statements.Block
|
||||||
import prog8.ast.statements.Subroutine
|
import prog8.ast.statements.Subroutine
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.optimizer.CallGraph
|
import prog8.compilerinterface.CallGraph
|
||||||
import prog8tests.helpers.assertSuccess
|
import prog8tests.helpers.assertSuccess
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
@ -8,6 +8,10 @@ import prog8.compilerinterface.ICompilationTarget
|
|||||||
import prog8.compiler.compileProgram
|
import prog8.compiler.compileProgram
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
|
import prog8tests.ast.helpers.assumeDirectory
|
||||||
|
import prog8tests.ast.helpers.mapCombinations
|
||||||
|
import prog8tests.ast.helpers.outputDir
|
||||||
|
import prog8tests.ast.helpers.workingDir
|
||||||
import prog8tests.helpers.*
|
import prog8tests.helpers.*
|
||||||
import kotlin.io.path.absolute
|
import kotlin.io.path.absolute
|
||||||
import kotlin.io.path.exists
|
import kotlin.io.path.exists
|
||||||
|
@ -8,6 +8,7 @@ import prog8.ast.expressions.StringLiteralValue
|
|||||||
import prog8.ast.statements.FunctionCallStatement
|
import prog8.ast.statements.FunctionCallStatement
|
||||||
import prog8.ast.statements.Label
|
import prog8.ast.statements.Label
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
|
import prog8tests.ast.helpers.*
|
||||||
import prog8tests.helpers.*
|
import prog8tests.helpers.*
|
||||||
import kotlin.io.path.name
|
import kotlin.io.path.name
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
@ -13,6 +13,7 @@ import prog8.compilerinterface.size
|
|||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
import prog8.compilerinterface.toConstantIntegerRange
|
import prog8.compilerinterface.toConstantIntegerRange
|
||||||
|
import prog8tests.ast.helpers.mapCombinations
|
||||||
import prog8tests.helpers.*
|
import prog8tests.helpers.*
|
||||||
import kotlin.test.assertContains
|
import kotlin.test.assertContains
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
@ -6,6 +6,10 @@ import org.junit.jupiter.api.Test
|
|||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import prog8.compiler.compileProgram
|
import prog8.compiler.compileProgram
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
|
import prog8tests.ast.helpers.assumeReadableFile
|
||||||
|
import prog8tests.ast.helpers.fixturesDir
|
||||||
|
import prog8tests.ast.helpers.outputDir
|
||||||
|
import prog8tests.ast.helpers.workingDir
|
||||||
import prog8tests.helpers.*
|
import prog8tests.helpers.*
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.absolute
|
import kotlin.io.path.absolute
|
||||||
|
@ -3,14 +3,14 @@ package prog8tests
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import prog8.ast.internedStringsModuleName
|
import prog8.ast.internedStringsModuleName
|
||||||
import prog8.compiler.ErrorReporter
|
|
||||||
import prog8.compilerinterface.ZeropageType
|
import prog8.compilerinterface.ZeropageType
|
||||||
import prog8.compiler.determineCompilationOptions
|
import prog8.compiler.determineCompilationOptions
|
||||||
import prog8.compiler.parseImports
|
import prog8.compiler.parseImports
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
|
import prog8.compilerinterface.ErrorReporter
|
||||||
|
import prog8tests.ast.helpers.outputDir
|
||||||
import prog8tests.helpers.assertSuccess
|
import prog8tests.helpers.assertSuccess
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
import prog8tests.helpers.outputDir
|
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@ -15,8 +15,8 @@ import prog8.ast.statements.*
|
|||||||
import prog8.compilerinterface.isInRegularRAMof
|
import prog8.compilerinterface.isInRegularRAMof
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import prog8tests.helpers.DummyFunctions
|
import prog8tests.ast.helpers.DummyFunctions
|
||||||
import prog8tests.helpers.DummyMemsizer
|
import prog8tests.ast.helpers.DummyMemsizer
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@ package prog8tests
|
|||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import prog8.ast.base.DataType
|
import prog8.ast.base.DataType
|
||||||
import prog8.compiler.*
|
|
||||||
import prog8.compiler.target.C64Target
|
import prog8.compiler.target.C64Target
|
||||||
import prog8.compiler.target.Cx16Target
|
import prog8.compiler.target.Cx16Target
|
||||||
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package prog8tests.helpers
|
package prog8tests.helpers
|
||||||
|
|
||||||
import prog8.compiler.*
|
import prog8.compiler.*
|
||||||
|
import prog8.compilerinterface.ErrorReporter
|
||||||
import prog8.compilerinterface.ICompilationTarget
|
import prog8.compilerinterface.ICompilationTarget
|
||||||
import prog8.compilerinterface.IErrorReporter
|
import prog8.compilerinterface.IErrorReporter
|
||||||
|
import prog8tests.ast.helpers.assumeReadableFile
|
||||||
|
import prog8tests.ast.helpers.outputDir
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.name
|
import kotlin.io.path.name
|
||||||
import kotlin.test.assertFalse
|
import kotlin.test.assertFalse
|
||||||
@ -28,7 +31,7 @@ internal fun compileFile(
|
|||||||
optimize: Boolean,
|
optimize: Boolean,
|
||||||
fileDir: Path,
|
fileDir: Path,
|
||||||
fileName: String,
|
fileName: String,
|
||||||
outputDir: Path = prog8tests.helpers.outputDir,
|
outputDir: Path = prog8tests.ast.helpers.outputDir,
|
||||||
errors: IErrorReporter? = null,
|
errors: IErrorReporter? = null,
|
||||||
writeAssembly: Boolean = true
|
writeAssembly: Boolean = true
|
||||||
) : CompilationResult {
|
) : CompilationResult {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests
|
package prog8tests.ast
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
@ -9,8 +9,8 @@ import prog8.ast.internedStringsModuleName
|
|||||||
import prog8.parser.ParseError
|
import prog8.parser.ParseError
|
||||||
import prog8.parser.Prog8Parser.parseModule
|
import prog8.parser.Prog8Parser.parseModule
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import prog8tests.helpers.DummyFunctions
|
import prog8tests.ast.helpers.DummyFunctions
|
||||||
import prog8tests.helpers.DummyMemsizer
|
import prog8tests.ast.helpers.DummyMemsizer
|
||||||
import kotlin.test.assertContains
|
import kotlin.test.assertContains
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests
|
package prog8tests.ast
|
||||||
|
|
||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
@ -16,9 +16,9 @@ import prog8.ast.statements.*
|
|||||||
import prog8.parser.ParseError
|
import prog8.parser.ParseError
|
||||||
import prog8.parser.Prog8Parser.parseModule
|
import prog8.parser.Prog8Parser.parseModule
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import prog8tests.helpers.assumeNotExists
|
import prog8tests.ast.helpers.assumeNotExists
|
||||||
import prog8tests.helpers.assumeReadableFile
|
import prog8tests.ast.helpers.assumeReadableFile
|
||||||
import prog8tests.helpers.fixturesDir
|
import prog8tests.ast.helpers.fixturesDir
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
import kotlin.io.path.isRegularFile
|
import kotlin.io.path.isRegularFile
|
||||||
import kotlin.io.path.name
|
import kotlin.io.path.name
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests
|
package prog8tests.ast
|
||||||
|
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
import org.hamcrest.core.StringStartsWith
|
import org.hamcrest.core.StringStartsWith
|
||||||
@ -6,10 +6,10 @@ import org.junit.jupiter.api.Test
|
|||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import prog8.parser.SourceCode.Companion.libraryFilePrefix
|
import prog8.parser.SourceCode.Companion.libraryFilePrefix
|
||||||
import prog8tests.helpers.assumeNotExists
|
import prog8tests.ast.helpers.assumeNotExists
|
||||||
import prog8tests.helpers.assumeReadableFile
|
import prog8tests.ast.helpers.assumeReadableFile
|
||||||
import prog8tests.helpers.fixturesDir
|
import prog8tests.ast.helpers.fixturesDir
|
||||||
import prog8tests.helpers.resourcesDir
|
import prog8tests.ast.helpers.resourcesDir
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests
|
package prog8tests.ast
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests.ast
|
package prog8tests.ast.ast
|
||||||
|
|
||||||
|
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
@ -12,8 +12,8 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.Position
|
import prog8.ast.base.Position
|
||||||
import prog8.ast.internedStringsModuleName
|
import prog8.ast.internedStringsModuleName
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import prog8tests.helpers.DummyFunctions
|
import prog8tests.ast.helpers.DummyFunctions
|
||||||
import prog8tests.helpers.DummyMemsizer
|
import prog8tests.ast.helpers.DummyMemsizer
|
||||||
import kotlin.test.assertContains
|
import kotlin.test.assertContains
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
import kotlin.test.assertSame
|
import kotlin.test.assertSame
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests.helpers
|
package prog8tests.ast.helpers
|
||||||
|
|
||||||
import prog8.ast.IBuiltinFunctions
|
import prog8.ast.IBuiltinFunctions
|
||||||
import prog8.ast.base.Position
|
import prog8.ast.base.Position
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests.helpers
|
package prog8tests.ast.helpers
|
||||||
|
|
||||||
import prog8.ast.base.DataType
|
import prog8.ast.base.DataType
|
||||||
import prog8.compiler.IMemSizer
|
import prog8.compiler.IMemSizer
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests.helpers
|
package prog8tests.ast.helpers
|
||||||
|
|
||||||
fun <A, B, R> mapCombinations(dim1: Iterable<A>, dim2: Iterable<B>, combine2: (A, B) -> R) =
|
fun <A, B, R> mapCombinations(dim1: Iterable<A>, dim2: Iterable<B>, combine2: (A, B) -> R) =
|
||||||
sequence {
|
sequence {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests.helpers
|
package prog8tests.ast.helpers
|
||||||
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.*
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package prog8tests
|
package prog8tests.ast
|
||||||
|
|
||||||
import org.hamcrest.MatcherAssert.assertThat
|
import org.hamcrest.MatcherAssert.assertThat
|
||||||
import org.hamcrest.Matchers.`is`
|
import org.hamcrest.Matchers.`is`
|
||||||
import org.junit.jupiter.api.Nested
|
import org.junit.jupiter.api.Nested
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
import prog8tests.helpers.*
|
import prog8tests.ast.helpers.*
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
import kotlin.io.path.div
|
import kotlin.io.path.div
|
||||||
import kotlin.test.assertFailsWith
|
import kotlin.test.assertFailsWith
|
||||||
|
@ -1,14 +1,12 @@
|
|||||||
package prog8.compiler.functions
|
package prog8.compilerinterface
|
||||||
|
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.base.*
|
import prog8.ast.base.*
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
import prog8.compilerinterface.CompilerException
|
|
||||||
import prog8.compiler.IMemSizer
|
import prog8.compiler.IMemSizer
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
|
||||||
|
|
||||||
class FParam(val name: String, val possibleDatatypes: Array<DataType>)
|
class FParam(val name: String, val possibleDatatypes: Array<DataType>)
|
||||||
|
|
||||||
|
|
||||||
@ -27,11 +25,11 @@ class CallConvention(val params: List<ParamConvention>, val returns: ReturnConve
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
val returnConv =
|
val returnConv =
|
||||||
when {
|
when {
|
||||||
returns.reg!=null -> returns.reg.toString()
|
returns.reg!=null -> returns.reg.toString()
|
||||||
returns.floatFac1 -> "floatFAC1"
|
returns.floatFac1 -> "floatFAC1"
|
||||||
else -> "<no returnvalue>"
|
else -> "<no returnvalue>"
|
||||||
}
|
}
|
||||||
return "CallConvention[" + paramConvs.joinToString() + " ; returns: $returnConv]"
|
return "CallConvention[" + paramConvs.joinToString() + " ; returns: $returnConv]"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,7 +50,7 @@ class FSignature(val name: String,
|
|||||||
else -> {
|
else -> {
|
||||||
val paramType = actualParamTypes.first()
|
val paramType = actualParamTypes.first()
|
||||||
if(pure)
|
if(pure)
|
||||||
// return type depends on arg type
|
// return type depends on arg type
|
||||||
when(paramType) {
|
when(paramType) {
|
||||||
DataType.UBYTE, DataType.BYTE -> ReturnConvention(paramType, RegisterOrPair.A, false)
|
DataType.UBYTE, DataType.BYTE -> ReturnConvention(paramType, RegisterOrPair.A, false)
|
||||||
DataType.UWORD, DataType.WORD -> ReturnConvention(paramType, RegisterOrPair.AY, false)
|
DataType.UWORD, DataType.WORD -> ReturnConvention(paramType, RegisterOrPair.AY, false)
|
||||||
@ -87,9 +85,12 @@ class FSignature(val name: String,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Suppress("UNUSED_ANONYMOUS_PARAMETER")
|
@Suppress("UNUSED_ANONYMOUS_PARAMETER")
|
||||||
private val functionSignatures: List<FSignature> = listOf(
|
private val functionSignatures: List<FSignature> = listOf(
|
||||||
// this set of function have no return value and operate in-place:
|
// this set of function have no return value and operate in-place:
|
||||||
FSignature("rol" , false, listOf(FParam("item", arrayOf(DataType.UBYTE, DataType.UWORD))), null),
|
FSignature("rol" , false, listOf(FParam("item", arrayOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
FSignature("ror" , false, listOf(FParam("item", arrayOf(DataType.UBYTE, DataType.UWORD))), null),
|
FSignature("ror" , false, listOf(FParam("item", arrayOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
FSignature("rol2" , false, listOf(FParam("item", arrayOf(DataType.UBYTE, DataType.UWORD))), null),
|
FSignature("rol2" , false, listOf(FParam("item", arrayOf(DataType.UBYTE, DataType.UWORD))), null),
|
||||||
@ -97,14 +98,14 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
FSignature("sort" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
FSignature("sort" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
||||||
FSignature("reverse" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
FSignature("reverse" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
||||||
FSignature("cmp" , false, listOf(FParam("value1", IntegerDatatypes), FParam("value2", NumericDatatypes)), null),
|
FSignature("cmp" , false, listOf(FParam("value1", IntegerDatatypes), FParam("value2", NumericDatatypes)), null),
|
||||||
// these few have a return value depending on the argument(s):
|
// these few have a return value depending on the argument(s):
|
||||||
FSignature("max" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinMax) }, // type depends on args
|
FSignature("max" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinMax) }, // type depends on args
|
||||||
FSignature("min" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinMin) }, // type depends on args
|
FSignature("min" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinMin) }, // type depends on args
|
||||||
FSignature("sum" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinSum) }, // type depends on args
|
FSignature("sum" , true, listOf(FParam("values", ArrayDatatypes)), null) { a, p, prg, ct -> collectionArg(a, p, prg, ::builtinSum) }, // type depends on args
|
||||||
FSignature("abs" , true, listOf(FParam("value", NumericDatatypes)), null, ::builtinAbs), // type depends on argument
|
FSignature("abs" , true, listOf(FParam("value", NumericDatatypes)), null, ::builtinAbs), // type depends on argument
|
||||||
FSignature("len" , true, listOf(FParam("values", IterableDatatypes)), null, ::builtinLen), // type is UBYTE or UWORD depending on actual length
|
FSignature("len" , true, listOf(FParam("values", IterableDatatypes)), null, ::builtinLen), // type is UBYTE or UWORD depending on actual length
|
||||||
FSignature("sizeof" , true, listOf(FParam("object", DataType.values())), DataType.UBYTE, ::builtinSizeof),
|
FSignature("sizeof" , true, listOf(FParam("object", DataType.values())), DataType.UBYTE, ::builtinSizeof),
|
||||||
// normal functions follow:
|
// normal functions follow:
|
||||||
FSignature("sgn" , true, listOf(FParam("value", NumericDatatypes)), DataType.BYTE, ::builtinSgn ),
|
FSignature("sgn" , true, listOf(FParam("value", NumericDatatypes)), DataType.BYTE, ::builtinSgn ),
|
||||||
FSignature("sin" , true, listOf(FParam("rads", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg, ct -> oneDoubleArg(a, p, prg, Math::sin) },
|
FSignature("sin" , true, listOf(FParam("rads", arrayOf(DataType.FLOAT))), DataType.FLOAT) { a, p, prg, ct -> oneDoubleArg(a, p, prg, Math::sin) },
|
||||||
FSignature("sin8" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.BYTE, ::builtinSin8 ),
|
FSignature("sin8" , true, listOf(FParam("angle8", arrayOf(DataType.UBYTE))), DataType.BYTE, ::builtinSin8 ),
|
||||||
@ -144,7 +145,7 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
FSignature("callfar" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
FSignature("callfar" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
||||||
FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
FSignature("callrom" , false, listOf(FParam("bank", arrayOf(DataType.UBYTE)), FParam("address", arrayOf(DataType.UWORD)), FParam("arg", arrayOf(DataType.UWORD))), null),
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
val BuiltinFunctions = functionSignatures.associateBy { it.name }
|
||||||
|
|
||||||
@ -297,7 +298,7 @@ private fun builtinSizeof(args: List<Expression>, position: Position, program: P
|
|||||||
val dt = args[0].inferType(program)
|
val dt = args[0].inferType(program)
|
||||||
if(dt.isKnown) {
|
if(dt.isKnown) {
|
||||||
val target = (args[0] as IdentifierReference).targetStatement(program)
|
val target = (args[0] as IdentifierReference).targetStatement(program)
|
||||||
?: throw CannotEvaluateException("sizeof", "no target")
|
?: throw CannotEvaluateException("sizeof", "no target")
|
||||||
|
|
||||||
return when {
|
return when {
|
||||||
dt.isArray -> {
|
dt.isArray -> {
|
||||||
@ -328,7 +329,7 @@ private fun builtinLen(args: List<Expression>, position: Position, program: Prog
|
|||||||
if(args[0] !is IdentifierReference)
|
if(args[0] !is IdentifierReference)
|
||||||
throw SyntaxError("len argument should be an identifier", position)
|
throw SyntaxError("len argument should be an identifier", position)
|
||||||
val target = (args[0] as IdentifierReference).targetVarDecl(program)
|
val target = (args[0] as IdentifierReference).targetVarDecl(program)
|
||||||
?: throw CannotEvaluateException("len", "no target vardecl")
|
?: throw CannotEvaluateException("len", "no target vardecl")
|
||||||
|
|
||||||
return when(target.datatype) {
|
return when(target.datatype) {
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F -> {
|
||||||
@ -440,10 +441,10 @@ private fun builtinSgn(args: List<Expression>, position: Position, program: Prog
|
|||||||
private fun numericLiteral(value: Number, position: Position): NumericLiteralValue {
|
private fun numericLiteral(value: Number, position: Position): NumericLiteralValue {
|
||||||
val floatNum=value.toDouble()
|
val floatNum=value.toDouble()
|
||||||
val tweakedValue: Number =
|
val tweakedValue: Number =
|
||||||
if(floatNum== floor(floatNum) && (floatNum>=-32768 && floatNum<=65535))
|
if(floatNum== floor(floatNum) && (floatNum>=-32768 && floatNum<=65535))
|
||||||
floatNum.toInt() // we have an integer disguised as a float.
|
floatNum.toInt() // we have an integer disguised as a float.
|
||||||
else
|
else
|
||||||
floatNum
|
floatNum
|
||||||
|
|
||||||
return when(tweakedValue) {
|
return when(tweakedValue) {
|
||||||
is Int -> NumericLiteralValue.optimalInteger(value.toInt(), position)
|
is Int -> NumericLiteralValue.optimalInteger(value.toInt(), position)
|
@ -1,4 +1,4 @@
|
|||||||
package prog8.optimizer
|
package prog8.compilerinterface
|
||||||
|
|
||||||
import prog8.ast.Module
|
import prog8.ast.Module
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
@ -10,7 +10,6 @@ import prog8.ast.expressions.FunctionCall
|
|||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.IAstVisitor
|
import prog8.ast.walk.IAstVisitor
|
||||||
import prog8.compilerinterface.IErrorReporter
|
|
||||||
|
|
||||||
|
|
||||||
class CallGraph(private val program: Program) : IAstVisitor {
|
class CallGraph(private val program: Program) : IAstVisitor {
|
@ -14,3 +14,47 @@ interface IErrorReporter {
|
|||||||
throw ParsingFailedError("There are $numErrors errors and $numWarnings warnings.")
|
throw ParsingFailedError("There are $numErrors errors and $numWarnings warnings.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class ErrorReporter: IErrorReporter {
|
||||||
|
private enum class MessageSeverity {
|
||||||
|
WARNING,
|
||||||
|
ERROR
|
||||||
|
}
|
||||||
|
private class CompilerMessage(val severity: MessageSeverity, val message: String, val position: Position)
|
||||||
|
|
||||||
|
private val messages = mutableListOf<CompilerMessage>()
|
||||||
|
private val alreadyReportedMessages = mutableSetOf<String>()
|
||||||
|
|
||||||
|
override fun err(msg: String, position: Position) {
|
||||||
|
messages.add(CompilerMessage(MessageSeverity.ERROR, msg, position))
|
||||||
|
}
|
||||||
|
override fun warn(msg: String, position: Position) {
|
||||||
|
messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun report() {
|
||||||
|
var numErrors = 0
|
||||||
|
var numWarnings = 0
|
||||||
|
messages.forEach {
|
||||||
|
when(it.severity) {
|
||||||
|
MessageSeverity.ERROR -> System.err.print("\u001b[91m") // bright red
|
||||||
|
MessageSeverity.WARNING -> System.err.print("\u001b[93m") // bright yellow
|
||||||
|
}
|
||||||
|
val msg = "${it.position.toClickableStr()} ${it.severity} ${it.message}".trim()
|
||||||
|
if(msg !in alreadyReportedMessages) {
|
||||||
|
System.err.println(msg)
|
||||||
|
alreadyReportedMessages.add(msg)
|
||||||
|
when(it.severity) {
|
||||||
|
MessageSeverity.WARNING -> numWarnings++
|
||||||
|
MessageSeverity.ERROR -> numErrors++
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.err.print("\u001b[0m") // reset color
|
||||||
|
}
|
||||||
|
messages.clear()
|
||||||
|
finalizeNumErrors(numErrors, numWarnings)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun noErrors() = messages.none { it.severity==MessageSeverity.ERROR }
|
||||||
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests
|
package prog8tests.interfaces
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package prog8tests
|
package prog8tests.interfaces
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import org.junit.jupiter.api.TestInstance
|
import org.junit.jupiter.api.TestInstance
|
||||||
|
@ -26,7 +26,6 @@ Future
|
|||||||
- add a flood fill routine to gfx2?
|
- add a flood fill routine to gfx2?
|
||||||
- add a diskio.f_seek() routine for the Cx16 that uses its seek dos api?
|
- add a diskio.f_seek() routine for the Cx16 that uses its seek dos api?
|
||||||
- make it possible for diskio to read and write from more than one file at the same time (= use multiple io channels)?
|
- make it possible for diskio to read and write from more than one file at the same time (= use multiple io channels)?
|
||||||
- refactor the asmgen into own project submodule
|
|
||||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_``
|
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_``
|
||||||
- [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ...
|
- [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ...
|
||||||
Perhaps replace all uses of .proc/.pend by .block/.bend will fix that?
|
Perhaps replace all uses of .proc/.pend by .block/.bend will fix that?
|
||||||
|
@ -2,6 +2,7 @@ include ':parser'
|
|||||||
include ':compilerInterfaces'
|
include ':compilerInterfaces'
|
||||||
include ':compilerAst'
|
include ':compilerAst'
|
||||||
include ':codeOptimizers'
|
include ':codeOptimizers'
|
||||||
|
include ':codeGeneration'
|
||||||
include ':compiler'
|
include ':compiler'
|
||||||
include ':dbusCompilerService'
|
include ':dbusCompilerService'
|
||||||
include ':httpCompilerService'
|
include ':httpCompilerService'
|
||||||
|
Loading…
Reference in New Issue
Block a user