rename mainModule to toplevelModule.

failed module no longer retains in the Ast.
improved some tests on that.
This commit is contained in:
Irmen de Jong 2021-10-19 21:49:05 +02:00
parent e5b9e1f5e7
commit 552e0c2248
7 changed files with 43 additions and 30 deletions

View File

@ -215,12 +215,12 @@ fun parseImports(filepath: Path,
}
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)
val toplevelModule = program.toplevelModule
val outputDirective = (toplevelModule.statements.singleOrNull { it is Directive && it.directive == "%output" } as? Directive)
val launcherDirective = (toplevelModule.statements.singleOrNull { it is Directive && it.directive == "%launcher" } as? Directive)
val outputTypeStr = outputDirective?.args?.single()?.name?.uppercase()
val launcherTypeStr = launcherDirective?.args?.single()?.name?.uppercase()
val zpoption: String? = (mainModule.statements.singleOrNull { it is Directive && it.directive == "%zeropage" }
val zpoption: String? = (toplevelModule.statements.singleOrNull { it is Directive && it.directive == "%zeropage" }
as? Directive)?.args?.single()?.name?.uppercase()
val allOptions = program.modules.flatMap { it.statements }.filter { it is Directive && it.directive == "%option" }
.flatMap { (it as Directive).args }.toSet()
@ -242,7 +242,7 @@ fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget
zpType = ZeropageType.BASICSAFE
}
val zpReserved = mainModule.statements
val zpReserved = toplevelModule.statements
.asSequence()
.filter { it is Directive && it.directive == "%zpreserved" }
.map { (it as Directive).args }

View File

@ -41,7 +41,11 @@ class ModuleImporter(private val program: Program,
val logMsg = "importing '${filePath.nameWithoutExtension}' (from file $srcPath)"
println(logMsg)
return Ok(importModule(SourceCode.File(srcPath)))
val module = importModule(SourceCode.File(srcPath))
return if(module==null)
Err(NoSuchFileException(srcPath.toFile()))
else
Ok(module)
}
fun importLibraryModule(name: String): Module? {
@ -51,19 +55,24 @@ class ModuleImporter(private val program: Program,
return executeImportDirective(import, null)
}
private fun importModule(src: SourceCode) : Module {
private fun importModule(src: SourceCode) : Module? {
val moduleAst = Prog8Parser.parseModule(src)
program.addModule(moduleAst)
// accept additional imports
val lines = moduleAst.statements.toMutableList()
lines.asSequence()
try {
val lines = moduleAst.statements.toMutableList()
lines.asSequence()
.mapIndexed { i, it -> i to it }
.filter { (it.second as? Directive)?.directive == "%import" }
.forEach { executeImportDirective(it.second as Directive, moduleAst) }
moduleAst.statements = lines
return moduleAst
moduleAst.statements = lines
return moduleAst
} catch (x: Exception) {
// in case of error, make sure the module we're importing is no longer in the Ast
program.removeModule(moduleAst)
throw x
}
}
private fun executeImportDirective(import: Directive, importingModule: Module?): Module? {
@ -103,7 +112,8 @@ class ModuleImporter(private val program: Program,
}
)
removeDirectivesFromImportedModule(importedModule)
if(importedModule!=null)
removeDirectivesFromImportedModule(importedModule)
return importedModule
}

View File

@ -13,7 +13,6 @@ import prog8.compiler.ZeropageType
import prog8.compiler.functions.BuiltinFunctions
import prog8.compiler.functions.builtinFunctionReturnType
import prog8.compiler.target.ICompilationTarget
import prog8.parser.SourceCode
import java.io.CharConversionException
import java.io.File
import java.util.*
@ -46,7 +45,7 @@ internal class AstChecker(private val program: Program,
if(compilerOptions.floats) {
if (compilerOptions.zeropage !in arrayOf(ZeropageType.FLOATSAFE, ZeropageType.BASICSAFE, ZeropageType.DONTUSE ))
errors.err("when floats are enabled, zero page type should be 'floatsafe' or 'basicsafe' or 'dontuse'", program.mainModule.position)
errors.err("when floats are enabled, zero page type should be 'floatsafe' or 'basicsafe' or 'dontuse'", program.toplevelModule.position)
}
super.visit(program)

View File

@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.TestInstance
import org.junit.jupiter.api.Disabled
import prog8.ast.Program
import prog8.ast.internedStringsModuleName
import prog8.compiler.IErrorReporter
import prog8.compiler.ModuleImporter
import prog8.parser.ParseError
@ -207,7 +208,6 @@ class TestModuleImporter {
}
@Test
@Disabled("TODO: module that imports faulty module should not be kept in Program.modules")
fun testImportingFileWithSyntaxError_twice() {
doTestImportingFileWithSyntaxError(2)
}
@ -227,7 +227,8 @@ class TestModuleImporter {
assertThat("startCol; should be 0-based", it.position.startCol, equalTo(6))
assertThat("endCol; should be 0-based", it.position.endCol, equalTo(6))
}
assertThat(program.modules.size, equalTo(2))
assertThat("imported module with error in it should not be present", program.modules.size, equalTo(1))
assertThat(program.modules[0].name, equalTo(internedStringsModuleName))
}
}
}
@ -303,7 +304,8 @@ class TestModuleImporter {
assertThat("startCol; should be 0-based", it.position.startCol, equalTo(6))
assertThat("endCol; should be 0-based", it.position.endCol, equalTo(6))
}
assertThat(program.modules.size, equalTo(2))
assertThat("imported module with error in it should not be present", program.modules.size, equalTo(1))
assertThat(program.modules[0].name, equalTo(internedStringsModuleName))
importer.errors.report()
}
}
@ -314,7 +316,6 @@ class TestModuleImporter {
}
@Test
@Disabled("TODO: module that imports faulty module should not be kept in Program.modules")
fun testImportingFileWithSyntaxError_twice() {
doTestImportingFileWithSyntaxError(2)
}

