mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
Merge branch 'irmen:v7.1' into v7.1
This commit is contained in:
commit
81abf29bec
@ -31,7 +31,8 @@ fun pathFrom(stringPath: String, vararg rest: String): Path = FileSystems.getDe
|
||||
|
||||
private fun compileMain(args: Array<String>): Boolean {
|
||||
val cli = ArgParser("prog8compiler", prefixStyle = ArgParser.OptionPrefixStyle.JVM)
|
||||
val startEmulator by cli.option(ArgType.Boolean, fullName = "emu", description = "auto-start emulator after successful compilation")
|
||||
val startEmulator1 by cli.option(ArgType.Boolean, fullName = "emu", description = "auto-start emulator after successful compilation")
|
||||
val startEmulator2 by cli.option(ArgType.Boolean, fullName = "emu2", description = "auto-start alternative emulator after successful compilation")
|
||||
val outputDir by cli.option(ArgType.String, fullName = "out", description = "directory for output files instead of current directory").default(".")
|
||||
val dontWriteAssembly by cli.option(ArgType.Boolean, fullName = "noasm", description="don't create assembly code")
|
||||
val dontOptimize by cli.option(ArgType.Boolean, fullName = "noopt", description = "don't perform any optimizations")
|
||||
@ -119,13 +120,17 @@ private fun compileMain(args: Array<String>): Boolean {
|
||||
return false
|
||||
}
|
||||
|
||||
if (startEmulator==true) {
|
||||
if (compilationResult.programName.isEmpty())
|
||||
if(startEmulator1==true || startEmulator2==true) {
|
||||
if (compilationResult.programName.isEmpty()) {
|
||||
println("\nCan't start emulator because no program was assembled.")
|
||||
else {
|
||||
compilationResult.compTarget.machine.launchEmulator(compilationResult.programName)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
if (startEmulator1==true)
|
||||
compilationResult.compTarget.machine.launchEmulator(1, compilationResult.programName)
|
||||
else if (startEmulator2==true)
|
||||
compilationResult.compTarget.machine.launchEmulator(2, compilationResult.programName)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.Module
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.Position
|
||||
import prog8.ast.expressions.StringLiteralValue
|
||||
@ -17,29 +16,20 @@ internal class AstIdentifiersChecker(private val program: Program, private val e
|
||||
errors.err("name conflict '$name', also defined in ${existing.position.file} line ${existing.position.line}", position)
|
||||
}
|
||||
|
||||
override fun visit(module: Module) {
|
||||
blocks.clear() // blocks may be redefined within a different module
|
||||
|
||||
super.visit(module)
|
||||
}
|
||||
|
||||
override fun visit(block: Block) {
|
||||
if(block.name in compTarget.machine.opcodeNames)
|
||||
errors.err("can't use a cpu opcode name as a symbol: '${block.name}'", block.position)
|
||||
|
||||
val existing = blocks[block.name]
|
||||
if(existing!=null)
|
||||
nameError(block.name, block.position, existing)
|
||||
if(existing!=null) {
|
||||
if(block.isInLibrary)
|
||||
nameError(existing.name, existing.position, block)
|
||||
else
|
||||
nameError(block.name, block.position, existing)
|
||||
}
|
||||
else
|
||||
blocks[block.name] = block
|
||||
|
||||
if(!block.isInLibrary) {
|
||||
val libraries = program.modules.filter { it.isLibraryModule }
|
||||
val libraryBlockNames = libraries.flatMap { it.statements.filterIsInstance<Block>().map { b -> b.name } }
|
||||
if(block.name in libraryBlockNames)
|
||||
errors.err("block is already defined in an included library module", block.position)
|
||||
}
|
||||
|
||||
super.visit(block)
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,6 @@ interface IMachineDefinition {
|
||||
fun getFloat(num: Number): IMachineFloat
|
||||
|
||||
fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List<String>
|
||||
fun launchEmulator(programName: String)
|
||||
fun launchEmulator(selectedEmulator: Int, programName: String)
|
||||
fun isRegularRAMaddress(address: Int): Boolean
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import prog8.compiler.*
|
||||
import prog8.compiler.target.CpuType
|
||||
import prog8.compiler.target.IMachineDefinition
|
||||
import prog8.compiler.target.IMachineFloat
|
||||
import prog8.compiler.target.cbm.viceMonListPostfix
|
||||
import java.io.IOException
|
||||
import kotlin.math.absoluteValue
|
||||
import kotlin.math.pow
|
||||
@ -35,10 +36,15 @@ internal object C64MachineDefinition: IMachineDefinition {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
override fun launchEmulator(programName: String) {
|
||||
override fun launchEmulator(selectedEmulator: Int, programName: String) {
|
||||
if(selectedEmulator!=1) {
|
||||
System.err.println("The c64 target only supports the main emulator (Vice).")
|
||||
return
|
||||
}
|
||||
|
||||
for(emulator in listOf("x64sc", "x64")) {
|
||||
println("\nStarting C-64 emulator $emulator...")
|
||||
val cmdline = listOf(emulator, "-silent", "-moncommands", "$programName.vice-mon-list",
|
||||
val cmdline = listOf(emulator, "-silent", "-moncommands", "$programName.$viceMonListPostfix",
|
||||
"-autostartprgmode", "1", "-autostart-warp", "-autostart", "$programName.prg")
|
||||
val processb = ProcessBuilder(cmdline).inheritIO()
|
||||
val process: Process
|
||||
|
@ -6,11 +6,14 @@ import prog8.compiler.target.IAssemblyProgram
|
||||
import prog8.compiler.target.generatedLabelPrefix
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
internal const val viceMonListPostfix = "vice-mon-list"
|
||||
|
||||
class AssemblyProgram(override val name: String, outputDir: Path, private val compTarget: String) : IAssemblyProgram {
|
||||
private val assemblyFile = outputDir.resolve("$name.asm")
|
||||
private val prgFile = outputDir.resolve("$name.prg")
|
||||
private val binFile = outputDir.resolve("$name.bin")
|
||||
private val viceMonListFile = outputDir.resolve("$name.vice-mon-list")
|
||||
private val viceMonListFile = outputDir.resolve("$name.$viceMonListPostfix")
|
||||
|
||||
override fun assemble(options: CompilationOptions): Int {
|
||||
// add "-Wlong-branch" to see warnings about conversion of branch instructions to jumps (default = do this silently)
|
||||
|
@ -4,6 +4,7 @@ import prog8.compiler.*
|
||||
import prog8.compiler.target.CpuType
|
||||
import prog8.compiler.target.IMachineDefinition
|
||||
import prog8.compiler.target.c64.C64MachineDefinition
|
||||
import prog8.compiler.target.cbm.viceMonListPostfix
|
||||
import java.io.IOException
|
||||
|
||||
internal object CX16MachineDefinition: IMachineDefinition {
|
||||
@ -32,10 +33,28 @@ internal object CX16MachineDefinition: IMachineDefinition {
|
||||
emptyList()
|
||||
}
|
||||
|
||||
override fun launchEmulator(programName: String) {
|
||||
for(emulator in listOf("x16emu")) {
|
||||
override fun launchEmulator(selectedEmulator: Int, programName: String) {
|
||||
val emulatorName: String
|
||||
val extraArgs: List<String>
|
||||
|
||||
when(selectedEmulator) {
|
||||
1 -> {
|
||||
emulatorName = "x16emu"
|
||||
extraArgs = emptyList()
|
||||
}
|
||||
2 -> {
|
||||
emulatorName = "box16"
|
||||
extraArgs = listOf("-sym", "$programName.$viceMonListPostfix")
|
||||
}
|
||||
else -> {
|
||||
System.err.println("Cx16 target only supports x16emu and box16 emulators.")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for(emulator in listOf(emulatorName)) {
|
||||
println("\nStarting Commander X16 emulator $emulator...")
|
||||
val cmdline = listOf(emulator, "-scale", "2", "-run", "-prg", "$programName.prg")
|
||||
val cmdline = listOf(emulator, "-scale", "2", "-run", "-prg", "$programName.prg") + extraArgs
|
||||
val processb = ProcessBuilder(cmdline).inheritIO()
|
||||
val process: Process
|
||||
try {
|
||||
|
@ -20,7 +20,7 @@ internal class UnusedCodeRemover(private val program: Program,
|
||||
private val callgraph = CallGraph(program)
|
||||
|
||||
override fun before(module: Module, parent: Node): Iterable<IAstModification> {
|
||||
return if (!module.isLibraryModule && (module.containsNoCodeNorVars() || callgraph.unused(module)))
|
||||
return if (!module.isLibrary() && (module.containsNoCodeNorVars() || callgraph.unused(module)))
|
||||
listOf(IAstModification.Remove(module, module.definingScope()))
|
||||
else
|
||||
noModifications
|
||||
@ -80,12 +80,12 @@ internal class UnusedCodeRemover(private val program: Program,
|
||||
val forceOutput = "force_output" in subroutine.definingBlock().options()
|
||||
if (subroutine !== program.entrypoint() && !forceOutput && !subroutine.inline && !subroutine.isAsmSubroutine) {
|
||||
if(callgraph.unused(subroutine)) {
|
||||
if(!subroutine.definingModule().isLibraryModule)
|
||||
if(!subroutine.definingModule().isLibrary())
|
||||
errors.warn("removing unused subroutine '${subroutine.name}'", subroutine.position)
|
||||
return listOf(IAstModification.Remove(subroutine, subroutine.definingScope()))
|
||||
}
|
||||
if(subroutine.containsNoCodeNorVars()) {
|
||||
if(!subroutine.definingModule().isLibraryModule)
|
||||
if(!subroutine.definingModule().isLibrary())
|
||||
errors.warn("removing empty subroutine '${subroutine.name}'", subroutine.position)
|
||||
val removals = mutableListOf(IAstModification.Remove(subroutine, subroutine.definingScope()))
|
||||
callgraph.calledBy[subroutine]?.let {
|
||||
|
@ -74,7 +74,7 @@ locallabel:
|
||||
val varInBlock = VarDecl(VarDeclType.VAR, DataType.UWORD, ZeropageWish.DONTCARE, null, "var_outside", null, false, false, false, Position.DUMMY)
|
||||
val block = Block("main", null, mutableListOf(labelInBlock, varInBlock, subroutine), false, Position.DUMMY)
|
||||
|
||||
val module = Module("test", mutableListOf(block), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(block), Position.DUMMY, Path.of(""))
|
||||
module.linkParents(ParentSentinel)
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.program = program
|
||||
|
@ -98,7 +98,7 @@ class TestMemory {
|
||||
val target = AssignTarget(null, null, DirectMemoryWrite(memexpr, Position.DUMMY), Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
module.linkParents(ParentSentinel)
|
||||
return target
|
||||
}
|
||||
@ -117,7 +117,7 @@ class TestMemory {
|
||||
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.linkParents(ParentSentinel)
|
||||
assertTrue(C64Target.isInRegularRAM(target, program))
|
||||
@ -130,7 +130,7 @@ class TestMemory {
|
||||
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.linkParents(ParentSentinel)
|
||||
assertTrue(C64Target.isInRegularRAM(target, program))
|
||||
@ -143,7 +143,7 @@ class TestMemory {
|
||||
val target = AssignTarget(IdentifierReference(listOf("address"), Position.DUMMY), null, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.linkParents(ParentSentinel)
|
||||
assertFalse(C64Target.isInRegularRAM(target, program))
|
||||
@ -156,7 +156,7 @@ class TestMemory {
|
||||
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.linkParents(ParentSentinel)
|
||||
assertTrue(C64Target.isInRegularRAM(target, program))
|
||||
@ -170,7 +170,7 @@ class TestMemory {
|
||||
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.linkParents(ParentSentinel)
|
||||
assertTrue(C64Target.isInRegularRAM(target, program))
|
||||
@ -184,7 +184,7 @@ class TestMemory {
|
||||
val target = AssignTarget(null, arrayindexed, null, Position.DUMMY)
|
||||
val assignment = Assignment(target, NumericLiteralValue.optimalInteger(0, Position.DUMMY), Position.DUMMY)
|
||||
val subroutine = Subroutine("test", emptyList(), emptyList(), emptyList(), emptyList(), emptySet(), null, false, false, mutableListOf(decl, assignment), Position.DUMMY)
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, false, Path.of(""))
|
||||
val module = Module("test", mutableListOf(subroutine), Position.DUMMY, Path.of(""))
|
||||
val program = Program("test", mutableListOf(module), DummyFunctions(), DummyMemsizer())
|
||||
module.linkParents(ParentSentinel)
|
||||
assertFalse(C64Target.isInRegularRAM(target, program))
|
||||
|
@ -24,7 +24,7 @@ class AstToSourceCode(val output: (text: String) -> Unit, val program: Program):
|
||||
}
|
||||
|
||||
override fun visit(module: Module) {
|
||||
if(!module.isLibraryModule) {
|
||||
if(!module.isLibrary()) {
|
||||
outputln("; ----------- module: ${module.name} -----------")
|
||||
super.visit(module)
|
||||
}
|
||||
|
@ -6,6 +6,8 @@ import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstVisitor
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import kotlin.io.path.name
|
||||
import kotlin.math.abs
|
||||
|
||||
const val internedStringsModuleName = "prog8_interned_strings"
|
||||
@ -263,7 +265,7 @@ class Program(val name: String,
|
||||
init {
|
||||
// insert a container module for all interned strings later
|
||||
if(modules.firstOrNull()?.name != internedStringsModuleName) {
|
||||
val internedStringsModule = Module(internedStringsModuleName, mutableListOf(), Position.DUMMY, true, Path.of(""))
|
||||
val internedStringsModule = Module(internedStringsModuleName, mutableListOf(), Position.DUMMY, Path.of(""))
|
||||
modules.add(0, internedStringsModule)
|
||||
val block = Block(internedStringsModuleName, null, mutableListOf(), true, Position.DUMMY)
|
||||
internedStringsModule.statements.add(block)
|
||||
@ -340,7 +342,6 @@ class Program(val name: String,
|
||||
class Module(override val name: String,
|
||||
override var statements: MutableList<Statement>,
|
||||
override val position: Position,
|
||||
val isLibraryModule: Boolean,
|
||||
val source: Path) : Node, INameScope {
|
||||
|
||||
override lateinit var parent: Node
|
||||
@ -364,10 +365,20 @@ class Module(override val name: String,
|
||||
replacement.parent = this
|
||||
}
|
||||
|
||||
override fun toString() = "Module(name=$name, pos=$position, lib=$isLibraryModule)"
|
||||
override fun toString() = "Module(name=$name, pos=$position, lib=${isLibrary()})"
|
||||
|
||||
fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||
fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
||||
|
||||
companion object {
|
||||
fun pathForResource(resourcePath: String): Path {
|
||||
return Paths.get("@embedded@/$resourcePath")
|
||||
}
|
||||
|
||||
fun isLibrary(source: Path) = source.name=="" || source.startsWith("@embedded@/")
|
||||
}
|
||||
|
||||
fun isLibrary() = isLibrary(source)
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,11 +19,11 @@ import java.nio.file.Path
|
||||
|
||||
private data class NumericLiteral(val number: Number, val datatype: DataType)
|
||||
|
||||
internal fun prog8Parser.ModuleContext.toAst(name: String, isLibrary: Boolean, source: Path, encoding: IStringEncoding) : Module {
|
||||
internal fun prog8Parser.ModuleContext.toAst(name: String, source: Path, encoding: IStringEncoding) : Module {
|
||||
val nameWithoutSuffix = if(name.endsWith(".p8")) name.substringBeforeLast('.') else name
|
||||
val directives = this.directive().map { it.toAst() }
|
||||
val blocks = this.block().map { it.toAst(isLibrary, encoding) }
|
||||
return Module(nameWithoutSuffix, (directives + blocks).toMutableList(), toPosition(), isLibrary, source)
|
||||
val blocks = this.block().map { it.toAst(Module.isLibrary(source), encoding) }
|
||||
return Module(nameWithoutSuffix, (directives + blocks).toMutableList(), toPosition(), source)
|
||||
}
|
||||
|
||||
private fun ParserRuleContext.toPosition() : Position {
|
||||
|
@ -44,7 +44,7 @@ class ModuleImporter(private val program: Program,
|
||||
if(!Files.isReadable(filePath))
|
||||
throw ParsingFailedError("No such file: $filePath")
|
||||
|
||||
return importModule(CharStreams.fromPath(filePath), filePath, false)
|
||||
return importModule(CharStreams.fromPath(filePath), filePath)
|
||||
}
|
||||
|
||||
fun importLibraryModule(name: String): Module? {
|
||||
@ -68,7 +68,7 @@ class ModuleImporter(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
private fun importModule(stream: CharStream, modulePath: Path, isLibrary: Boolean): Module {
|
||||
private fun importModule(stream: CharStream, modulePath: Path): Module {
|
||||
val moduleName = moduleName(modulePath.fileName)
|
||||
val lexer = CustomLexer(modulePath, stream)
|
||||
lexer.removeErrorListeners()
|
||||
@ -87,7 +87,7 @@ class ModuleImporter(private val program: Program,
|
||||
// tokens.commentTokens().forEach { println(it) }
|
||||
|
||||
// convert to Ast
|
||||
val moduleAst = parseTree.toAst(moduleName, isLibrary, modulePath, encoder)
|
||||
val moduleAst = parseTree.toAst(moduleName, modulePath, encoder)
|
||||
moduleAst.program = program
|
||||
moduleAst.linkParents(program.namespace)
|
||||
program.modules.add(moduleAst)
|
||||
@ -122,7 +122,7 @@ class ModuleImporter(private val program: Program,
|
||||
resource.use {
|
||||
println("importing '$moduleName' (library)")
|
||||
val content = it.reader().readText().replace("\r\n", "\n")
|
||||
importModule(CharStreams.fromString(content), Paths.get("@embedded@/$resourcePath"), true)
|
||||
importModule(CharStreams.fromString(content), Module.pathForResource(resourcePath))
|
||||
}
|
||||
} else {
|
||||
val modulePath = tryGetModuleFromFile(moduleName, source, import.position)
|
||||
|
@ -249,7 +249,7 @@ main {
|
||||
// parser.removeErrorListeners()
|
||||
// parser.addErrorListener(MyErrorListener())
|
||||
|
||||
val ast = parser.module().toAst("test", false, Path.of(""), DummyEncoding)
|
||||
val ast = parser.module().toAst("test", Path.of(""), DummyEncoding)
|
||||
assertIs<Block>(ast.statements.first())
|
||||
assertEquals((ast.statements.first() as Block).name, "main")
|
||||
}
|
||||
|
@ -166,7 +166,9 @@ For MacOS you can use the Homebrew system to install a recent version of OpenJDK
|
||||
|
||||
Finally: an **emulator** (or a real machine ofcourse) to test and run your programs on.
|
||||
In C64 mode, the compiler assumes the presence of the `Vice emulator <http://vice-emu.sourceforge.net/>`_.
|
||||
If you're targeting the CommanderX16 instead, there's the `x16emu <https://github.com/commanderx16/x16-emulator>`_.
|
||||
If you're targeting the CommanderX16 instead, there's a choice of the official `x16emu <https://github.com/commanderx16/x16-emulator>`_
|
||||
and the unofficial `box16 <https://github.com/indigodarkwolf/box16>`_ (you can select which one you want to launch
|
||||
using the ``-emu`` or ``-emu2`` command line options)
|
||||
|
||||
.. attention:: **Commander-X16 V38 versus V39**
|
||||
|
||||
|
@ -3,6 +3,10 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- rename libdirs option to srcdirs?
|
||||
- can we derive module.name from module.source (taking just the filename base)?
|
||||
- can Position.file be a Path- making the source variable for nodes unnecessary?
|
||||
|
||||
|
||||
- refactor code to improve testability and other things, see [CompilerDevelopment](CompilerDevelopment.md)
|
||||
- simplify cx16.joystick_get2() once this cx16 rom issue is resolved: https://github.com/commanderx16/x16-rom/issues/203
|
||||
@ -24,6 +28,9 @@ Future
|
||||
- refactor the compiler optimizers into own project submodule
|
||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_``
|
||||
- [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ...
|
||||
Perhaps replace all uses of .proc/.pend by .block/.bend will fix that?
|
||||
(but we lose the optimizing aspect of the assembler where it strips out unused code.
|
||||
There's not really a dynamic switch possible as all assembly lib code is static and uses one or the other)
|
||||
- introduce byte-index operator to avoid index multiplications in loops over arrays?
|
||||
see https://www.reddit.com/r/programming/comments/alhj59/creating_a_programming_language_and_cross/eg898b9?utm_source=share&utm_medium=web2x&context=3
|
||||
|
||||
|
@ -2,3 +2,4 @@ org.gradle.caching=true
|
||||
org.gradle.console=rich
|
||||
org.gradle.parallel=true
|
||||
org.gradle.daemon=true
|
||||
kotlin.code.style=official
|
||||
|
Loading…
x
Reference in New Issue
Block a user