From 17068130bb585c2c9fb6e096520d345753ba3a70 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 28 Apr 2021 20:04:23 +0200 Subject: [PATCH] removed PROG8_LIBDIR env variables and replaced with -libdirs command line option --- compiler/res/prog8lib/cx16/gfx2.p8 | 2 - compiler/src/prog8/CompilerMain.kt | 15 +++++--- compiler/src/prog8/compiler/Compiler.kt | 16 ++++---- compilerAst/src/prog8/parser/ModuleParsing.kt | 37 +++++++------------ docs/source/building.rst | 8 ++-- .../src/prog8/http/TestHttp.kt | 2 +- 6 files changed, 37 insertions(+), 43 deletions(-) diff --git a/compiler/res/prog8lib/cx16/gfx2.p8 b/compiler/res/prog8lib/cx16/gfx2.p8 index 0ee325008..9183e2cbc 100644 --- a/compiler/res/prog8lib/cx16/gfx2.p8 +++ b/compiler/res/prog8lib/cx16/gfx2.p8 @@ -23,8 +23,6 @@ ; higher color dephts in highres are not supported due to lack of VRAM -; TODO use trb / tsb instructions more for and/or bit manipulations? - ; TODO can we make a FB vector table and emulation routines for the Cx16s' GRAPH_init() call? to replace the builtin 320x200 fb driver? gfx2 { diff --git a/compiler/src/prog8/CompilerMain.kt b/compiler/src/prog8/CompilerMain.kt index 64c5c443c..4f3751838 100644 --- a/compiler/src/prog8/CompilerMain.kt +++ b/compiler/src/prog8/CompilerMain.kt @@ -1,15 +1,13 @@ package prog8 -import kotlinx.cli.ArgParser -import kotlinx.cli.ArgType -import kotlinx.cli.default -import kotlinx.cli.multiple +import kotlinx.cli.* import prog8.ast.base.AstException import prog8.compiler.CompilationResult import prog8.compiler.compileProgram import prog8.compiler.target.C64Target import prog8.compiler.target.Cx16Target import prog8.parser.ParsingFailedError +import java.io.File import java.nio.file.FileSystems import java.nio.file.Path import java.nio.file.StandardWatchEventKinds @@ -43,6 +41,7 @@ private fun compileMain(args: Array) { val slowCodegenWarnings by cli.option(ArgType.Boolean, fullName = "slowwarn", description="show debug warnings about slow/problematic assembly code generation") val compilationTarget by cli.option(ArgType.String, fullName = "target", description = "target output of the compiler, currently '${C64Target.name}' and '${Cx16Target.name}' available").default(C64Target.name) val moduleFiles by cli.argument(ArgType.String, fullName = "modules", description = "main module file(s) to compile").multiple(999) + val libDirs by cli.option(ArgType.String, fullName="libdirs", description = "list of extra paths to search in for imported modules").multiple().delimiter(File.pathSeparator) try { cli.parse(args) @@ -57,6 +56,10 @@ private fun compileMain(args: Array) { exitProcess(1) } + val libdirs = libDirs.toMutableList() + if(libdirs.firstOrNull()!=".") + libdirs.add(0, ".") + if(watchMode==true) { val watchservice = FileSystems.getDefault().newWatchService() val allImportedFiles = mutableSetOf() @@ -66,7 +69,7 @@ private fun compileMain(args: Array) { val results = mutableListOf() for(filepathRaw in moduleFiles) { val filepath = pathFrom(filepathRaw).normalize() - val compilationResult = compileProgram(filepath, dontOptimize!=true, dontWriteAssembly!=true, slowCodegenWarnings==true, compilationTarget, outputPath) + val compilationResult = compileProgram(filepath, dontOptimize!=true, dontWriteAssembly!=true, slowCodegenWarnings==true, compilationTarget, libdirs, outputPath) results.add(compilationResult) } @@ -103,7 +106,7 @@ private fun compileMain(args: Array) { val filepath = pathFrom(filepathRaw).normalize() val compilationResult: CompilationResult try { - compilationResult = compileProgram(filepath, dontOptimize!=true, dontWriteAssembly!=true, slowCodegenWarnings==true, compilationTarget, outputPath) + compilationResult = compileProgram(filepath, dontOptimize!=true, dontWriteAssembly!=true, slowCodegenWarnings==true, compilationTarget, libdirs, outputPath) if(!compilationResult.success) exitProcess(1) } catch (x: ParsingFailedError) { diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 45814dcd1..d133dc3d7 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -70,6 +70,7 @@ fun compileProgram(filepath: Path, writeAssembly: Boolean, slowCodegenWarnings: Boolean, compilationTarget: String, + libdirs: List, outputDir: Path): CompilationResult { var programName = "" lateinit var programAst: Program @@ -89,7 +90,7 @@ fun compileProgram(filepath: Path, try { val totalTime = measureTimeMillis { // import main module and everything it needs - val (ast, compilationOptions, imported) = parseImports(filepath, errors, compTarget) + val (ast, compilationOptions, imported) = parseImports(filepath, errors, compTarget, libdirs) compilationOptions.slowCodegenWarnings = slowCodegenWarnings compilationOptions.optimize = optimize programAst = ast @@ -165,14 +166,15 @@ private class BuiltinFunctionsFacade(functions: Map): IBuilt builtinFunctionReturnType(name, args, program) } -private fun parseImports(filepath: Path, errors: IErrorReporter, compTarget: ICompilationTarget): Triple> { +private fun parseImports(filepath: Path, errors: IErrorReporter, compTarget: ICompilationTarget, libdirs: List): Triple> { val compilationTargetName = compTarget.name println("Compiler target: $compilationTargetName. Parsing...") - val importer = ModuleImporter() val bf = BuiltinFunctionsFacade(BuiltinFunctions) val programAst = Program(moduleName(filepath.fileName), mutableListOf(), bf, compTarget) bf.program = programAst - importer.importModule(programAst, filepath, compTarget, compilationTargetName) + + val importer = ModuleImporter(programAst, compTarget, compilationTargetName, libdirs) + importer.importModule(filepath) errors.report() val importedFiles = programAst.modules.filter { !it.source.startsWith("@embedded@") }.map { it.source } @@ -182,11 +184,11 @@ private fun parseImports(filepath: Path, errors: IErrorReporter, compTarget: ICo // depending on the machine and compiler options we may have to include some libraries for(lib in compTarget.machine.importLibs(compilerOptions, compilationTargetName)) - importer.importLibraryModule(programAst, lib, compTarget, compilationTargetName) + importer.importLibraryModule(lib) // always import prog8_lib and math - importer.importLibraryModule(programAst, "math", compTarget, compilationTargetName) - importer.importLibraryModule(programAst, "prog8_lib", compTarget, compilationTargetName) + importer.importLibraryModule("math") + importer.importLibraryModule("prog8_lib") errors.report() return Triple(programAst, compilerOptions, importedFiles) } diff --git a/compilerAst/src/prog8/parser/ModuleParsing.kt b/compilerAst/src/prog8/parser/ModuleParsing.kt index 415b4fa5d..7e9c37e35 100644 --- a/compilerAst/src/prog8/parser/ModuleParsing.kt +++ b/compilerAst/src/prog8/parser/ModuleParsing.kt @@ -25,9 +25,9 @@ fun moduleName(fileName: Path) = fileName.toString().substringBeforeLast('.') internal fun pathFrom(stringPath: String, vararg rest: String): Path = FileSystems.getDefault().getPath(stringPath, *rest) -class ModuleImporter { +class ModuleImporter(val program: Program, val encoder: IStringEncoding, val compilationTargetName: String, val libdirs: List) { - fun importModule(program: Program, filePath: Path, encoder: IStringEncoding, compilationTargetName: String): Module { + fun importModule(filePath: Path): Module { print("importing '${moduleName(filePath.fileName)}'") if(filePath.parent!=null) { var importloc = filePath.toString() @@ -42,15 +42,14 @@ class ModuleImporter { throw ParsingFailedError("No such file: $filePath") val content = filePath.toFile().readText().replace("\r\n", "\n") - return importModule(program, CharStreams.fromString(content), filePath, false, encoder, compilationTargetName) + return importModule(CharStreams.fromString(content), filePath, false) } - fun importLibraryModule(program: Program, name: String, - encoder: IStringEncoding, compilationTargetName: String): Module? { + fun importLibraryModule(name: String): Module? { val import = Directive("%import", listOf( DirectiveArg("", name, 42, position = Position("<<>>", 0, 0, 0)) ), Position("<<>>", 0, 0, 0)) - return executeImportDirective(program, import, Paths.get(""), encoder, compilationTargetName) + return executeImportDirective(import, Paths.get("")) } private class MyErrorListener: ConsoleErrorListener() { @@ -67,8 +66,7 @@ class ModuleImporter { } } - private fun importModule(program: Program, stream: CharStream, modulePath: Path, isLibrary: Boolean, - encoder: IStringEncoding, compilationTargetName: String): Module { + private fun importModule(stream: CharStream, modulePath: Path, isLibrary: Boolean): Module { val moduleName = moduleName(modulePath.fileName) val lexer = CustomLexer(modulePath, stream) lexer.removeErrorListeners() @@ -97,14 +95,13 @@ class ModuleImporter { lines.asSequence() .mapIndexed { i, it -> i to it } .filter { (it.second as? Directive)?.directive == "%import" } - .forEach { executeImportDirective(program, it.second as Directive, modulePath, encoder, compilationTargetName) } + .forEach { executeImportDirective(it.second as Directive, modulePath) } moduleAst.statements = lines return moduleAst } - private fun executeImportDirective(program: Program, import: Directive, source: Path, - encoder: IStringEncoding, compilationTargetName: String): Module? { + private fun executeImportDirective(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!! @@ -123,12 +120,11 @@ class ModuleImporter { resource.use { println("importing '$moduleName' (library)") val content = it.reader().readText().replace("\r\n", "\n") - importModule(program, CharStreams.fromString(content), Paths.get("@embedded@/$resourcePath"), - true, encoder, compilationTargetName) + importModule(CharStreams.fromString(content), Paths.get("@embedded@/$resourcePath"), true) } } else { val modulePath = tryGetModuleFromFile(moduleName, source, import.position) - importModule(program, modulePath, encoder, compilationTargetName) + importModule(modulePath) } removeDirectivesFromImportedModule(importedModule) @@ -160,15 +156,10 @@ class ModuleImporter { 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(".")) - - val propPath = System.getProperty("prog8.libdir") - if(propPath!=null) - locations.add(pathFrom(propPath)) - val envPath = System.getenv("PROG8_LIBDIR") - if(envPath!=null) - locations.add(pathFrom(envPath)) - locations.add(Paths.get(Paths.get("").toAbsolutePath().toString(), "prog8lib")) + val libpaths = libdirs.map {Path.of(it)} + val locations = + (if(source.toString().isEmpty()) libpaths else libpaths.drop(1) + (source.parent ?: Path.of("."))) + + Paths.get(Paths.get("").toAbsolutePath().toString(), "prog8lib") locations.forEach { val file = pathFrom(it.toString(), fileName) diff --git a/docs/source/building.rst b/docs/source/building.rst index 86d825b39..c4851863c 100644 --- a/docs/source/building.rst +++ b/docs/source/building.rst @@ -117,11 +117,11 @@ They are embedded into the packaged release version of the compiler so you don't where they are, but their names are still reserved. -User defined library files -^^^^^^^^^^^^^^^^^^^^^^^^^^ +User defined library files and -location +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can create library files yourself too that can be shared among programs. -You can tell the compiler where it should look for these files, by setting the java command line property ``prog8.libdir`` -or by setting the ``PROG8_LIBDIR`` environment variable to the correct directory. +You can tell the compiler where it should look for these files, by using +the libdirs command line option. .. _debugging: diff --git a/httpCompilerService/src/prog8/http/TestHttp.kt b/httpCompilerService/src/prog8/http/TestHttp.kt index e46e8c946..8820fde7f 100644 --- a/httpCompilerService/src/prog8/http/TestHttp.kt +++ b/httpCompilerService/src/prog8/http/TestHttp.kt @@ -29,7 +29,7 @@ class RequestParser : Take { val form = RqFormBase(request) val names = form.names() val a = form.param("a").single() - val compilationResult = compileProgram(Path.of(a), true, true, true, "c64", Path.of(".")) + val compilationResult = compileProgram(Path.of(a), true, true, true, "c64", emptyList(), Path.of(".")) return RsJson(Jsonding()) } }