From bc37097df231fa995d7aab1db75f10d1b14d1358 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 9 Feb 2021 18:38:44 +0100 Subject: [PATCH] reducing dependencies --- .../compiler/BeforeAsmGenerationAstChanger.kt | 4 +- compiler/src/prog8/compiler/Compiler.kt | 22 ++++---- .../compiler/astprocessing/AstChecker.kt | 7 +-- .../compiler/astprocessing/AstExtensions.kt | 13 ++--- .../astprocessing/AstIdentifiersChecker.kt | 14 ++--- .../compiler/target/ICompilationTarget.kt | 2 +- compiler/test/UnitTests.kt | 53 ++++++++----------- 7 files changed, 53 insertions(+), 62 deletions(-) diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index caa7cf0bd..dd890256a 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -11,7 +11,7 @@ import prog8.ast.walk.IAstModification import prog8.compiler.target.ICompilationTarget -internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorReporter) : AstWalker() { +internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorReporter, private val compTarget: ICompilationTarget) : AstWalker() { private val noModifications = emptyList() @@ -38,7 +38,7 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: E // But it can only be done if the target variable IS NOT OCCURRING AS AN OPERAND ITSELF. if(!assignment.isAugmentable && assignment.target.identifier != null - && ICompilationTarget.instance.isInRegularRAM(assignment.target, program)) { + && compTarget.isInRegularRAM(assignment.target, program)) { val binExpr = assignment.value as? BinaryExpression if (binExpr != null && binExpr.operator !in comparisonOperators) { if (binExpr.left !is BinaryExpression) { diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 006410eed..92dcc92db 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -11,8 +11,8 @@ import prog8.ast.statements.Directive import prog8.compiler.astprocessing.* import prog8.compiler.functions.* import prog8.compiler.target.C64Target -import prog8.compiler.target.ICompilationTarget import prog8.compiler.target.Cx16Target +import prog8.compiler.target.ICompilationTarget import prog8.compiler.target.asmGeneratorFor import prog8.optimizer.* import prog8.parser.ModuleImporter @@ -90,10 +90,10 @@ fun compileProgram(filepath: Path, compilationOptions.optimize = optimize programAst = ast importedFiles = imported - processAst(programAst, errors, compilationOptions) + processAst(programAst, errors, compilationOptions, ICompilationTarget.instance) if (compilationOptions.optimize) optimizeAst(programAst, errors, BuiltinFunctionsFacade(BuiltinFunctions)) - postprocessAst(programAst, errors, compilationOptions) + postprocessAst(programAst, errors, compilationOptions, ICompilationTarget.instance) // printAst(programAst) @@ -237,10 +237,10 @@ private fun determineCompilationOptions(program: Program): CompilationOptions { ) } -private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions) { +private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions, compTarget: ICompilationTarget) { // perform initial syntax checks and processings - println("Processing for target ${ICompilationTarget.instance.name}...") - programAst.checkIdentifiers(errors) + println("Processing for target ${compTarget.name}...") + programAst.checkIdentifiers(errors, compTarget) errors.handle() programAst.constantFold(errors) errors.handle() @@ -249,9 +249,9 @@ private fun processAst(programAst: Program, errors: ErrorReporter, compilerOptio programAst.addTypecasts(errors) errors.handle() programAst.variousCleanups() - programAst.checkValid(compilerOptions, errors) + programAst.checkValid(compilerOptions, errors, compTarget) errors.handle() - programAst.checkIdentifiers(errors) + programAst.checkIdentifiers(errors, compTarget) errors.handle() } @@ -275,11 +275,11 @@ private fun optimizeAst(programAst: Program, errors: ErrorReporter, functions: I errors.handle() } -private fun postprocessAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions) { +private fun postprocessAst(programAst: Program, errors: ErrorReporter, compilerOptions: CompilationOptions, compTarget: ICompilationTarget) { programAst.addTypecasts(errors) errors.handle() programAst.variousCleanups() - programAst.checkValid(compilerOptions, errors) // check if final tree is still valid + programAst.checkValid(compilerOptions, errors, compTarget) // check if final tree is still valid errors.handle() val callGraph = CallGraph(programAst) callGraph.checkRecursiveCalls(errors) @@ -291,7 +291,7 @@ private fun postprocessAst(programAst: Program, errors: ErrorReporter, compilerO private fun writeAssembly(programAst: Program, errors: ErrorReporter, outputDir: Path, compilerOptions: CompilationOptions): String { // asm generation directly from the Ast, - programAst.processAstBeforeAsmGeneration(errors) + programAst.processAstBeforeAsmGeneration(errors, ICompilationTarget.instance) errors.handle() // printAst(programAst) diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 35065d42a..aee3532e4 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -12,13 +12,14 @@ import prog8.compiler.ErrorReporter import prog8.compiler.functions.BuiltinFunctions import prog8.compiler.functions.builtinFunctionReturnType import prog8.compiler.target.C64Target -import prog8.compiler.target.ICompilationTarget import prog8.compiler.target.Cx16Target +import prog8.compiler.target.ICompilationTarget import java.io.File internal class AstChecker(private val program: Program, private val compilerOptions: CompilationOptions, - private val errors: ErrorReporter + private val errors: ErrorReporter, + private val compTarget: ICompilationTarget ) : IAstVisitor { override fun visit(program: Program) { @@ -1286,7 +1287,7 @@ internal class AstChecker(private val program: Program, // check if the floating point values are all within range val doubles = value.value.map {it.constValue(program)?.number!!.toDouble()}.toDoubleArray() - if(doubles.any { it < ICompilationTarget.instance.machine.FLOAT_MAX_NEGATIVE || it > ICompilationTarget.instance.machine.FLOAT_MAX_POSITIVE }) + if(doubles.any { it < compTarget.machine.FLOAT_MAX_NEGATIVE || it > compTarget.machine.FLOAT_MAX_POSITIVE }) return err("floating point value overflow") return true } diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index 0f50b55c0..6a83cc6d1 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -6,15 +6,16 @@ import prog8.ast.base.FatalAstException import prog8.ast.statements.Directive import prog8.compiler.BeforeAsmGenerationAstChanger import prog8.compiler.CompilationOptions +import prog8.compiler.target.ICompilationTarget -internal fun Program.checkValid(compilerOptions: CompilationOptions, errors: ErrorReporter) { - val checker = AstChecker(this, compilerOptions, errors) +internal fun Program.checkValid(compilerOptions: CompilationOptions, errors: ErrorReporter, compTarget: ICompilationTarget) { + val checker = AstChecker(this, compilerOptions, errors, compTarget) checker.visit(this) } -internal fun Program.processAstBeforeAsmGeneration(errors: ErrorReporter) { - val fixer = BeforeAsmGenerationAstChanger(this, errors) +internal fun Program.processAstBeforeAsmGeneration(errors: ErrorReporter, compTarget: ICompilationTarget) { + val fixer = BeforeAsmGenerationAstChanger(this, errors, compTarget) fixer.visit(this) fixer.applyModifications() } @@ -36,9 +37,9 @@ internal fun Program.verifyFunctionArgTypes() { fixer.visit(this) } -internal fun Program.checkIdentifiers(errors: ErrorReporter) { +internal fun Program.checkIdentifiers(errors: ErrorReporter, compTarget: ICompilationTarget) { - val checker2 = AstIdentifiersChecker(this, errors) + val checker2 = AstIdentifiersChecker(this, errors, compTarget) checker2.visit(this) if(errors.isEmpty()) { diff --git a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt index 663a33a54..e8bdcb783 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt @@ -14,7 +14,7 @@ import prog8.ast.walk.IAstVisitor import prog8.compiler.functions.BuiltinFunctions import prog8.compiler.target.ICompilationTarget -internal class AstIdentifiersChecker(private val program: Program, private val errors: ErrorReporter) : IAstVisitor { +internal class AstIdentifiersChecker(private val program: Program, private val errors: ErrorReporter, private val compTarget: ICompilationTarget) : IAstVisitor { private var blocks = mutableMapOf() private fun nameError(name: String, position: Position, existing: Statement) { @@ -28,7 +28,7 @@ internal class AstIdentifiersChecker(private val program: Program, private val e } override fun visit(block: Block) { - if(block.name in ICompilationTarget.instance.machine.opcodeNames) + if(block.name in compTarget.machine.opcodeNames) errors.err("can't use a cpu opcode name as a symbol: '${block.name}'", block.position) val existing = blocks[block.name] @@ -50,8 +50,8 @@ internal class AstIdentifiersChecker(private val program: Program, private val e override fun visit(directive: Directive) { if(directive.directive=="%target") { val compatibleTarget = directive.args.single().name - if (compatibleTarget != ICompilationTarget.instance.name) - errors.err("module's compilation target ($compatibleTarget) differs from active target (${ICompilationTarget.instance.name})", directive.position) + if (compatibleTarget != compTarget.name) + errors.err("module's compilation target ($compatibleTarget) differs from active target (${compTarget.name})", directive.position) } super.visit(directive) @@ -63,7 +63,7 @@ internal class AstIdentifiersChecker(private val program: Program, private val e if(decl.name in BuiltinFunctions) errors.err("builtin function cannot be redefined", decl.position) - if(decl.name in ICompilationTarget.instance.machine.opcodeNames) + if(decl.name in compTarget.machine.opcodeNames) errors.err("can't use a cpu opcode name as a symbol: '${decl.name}'", decl.position) if(decl.datatype==DataType.STRUCT) { @@ -102,7 +102,7 @@ internal class AstIdentifiersChecker(private val program: Program, private val e } override fun visit(subroutine: Subroutine) { - if(subroutine.name in ICompilationTarget.instance.machine.opcodeNames) { + if(subroutine.name in compTarget.machine.opcodeNames) { errors.err("can't use a cpu opcode name as a symbol: '${subroutine.name}'", subroutine.position) } else if(subroutine.name in BuiltinFunctions) { // the builtin functions can't be redefined @@ -142,7 +142,7 @@ internal class AstIdentifiersChecker(private val program: Program, private val e } override fun visit(label: Label) { - if(label.name in ICompilationTarget.instance.machine.opcodeNames) + if(label.name in compTarget.machine.opcodeNames) errors.err("can't use a cpu opcode name as a symbol: '${label.name}'", label.position) if(label.name in BuiltinFunctions) { diff --git a/compiler/src/prog8/compiler/target/ICompilationTarget.kt b/compiler/src/prog8/compiler/target/ICompilationTarget.kt index 3de5339ea..708d58fcc 100644 --- a/compiler/src/prog8/compiler/target/ICompilationTarget.kt +++ b/compiler/src/prog8/compiler/target/ICompilationTarget.kt @@ -24,7 +24,7 @@ internal interface ICompilationTarget: IStringEncoding { fun memorySize(dt: DataType): Int companion object { - lateinit var instance: ICompilationTarget + lateinit var instance: ICompilationTarget // TODO reduce dependency on this by just passing the instance as a parameter } fun isInRegularRAM(target: AssignTarget, program: Program): Boolean { diff --git a/compiler/test/UnitTests.kt b/compiler/test/UnitTests.kt index 1607f9592..e66458f7e 100644 --- a/compiler/test/UnitTests.kt +++ b/compiler/test/UnitTests.kt @@ -14,7 +14,6 @@ import prog8.ast.statements.* import prog8.ast.toHex import prog8.compiler.* import prog8.compiler.target.C64Target -import prog8.compiler.target.ICompilationTarget import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage import prog8.compiler.target.c64.C64MachineDefinition.FLOAT_MAX_NEGATIVE import prog8.compiler.target.c64.C64MachineDefinition.FLOAT_MAX_POSITIVE @@ -415,67 +414,64 @@ class TestMemory { @Test fun testInValidRamC64_memory_addresses() { - ICompilationTarget.instance = C64Target var memexpr = NumericLiteralValue.optimalInteger(0x0000, Position.DUMMY) var target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) val program = Program("test", mutableListOf(), DummyFunctions()) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0x1000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0x9fff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0xc000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0xcfff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) } @Test fun testNotInValidRamC64_memory_addresses() { - ICompilationTarget.instance = C64Target var memexpr = NumericLiteralValue.optimalInteger(0xa000, Position.DUMMY) var target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) val program = Program("test", mutableListOf(), DummyFunctions()) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0xafff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0xd000, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) memexpr = NumericLiteralValue.optimalInteger(0xffff, Position.DUMMY) target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) } @Test fun testInValidRamC64_memory_identifiers() { - ICompilationTarget.instance = C64Target var target = createTestProgramForMemoryRefViaVar(0x1000, VarDeclType.VAR) val program = Program("test", mutableListOf(), DummyFunctions()) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) target = createTestProgramForMemoryRefViaVar(0xd020, VarDeclType.VAR) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) target = createTestProgramForMemoryRefViaVar(0x1000, VarDeclType.CONST) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) target = createTestProgramForMemoryRefViaVar(0xd020, VarDeclType.CONST) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) target = createTestProgramForMemoryRefViaVar(0x1000, VarDeclType.MEMORY) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) } @Test @@ -492,16 +488,14 @@ class TestMemory { @Test fun testInValidRamC64_memory_expression() { - ICompilationTarget.instance = C64Target val memexpr = PrefixExpression("+", NumericLiteralValue.optimalInteger(0x1000, Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY) val program = Program("test", mutableListOf(), DummyFunctions()) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) } @Test fun testInValidRamC64_variable() { - ICompilationTarget.instance = C64Target val decl = VarDecl(VarDeclType.VAR, DataType.BYTE, ZeropageWish.DONTCARE, null, "address", null, null, false, false, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY) @@ -509,12 +503,11 @@ class TestMemory { val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of("")) val program = Program("test", mutableListOf(module), DummyFunctions()) module.linkParents(ParentSentinel) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) } @Test fun testInValidRamC64_memmap_variable() { - ICompilationTarget.instance = C64Target val address = 0x1000 val decl = VarDecl(VarDeclType.MEMORY, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", null, NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) @@ -523,12 +516,11 @@ class TestMemory { val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of("")) val program = Program("test", mutableListOf(module), DummyFunctions()) module.linkParents(ParentSentinel) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) } @Test fun testNotInValidRamC64_memmap_variable() { - ICompilationTarget.instance = C64Target val address = 0xd020 val decl = VarDecl(VarDeclType.MEMORY, DataType.UBYTE, ZeropageWish.DONTCARE, null, "address", null, NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY) val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY) @@ -537,12 +529,11 @@ class TestMemory { val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of("")) val program = Program("test", mutableListOf(module), DummyFunctions()) module.linkParents(ParentSentinel) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) } @Test fun testInValidRamC64_array() { - ICompilationTarget.instance = C64Target val decl = VarDecl(VarDeclType.VAR, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", null, null, false, false, Position.DUMMY) val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) val target = AssignTarget(null, arrayindexed, null, Position.DUMMY) @@ -551,12 +542,11 @@ class TestMemory { val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of("")) val program = Program("test", mutableListOf(module), DummyFunctions()) module.linkParents(ParentSentinel) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) } @Test fun testInValidRamC64_array_memmapped() { - ICompilationTarget.instance = C64Target val address = 0x1000 val decl = VarDecl(VarDeclType.MEMORY, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", null, NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY) val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) @@ -566,12 +556,11 @@ class TestMemory { val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of("")) val program = Program("test", mutableListOf(module), DummyFunctions()) module.linkParents(ParentSentinel) - assertTrue(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertTrue(C64Target.isInRegularRAM(target, program)) } @Test fun testNotValidRamC64_array_memmapped() { - ICompilationTarget.instance = C64Target val address = 0xe000 val decl = VarDecl(VarDeclType.MEMORY, DataType.ARRAY_UB, ZeropageWish.DONTCARE, null, "address", null, NumericLiteralValue.optimalInteger(address, Position.DUMMY), false, false, Position.DUMMY) val arrayindexed = ArrayIndexedExpression(IdentifierReference(listOf("address"), Position.DUMMY), ArrayIndex(NumericLiteralValue.optimalInteger(1, Position.DUMMY), Position.DUMMY), Position.DUMMY) @@ -581,6 +570,6 @@ class TestMemory { val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of("")) val program = Program("test", mutableListOf(module), DummyFunctions()) module.linkParents(ParentSentinel) - assertFalse(ICompilationTarget.instance.isInRegularRAM(target, program)) + assertFalse(C64Target.isInRegularRAM(target, program)) } }