prog8 lib modules are now embedded resource files

This commit is contained in:
Irmen de Jong 2019-01-10 19:11:45 +01:00
parent e3eace9e28
commit aa00db4d80
4 changed files with 49 additions and 41 deletions

View File

@ -1,8 +1,7 @@
#!/usr/bin/env sh #!/usr/bin/env sh
PROG8_LIBDIR=./out/production/compiler/prog8lib
PROG8CLASSPATH=./out/production/compiler:./out/production/parser PROG8CLASSPATH=./out/production/compiler:./out/production/parser
KOTLINPATH=${HOME}/.IntelliJIdea2018.3/config/plugins/Kotlin 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 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 $*

View File

@ -30,8 +30,8 @@
memory uword IRQ_VEC = $FFFE ; 6502 interrupt vector, determined by the kernal if banked in 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 ; 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 Screen = $0400 ; to have this as an array[40*25] the compiler would have to support array size > 255
const uword Colors = $d800 ; @todo matrix/array? needs 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) ; the default locations of the 8 sprite pointers (store address of sprite / 64)
memory ubyte SPRPTR0 = 2040 memory ubyte SPRPTR0 = 2040
@ -42,7 +42,7 @@
memory ubyte SPRPTR5 = 2045 memory ubyte SPRPTR5 = 2045
memory ubyte SPRPTR6 = 2046 memory ubyte SPRPTR6 = 2046
memory ubyte SPRPTR7 = 2047 memory ubyte SPRPTR7 = 2047
memory ubyte[8] SPRPTR = 2040 memory ubyte[8] SPRPTR = 2040 ; the 8 sprite pointers as an array.
; ---- VIC-II registers ---- ; ---- VIC-II registers ----
@ -63,7 +63,7 @@
memory ubyte SP6Y = $d00d memory ubyte SP6Y = $d00d
memory ubyte SP7X = $d00e memory ubyte SP7X = $d00e
memory ubyte SP7Y = $d00f 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 MSIGX = $d010
memory ubyte SCROLY = $d011 memory ubyte SCROLY = $d011

View File

@ -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) -> () { 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) ; ---- print the uword in A/Y in decimal form, with left padding 0s (5 positions total)
; @todo shorter in loop form?
%asm {{ %asm {{
jsr c64utils.uword2decimal jsr c64utils.uword2decimal
lda c64utils.word2decimal_output ldy #0
- lda c64utils.word2decimal_output,y
jsr c64.CHROUT jsr c64.CHROUT
lda c64utils.word2decimal_output+1 iny
jsr c64.CHROUT cpy #5
lda c64utils.word2decimal_output+2 bne -
jsr c64.CHROUT rts
lda c64utils.word2decimal_output+3
jsr c64.CHROUT
lda c64utils.word2decimal_output+4
jmp c64.CHROUT
}} }}
} }

View File

@ -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('.') fun importModule(stream: CharStream, moduleName: String): Module {
val input = CharStreams.fromPath(filePath) val lexer = prog8Lexer(stream)
val lexer = prog8Lexer(input)
val lexerErrors = LexerErrorListener() val lexerErrors = LexerErrorListener()
lexer.addErrorListener(lexerErrors) lexer.addErrorListener(lexerErrors)
val tokens = CommentHandlingTokenStream(lexer) val tokens = CommentHandlingTokenStream(lexer)
@ -45,7 +31,7 @@ fun importModule(filePath: Path) : Module {
val parseTree = parser.module() val parseTree = parser.module()
val numberOfErrors = parser.numberOfSyntaxErrors + lexerErrors.numberOfErrors val numberOfErrors = parser.numberOfSyntaxErrors + lexerErrors.numberOfErrors
if(numberOfErrors > 0) 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: // You can do something with the parsed comments:
// tokens.commentTokens().forEach { println(it) } // tokens.commentTokens().forEach { println(it) }
@ -63,7 +49,7 @@ fun importModule(filePath: Path) : Module {
.asSequence() .asSequence()
.mapIndexed { i, it -> Pair(i, it) } .mapIndexed { i, it -> Pair(i, it) }
.filter { (it.second as? Directive)?.directive == "%import" } .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() .toList()
imports.reversed().forEach { 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 fileName = "$name.p8"
val locations = mutableListOf(Paths.get(importedFrom.parent.toString())) 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) if(import.directive!="%import" || import.args.size!=1 || import.args[0].name==null)
throw SyntaxError("invalid import directive", import.position) throw SyntaxError("invalid import directive", import.position)
val moduleName = import.args[0].name!! val moduleName = import.args[0].name!!
@ -114,9 +117,19 @@ fun executeImportDirective(import: Directive, importedFrom: Path): Module? {
if(importedModules.containsKey(moduleName)) if(importedModules.containsKey(moduleName))
return null return null
val modulePath = discoverImportedModule(moduleName, importedFrom, import.position) val resource = import::class.java.getResource("/prog8lib/$moduleName.p8")
val importedModule = importModule(modulePath) val importedModule =
importedModule.checkImportedValid() 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 return importedModule
} }