diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 83452ba8e..35f66ed6b 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -367,10 +367,10 @@ internal fun determineCompilationOptions(program: Program, compTarget: ICompilat 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 outputTypeStr = outputDirective?.args?.single()?.string?.uppercase() + val launcherTypeStr = launcherDirective?.args?.single()?.string?.uppercase() val zpoption: String? = (toplevelModule.statements.singleOrNull { it is Directive && it.directive == "%zeropage" } - as? Directive)?.args?.single()?.name?.uppercase() + as? Directive)?.args?.single()?.string?.uppercase() val allOptions = program.modules.flatMap { it.options() }.toSet() val floatsEnabled = "enable_floats" in allOptions var noSysInit = "no_sysinit" in allOptions diff --git a/compiler/src/prog8/compiler/ModuleImporter.kt b/compiler/src/prog8/compiler/ModuleImporter.kt index 10ce163ac..d60537f43 100644 --- a/compiler/src/prog8/compiler/ModuleImporter.kt +++ b/compiler/src/prog8/compiler/ModuleImporter.kt @@ -46,7 +46,7 @@ class ModuleImporter(private val program: Program, fun importImplicitLibraryModule(name: String): Module? { val import = Directive("%import", listOf( - DirectiveArg("", name, 42u, position = Position("<<>>", 0, 0, 0)) + DirectiveArg(name, 42u, position = Position("<<>>", 0, 0, 0)) ), Position("<<>>", 0, 0, 0)) return executeImportDirective(import, null) } @@ -75,9 +75,7 @@ class ModuleImporter(private val program: Program, private fun executeImportDirective(import: Directive, importingModule: Module?): Module? { if(import.directive!="%import" || import.args.size!=1) throw SyntaxError("invalid import directive", import.position) - if(!import.args[0].str.isNullOrEmpty() || import.args[0].name==null) - throw SyntaxError("%import requires unquoted module name", import.position) - val moduleName = import.args[0].name!! + val moduleName = import.args[0].string!! if("$moduleName.p8" == import.position.file) throw SyntaxError("cannot import self", import.position) diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 67307f99d..3c252baee 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -955,24 +955,24 @@ internal class AstChecker(private val program: Program, "%output" -> { if(directive.parent !is Module) err("this directive may only occur at module level") - if(directive.args.size!=1 || directive.args[0].name !in OutputType.entries.map {it.name.lowercase()}) + if(directive.args.size!=1 || directive.args[0].string !in OutputType.entries.map {it.name.lowercase()}) err("invalid output directive type") } "%launcher" -> { if(directive.parent !is Module) err("this directive may only occur at module level") - if(directive.args.size!=1 || directive.args[0].name !in CbmPrgLauncherType.entries.map{it.name.lowercase()}) + if(directive.args.size!=1 || directive.args[0].string !in CbmPrgLauncherType.entries.map{it.name.lowercase()}) err("invalid launcher directive type") } "%zeropage" -> { if(directive.parent !is Module) err("this directive may only occur at module level") if(directive.args.size!=1 || - directive.args[0].name != "basicsafe" && - directive.args[0].name != "floatsafe" && - directive.args[0].name != "kernalsafe" && - directive.args[0].name != "dontuse" && - directive.args[0].name != "full") + directive.args[0].string != "basicsafe" && + directive.args[0].string != "floatsafe" && + directive.args[0].string != "kernalsafe" && + directive.args[0].string != "dontuse" && + directive.args[0].string != "full") err("invalid zp type, expected basicsafe, floatsafe, kernalsafe, dontuse, or full") } "%zpreserved", "%zpallowed" -> { @@ -998,9 +998,9 @@ internal class AstChecker(private val program: Program, "%import" -> { if(directive.parent !is Module) err("this directive may only occur at module level") - if(directive.args.size!=1 || directive.args[0].name==null) + if(directive.args.size!=1 || directive.args[0].string==null) err("invalid import directive, expected module name argument") - if(directive.args[0].name == (directive.parent as? Module)?.name) + if(directive.args[0].string == (directive.parent as? Module)?.name) err("invalid import directive, cannot import itself") } "%breakpoint" -> { @@ -1012,44 +1012,44 @@ internal class AstChecker(private val program: Program, "%asminclude" -> { if(directive.parent !is INameScope || directive.parent is Module) err("this directive can't be used here") - if(directive.args.size!=1 || directive.args[0].str==null) + if(directive.args.size!=1 || directive.args[0].string==null) err("invalid asminclude directive, expected argument: \"filename\"") - checkFileExists(directive, directive.args[0].str!!) + checkFileExists(directive, directive.args[0].string!!) } "%asmbinary" -> { if(directive.parent !is INameScope || directive.parent is Module) err("this directive can't be used here") val errormsg = "invalid asmbinary directive, expected arguments: \"filename\" [, offset [, length ] ]" if(directive.args.isEmpty()) err(errormsg) - else if(directive.args[0].str==null) err(errormsg) + else if(directive.args[0].string==null) err(errormsg) else if(directive.args.size>=2 && directive.args[1].int==null) err(errormsg) else if(directive.args.size==3 && directive.args[2].int==null) err(errormsg) else if(directive.args.size>3) err(errormsg) - else checkFileExists(directive, directive.args[0].str!!) + else checkFileExists(directive, directive.args[0].string!!) } "%option" -> { if(directive.parent !is Block && directive.parent !is Module) err("this directive may only occur in a block or at module level") if(directive.args.isEmpty()) err("missing option directive argument(s)") - else if(directive.args.map{it.name in arrayOf("enable_floats", "force_output", "no_sysinit", "merge", "verafxmuls", "no_symbol_prefixing", "ignore_unused")}.any { !it }) + else if(directive.args.map{it.string in arrayOf("enable_floats", "force_output", "no_sysinit", "merge", "verafxmuls", "no_symbol_prefixing", "ignore_unused")}.any { !it }) err("invalid option directive argument(s)") if(directive.parent is Block) { - if(directive.args.any {it.name !in arrayOf("force_output", "merge", "verafxmuls", "no_symbol_prefixing", "ignore_unused")}) + if(directive.args.any {it.string !in arrayOf("force_output", "merge", "verafxmuls", "no_symbol_prefixing", "ignore_unused")}) err("using an option that is not valid for blocks") } if(directive.parent is Module) { - if(directive.args.any {it.name !in arrayOf("enable_floats", "no_sysinit", "no_symbol_prefixing", "ignore_unused")}) + if(directive.args.any {it.string !in arrayOf("enable_floats", "no_sysinit", "no_symbol_prefixing", "ignore_unused")}) err("using an option that is not valid for modules") } - if(directive.args.any { it.name=="verafxmuls" } && compilerOptions.compTarget.name != Cx16Target.NAME) + if(directive.args.any { it.string=="verafxmuls" } && compilerOptions.compTarget.name != Cx16Target.NAME) err("verafx option is only valid on cx16 target") } "%encoding" -> { if(directive.parent !is Module) err("this directive may only occur at module level") val allowedEncodings = Encoding.entries.map {it.prefix} - if(directive.args.size!=1 || directive.args[0].name !in allowedEncodings) + if(directive.args.size!=1 || directive.args[0].string !in allowedEncodings) err("invalid encoding directive, expected one of $allowedEncodings") } else -> throw SyntaxError("invalid directive ${directive.directive}", directive.position) diff --git a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt index 3689da22d..1f8ab4620 100644 --- a/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SimplifiedAstMaker.kt @@ -201,13 +201,13 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro val directives = srcBlock.statements.filterIsInstance() for (directive in directives.filter { it.directive == "%option" }) { for (arg in directive.args) { - when (arg.name) { + when (arg.string) { "no_symbol_prefixing" -> noSymbolPrefixing = true "ignore_unused" -> ignoreUnused = true "force_output" -> forceOutput = true "merge" -> { /* ignore this one */ } "verafxmuls" -> veraFxMuls = true - else -> throw FatalAstException("weird directive option: ${arg.name}") + else -> throw FatalAstException("weird directive option: ${arg.string}") } } } @@ -253,7 +253,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro PtAlign(align, directive.position) } "%asmbinary" -> { - val filename = directive.args[0].str!! + val filename = directive.args[0].string!! val offset: UInt? = if(directive.args.size>=2) directive.args[1].int!! else null val length: UInt? = if(directive.args.size>=3) directive.args[2].int!! else null val abspath = if(File(filename).isFile) { @@ -268,7 +268,7 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro throw FatalAstException("included file doesn't exist") } "%asminclude" -> { - val result = loadAsmIncludeFile(directive.args[0].str!!, directive.definingModule.source) + val result = loadAsmIncludeFile(directive.args[0].string!!, directive.definingModule.source) val assembly = result.getOrElse { throw it } PtInlineAssembly(assembly.trimEnd().trimStart('\r', '\n'), false, directive.position) } diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index 4994fa708..87040e191 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -17,7 +17,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter, override fun after(block: Block, parent: Node): Iterable { val inheritOptions = block.definingModule.options() intersect setOf("no_symbol_prefixing", "ignore_unused") subtract block.options() if(inheritOptions.isNotEmpty()) { - val directive = Directive("%option", inheritOptions.map{ DirectiveArg(null, it, null, block.position) }, block.position) + val directive = Directive("%option", inheritOptions.map{ DirectiveArg(it, null, block.position) }, block.position) return listOf(IAstModification.InsertFirst(directive, block)) } diff --git a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt index de4acad1a..d48253a97 100644 --- a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt +++ b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt @@ -107,8 +107,7 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program: for(arg in directive.args) { when { arg.int!=null -> output(arg.int.toString()) - arg.name!=null -> output(arg.name) - arg.str!=null -> output("\"${arg.str}\"") + arg.string!=null -> output(arg.string) } if(arg!==directive.args.last()) output(",") diff --git a/compilerAst/src/prog8/ast/AstToplevel.kt b/compilerAst/src/prog8/ast/AstToplevel.kt index 43ad67c9f..0ccd45ae8 100644 --- a/compilerAst/src/prog8/ast/AstToplevel.kt +++ b/compilerAst/src/prog8/ast/AstToplevel.kt @@ -328,7 +328,7 @@ open class Module(final override val statements: MutableList, override fun toString() = "Module(name=$name, pos=$position, lib=${isLibrary})" override fun referencesIdentifier(nameInSource: List): Boolean = statements.any { it.referencesIdentifier(nameInSource) } - fun options() = statements.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.map {it.name!!}.toSet() + fun options() = statements.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.map {it.string!!}.toSet() fun accept(visitor: IAstVisitor) = visitor.visit(this) fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) @@ -336,7 +336,7 @@ open class Module(final override val statements: MutableList, val textEncoding: Encoding by lazy { val encoding = (statements.singleOrNull { it is Directive && it.directive == "%encoding" } as? Directive) if(encoding!=null) - Encoding.entries.first { it.prefix==encoding.args[0].name } + Encoding.entries.first { it.prefix==encoding.args[0].string } else program.encoding.defaultEncoding } diff --git a/compilerAst/src/prog8/ast/Program.kt b/compilerAst/src/prog8/ast/Program.kt index 00232b1ac..2549724c2 100644 --- a/compilerAst/src/prog8/ast/Program.kt +++ b/compilerAst/src/prog8/ast/Program.kt @@ -25,7 +25,7 @@ class Program(val name: String, // insert a container module for all interned strings later val internedStringsModule = Module(mutableListOf(), Position.DUMMY, SourceCode.Generated(internedStringsModuleName)) val block = Block(internedStringsModuleName, null, mutableListOf(), true, Position.DUMMY) - val directive = Directive("%option", listOf(DirectiveArg(null,"no_symbol_prefixing", null, Position.DUMMY)), Position.DUMMY) + val directive = Directive("%option", listOf(DirectiveArg("no_symbol_prefixing", null, Position.DUMMY)), Position.DUMMY) block.statements.add(directive) directive.linkParents(block) internedStringsModule.statements.add(block) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index ce066c3bc..5b6cafe1a 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -445,9 +445,13 @@ internal fun DirectiveContext.toAst() : Directive = private fun DirectiveargContext.toAst() : DirectiveArg { val str = stringliteral() - if(str?.encoding?.text!=null) - throw SyntaxError("don't use a string encoding for directive arguments", toPosition()) - return DirectiveArg(str?.text?.substring(1, text.length-1), identifier()?.text, integerliteral()?.toAst()?.number?.toUInt(), toPosition()) + if(str!=null) { + if (str.encoding?.text != null) + throw SyntaxError("don't use a string encoding for directive arguments", toPosition()) + return DirectiveArg(str.text.substring(1, text.length-1), integerliteral()?.toAst()?.number?.toUInt(), toPosition()) + } + + return DirectiveArg(identifier()?.text, integerliteral()?.toAst()?.number?.toUInt(), toPosition()) } private fun IntegerliteralContext.toAst(): NumericLiteralNode { diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 265556092..1af675fc0 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -94,7 +94,7 @@ class Block(override val name: String, override fun toString() = "Block(name=$name, address=$address, ${statements.size} statements)" override fun referencesIdentifier(nameInSource: List): Boolean = statements.any { it.referencesIdentifier(nameInSource) } - fun options() = statements.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.map {it.name!!}.toSet() + fun options() = statements.filter { it is Directive && it.directive == "%option" }.flatMap { (it as Directive).args }.map {it.string!!}.toSet() } // note: a Directive is not strictly always Statement (in module scope, it's a Module Element rather) @@ -132,14 +132,14 @@ data class Directive(val directive: String, val args: List, overri override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) } -data class DirectiveArg(val str: String?, val name: String?, val int: UInt?, override val position: Position) : Node { +data class DirectiveArg(val string: String?, val int: UInt?, override val position: Position) : Node { override lateinit var parent: Node override fun linkParents(parent: Node) { this.parent = parent } override fun replaceChildNode(node: Node, replacement: Node) = throw FatalAstException("can't replace here") - override fun copy() = DirectiveArg(str, name, int, position) + override fun copy() = DirectiveArg(string, int, position) override fun referencesIdentifier(nameInSource: List): Boolean = false } diff --git a/compilerAst/src/prog8/compiler/CallGraph.kt b/compilerAst/src/prog8/compiler/CallGraph.kt index a98c4e784..15cc6ba23 100644 --- a/compilerAst/src/prog8/compiler/CallGraph.kt +++ b/compilerAst/src/prog8/compiler/CallGraph.kt @@ -56,7 +56,7 @@ class CallGraph(private val program: Program) : IAstVisitor { override fun visit(directive: Directive) { val thisModule = directive.definingModule if (directive.directive == "%import") { - val importedModule = program.modules.singleOrNull { it.name == directive.args[0].name } // the module may no longer exist at all due to optimizations + val importedModule = program.modules.singleOrNull { it.name == directive.args[0].string } // the module may no longer exist at all due to optimizations if(importedModule!=null) { imports[thisModule] = imports.getValue(thisModule) + importedModule importedBy[importedModule] = importedBy.getValue(importedModule) + thisModule