diff --git a/compiler/src/prog8/parser/ModuleParsing.kt b/compiler/src/prog8/parser/ModuleParsing.kt index 364cc2aa6..911ca37fd 100644 --- a/compiler/src/prog8/parser/ModuleParsing.kt +++ b/compiler/src/prog8/parser/ModuleParsing.kt @@ -100,7 +100,51 @@ internal class ModuleImporter { return moduleAst } - private fun discoverImportedModuleFile(name: String, source: Path, position: Position?): Path { + private fun executeImportDirective(program: Program, import: Directive, source: Path): Module? { + if(import.directive!="%import" || import.args.size!=1 || import.args[0].name==null) + throw SyntaxError("invalid import directive", import.position) + val moduleName = import.args[0].name!! + if("$moduleName.p8" == import.position.file) + throw SyntaxError("cannot import self", import.position) + + val existing = program.modules.singleOrNull { it.name == moduleName } + if(existing!=null) + return null + + val rsc = tryGetModuleFromResource("$moduleName.p8") + val importedModule = + if(rsc!=null) { + // load the module from the embedded resource + val (resource, resourcePath) = rsc + resource.use { + println("importing '$moduleName' (library)") + importModule(program, CharStreams.fromStream(it), Paths.get("@embedded@/$resourcePath"), true) + } + } else { + val modulePath = tryGetModuleFromFile(moduleName, source, import.position) + importModule(program, modulePath) + } + + importedModule.checkImportedValid() + return importedModule + } + + private fun tryGetModuleFromResource(name: String): Pair? { + val target = CompilationTarget.instance.name + val targetSpecificPath = "/prog8lib/$target/$name" + val targetSpecificResource = object{}.javaClass.getResourceAsStream(targetSpecificPath) + if(targetSpecificResource!=null) + return Pair(targetSpecificResource, targetSpecificPath) + + val generalPath = "/prog8lib/$name" + val generalResource = object{}.javaClass.getResourceAsStream(generalPath) + if(generalResource!=null) + return Pair(generalResource, generalPath) + + return null + } + + private fun tryGetModuleFromFile(name: String, source: Path, position: Position?): Path { val fileName = "$name.p8" val locations = if(source.toString().isEmpty()) mutableListOf() else mutableListOf(source.parent ?: Path.of(".")) @@ -119,48 +163,4 @@ internal class ModuleImporter { throw ParsingFailedError("$position Import: no module source file '$fileName' found (I've looked in: embedded libs and $locations)") } - - private fun executeImportDirective(program: Program, import: Directive, source: Path): Module? { - if(import.directive!="%import" || import.args.size!=1 || import.args[0].name==null) - throw SyntaxError("invalid import directive", import.position) - val moduleName = import.args[0].name!! - if("$moduleName.p8" == import.position.file) - throw SyntaxError("cannot import self", import.position) - - val existing = program.modules.singleOrNull { it.name == moduleName } - if(existing!=null) - return null - - val rsc = tryGetEmbeddedResource("$moduleName.p8") - val importedModule = - if(rsc!=null) { - // load the module from the embedded resource - val (resource, resourcePath) = rsc - resource.use { - println("importing '$moduleName' (library)") - importModule(program, CharStreams.fromStream(it), Paths.get("@embedded@/$resourcePath"), true) - } - } else { - val modulePath = discoverImportedModuleFile(moduleName, source, import.position) - importModule(program, modulePath) - } - - importedModule.checkImportedValid() - return importedModule - } - - private fun tryGetEmbeddedResource(name: String): Pair? { - val target = CompilationTarget.instance.name - val targetSpecificPath = "/prog8lib/$target/$name" - val targetSpecificResource = object{}.javaClass.getResourceAsStream(targetSpecificPath) - if(targetSpecificResource!=null) - return Pair(targetSpecificResource, targetSpecificPath) - - val generalPath = "/prog8lib/$name" - val generalResource = object{}.javaClass.getResourceAsStream(generalPath) - if(generalResource!=null) - return Pair(generalResource, generalPath) - - return null - } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 2e829a984..d9c7fc0b2 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -6,7 +6,7 @@ TODO - use (zp) addressing mode on 65c02 specific code rather than ldy#0 / lda (zp),y - optimize pointer access code @(pointer)? use a subroutine? macro? 65c02 vs 6502? - can we get rid of the --longOptionName command line options and only keep the short versions? https://github.com/Kotlin/kotlinx-cli/issues/50 -- detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation +- optimizer: detect variables that are written but never read - mark those as unused too and remove them, such as uword unused = memory("unused222", 20) - also remove the memory slab allocation - hoist all variable declarations up to the subroutine scope *before* even the constant folding takes place (to avoid undefined symbol errors when referring to a variable from another nested scope in the subroutine) - make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as '_' - option to load the built-in library files from a directory instead of the embedded ones (for easier library development/debugging) diff --git a/examples/cx16/assembler/assem.p8 b/examples/cx16/assembler/assem.p8 index c51721a2d..3df32fb1d 100644 --- a/examples/cx16/assembler/assem.p8 +++ b/examples/cx16/assembler/assem.p8 @@ -420,6 +420,8 @@ instructions { return am_Invalid } + ; TODO: explore (benchmark) hash based matchers + asmsub match(uword mnemonic_ptr @AY) -> uword @AY { ; -- input: mnemonic_ptr in AY, output: pointer to instruction info structure or $0000 in AY %asm {{ diff --git a/examples/cx16/assembler/perfecthash.py b/examples/cx16/assembler/perfecthash.py index 9f4f27317..a4c32f8a8 100644 --- a/examples/cx16/assembler/perfecthash.py +++ b/examples/cx16/assembler/perfecthash.py @@ -150,24 +150,3 @@ def in_word_set(string: str) -> bool: word = wordlist[index] return word==string return False - - -# if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) -# { -# register unsigned int key = hash (str, len); -# -# if (key <= MAX_HASH_VALUE) -# { -# register int index = lookup[key]; -# -# if (index >= 0) -# { -# register const char *s = wordlist[index]; -# -# if (*str == *s && !strcmp (str + 1, s + 1)) -# return s; -# } -# } -# } -# return 0; -# }