diff --git a/compiler/src/prog8/compiler/ModuleImporter.kt b/compiler/src/prog8/compiler/ModuleImporter.kt index 3bd45a73f..28e417274 100644 --- a/compiler/src/prog8/compiler/ModuleImporter.kt +++ b/compiler/src/prog8/compiler/ModuleImporter.kt @@ -4,6 +4,7 @@ import com.github.michaelbull.result.* import prog8.ast.Module import prog8.ast.Program import prog8.ast.base.SyntaxError +import prog8.ast.statements.Block import prog8.ast.statements.Directive import prog8.ast.statements.DirectiveArg import prog8.code.core.IErrorReporter @@ -107,6 +108,18 @@ class ModuleImporter(private val program: Program, ) removeDirectivesFromImportedModule(importedModule) + + // modules can contain blocks with "merge" option. + // their content has to be merged into already existing block with the same name. + val blocks = importedModule.statements.filterIsInstance() + for(block in blocks) { + if("merge" in block.options()) { + val existingBlock = program.allBlocks.first { it.name==block.name} + existingBlock.statements.addAll(block.statements.filter { it !is Directive}) + importedModule.statements.remove(block) + } + } + return importedModule } diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 47e6891f2..38722b475 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -727,7 +727,7 @@ internal class AstChecker(private val program: Program, err("this directive may only occur in a block or at module level") if(directive.args.isEmpty()) err("missing option directive argument(s)") - else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page")}.any { !it }) + else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "align_word", "align_page", "merge")}.any { !it }) err("invalid option directive argument(s)") } else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position) diff --git a/compiler/test/ModuleImporterTests.kt b/compiler/test/ModuleImporterTests.kt index 908383f75..d6a9e6459 100644 --- a/compiler/test/ModuleImporterTests.kt +++ b/compiler/test/ModuleImporterTests.kt @@ -15,7 +15,11 @@ import prog8.compiler.ModuleImporter import prog8.parser.ParseError import prog8.code.core.SourceCode import prog8.code.core.internedStringsModuleName -import prog8tests.helpers.* +import prog8tests.helpers.Helpers +import prog8tests.helpers.DummyFunctions +import prog8tests.helpers.DummyMemsizer +import prog8tests.helpers.DummyStringEncoder +import prog8tests.helpers.ErrorReporterForTests import kotlin.io.path.* @@ -39,9 +43,9 @@ class TestModuleImporter: FunSpec({ context("WithInvalidPath") { test("testNonexisting") { - val dirRel = assumeDirectory(".", workingDir.relativize(fixturesDir)) + val dirRel = Helpers.assumeDirectory(".", Helpers.workingDir.relativize(Helpers.fixturesDir)) val importer = makeImporter(null, dirRel.invariantSeparatorsPathString) - val srcPathRel = assumeNotExists(dirRel, "i_do_not_exist") + val srcPathRel = Helpers.assumeNotExists(dirRel, "i_do_not_exist") val srcPathAbs = srcPathRel.absolute() val error1 = importer.importModule(srcPathRel).getErrorOrElse { fail("should have import error") } withClue(".file should be normalized") { @@ -62,7 +66,7 @@ class TestModuleImporter: FunSpec({ } test("testDirectory") { - val srcPathRel = assumeDirectory(workingDir.relativize(fixturesDir)) + val srcPathRel = Helpers.assumeDirectory(Helpers.workingDir.relativize(Helpers.fixturesDir)) val srcPathAbs = srcPathRel.absolute() val searchIn = Path(".", "$srcPathRel").invariantSeparatorsPathString val importer = makeImporter(null, searchIn) @@ -95,11 +99,11 @@ class TestModuleImporter: FunSpec({ test("testAbsolute") { val searchIn = listOf( - Path(".").div(workingDir.relativize(fixturesDir)), // we do want a dot "." in front + Path(".").div(Helpers.workingDir.relativize(Helpers.fixturesDir)), // we do want a dot "." in front ).map { it.invariantSeparatorsPathString } val importer = makeImporter(null, searchIn) val fileName = "ast_simple_main.p8" - val path = assumeReadableFile(searchIn[0], fileName) + val path = Helpers.assumeReadableFile(searchIn[0], fileName) val module = importer.importModule(path.absolute()).getOrElse { throw it } program.modules.size shouldBe 2 @@ -109,11 +113,11 @@ class TestModuleImporter: FunSpec({ test("testRelativeToWorkingDir") { val searchIn = listOf( - Path(".").div(workingDir.relativize(fixturesDir)), // we do want a dot "." in front + Path(".").div(Helpers.workingDir.relativize(Helpers.fixturesDir)), // we do want a dot "." in front ).map { it.invariantSeparatorsPathString } val importer = makeImporter(null, searchIn) val fileName = "ast_simple_main.p8" - val path = assumeReadableFile(searchIn[0], fileName) + val path = Helpers.assumeReadableFile(searchIn[0], fileName) withClue("sanity check: path should NOT be absolute") { path.isAbsolute shouldBe false } @@ -126,12 +130,12 @@ class TestModuleImporter: FunSpec({ test("testRelativeTo1stDirInSearchList") { val searchIn = Path(".") - .div(workingDir.relativize(fixturesDir)) + .div(Helpers.workingDir.relativize(Helpers.fixturesDir)) .invariantSeparatorsPathString val importer = makeImporter(null, searchIn) val fileName = "ast_simple_main.p8" val path = Path(".", fileName) - assumeReadableFile(searchIn, path) + Helpers.assumeReadableFile(searchIn, path) val module = importer.importModule(path).getOrElse { throw it } program.modules.size shouldBe 2 @@ -141,14 +145,14 @@ class TestModuleImporter: FunSpec({ context("WithBadFile") { test("testWithSyntaxError") { - val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) + val searchIn = Helpers.assumeDirectory("./", Helpers.workingDir.relativize(Helpers.fixturesDir)) val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) - val srcPath = assumeReadableFile(fixturesDir, "ast_file_with_syntax_error.p8") + val srcPath = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_file_with_syntax_error.p8") val act = { importer.importModule(srcPath) } repeat(2) { n -> withClue(count[n] + " call") { - shouldThrow() { act() }.let { + shouldThrow { act() }.let { it.position.file shouldBe SourceCode.relative(srcPath).toString() withClue("line; should be 1-based") { it.position.line shouldBe 2 } withClue("startCol; should be 0-based") { it.position.startCol shouldBe 6 } @@ -160,10 +164,10 @@ class TestModuleImporter: FunSpec({ } fun doTestImportingFileWithSyntaxError(repetitions: Int) { - val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) + val searchIn = Helpers.assumeDirectory("./", Helpers.workingDir.relativize(Helpers.fixturesDir)) val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) - val importing = assumeReadableFile(fixturesDir, "import_file_with_syntax_error.p8") - val imported = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") + val importing = Helpers.assumeReadableFile(Helpers.fixturesDir, "import_file_with_syntax_error.p8") + val imported = Helpers.assumeReadableFile(Helpers.fixturesDir, "file_with_syntax_error.p8") val act = { importer.importModule(importing) } @@ -194,11 +198,11 @@ class TestModuleImporter: FunSpec({ context("ImportLibraryModule") { context("WithInvalidName") { test("testWithNonExistingName") { - val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) + val searchIn = Helpers.assumeDirectory("./", Helpers.workingDir.relativize(Helpers.fixturesDir)) val errors = ErrorReporterForTests(false) val importer = makeImporter(errors, searchIn.invariantSeparatorsPathString) - val filenameNoExt = assumeNotExists(fixturesDir, "i_do_not_exist").name - val filenameWithExt = assumeNotExists(fixturesDir, "i_do_not_exist.p8").name + val filenameNoExt = Helpers.assumeNotExists(Helpers.fixturesDir, "i_do_not_exist").name + val filenameWithExt = Helpers.assumeNotExists(Helpers.fixturesDir, "i_do_not_exist.p8").name repeat(2) { n -> val result = importer.importLibraryModule(filenameNoExt) @@ -221,9 +225,9 @@ class TestModuleImporter: FunSpec({ context("WithValidName") { context("WithBadFile") { test("testWithSyntaxError") { - val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) + val searchIn = Helpers.assumeDirectory("./", Helpers.workingDir.relativize(Helpers.fixturesDir)) val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) - val srcPath = assumeReadableFile(fixturesDir, "ast_file_with_syntax_error.p8") + val srcPath = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_file_with_syntax_error.p8") repeat(2) { n -> withClue(count[n] + " call") { shouldThrow() @@ -241,15 +245,15 @@ class TestModuleImporter: FunSpec({ fun doTestImportingFileWithSyntaxError(repetitions: Int) { - val searchIn = assumeDirectory("./", workingDir.relativize(fixturesDir)) + val searchIn = Helpers.assumeDirectory("./", Helpers.workingDir.relativize(Helpers.fixturesDir)) val importer = makeImporter(null, searchIn.invariantSeparatorsPathString) - val importing = assumeReadableFile(fixturesDir, "import_file_with_syntax_error.p8") - val imported = assumeReadableFile(fixturesDir, "file_with_syntax_error.p8") + val importing = Helpers.assumeReadableFile(Helpers.fixturesDir, "import_file_with_syntax_error.p8") + val imported = Helpers.assumeReadableFile(Helpers.fixturesDir, "file_with_syntax_error.p8") val act = { importer.importLibraryModule(importing.nameWithoutExtension) } repeat(repetitions) { n -> withClue(count[n] + " call") { - shouldThrow() { + shouldThrow { act() }.let { it.position.file shouldBe SourceCode.relative(imported).toString() withClue("line; should be 1-based") { it.position.line shouldBe 2 } diff --git a/compiler/test/TestCompilerOnExamples.kt b/compiler/test/TestCompilerOnExamples.kt index 2f7381612..d5202b0ff 100644 --- a/compiler/test/TestCompilerOnExamples.kt +++ b/compiler/test/TestCompilerOnExamples.kt @@ -8,10 +8,8 @@ import prog8.code.target.Cx16Target import prog8.compiler.CompilationResult import prog8.compiler.CompilerArguments import prog8.compiler.compileProgram -import prog8tests.helpers.assumeDirectory -import prog8tests.helpers.cartesianProduct -import prog8tests.helpers.outputDir -import prog8tests.helpers.workingDir +import prog8tests.helpers.Helpers +import prog8tests.helpers.Combinations import java.nio.file.Path import kotlin.io.path.absolute import kotlin.io.path.exists @@ -23,7 +21,7 @@ import kotlin.io.path.exists * from source file loading all the way through to running 64tass. */ -private val examplesDir = assumeDirectory(workingDir, "../examples") +private val examplesDir = Helpers.assumeDirectory(Helpers.workingDir, "../examples") private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilationTarget): CompilationResult? { val args = CompilerArguments( @@ -37,7 +35,7 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat asmListfile = false, experimentalCodegen = false, compilationTarget = target.name, - outputDir = outputDir + outputDir = Helpers.outputDir ) return compileProgram(args) } @@ -45,12 +43,12 @@ private fun compileTheThing(filepath: Path, optimize: Boolean, target: ICompilat private fun prepareTestFiles(source: String, optimize: Boolean, target: ICompilationTarget): Pair { val searchIn = mutableListOf(examplesDir) if (target is Cx16Target) { - searchIn.add(0, assumeDirectory(examplesDir, "cx16")) + searchIn.add(0, Helpers.assumeDirectory(examplesDir, "cx16")) } val filepath = searchIn.asSequence() .map { it.resolve("$source.p8") } .map { it.normalize().absolute() } - .map { workingDir.relativize(it) } + .map { Helpers.workingDir.relativize(it) } .first { it.exists() } val displayName = "${examplesDir.relativize(filepath.absolute())}: ${target.name}, optimize=$optimize" return Pair(displayName, filepath) @@ -59,7 +57,7 @@ private fun prepareTestFiles(source: String, optimize: Boolean, target: ICompila class TestCompilerOnExamplesC64: FunSpec({ - val onlyC64 = cartesianProduct( + val onlyC64 = Combinations.cartesianProduct( listOf( "balloonflight", "bdmusic", @@ -86,7 +84,7 @@ class TestCompilerOnExamplesC64: FunSpec({ class TestCompilerOnExamplesCx16: FunSpec({ - val onlyCx16 = cartesianProduct( + val onlyCx16 = Combinations.cartesianProduct( listOf( "vtui/testvtui", "amiga", @@ -118,7 +116,7 @@ class TestCompilerOnExamplesCx16: FunSpec({ class TestCompilerOnExamplesBothC64andCx16: FunSpec({ - val bothCx16AndC64 = cartesianProduct( + val bothCx16AndC64 = Combinations.cartesianProduct( listOf( "animals", "balls", diff --git a/compiler/test/TestCompilerOnImportsAndIncludes.kt b/compiler/test/TestCompilerOnImportsAndIncludes.kt index 26cb14917..1852de970 100644 --- a/compiler/test/TestCompilerOnImportsAndIncludes.kt +++ b/compiler/test/TestCompilerOnImportsAndIncludes.kt @@ -24,11 +24,11 @@ class TestCompilerOnImportsAndIncludes: FunSpec({ context("Import") { test("testImportFromSameFolder") { - val filepath = assumeReadableFile(fixturesDir, "importFromSameFolder.p8") - assumeReadableFile(fixturesDir, "foo_bar.p8") + val filepath = Helpers.assumeReadableFile(Helpers.fixturesDir, "importFromSameFolder.p8") + Helpers.assumeReadableFile(Helpers.fixturesDir, "foo_bar.p8") val platform = Cx16Target() - val result = compileFile(platform, optimize = false, fixturesDir, filepath.name)!! + val result = compileFile(platform, optimize = false, Helpers.fixturesDir, filepath.name)!! val program = result.program val startSub = program.entrypoint @@ -46,11 +46,11 @@ class TestCompilerOnImportsAndIncludes: FunSpec({ context("AsmInclude") { test("testAsmIncludeFromSameFolder") { - val filepath = assumeReadableFile(fixturesDir, "asmIncludeFromSameFolder.p8") - assumeReadableFile(fixturesDir, "foo_bar.asm") + val filepath = Helpers.assumeReadableFile(Helpers.fixturesDir, "asmIncludeFromSameFolder.p8") + Helpers.assumeReadableFile(Helpers.fixturesDir, "foo_bar.asm") val platform = Cx16Target() - val result = compileFile(platform, optimize = false, fixturesDir, filepath.name)!! + val result = compileFile(platform, optimize = false, Helpers.fixturesDir, filepath.name)!! val program = result.program val startSub = program.entrypoint @@ -71,17 +71,17 @@ class TestCompilerOnImportsAndIncludes: FunSpec({ context("Asmbinary") { test("testAsmbinaryDirectiveWithNonExistingFile") { - val p8Path = assumeReadableFile(fixturesDir, "asmBinaryNonExisting.p8") - assumeNotExists(fixturesDir, "i_do_not_exist.bin") + val p8Path = Helpers.assumeReadableFile(Helpers.fixturesDir, "asmBinaryNonExisting.p8") + Helpers.assumeNotExists(Helpers.fixturesDir, "i_do_not_exist.bin") - compileFile(Cx16Target(), false, p8Path.parent, p8Path.name, outputDir) shouldBe null + compileFile(Cx16Target(), false, p8Path.parent, p8Path.name, Helpers.outputDir) shouldBe null } test("testAsmbinaryDirectiveWithNonReadableFile") { - val p8Path = assumeReadableFile(fixturesDir, "asmBinaryNonReadable.p8") - assumeDirectory(fixturesDir, "subFolder") + val p8Path = Helpers.assumeReadableFile(Helpers.fixturesDir, "asmBinaryNonReadable.p8") + Helpers.assumeDirectory(Helpers.fixturesDir, "subFolder") - compileFile(Cx16Target(), false, p8Path.parent, p8Path.name, outputDir) shouldBe null + compileFile(Cx16Target(), false, p8Path.parent, p8Path.name, Helpers.outputDir) shouldBe null } val tests = listOf( @@ -92,18 +92,18 @@ class TestCompilerOnImportsAndIncludes: FunSpec({ tests.forEach { val (where, p8Str, _) = it test("%asmbinary from ${where}folder") { - val p8Path = assumeReadableFile(fixturesDir, p8Str) - // val binPath = assumeReadableFile(fixturesDir, binStr) + val p8Path = Helpers.assumeReadableFile(Helpers.fixturesDir, p8Str) + // val binPath = Helpers.assumeReadableFile(Helpers.fixturesDir, binStr) // the bug we're testing for (#54) was hidden if outputDir == workingDir withClue("sanity check: workingDir and outputDir should not be the same folder") { - outputDir.normalize().toAbsolutePath() shouldNotBe workingDir.normalize().toAbsolutePath() + Helpers.outputDir.normalize().toAbsolutePath() shouldNotBe Helpers.workingDir.normalize().toAbsolutePath() } withClue("argument to assembler directive .binary " + "should be relative to the generated .asm file (in output dir), " + "NOT relative to .p8 neither current working dir") { - compileFile(Cx16Target(), false, p8Path.parent, p8Path.name, outputDir) shouldNotBe null + compileFile(Cx16Target(), false, p8Path.parent, p8Path.name, Helpers.outputDir) shouldNotBe null } } } diff --git a/compiler/test/TestCompilerOnRanges.kt b/compiler/test/TestCompilerOnRanges.kt index 0f4138510..cfc8cf0f6 100644 --- a/compiler/test/TestCompilerOnRanges.kt +++ b/compiler/test/TestCompilerOnRanges.kt @@ -18,7 +18,7 @@ import prog8.code.core.Position import prog8.code.target.C64Target import prog8.code.target.Cx16Target import prog8tests.helpers.ErrorReporterForTests -import prog8tests.helpers.cartesianProduct +import prog8tests.helpers.Combinations import prog8tests.helpers.compileText @@ -93,7 +93,7 @@ class TestCompilerOnRanges: FunSpec({ } context("floatArrayInitializerWithRange") { - val combos = cartesianProduct( + val combos = Combinations.cartesianProduct( listOf("", "42", "41"), // sizeInDecl listOf("%import floats", ""), // optEnableFloats listOf(Cx16Target(), C64Target()), // platform diff --git a/compiler/test/TestCompilerOptionLibdirs.kt b/compiler/test/TestCompilerOptionLibdirs.kt index 23a69e261..cc9861328 100644 --- a/compiler/test/TestCompilerOptionLibdirs.kt +++ b/compiler/test/TestCompilerOptionLibdirs.kt @@ -6,10 +6,7 @@ import prog8.code.target.Cx16Target import prog8.compiler.CompilationResult import prog8.compiler.CompilerArguments import prog8.compiler.compileProgram -import prog8tests.helpers.assumeReadableFile -import prog8tests.helpers.fixturesDir -import prog8tests.helpers.outputDir -import prog8tests.helpers.workingDir +import prog8tests.helpers.Helpers import java.nio.file.Path import kotlin.io.path.absolute import kotlin.io.path.createTempFile @@ -26,7 +23,7 @@ class TestCompilerOptionSourcedirs: FunSpec({ lateinit var tempFileInWorkingDir: Path beforeSpec { - tempFileInWorkingDir = createTempFile(directory = workingDir, prefix = "tmp_", suffix = ".p8") + tempFileInWorkingDir = createTempFile(directory = Helpers.workingDir, prefix = "tmp_", suffix = ".p8") .also { it.writeText(""" main { sub start() { @@ -52,39 +49,39 @@ class TestCompilerOptionSourcedirs: FunSpec({ experimentalCodegen = false, compilationTarget = Cx16Target.NAME, sourceDirs, - outputDir + Helpers.outputDir ) return compileProgram(args) } test("testAbsoluteFilePathInWorkingDir") { - val filepath = assumeReadableFile(tempFileInWorkingDir.absolute()) + val filepath = Helpers.assumeReadableFile(tempFileInWorkingDir.absolute()) compileFile(filepath, listOf()) shouldNotBe null } test("testFilePathInWorkingDirRelativeToWorkingDir") { - val filepath = assumeReadableFile(workingDir.relativize(tempFileInWorkingDir.absolute())) + val filepath = Helpers.assumeReadableFile(Helpers.workingDir.relativize(tempFileInWorkingDir.absolute())) compileFile(filepath, listOf()) shouldNotBe null } test("testFilePathInWorkingDirRelativeTo1stInSourcedirs") { - val filepath = assumeReadableFile(tempFileInWorkingDir) - compileFile(filepath.fileName, listOf(workingDir.toString())) shouldNotBe null + val filepath = Helpers.assumeReadableFile(tempFileInWorkingDir) + compileFile(filepath.fileName, listOf(Helpers.workingDir.toString())) shouldNotBe null } test("testAbsoluteFilePathOutsideWorkingDir") { - val filepath = assumeReadableFile(fixturesDir, "ast_simple_main.p8") + val filepath = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8") compileFile(filepath.absolute(), listOf()) shouldNotBe null } test("testFilePathOutsideWorkingDirRelativeToWorkingDir") { - val filepath = workingDir.relativize(assumeReadableFile(fixturesDir, "ast_simple_main.p8").absolute()) + val filepath = Helpers.workingDir.relativize(Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8").absolute()) compileFile(filepath, listOf()) shouldNotBe null } test("testFilePathOutsideWorkingDirRelativeTo1stInSourcedirs") { - val filepath = assumeReadableFile(fixturesDir, "ast_simple_main.p8") - val sourcedirs = listOf("$fixturesDir") + val filepath = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8") + val sourcedirs = listOf("${Helpers.fixturesDir}") compileFile(filepath.fileName, sourcedirs) shouldNotBe null } diff --git a/compiler/test/TestImportedModulesOrderAndOptions.kt b/compiler/test/TestImportedModulesOrderAndOptions.kt index c5ba4c21f..1bb5bcbe9 100644 --- a/compiler/test/TestImportedModulesOrderAndOptions.kt +++ b/compiler/test/TestImportedModulesOrderAndOptions.kt @@ -10,8 +10,8 @@ import prog8.code.target.C64Target import prog8.compiler.determineCompilationOptions import prog8.compiler.parseImports import prog8tests.helpers.ErrorReporterForTests +import prog8tests.helpers.Helpers import prog8tests.helpers.compileText -import prog8tests.helpers.outputDir class TestImportedModulesOrderAndOptions: FunSpec({ @@ -84,7 +84,7 @@ main { } """ val filenameBase = "on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) - val filepath = outputDir.resolve("$filenameBase.p8") + val filepath = Helpers.outputDir.resolve("$filenameBase.p8") filepath.toFile().writeText(sourceText) val (program, options, importedfiles) = parseImports(filepath, errors, C64Target(), emptyList()) diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 06cf41cc3..654205184 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -298,7 +298,7 @@ class TestOptimization: FunSpec({ floats = false, noSysInit = true, compTarget = C64Target(), - loadAddress = 0u, outputDir= outputDir) + loadAddress = 0u, outputDir= Helpers.outputDir) result.program.processAstBeforeAsmGeneration(options, ErrorReporterForTests()) // assignment is now split into: diff --git a/compiler/test/TestSymbolTable.kt b/compiler/test/TestSymbolTable.kt index 3bc524ffa..38f306d4a 100644 --- a/compiler/test/TestSymbolTable.kt +++ b/compiler/test/TestSymbolTable.kt @@ -22,7 +22,7 @@ class TestSymbolTable: FunSpec({ test("symboltable flatten") { val st = makeSt() st.flat[listOf("zzzzz")] shouldBe null - st.flat.getValue(listOf("sin")).type shouldBe StNodeType.BUILTINFUNC + st.flat.getValue(listOf("msb")).type shouldBe StNodeType.BUILTINFUNC st.flat.getValue(listOf("block2")).type shouldBe StNodeType.BLOCK st.flat.getValue(listOf("block2", "sub2", "subsub", "label")).type shouldBe StNodeType.LABEL st.flat[listOf("block2", "sub2", "subsub", "label", "zzzz")] shouldBe null @@ -37,8 +37,8 @@ class TestSymbolTable: FunSpec({ default = st.lookupOrElse(listOf("undefined")) { StNode("default", StNodeType.LABEL, Position.DUMMY) } default.name shouldBe "default" - val sinfunc = st.lookupOrElse("sin") { fail("sin must be found") } - sinfunc.type shouldBe StNodeType.BUILTINFUNC + val msbFunc = st.lookupOrElse("msb") { fail("msb must be found") } + msbFunc.type shouldBe StNodeType.BUILTINFUNC val variable = st.lookupOrElse(listOf("block1", "sub2", "v2")) { fail("v2 must be found") } variable.type shouldBe StNodeType.STATICVAR @@ -92,7 +92,7 @@ private fun makeSt(): SymbolTable { sub221.add(StNode("label", StNodeType.LABEL, Position.DUMMY)) sub22.add(sub221) - val builtinfunc = StNode("sin", StNodeType.BUILTINFUNC, Position.DUMMY) + val builtinfunc = StNode("msb", StNodeType.BUILTINFUNC, Position.DUMMY) st.add(block1) st.add(block2) st.add(builtinfunc) diff --git a/compiler/test/ast/TestProg8Parser.kt b/compiler/test/ast/TestProg8Parser.kt index 47e3d4dc0..d2a93fde7 100644 --- a/compiler/test/ast/TestProg8Parser.kt +++ b/compiler/test/ast/TestProg8Parser.kt @@ -177,8 +177,8 @@ class TestProg8Parser: FunSpec( { context("ImportDirectives") { test("should not be looked into by the parser") { - val importedNoExt = assumeNotExists(fixturesDir, "i_do_not_exist") - assumeNotExists(fixturesDir, "i_do_not_exist.p8") + val importedNoExt = Helpers.assumeNotExists(Helpers.fixturesDir, "i_do_not_exist") + Helpers.assumeNotExists(Helpers.fixturesDir, "i_do_not_exist.p8") val text = "%import ${importedNoExt.name}" val module = parseModule(SourceCode.Text(text)) @@ -193,7 +193,7 @@ class TestProg8Parser: FunSpec( { } test("from an empty file should result in empty Module") { - val path = assumeReadableFile(fixturesDir, "ast_empty.p8") + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_empty.p8") val module = parseModule(SourceCode.File(path)) module.statements.size shouldBe 0 } @@ -212,7 +212,7 @@ class TestProg8Parser: FunSpec( { } test("parsed from a file") { - val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8") + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8") val module = parseModule(SourceCode.File(path)) module.name shouldBe path.nameWithoutExtension } @@ -275,7 +275,7 @@ class TestProg8Parser: FunSpec( { } test("in ParseError from bad file source code") { - val path = assumeReadableFile(fixturesDir, "ast_file_with_syntax_error.p8") + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_file_with_syntax_error.p8") val e = shouldThrow { parseModule(SourceCode.File(path)) } assertPosition(e.position, SourceCode.relative(path).toString(), 2, 6) @@ -291,13 +291,13 @@ class TestProg8Parser: FunSpec( { } test("of Module parsed from a file") { - val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8") + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8") val module = parseModule(SourceCode.File(path)) assertPositionOf(module, SourceCode.relative(path).toString(), 1, 0) } test("of non-root Nodes parsed from file") { - val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8") + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8") val module = parseModule(SourceCode.File(path)) val mpf = module.position.file @@ -361,7 +361,7 @@ class TestProg8Parser: FunSpec( { } test("isn't absolute for filesystem paths") { - val path = assumeReadableFile(fixturesDir, "ast_simple_main.p8") + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, "ast_simple_main.p8") val module = parseModule(SourceCode.File(path)) assertSomethingForAllNodes(module) { Path(it.position.file).isAbsolute shouldBe false diff --git a/compiler/test/ast/TestSourceCode.kt b/compiler/test/ast/TestSourceCode.kt index 16b48d44a..3bd0c427d 100644 --- a/compiler/test/ast/TestSourceCode.kt +++ b/compiler/test/ast/TestSourceCode.kt @@ -6,10 +6,7 @@ import io.kotest.matchers.shouldBe import io.kotest.matchers.string.shouldContain import prog8.code.core.SourceCode import prog8.code.core.SourceCode.Companion.libraryFilePrefix -import prog8tests.helpers.assumeNotExists -import prog8tests.helpers.assumeReadableFile -import prog8tests.helpers.fixturesDir -import prog8tests.helpers.resourcesDir +import prog8tests.helpers.Helpers import kotlin.io.path.Path @@ -32,26 +29,26 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromPathWithNonExistingPath() { val filename = "i_do_not_exist.p8" - val path = assumeNotExists(fixturesDir, filename) + val path = Helpers.assumeNotExists(Helpers.fixturesDir, filename) shouldThrow { SourceCode.File(path) } } @Test fun testFromPathWithMissingExtension_p8() { - val pathWithoutExt = assumeNotExists(fixturesDir,"simple_main") - assumeReadableFile(fixturesDir,"ast_simple_main.p8") + val pathWithoutExt = Helpers.assumeNotExists(Helpers.fixturesDir,"simple_main") + Helpers.assumeReadableFile(Helpers.fixturesDir,"ast_simple_main.p8") shouldThrow { SourceCode.File(pathWithoutExt) } } @Test fun testFromPathWithDirectory() { - shouldThrow { SourceCode.File(fixturesDir) } + shouldThrow { SourceCode.File(Helpers.fixturesDir) } } @Test fun testFromPathWithExistingPath() { val filename = "ast_simple_main.p8" - val path = assumeReadableFile(fixturesDir, filename) + val path = Helpers.assumeReadableFile(Helpers.fixturesDir, filename) val src = SourceCode.File(path) val expectedOrigin = SourceCode.relative(path).toString() src.origin shouldBe expectedOrigin @@ -64,7 +61,7 @@ class TestSourceCode: AnnotationSpec() { fun testFromPathWithExistingNonNormalizedPath() { val filename = "ast_simple_main.p8" val path = Path(".", "test", "..", "test", "fixtures", filename) - val srcFile = assumeReadableFile(path).toFile() + val srcFile = Helpers.assumeReadableFile(path).toFile() val src = SourceCode.File(path) val expectedOrigin = SourceCode.relative(path).toString() src.origin shouldBe expectedOrigin @@ -74,7 +71,7 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromResourcesWithExistingP8File_withoutLeadingSlash() { val pathString = "prog8lib/math.p8" - val srcFile = assumeReadableFile(resourcesDir, pathString).toFile() + val srcFile = Helpers.assumeReadableFile(Helpers.resourcesDir, pathString).toFile() val src = SourceCode.Resource(pathString) src.origin shouldBe "$libraryFilePrefix/$pathString" @@ -86,7 +83,7 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromResourcesWithExistingP8File_withLeadingSlash() { val pathString = "/prog8lib/math.p8" - val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile() + val srcFile = Helpers.assumeReadableFile(Helpers.resourcesDir, pathString.substring(1)).toFile() val src = SourceCode.Resource(pathString) src.origin shouldBe "$libraryFilePrefix$pathString" @@ -96,7 +93,7 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromResourcesWithExistingAsmFile_withoutLeadingSlash() { val pathString = "prog8lib/math.asm" - val srcFile = assumeReadableFile(resourcesDir, pathString).toFile() + val srcFile = Helpers.assumeReadableFile(Helpers.resourcesDir, pathString).toFile() val src = SourceCode.Resource(pathString) src.origin shouldBe "$libraryFilePrefix/$pathString" @@ -107,7 +104,7 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromResourcesWithExistingAsmFile_withLeadingSlash() { val pathString = "/prog8lib/math.asm" - val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile() + val srcFile = Helpers.assumeReadableFile(Helpers.resourcesDir, pathString.substring(1)).toFile() val src = SourceCode.Resource(pathString) src.origin shouldBe "$libraryFilePrefix$pathString" @@ -117,7 +114,7 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromResourcesWithNonNormalizedPath() { val pathString = "/prog8lib/../prog8lib/math.p8" - val srcFile = assumeReadableFile(resourcesDir, pathString.substring(1)).toFile() + val srcFile = Helpers.assumeReadableFile(Helpers.resourcesDir, pathString.substring(1)).toFile() val src = SourceCode.Resource(pathString) src.origin shouldBe "$libraryFilePrefix/prog8lib/math.p8" @@ -129,14 +126,14 @@ class TestSourceCode: AnnotationSpec() { @Test fun testFromResourcesWithNonExistingFile_withLeadingSlash() { val pathString = "/prog8lib/i_do_not_exist" - assumeNotExists(resourcesDir, pathString.substring(1)) + Helpers.assumeNotExists(Helpers.resourcesDir, pathString.substring(1)) shouldThrow { SourceCode.Resource(pathString) } } @Test fun testFromResourcesWithNonExistingFile_withoutLeadingSlash() { val pathString = "prog8lib/i_do_not_exist" - assumeNotExists(resourcesDir, pathString) + Helpers.assumeNotExists(Helpers.resourcesDir, pathString) shouldThrow { SourceCode.Resource(pathString) } } diff --git a/compiler/test/helpers/compileXyz.kt b/compiler/test/helpers/compileXyz.kt index c2bb6efd1..6d0f24139 100644 --- a/compiler/test/helpers/compileXyz.kt +++ b/compiler/test/helpers/compileXyz.kt @@ -19,13 +19,13 @@ internal fun compileFile( optimize: Boolean, fileDir: Path, fileName: String, - outputDir: Path = prog8tests.helpers.outputDir, + outputDir: Path = prog8tests.helpers.Helpers.outputDir, errors: IErrorReporter? = null, writeAssembly: Boolean = true, optFloatExpr: Boolean = true ) : CompilationResult? { val filepath = fileDir.resolve(fileName) - assumeReadableFile(filepath) + Helpers.assumeReadableFile(filepath) val args = CompilerArguments( filepath, optimize, @@ -56,7 +56,7 @@ internal fun compileText( writeAssembly: Boolean = true, optFloatExpr: Boolean = true ) : CompilationResult? { - val filePath = outputDir.resolve("on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + ".p8") + val filePath = Helpers.outputDir.resolve("on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + ".p8") // we don't assumeNotExists(filePath) - should be ok to just overwrite it filePath.toFile().writeText(sourceText) return compileFile(platform, optimize, filePath.parent, filePath.name, errors=errors, writeAssembly=writeAssembly, optFloatExpr = optFloatExpr) @@ -71,7 +71,7 @@ internal fun generateAssembly( floats = true, noSysInit = true, compTarget = C64Target(), - loadAddress = 0u, outputDir = outputDir) + loadAddress = 0u, outputDir = Helpers.outputDir) coptions.compTarget.machine.zeropage = C64Zeropage(coptions) val st = SymbolTableMaker().makeFrom(program) val errors = ErrorReporterForTests() diff --git a/compiler/test/helpers/mapCombinations.kt b/compiler/test/helpers/mapCombinations.kt index e1757ba36..cccfaabaa 100644 --- a/compiler/test/helpers/mapCombinations.kt +++ b/compiler/test/helpers/mapCombinations.kt @@ -1,50 +1,68 @@ package prog8tests.helpers -fun cartesianProduct(c1: Collection, c2: Collection): Sequence> { - return c1.flatMap { lhsElem -> c2.map { rhsElem -> lhsElem to rhsElem } }.asSequence() -} - -fun cartesianProduct(c1: Collection, c2: Collection, c3: Collection): Sequence> { - return sequence { - for (a in c1) - for (b in c2) - for (c in c3) - yield(Triple(a,b,c)) +object Combinations { + fun cartesianProduct(c1: Collection, c2: Collection): Sequence> { + return c1.flatMap { lhsElem -> c2.map { rhsElem -> lhsElem to rhsElem } }.asSequence() } -} -data class Product(val first: T, val second: U, val third: V, val fourth: W) - -fun cartesianProduct(c1: Collection, c2: Collection, c3: Collection, c4: Collection): Sequence> { - return sequence { - for (a in c1) - for (b in c2) - for (c in c3) - for (d in c4) - yield(Product(a,b,c,d)) + fun cartesianProduct(c1: Collection, c2: Collection, c3: Collection): Sequence> { + return sequence { + for (a in c1) + for (b in c2) + for (c in c3) + yield(Triple(a, b, c)) + } } -} -fun mapCombinations(dim1: Iterable, dim2: Iterable, combine2: (A, B) -> R) = - sequence { - for (a in dim1) - for (b in dim2) - yield(combine2(a, b)) - }.toList() + data class Product(val first: T, val second: U, val third: V, val fourth: W) -fun mapCombinations(dim1: Iterable, dim2: Iterable, dim3: Iterable, combine3: (A, B, C) -> R) = - sequence { - for (a in dim1) - for (b in dim2) - for (c in dim3) - yield(combine3(a, b, c)) - }.toList() + fun cartesianProduct( + c1: Collection, + c2: Collection, + c3: Collection, + c4: Collection + ): Sequence> { + return sequence { + for (a in c1) + for (b in c2) + for (c in c3) + for (d in c4) + yield(Product(a, b, c, d)) + } + } -fun mapCombinations(dim1: Iterable, dim2: Iterable, dim3: Iterable, dim4: Iterable, combine4: (A, B, C, D) -> R) = - sequence { - for (a in dim1) - for (b in dim2) - for (c in dim3) - for (d in dim4) - yield(combine4(a, b, c, d)) - }.toList() + fun mapCombinations(dim1: Iterable, dim2: Iterable, combine2: (A, B) -> R) = + sequence { + for (a in dim1) + for (b in dim2) + yield(combine2(a, b)) + }.toList() + + fun mapCombinations( + dim1: Iterable, + dim2: Iterable, + dim3: Iterable, + combine3: (A, B, C) -> R + ) = + sequence { + for (a in dim1) + for (b in dim2) + for (c in dim3) + yield(combine3(a, b, c)) + }.toList() + + fun mapCombinations( + dim1: Iterable, + dim2: Iterable, + dim3: Iterable, + dim4: Iterable, + combine4: (A, B, C, D) -> R + ) = + sequence { + for (a in dim1) + for (b in dim2) + for (c in dim3) + for (d in dim4) + yield(combine4(a, b, c, d)) + }.toList() +} \ No newline at end of file diff --git a/compiler/test/helpers/paths.kt b/compiler/test/helpers/paths.kt index df59785f7..74b77eed4 100644 --- a/compiler/test/helpers/paths.kt +++ b/compiler/test/helpers/paths.kt @@ -7,63 +7,69 @@ import java.nio.file.Path import kotlin.io.path.* -val workingDir = assumeDirectory("").absolute() // Note: "." does NOT work..! -val fixturesDir = assumeDirectory(workingDir,"test/fixtures") -val resourcesDir = assumeDirectory(workingDir,"res") -val outputDir: Path = createIfNotExists(workingDir, "build/tmp/test").also{ assumeDirectory(workingDir, "build/tmp/test") } +object Helpers { + val workingDir = assumeDirectory("").absolute() // Note: "." does NOT work..! + val fixturesDir = assumeDirectory(workingDir, "test/fixtures") + val resourcesDir = assumeDirectory(workingDir, "res") + val outputDir: Path = + createIfNotExists(workingDir, "build/tmp/test").also { assumeDirectory(workingDir, "build/tmp/test") } -fun createIfNotExists(workingDir: Path, path: String): Path { - val dir = workingDir / path - if(!dir.toFile().isDirectory) - Files.createDirectories(dir) - return dir -} - -fun assumeNotExists(path: Path): Path { - withClue("sanity check: should not exist: ${path.absolute()}") { - path.exists() shouldBe false + fun createIfNotExists(workingDir: Path, path: String): Path { + val dir = workingDir / path + if (!dir.toFile().isDirectory) + Files.createDirectories(dir) + return dir } - return path -} -fun assumeNotExists(pathStr: String): Path = assumeNotExists(Path(pathStr)) -fun assumeNotExists(path: Path, other: String): Path = assumeNotExists(path / other) - -fun assumeReadable(path: Path): Path { - withClue("sanity check: should be readable: ${path.absolute()}") { - path.isReadable() shouldBe true + fun assumeNotExists(path: Path): Path { + withClue("sanity check: should not exist: ${path.absolute()}") { + path.exists() shouldBe false + } + return path } - return path -} -fun assumeReadableFile(path: Path): Path { - withClue("sanity check: should be normal file: ${path.absolute()}") { - path.isRegularFile() shouldBe true + fun assumeNotExists(pathStr: String): Path = assumeNotExists(Path(pathStr)) + fun assumeNotExists(path: Path, other: String): Path = assumeNotExists(path / other) + + fun assumeReadable(path: Path): Path { + withClue("sanity check: should be readable: ${path.absolute()}") { + path.isReadable() shouldBe true + } + return path } - return assumeReadable(path) -} -fun assumeReadableFile(pathStr: String): Path = assumeReadableFile(Path(pathStr)) -fun assumeReadableFile(pathStr: String, other: Path): Path = assumeReadableFile(Path(pathStr), other) -fun assumeReadableFile(pathStr: String, other: String): Path = assumeReadableFile(Path(pathStr), other) -fun assumeReadableFile(path: Path, other: String): Path = assumeReadableFile(path / other) -fun assumeReadableFile(path: Path, other: Path): Path = assumeReadableFile(path / other) - -fun assumeDirectory(path: Path): Path { - withClue("sanity check; should be directory: $path") { - path.isDirectory() shouldBe true + fun assumeReadableFile(path: Path): Path { + withClue("sanity check: should be normal file: ${path.absolute()}") { + path.isRegularFile() shouldBe true + } + return assumeReadable(path) } - return path -} -fun assumeDirectory(pathStr: String): Path = assumeDirectory(Path(pathStr)) -fun assumeDirectory(path: Path, other: String): Path = assumeDirectory(path / other) -fun assumeDirectory(pathStr: String, other: String): Path = assumeDirectory(Path(pathStr) / other) -fun assumeDirectory(pathStr: String, other: Path): Path = assumeDirectory(Path(pathStr) / other) + fun assumeReadableFile(pathStr: String): Path = assumeReadableFile(Path(pathStr)) + fun assumeReadableFile(pathStr: String, other: Path): Path = assumeReadableFile(Path(pathStr), other) + fun assumeReadableFile(pathStr: String, other: String): Path = assumeReadableFile(Path(pathStr), other) + fun assumeReadableFile(path: Path, other: String): Path = assumeReadableFile(path / other) + fun assumeReadableFile(path: Path, other: Path): Path = assumeReadableFile(path / other) + + fun assumeDirectory(path: Path): Path { + withClue("sanity check; should be directory: $path") { + path.isDirectory() shouldBe true + } + return path + } + + fun assumeDirectory(pathStr: String): Path = assumeDirectory(Path(pathStr)) + fun assumeDirectory(path: Path, other: String): Path = assumeDirectory(path / other) + fun assumeDirectory(pathStr: String, other: String): Path = assumeDirectory(Path(pathStr) / other) + fun assumeDirectory(pathStr: String, other: Path): Path = assumeDirectory(Path(pathStr) / other) -@Deprecated("Directories are checked automatically at init.", - ReplaceWith("/* nothing */")) -@Suppress("UNUSED_PARAMETER") -fun sanityCheckDirectories(workingDirName: String? = null) { -} + @Deprecated( + "Directories are checked automatically at init.", + ReplaceWith("/* nothing */") + ) + @Suppress("UNUSED_PARAMETER") + fun sanityCheckDirectories(workingDirName: String? = null) { + } + +} \ No newline at end of file diff --git a/compiler/test/helpers_pathsTests.kt b/compiler/test/helpers_pathsTests.kt index e8f814ebc..7dee6aeef 100644 --- a/compiler/test/helpers_pathsTests.kt +++ b/compiler/test/helpers_pathsTests.kt @@ -4,7 +4,7 @@ import io.kotest.assertions.throwables.shouldThrow import io.kotest.assertions.withClue import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe -import prog8tests.helpers.* +import prog8tests.helpers.Helpers import kotlin.io.path.Path import kotlin.io.path.div @@ -20,21 +20,21 @@ class PathsHelpersTests: FunSpec({ context("WithOnePathArg") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" withClue("should return the path") { - assumeNotExists(path) shouldBe path + Helpers.assumeNotExists(path) shouldBe path } } test("on existing file") { shouldThrow { - assumeNotExists(fixturesDir / "ast_simple_main.p8") + Helpers.assumeNotExists(Helpers.fixturesDir / "ast_simple_main.p8") } } test("on existing directory") { shouldThrow { - assumeNotExists(fixturesDir) + Helpers.assumeNotExists(Helpers.fixturesDir) } } } @@ -42,22 +42,22 @@ class PathsHelpersTests: FunSpec({ context("WithOneStringArg") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" withClue("should return the path") { - assumeNotExists("$path") shouldBe path + Helpers.assumeNotExists("$path") shouldBe path } } test("on existing file") { - val path = fixturesDir / "ast_simple_main.p8" + val path = Helpers.fixturesDir / "ast_simple_main.p8" shouldThrow { - assumeNotExists("$path") + Helpers.assumeNotExists("$path") } } test("on existing directory") { shouldThrow { - assumeNotExists("$fixturesDir") + Helpers.assumeNotExists("${Helpers.fixturesDir}") } } } @@ -65,21 +65,21 @@ class PathsHelpersTests: FunSpec({ context("WithPathAndStringArgs") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" withClue("should return the path") { - assumeNotExists(fixturesDir / "i_do_not_exist") shouldBe path + Helpers.assumeNotExists(Helpers.fixturesDir / "i_do_not_exist") shouldBe path } } test("on existing file") { shouldThrow { - assumeNotExists(fixturesDir, "ast_simple_main.p8") + Helpers.assumeNotExists(Helpers.fixturesDir, "ast_simple_main.p8") } } test("on existing directory") { shouldThrow { - assumeNotExists(fixturesDir, "..") + Helpers.assumeNotExists(Helpers.fixturesDir, "..") } } } @@ -89,46 +89,46 @@ class PathsHelpersTests: FunSpec({ context("WithOnePathArg") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" shouldThrow { - assumeDirectory(path) + Helpers.assumeDirectory(path) } } test("on existing file") { - val path = fixturesDir / "ast_simple_main.p8" + val path = Helpers.fixturesDir / "ast_simple_main.p8" shouldThrow { - assumeDirectory(path) + Helpers.assumeDirectory(path) } } test("on existing directory") { - val path = workingDir + val path = Helpers.workingDir withClue("should return the path") { - assumeDirectory(path) shouldBe path + Helpers.assumeDirectory(path) shouldBe path } } } context("WithOneStringArg") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" shouldThrow { - assumeDirectory("$path") + Helpers.assumeDirectory("$path") } } test("on existing file") { - val path = fixturesDir / "ast_simple_main.p8" + val path = Helpers.fixturesDir / "ast_simple_main.p8" shouldThrow { - assumeDirectory("$path") + Helpers.assumeDirectory("$path") } } test("on existing directory") { - val path = workingDir + val path = Helpers.workingDir withClue("should return the path") { - assumeDirectory("$path") shouldBe path + Helpers.assumeDirectory("$path") shouldBe path } } } @@ -136,20 +136,20 @@ class PathsHelpersTests: FunSpec({ context("WithPathAndStringArgs") { test("on non-existing path") { shouldThrow { - assumeDirectory(fixturesDir, "i_do_not_exist") + Helpers.assumeDirectory(Helpers.fixturesDir, "i_do_not_exist") } } test("on existing file") { shouldThrow { - assumeDirectory(fixturesDir, "ast_simple_main.p8") + Helpers.assumeDirectory(Helpers.fixturesDir, "ast_simple_main.p8") } } test("on existing directory") { - val path = workingDir / ".." + val path = Helpers.workingDir / ".." withClue("should return resulting path") { - assumeDirectory(workingDir / "..") shouldBe path + Helpers.assumeDirectory(Helpers.workingDir / "..") shouldBe path } } } @@ -157,20 +157,20 @@ class PathsHelpersTests: FunSpec({ context("WithStringAndStringArgs") { test("on non-existing path") { shouldThrow { - assumeDirectory("$fixturesDir", "i_do_not_exist") + Helpers.assumeDirectory("${Helpers.fixturesDir}", "i_do_not_exist") } } test("on existing file") { shouldThrow { - assumeDirectory("$fixturesDir", "ast_simple_main.p8") + Helpers.assumeDirectory("${Helpers.fixturesDir}", "ast_simple_main.p8") } } test("on existing directory") { - val path = workingDir / ".." + val path = Helpers.workingDir / ".." withClue("should return resulting path") { - assumeDirectory(workingDir / "..") shouldBe path + Helpers.assumeDirectory(Helpers.workingDir / "..") shouldBe path } } } @@ -178,20 +178,20 @@ class PathsHelpersTests: FunSpec({ context("WithStringAndPathArgs") { test("on non-existing path") { shouldThrow { - assumeDirectory("$fixturesDir", Path("i_do_not_exist")) + Helpers.assumeDirectory("${Helpers.fixturesDir}", Path("i_do_not_exist")) } } test("on existing file") { shouldThrow { - assumeDirectory("$fixturesDir", Path("ast_simple_main.p8")) + Helpers.assumeDirectory("${Helpers.fixturesDir}", Path("ast_simple_main.p8")) } } test("on existing directory") { - val path = workingDir / ".." + val path = Helpers.workingDir / ".." withClue("should return resulting path") { - assumeDirectory(workingDir / Path("..")) shouldBe path + Helpers.assumeDirectory(Helpers.workingDir / Path("..")) shouldBe path } } } @@ -202,22 +202,22 @@ class PathsHelpersTests: FunSpec({ context("WithOnePathArg") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" shouldThrow { - assumeReadableFile(path) + Helpers.assumeReadableFile(path) } } test("on readable file") { - val path = fixturesDir / "ast_simple_main.p8" + val path = Helpers.fixturesDir / "ast_simple_main.p8" withClue("should return the path") { - assumeReadableFile(path) shouldBe path + Helpers.assumeReadableFile(path) shouldBe path } } test("on directory") { shouldThrow { - assumeReadableFile(fixturesDir) + Helpers.assumeReadableFile(Helpers.fixturesDir) } } } @@ -225,22 +225,22 @@ class PathsHelpersTests: FunSpec({ context("WithOneStringArg") { test("on non-existing path") { - val path = fixturesDir / "i_do_not_exist" + val path = Helpers.fixturesDir / "i_do_not_exist" shouldThrow { - assumeReadableFile("$path") + Helpers.assumeReadableFile("$path") } } test("on readable file") { - val path = fixturesDir / "ast_simple_main.p8" + val path = Helpers.fixturesDir / "ast_simple_main.p8" withClue("should return the resulting path") { - assumeReadableFile("$path") shouldBe path + Helpers.assumeReadableFile("$path") shouldBe path } } test("on directory") { shouldThrow { - assumeReadableFile("$fixturesDir") + Helpers.assumeReadableFile("${Helpers.fixturesDir}") } } } @@ -248,20 +248,20 @@ class PathsHelpersTests: FunSpec({ context("WithPathAndStringArgs") { test("on non-existing path") { shouldThrow { - assumeReadableFile(fixturesDir, "i_do_not_exist") + Helpers.assumeReadableFile(Helpers.fixturesDir, "i_do_not_exist") } } test("on readable file") { - val path = fixturesDir / "ast_simple_main.p8" + val path = Helpers.fixturesDir / "ast_simple_main.p8" withClue("should return the resulting path") { - assumeReadableFile(fixturesDir / "ast_simple_main.p8") shouldBe path + Helpers.assumeReadableFile(Helpers.fixturesDir / "ast_simple_main.p8") shouldBe path } } test("on directory") { shouldThrow { - assumeReadableFile(fixturesDir, "..") + Helpers.assumeReadableFile(Helpers.fixturesDir, "..") } } } @@ -269,19 +269,19 @@ class PathsHelpersTests: FunSpec({ context("WithPathAndPathArgs") { test("on non-existing path") { shouldThrow { - assumeReadableFile(fixturesDir, Path("i_do_not_exist")) + Helpers.assumeReadableFile(Helpers.fixturesDir, Path("i_do_not_exist")) } } test("on readable file") { withClue("should return the resulting path") { - assumeReadableFile(fixturesDir / Path("ast_simple_main.p8")) shouldBe fixturesDir / "ast_simple_main.p8" + Helpers.assumeReadableFile(Helpers.fixturesDir / Path("ast_simple_main.p8")) shouldBe Helpers.fixturesDir / "ast_simple_main.p8" } } test("on directory") { shouldThrow { - assumeReadableFile(fixturesDir, Path("..")) + Helpers.assumeReadableFile(Helpers.fixturesDir, Path("..")) } } } @@ -289,19 +289,19 @@ class PathsHelpersTests: FunSpec({ context("WithStringAndStringArgs") { test("on non-existing path") { shouldThrow { - assumeReadableFile("$fixturesDir", "i_do_not_exist") + Helpers.assumeReadableFile("${Helpers.fixturesDir}", "i_do_not_exist") } } test("on readable file") { withClue("should return the resulting path") { - assumeReadableFile(fixturesDir / "ast_simple_main.p8") shouldBe fixturesDir / "ast_simple_main.p8" + Helpers.assumeReadableFile(Helpers.fixturesDir / "ast_simple_main.p8") shouldBe Helpers.fixturesDir / "ast_simple_main.p8" } } test("on directory") { shouldThrow { - assumeReadableFile("$fixturesDir", "..") + Helpers.assumeReadableFile("${Helpers.fixturesDir}", "..") } } } diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index 264e98e8a..29cc1569d 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -121,6 +121,7 @@ Directives Can be useful to make sure some data is generated that would otherwise be discarded because the compiler thinks it's not referenced (such as sprite data) - ``align_word`` (in a block) will make the assembler align the start address of this block on a word boundary in memory (so, an even memory address). - ``align_page`` (in a block) will make the assembler align the start address of this block on a page boundary in memory (so, the LSB of the address is 0). + - ``merge`` (in a block) will merge this block's contents into an already existing block with the same name. Useful in library scenarios. .. data:: %asmbinary "" [, [, ]] diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 075883fe5..19b47425a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -12,6 +12,8 @@ For next release Inlined subroutines cannot contain further nested subroutines! Once this works, look for library subroutines that should be inlined. - vm: add support for status bits, status-branch instructions, and cmp() and abs() functions. +- floats: remove all floating point builtin functions and move them to the floats module instead, + note: first try to move only sin and cos and see if the various examples still work! ...