diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index e0ae421e1..e3166773e 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -168,7 +168,7 @@ private class BuiltinFunctionsFacade(functions: Map): IBuilt builtinFunctionReturnType(name, args, program) } -private fun parseImports(filepath: Path, +fun parseImports(filepath: Path, errors: IErrorReporter, compTarget: ICompilationTarget, libdirs: List): Triple> { @@ -200,7 +200,7 @@ private fun parseImports(filepath: Path, return Triple(programAst, compilerOptions, importedFiles) } -private fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget): CompilationOptions { +fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget): CompilationOptions { val mainModule = program.mainModule val outputDirective = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%output" } as? Directive) val launcherDirective = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%launcher" } as? Directive) diff --git a/compiler/test/TestImportedModulesOrderAndOptions.kt b/compiler/test/TestImportedModulesOrderAndOptions.kt new file mode 100644 index 000000000..7cb3d061b --- /dev/null +++ b/compiler/test/TestImportedModulesOrderAndOptions.kt @@ -0,0 +1,97 @@ +package prog8tests + +import org.junit.jupiter.api.* +import prog8.ast.internedStringsModuleName +import prog8.compiler.* +import prog8tests.helpers.* + +import prog8.compiler.target.C64Target +import kotlin.test.assertEquals +import kotlin.test.assertTrue + + +@TestInstance(TestInstance.Lifecycle.PER_CLASS) +class TestImportedModulesOrderAndOptions { + + @Test + fun testImportedModuleOrderCorrect() { + val result = compileText(C64Target, false, """ +%import textio +%import floats + +main { + sub start() { + ; nothing + } +} +""").assertSuccess() + assertTrue(result.programAst.mainModule.name.startsWith("on_the_fly_test")) + + val moduleNames = result.programAst.modules.map { it.name } + assertTrue(moduleNames[0].startsWith("on_the_fly_test"), "main module must be first") + assertEquals(listOf( + "prog8_interned_strings", + "textio", + "syslib", + "conv", + "floats", + "math", + "prog8_lib" + ), moduleNames.drop(1), "module order in parse tree") + } + + @Test + fun testCompilationOptionsCorrectFromMain() { + val result = compileText(C64Target, false, """ +%import textio +%import floats +%zeropage dontuse +%option no_sysinit + +main { + sub start() { + ; nothing + } +} +""").assertSuccess() + assertTrue(result.programAst.mainModule.name.startsWith("on_the_fly_test")) + val options = determineCompilationOptions(result.programAst, C64Target) + assertTrue(options.floats) + assertEquals(ZeropageType.DONTUSE, options.zeropage) + assertTrue(options.noSysInit) + } + + @Test + fun testModuleOrderAndCompilationOptionsCorrectWithJustImports() { + val errors = ErrorReporter() + val sourceText = """ +%import textio +%import floats +%option no_sysinit +%zeropage dontuse + +main { + sub start() { + ; nothing + } +} +""" + val filenameBase = "on_the_fly_test_" + sourceText.hashCode().toUInt().toString(16) + val filepath = outputDir.resolve("$filenameBase.p8") + filepath.toFile().writeText(sourceText) + val (program, options, importedfiles) = parseImports(filepath, errors, C64Target, emptyList()) + + assertEquals(filenameBase, program.mainModule.name) + assertEquals(1, importedfiles.size, "all imports other than the test source must have been internal resources library files") + assertEquals(listOf( + internedStringsModuleName, + filenameBase, + "textio", "syslib", "conv", "floats", "math", "prog8_lib" + ), program.modules.map {it.name}, "module order in parse tree") + assertTrue(options.floats) + assertEquals(ZeropageType.DONTUSE, options.zeropage, "zeropage option must be correctly taken from main module, not from float module import logic") + assertTrue(options.noSysInit) + } + + +} diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt index 861f80f68..6d20882a5 100644 --- a/compilerAst/src/prog8/ast/AstToplevel.kt +++ b/compilerAst/src/prog8/ast/AstToplevel.kt @@ -251,7 +251,7 @@ class Program(val name: String, fun addModule(module: Module): Program { require(null == _modules.firstOrNull { it.name == module.name }) { "module '${module.name}' already present" } - _modules.add(0, module) + _modules.add(module) module.linkParents(namespace) module.program = this return this