View File

@ -19,7 +19,7 @@ import kotlin.io.path.exists
* They are not really unit tests, but rather tests of the whole process,
* from source file loading all the way through to running 64tass.
*/
//@Disabled("to save some time")
// @Disabled("disable to save some time")
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class TestCompilerOnExamples {
private val examplesDir = assumeDirectory(workingDir, "../examples")
@ -49,7 +49,7 @@ class TestCompilerOnExamples {
}
@TestFactory
// @Disabled
// @Disabled("disable to save some time")
fun bothCx16AndC64() = mapCombinations(
dim1 = listOf(
"animals",
@ -80,7 +80,7 @@ class TestCompilerOnExamples {
)
@TestFactory
// @Disabled
// @Disabled("disable to save some time")
fun onlyC64() = mapCombinations(
dim1 = listOf(
"balloonflight",
@ -99,7 +99,7 @@ class TestCompilerOnExamples {
)
@TestFactory
// @Disabled
// @Disabled("disable to save some time")
fun onlyCx16() = mapCombinations(
dim1 = listOf(
"vtui/testvtui",

View File

@ -19,7 +19,7 @@ import kotlin.test.assertTrue
class TestImportedModulesOrderAndOptions {
@Test
fun testImportedModuleOrderCorrect() {
fun testImportedModuleOrderAndMainModuleCorrect() {
val result = compileText(C64Target, false, """
%import textio
%import floats
@ -30,7 +30,7 @@ main {
}
}
""").assertSuccess()
assertTrue(result.programAst.mainModule.name.startsWith("on_the_fly_test"))
assertTrue(result.programAst.toplevelModule.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")
@ -43,6 +43,8 @@ main {
"math",
"prog8_lib"
), moduleNames.drop(1), "module order in parse tree")
assertTrue(result.programAst.toplevelModule.name.startsWith("on_the_fly_test"))
}
@Test
@ -59,7 +61,7 @@ main {
}
}
""").assertSuccess()
assertTrue(result.programAst.mainModule.name.startsWith("on_the_fly_test"))
assertTrue(result.programAst.toplevelModule.name.startsWith("on_the_fly_test"))
val options = determineCompilationOptions(result.programAst, C64Target)
assertTrue(options.floats)
assertEquals(ZeropageType.DONTUSE, options.zeropage)
@ -86,7 +88,7 @@ main {
filepath.toFile().writeText(sourceText)
val (program, options, importedfiles) = parseImports(filepath, errors, C64Target, emptyList())
assertEquals(filenameBase, program.mainModule.name)
assertEquals(filenameBase, program.toplevelModule.name)
assertEquals(1, importedfiles.size, "all imports other than the test source must have been internal resources library files")
assertEquals(listOf(
internedStringsModuleName,

View File

@ -264,6 +264,8 @@ class Program(val name: String,
return this
}
fun removeModule(module: Module) = _modules.remove(module)
fun moveModuleToFront(module: Module): Program {
require(_modules.contains(module))
{ "Not a module of this program: '${module.name}'"}
@ -285,11 +287,11 @@ class Program(val name: String,
}
}
val mainModule: Module // TODO: rename Program.mainModule - it's NOT necessarily the one containing the main *block*!
val toplevelModule: Module
get() = modules.first { it.name!=internedStringsModuleName }
val definedLoadAddress: Int
get() = mainModule.loadAddress
get() = toplevelModule.loadAddress
var actualLoadAddress: Int = 0
private val internedStringsUnique = mutableMapOf<Pair<String, Boolean>, List<String>>()
@ -344,7 +346,6 @@ class Program(val name: String,
_modules[idx] = replacement
replacement.parent = this // TODO: why not replacement.program = this; replacement.linkParents(namespace)?!
}
}
open class Module(final override var statements: MutableList<Statement>,