diff --git a/il65/src/il65/Main.kt b/il65/src/il65/Main.kt index cc68601cc..075bc8b96 100644 --- a/il65/src/il65/Main.kt +++ b/il65/src/il65/Main.kt @@ -3,8 +3,10 @@ package il65 import java.nio.file.Paths import il65.ast.* import il65.parser.* +import il65.compiler.* import il65.optimizing.optimizeExpressions import il65.optimizing.optimizeStatements +import kotlin.system.exitProcess fun main(args: Array) { @@ -20,20 +22,34 @@ fun main(args: Array) { moduleAst.optimizeExpressions(globalNamespace) moduleAst.optimizeStatements(globalNamespace) - moduleAst.checkValid(globalNamespace) // check if final tree is valid + val globalNamespaceAfterOptimize = moduleAst.namespace() // it could have changed in the meantime + moduleAst.checkValid(globalNamespaceAfterOptimize) // check if final tree is valid // determine special compiler options val options = moduleAst.statements.filter { it is Directive && it.directive=="%option" }.flatMap { (it as Directive).args }.toSet() val optionEnableFloats = options.contains(DirectiveArg(null, "enable_floats", null)) - if(optionEnableFloats) println("Compiler: floats enabled") + val compilerOptions = CompilationOptions(OutputType.PRG, + Launcher.BASIC, + Zeropage.COMPATIBLE, + optionEnableFloats) + + val intermediate = moduleAst.compileToIntermediate(compilerOptions, globalNamespaceAfterOptimize) + intermediate.optimize() + +// val assembler = intermediate.compileToAssembly() +// assembler.assemble(compilerOptions, "input", "output") +// val monitorfile = assembler.genereateBreakpointList() + + // start the vice emulator +// val program = "foo" +// val cmdline = listOf("x64", "-moncommands", monitorfile, +// "-autostartprgmode", "1", "-autostart-warp", "-autostart", program) +// ProcessBuilder(cmdline).inheritIO().start() - // todo compile to asm... - moduleAst.statements.forEach { - println(it) - } } catch (px: ParsingFailedError) { System.err.println(px.message) + exitProcess(1) } } diff --git a/il65/src/il65/compiler/Compiler.kt b/il65/src/il65/compiler/Compiler.kt new file mode 100644 index 000000000..5604fc7e2 --- /dev/null +++ b/il65/src/il65/compiler/Compiler.kt @@ -0,0 +1,105 @@ +package il65.compiler + +import il65.ast.INameScope +import il65.ast.Module +import kotlin.system.exitProcess + + +fun Module.compileToIntermediate(options: CompilationOptions, namespace: INameScope): IntermediateForm { + + val compiler = Compiler(options, namespace) + return compiler.compile(this) +} + + +class Compiler(val options: CompilationOptions, val namespace: INameScope) { + fun compile(module: Module) : IntermediateForm { + println("......@TODO compile Ast into Intermediate result......") // todo + return IntermediateForm(module.name) + } +} + + +class IntermediateForm(val name: String) { + fun optimize() { + println("......@TODO optimize intermediate result......") // todo + } + + fun compileToAssembly(): AssemblyResult { + println("......@TODO compile intermediate result to assembly code......") // todo + return AssemblyResult(name) + } + +} + +enum class OutputType { + RAW, + PRG +} + +enum class Launcher { + BASIC, + NONE +} + +enum class Zeropage { + COMPATIBLE, + FULL, + FULL_RESTORE +} + + +data class CompilationOptions(val output: OutputType, + val launcher: Launcher, + val zeropage: Zeropage, + val floats: Boolean) + + +class AssemblyResult(val name: String) { + fun assemble(options: CompilationOptions, inputfilename: String, outputfilename: String) { + println("......@TODO assemble with 64tass......") // todo + + val command = mutableListOf("64tass", "--ascii", "--case-sensitive", "-Wall", "-Wno-strict-bool", + "--dump-labels", "--vice-labels", "-l", outputfilename+".vice-mon-list", + "--no-monitor", "--output", outputfilename, inputfilename) + + when(options.output) { + OutputType.PRG -> { + command.add("--cbm-prg") + println("\nCreating C-64 prg.") + } + OutputType.RAW -> { + command.add("--nostart") + println("\nCreating raw binary.") + } + } + + val proc = ProcessBuilder(command).inheritIO().start() + val result = proc.waitFor() + if(result!=0) { + System.err.println("assembler failed with returncode $result") + exitProcess(result) + } + } + + fun genereateBreakpointList(): String { +/* + def generate_breakpoint_list(self, program_filename: str) -> str: + breakpoints = [] + vice_mon_file = program_filename + ".vice-mon-list" + with open(vice_mon_file, "rU") as f: + for line in f: + match = re.fullmatch(r"al (?P
\w+) \S+_il65_breakpoint_\d+.?", line, re.DOTALL) + if match: + breakpoints.append("$" + match.group("address")) + with open(vice_mon_file, "at") as f: + print("; vice monitor breakpoint list now follows", file=f) + print("; {:d} breakpoints have been defined here".format(len(breakpoints)), file=f) + print("del", file=f) + for b in breakpoints: + print("break", b, file=f) + return vice_mon_file + */ + return "monitorfile.txt" + } +} \ No newline at end of file