From aa00db4d80823f4af189913d00c0da473f03b3df Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 10 Jan 2019 19:11:45 +0100 Subject: [PATCH] prog8 lib modules are now embedded resource files --- compile.sh | 3 +- compiler/res/prog8lib/c64lib.p8 | 10 ++-- compiler/res/prog8lib/c64utils.p8 | 16 +++--- compiler/src/prog8/parser/ModuleParsing.kt | 61 +++++++++++++--------- 4 files changed, 49 insertions(+), 41 deletions(-) diff --git a/compile.sh b/compile.sh index 1628aafa2..00f1b8851 100755 --- a/compile.sh +++ b/compile.sh @@ -1,8 +1,7 @@ #!/usr/bin/env sh -PROG8_LIBDIR=./out/production/compiler/prog8lib PROG8CLASSPATH=./out/production/compiler:./out/production/parser KOTLINPATH=${HOME}/.IntelliJIdea2018.3/config/plugins/Kotlin LIBJARS=${KOTLINPATH}/lib/kotlin-stdlib.jar:${KOTLINPATH}/lib/kotlin-reflect.jar:./parser//antlr/lib/antlr-runtime-4.7.2.jar -java -Dprog8.libdir=${PROG8_LIBDIR} -cp ${PROG8CLASSPATH}:${LIBJARS} prog8.CompilerMainKt $* +java -cp ${PROG8CLASSPATH}:${LIBJARS} prog8.CompilerMainKt $* diff --git a/compiler/res/prog8lib/c64lib.p8 b/compiler/res/prog8lib/c64lib.p8 index 8de5f1ba9..ac9ee9a22 100644 --- a/compiler/res/prog8lib/c64lib.p8 +++ b/compiler/res/prog8lib/c64lib.p8 @@ -30,9 +30,9 @@ memory uword IRQ_VEC = $FFFE ; 6502 interrupt vector, determined by the kernal if banked in ; the default addresses for the character screen chars and colors - const uword Screen = $0400 ; @todo matrix/array? needs to support array size > 255 - const uword Colors = $d800 ; @todo matrix/array? needs to support array size > 255 - + const uword Screen = $0400 ; to have this as an array[40*25] the compiler would have to support array size > 255 + const uword Colors = $d800 ; to have this as an array[40*25] the compiler would have to support array size > 255 + ; the default locations of the 8 sprite pointers (store address of sprite / 64) memory ubyte SPRPTR0 = 2040 memory ubyte SPRPTR1 = 2041 @@ -42,7 +42,7 @@ memory ubyte SPRPTR5 = 2045 memory ubyte SPRPTR6 = 2046 memory ubyte SPRPTR7 = 2047 - memory ubyte[8] SPRPTR = 2040 + memory ubyte[8] SPRPTR = 2040 ; the 8 sprite pointers as an array. ; ---- VIC-II registers ---- @@ -63,7 +63,7 @@ memory ubyte SP6Y = $d00d memory ubyte SP7X = $d00e memory ubyte SP7Y = $d00f - memory ubyte[16] SPXY = $d000 + memory ubyte[16] SPXY = $d000 ; the 8 sprite X and Y registers as an array. memory ubyte MSIGX = $d010 memory ubyte SCROLY = $d011 diff --git a/compiler/res/prog8lib/c64utils.p8 b/compiler/res/prog8lib/c64utils.p8 index 397a9f793..e29c2457c 100644 --- a/compiler/res/prog8lib/c64utils.p8 +++ b/compiler/res/prog8lib/c64utils.p8 @@ -929,19 +929,15 @@ asmsub print_uwhex (ubyte prefix @ Pc, uword value @ AY) -> clobbers(A,X,Y) -> asmsub print_uw0 (uword value @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total) - ; @todo shorter in loop form? %asm {{ jsr c64utils.uword2decimal - lda c64utils.word2decimal_output + ldy #0 +- lda c64utils.word2decimal_output,y jsr c64.CHROUT - lda c64utils.word2decimal_output+1 - jsr c64.CHROUT - lda c64utils.word2decimal_output+2 - jsr c64.CHROUT - lda c64utils.word2decimal_output+3 - jsr c64.CHROUT - lda c64utils.word2decimal_output+4 - jmp c64.CHROUT + iny + cpy #5 + bne - + rts }} } diff --git a/compiler/src/prog8/parser/ModuleParsing.kt b/compiler/src/prog8/parser/ModuleParsing.kt index 9da40d9a8..5ec54b819 100644 --- a/compiler/src/prog8/parser/ModuleParsing.kt +++ b/compiler/src/prog8/parser/ModuleParsing.kt @@ -21,23 +21,9 @@ private class LexerErrorListener: BaseErrorListener() { } } -fun importModule(filePath: Path) : Module { - print("importing '${filePath.fileName}'") - if(filePath.parent!=null) { - var importloc = filePath.toString() - val curdir = Paths.get("").toAbsolutePath().toString() - if(importloc.startsWith(curdir)) - importloc = "." + importloc.substring(curdir.length) - println(" (from '$importloc')") - } - else - println("") - if(!Files.isReadable(filePath)) - throw ParsingFailedError("No such file: $filePath") - val moduleName = filePath.fileName.toString().substringBeforeLast('.') - val input = CharStreams.fromPath(filePath) - val lexer = prog8Lexer(input) +fun importModule(stream: CharStream, moduleName: String): Module { + val lexer = prog8Lexer(stream) val lexerErrors = LexerErrorListener() lexer.addErrorListener(lexerErrors) val tokens = CommentHandlingTokenStream(lexer) @@ -45,7 +31,7 @@ fun importModule(filePath: Path) : Module { val parseTree = parser.module() val numberOfErrors = parser.numberOfSyntaxErrors + lexerErrors.numberOfErrors if(numberOfErrors > 0) - throw ParsingFailedError("There are $numberOfErrors errors in '${filePath.fileName}'.") + throw ParsingFailedError("There are $numberOfErrors errors in '$moduleName.p8'.") // You can do something with the parsed comments: // tokens.commentTokens().forEach { println(it) } @@ -63,7 +49,7 @@ fun importModule(filePath: Path) : Module { .asSequence() .mapIndexed { i, it -> Pair(i, it) } .filter { (it.second as? Directive)?.directive == "%import" } - .map { Pair(it.first, executeImportDirective(it.second as Directive, filePath)) } + .map { Pair(it.first, executeImportDirective(it.second as Directive, Paths.get("$moduleName.p8"))) } .toList() imports.reversed().forEach { @@ -81,10 +67,27 @@ fun importModule(filePath: Path) : Module { } -fun discoverImportedModule(name: String, importedFrom: Path, position: Position?): Path { +fun importModule(filePath: Path) : Module { + print("importing '${filePath.fileName}'") + if(filePath.parent!=null) { + var importloc = filePath.toString() + val curdir = Paths.get("").toAbsolutePath().toString() + if(importloc.startsWith(curdir)) + importloc = "." + importloc.substring(curdir.length) + println(" (from '$importloc')") + } + else + println("") + if(!Files.isReadable(filePath)) + throw ParsingFailedError("No such file: $filePath") - // @todo: be able to actually load the library p8's as a resource instead of from a file + val moduleName = filePath.fileName.toString().substringBeforeLast('.') + val input = CharStreams.fromPath(filePath) + return importModule(input, moduleName) +} + +private fun discoverImportedModuleFile(name: String, importedFrom: Path, position: Position?): Path { val fileName = "$name.p8" val locations = mutableListOf(Paths.get(importedFrom.parent.toString())) @@ -105,7 +108,7 @@ fun discoverImportedModule(name: String, importedFrom: Path, position: Position? } -fun executeImportDirective(import: Directive, importedFrom: Path): Module? { +private fun executeImportDirective(import: Directive, importedFrom: 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!! @@ -114,9 +117,19 @@ fun executeImportDirective(import: Directive, importedFrom: Path): Module? { if(importedModules.containsKey(moduleName)) return null - val modulePath = discoverImportedModule(moduleName, importedFrom, import.position) - val importedModule = importModule(modulePath) - importedModule.checkImportedValid() + val resource = import::class.java.getResource("/prog8lib/$moduleName.p8") + val importedModule = + if(resource!=null) { + // load the module from the embedded resource + resource.openStream().use { + println("importing '$moduleName' (embedded library)") + importModule(CharStreams.fromStream(it), moduleName) + } + } else { + val modulePath = discoverImportedModuleFile(moduleName, importedFrom, import.position) + importModule(modulePath) + } + importedModule.checkImportedValid() return importedModule }