mirror of
https://github.com/irmen/prog8.git
synced 2024-07-13 12:29:05 +00:00
cleaning up AsmGen interface
This commit is contained in:
parent
f538c9f0c3
commit
6bdd81623f
@ -26,8 +26,7 @@ const val subroutineFloatEvalResultVar2 = "prog8_float_eval_result2"
|
||||
|
||||
class AsmGen6502(internal val program: Program,
|
||||
internal val errors: IErrorReporter,
|
||||
internal val options: CompilationOptions,
|
||||
internal val outputDir: Path): IAssemblyGenerator {
|
||||
internal val options: CompilationOptions): IAssemblyGenerator {
|
||||
|
||||
// for expressions and augmented assignments:
|
||||
val optimizedByteMultiplications = setOf(3,5,6,7,9,10,11,12,13,14,15,20,25,40,50,80,100)
|
||||
@ -76,7 +75,7 @@ class AsmGen6502(internal val program: Program,
|
||||
slaballocations()
|
||||
footer()
|
||||
|
||||
val output = outputDir.resolve("${program.name}.asm")
|
||||
val output = options.outputDir.resolve("${program.name}.asm")
|
||||
if(options.optimize) {
|
||||
val separateLines = assemblyLines.flatMapTo(mutableListOf()) { it.split('\n') }
|
||||
assemblyLines.clear()
|
||||
@ -90,7 +89,7 @@ class AsmGen6502(internal val program: Program,
|
||||
}
|
||||
|
||||
return if(errors.noErrors())
|
||||
AssemblyProgram(program.name, outputDir, compTarget.name)
|
||||
AssemblyProgram(program.name, options.outputDir, compTarget.name)
|
||||
else {
|
||||
errors.report()
|
||||
return null
|
||||
@ -1591,7 +1590,7 @@ $repeatLabel lda $counterVar
|
||||
TODO("%asmbinary inside non-library, non-filesystem module")
|
||||
val sourcePath = Path(stmt.definingModule.source.origin)
|
||||
val includedPath = sourcePath.resolveSibling(includedName)
|
||||
val pathForAssembler = outputDir // #54: 64tass needs the path *relative to the .asm file*
|
||||
val pathForAssembler = options.outputDir // #54: 64tass needs the path *relative to the .asm file*
|
||||
.toAbsolutePath()
|
||||
.relativize(includedPath.toAbsolutePath())
|
||||
.normalize() // avoid assembler warnings (-Wportable; only some, not all)
|
||||
|
@ -5,18 +5,16 @@ import prog8.compilerinterface.CompilationOptions
|
||||
import prog8.compilerinterface.IAssemblyGenerator
|
||||
import prog8.compilerinterface.IAssemblyProgram
|
||||
import prog8.compilerinterface.IErrorReporter
|
||||
import java.nio.file.Path
|
||||
|
||||
class ExperimentalAsmGen6502(internal val program: Program,
|
||||
internal val errors: IErrorReporter,
|
||||
internal val options: CompilationOptions,
|
||||
internal val outputDir: Path
|
||||
internal val options: CompilationOptions
|
||||
): IAssemblyGenerator {
|
||||
override fun compileToAssembly(): IAssemblyProgram? {
|
||||
|
||||
println("\n** experimental 65(c)02 code generator **\n")
|
||||
|
||||
println("..todo: create assembly code..")
|
||||
println("..todo: create assembly code into ${options.outputDir.toAbsolutePath()}..")
|
||||
return AssemblyProgram("dummy")
|
||||
}
|
||||
}
|
@ -1,20 +1,18 @@
|
||||
package prog8.codegen.target
|
||||
|
||||
import prog8.ast.base.ByteDatatypes
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.PassByReferenceDatatypes
|
||||
import prog8.ast.base.WordDatatypes
|
||||
import prog8.ast.expressions.Expression
|
||||
import prog8.ast.statements.RegisterOrStatusflag
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.codegen.target.c128.C128MachineDefinition
|
||||
import prog8.codegen.target.cbm.CbmMemorySizer
|
||||
import prog8.codegen.target.cbm.asmsub6502ArgsEvalOrder
|
||||
import prog8.codegen.target.cbm.asmsub6502ArgsHaveRegisterClobberRisk
|
||||
import prog8.compilerinterface.ICompilationTarget
|
||||
import prog8.compilerinterface.IMemSizer
|
||||
import prog8.compilerinterface.IStringEncoding
|
||||
|
||||
|
||||
object C128Target: ICompilationTarget, IStringEncoding by Encoder {
|
||||
object C128Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by CbmMemorySizer {
|
||||
override val name = "c128"
|
||||
override val machine = C128MachineDefinition()
|
||||
|
||||
@ -22,13 +20,4 @@ object C128Target: ICompilationTarget, IStringEncoding by Encoder {
|
||||
asmsub6502ArgsEvalOrder(sub)
|
||||
override fun asmsubArgsHaveRegisterClobberRisk(args: List<Expression>, paramRegisters: List<RegisterOrStatusflag>) =
|
||||
asmsub6502ArgsHaveRegisterClobberRisk(args, paramRegisters)
|
||||
|
||||
override fun memorySize(dt: DataType): Int {
|
||||
return when(dt) {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> machine.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,18 @@
|
||||
package prog8.codegen.target
|
||||
|
||||
import prog8.ast.base.ByteDatatypes
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.PassByReferenceDatatypes
|
||||
import prog8.ast.base.WordDatatypes
|
||||
import prog8.ast.expressions.Expression
|
||||
import prog8.ast.statements.RegisterOrStatusflag
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.codegen.target.c64.C64MachineDefinition
|
||||
import prog8.codegen.target.cbm.CbmMemorySizer
|
||||
import prog8.codegen.target.cbm.asmsub6502ArgsEvalOrder
|
||||
import prog8.codegen.target.cbm.asmsub6502ArgsHaveRegisterClobberRisk
|
||||
import prog8.compilerinterface.ICompilationTarget
|
||||
import prog8.compilerinterface.IMemSizer
|
||||
import prog8.compilerinterface.IStringEncoding
|
||||
|
||||
|
||||
object C64Target: ICompilationTarget, IStringEncoding by Encoder {
|
||||
object C64Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by CbmMemorySizer {
|
||||
override val name = "c64"
|
||||
override val machine = C64MachineDefinition()
|
||||
|
||||
@ -22,13 +20,4 @@ object C64Target: ICompilationTarget, IStringEncoding by Encoder {
|
||||
asmsub6502ArgsEvalOrder(sub)
|
||||
override fun asmsubArgsHaveRegisterClobberRisk(args: List<Expression>, paramRegisters: List<RegisterOrStatusflag>) =
|
||||
asmsub6502ArgsHaveRegisterClobberRisk(args, paramRegisters)
|
||||
|
||||
override fun memorySize(dt: DataType): Int {
|
||||
return when(dt) {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> machine.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,18 @@
|
||||
package prog8.codegen.target
|
||||
|
||||
import prog8.ast.base.ByteDatatypes
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.PassByReferenceDatatypes
|
||||
import prog8.ast.base.WordDatatypes
|
||||
import prog8.ast.expressions.Expression
|
||||
import prog8.ast.statements.RegisterOrStatusflag
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.codegen.target.cbm.CbmMemorySizer
|
||||
import prog8.codegen.target.cbm.asmsub6502ArgsEvalOrder
|
||||
import prog8.codegen.target.cbm.asmsub6502ArgsHaveRegisterClobberRisk
|
||||
import prog8.codegen.target.cx16.CX16MachineDefinition
|
||||
import prog8.compilerinterface.ICompilationTarget
|
||||
import prog8.compilerinterface.IMemSizer
|
||||
import prog8.compilerinterface.IStringEncoding
|
||||
|
||||
|
||||
object Cx16Target: ICompilationTarget, IStringEncoding by Encoder {
|
||||
object Cx16Target: ICompilationTarget, IStringEncoding by Encoder, IMemSizer by CbmMemorySizer {
|
||||
override val name = "cx16"
|
||||
override val machine = CX16MachineDefinition()
|
||||
|
||||
@ -22,14 +20,4 @@ object Cx16Target: ICompilationTarget, IStringEncoding by Encoder {
|
||||
asmsub6502ArgsEvalOrder(sub)
|
||||
override fun asmsubArgsHaveRegisterClobberRisk(args: List<Expression>, paramRegisters: List<RegisterOrStatusflag>) =
|
||||
asmsub6502ArgsHaveRegisterClobberRisk(args, paramRegisters)
|
||||
|
||||
override fun memorySize(dt: DataType): Int {
|
||||
return when(dt) {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> machine.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,31 @@
|
||||
package prog8.codegen.target.cbm
|
||||
|
||||
import prog8.ast.base.*
|
||||
import prog8.ast.expressions.StringLiteralValue
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.compilerinterface.IMemSizer
|
||||
|
||||
internal object CbmMemorySizer: IMemSizer {
|
||||
override fun memorySize(dt: DataType): Int {
|
||||
return when(dt) {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> Mflpt5.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
override fun memorySize(decl: VarDecl): Int {
|
||||
return when(decl.type) {
|
||||
VarDeclType.CONST -> 0
|
||||
VarDeclType.VAR, VarDeclType.MEMORY -> {
|
||||
when(val dt = decl.datatype) {
|
||||
in NumericDatatypes -> return memorySize(dt)
|
||||
in ArrayDatatypes -> decl.arraysize!!.constIndex()!! * memorySize(ArrayToElementTypes.getValue(dt))
|
||||
DataType.STR -> (decl.value as StringLiteralValue).value.length + 1
|
||||
else -> 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -75,6 +75,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult {
|
||||
asmQuiet = args.quietAssembler
|
||||
asmListfile = args.asmListfile
|
||||
experimentalCodegen = args.experimentalCodegen
|
||||
outputDir = args.outputDir.normalize()
|
||||
}
|
||||
program = programresult
|
||||
importedFiles = imported
|
||||
@ -97,7 +98,7 @@ fun compileProgram(args: CompilerArguments): CompilationResult {
|
||||
// printProgram(program)
|
||||
|
||||
if (args.writeAssembly) {
|
||||
when (val result = writeAssembly(program, args.errors, args.outputDir, compilationOptions)) {
|
||||
when (val result = writeAssembly(program, args.errors, compilationOptions)) {
|
||||
is WriteAssemblyResult.Ok -> programName = result.filename
|
||||
is WriteAssemblyResult.Fail -> {
|
||||
System.err.println(result.error)
|
||||
@ -339,7 +340,6 @@ private sealed class WriteAssemblyResult {
|
||||
|
||||
private fun writeAssembly(program: Program,
|
||||
errors: IErrorReporter,
|
||||
outputDir: Path,
|
||||
compilerOptions: CompilationOptions
|
||||
): WriteAssemblyResult {
|
||||
// asm generation directly from the Ast
|
||||
@ -350,11 +350,7 @@ private fun writeAssembly(program: Program,
|
||||
// printProgram(program)
|
||||
|
||||
compilerOptions.compTarget.machine.initializeZeropage(compilerOptions)
|
||||
val assembly = asmGeneratorFor(
|
||||
program,
|
||||
errors,
|
||||
compilerOptions,
|
||||
outputDir).compileToAssembly()
|
||||
val assembly = asmGeneratorFor(program, errors, compilerOptions).compileToAssembly()
|
||||
errors.report()
|
||||
|
||||
return if(assembly!=null && errors.noErrors()) {
|
||||
@ -378,15 +374,14 @@ internal fun asmGeneratorFor(
|
||||
program: Program,
|
||||
errors: IErrorReporter,
|
||||
options: CompilationOptions,
|
||||
outputDir: Path
|
||||
): IAssemblyGenerator
|
||||
{
|
||||
if(options.experimentalCodegen) {
|
||||
if (options.compTarget.machine.cpu in arrayOf(CpuType.CPU6502, CpuType.CPU65c02))
|
||||
return ExperimentalAsmGen6502(program, errors, options, outputDir)
|
||||
return ExperimentalAsmGen6502(program, errors, options)
|
||||
} else {
|
||||
if (options.compTarget.machine.cpu in arrayOf(CpuType.CPU6502, CpuType.CPU65c02))
|
||||
return AsmGen6502(program, errors, options, outputDir)
|
||||
return AsmGen6502(program, errors, options)
|
||||
}
|
||||
|
||||
throw NotImplementedError("no asm generator for cpu ${options.compTarget.machine.cpu}")
|
||||
|
@ -10,16 +10,23 @@ import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.ast.walk.IAstVisitor
|
||||
import prog8.compilerinterface.AssemblyError
|
||||
import prog8.compilerinterface.CompilationOptions
|
||||
import prog8.compilerinterface.IErrorReporter
|
||||
import prog8.compilerinterface.isIOAddress
|
||||
import prog8.compilerinterface.*
|
||||
import prog8.optimizer.getTempVarName
|
||||
|
||||
internal class BeforeAsmAstChanger(val program: Program, private val options: CompilationOptions,
|
||||
private val errors: IErrorReporter
|
||||
) : AstWalker() {
|
||||
|
||||
private val allBlockVars = mutableMapOf<Block, MutableSet<VarDecl>>()
|
||||
private val allSubroutineVars = mutableMapOf<Subroutine, MutableSet<VarDecl>>()
|
||||
// internal lateinit var allocation: IVariableAllocation
|
||||
//
|
||||
// override fun after(program: Program): Iterable<IAstModification> {
|
||||
// allocation = VariableAllocation(allBlockVars, allSubroutineVars)
|
||||
// allocation.dump(program.memsizer)
|
||||
// return super.after(program)
|
||||
// }
|
||||
|
||||
override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
|
||||
throw FatalAstException("break should have been replaced by goto $breakStmt")
|
||||
}
|
||||
@ -58,6 +65,25 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
||||
if (decl.type == VarDeclType.VAR && decl.value != null && decl.datatype in NumericDatatypes)
|
||||
throw FatalAstException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
||||
}
|
||||
|
||||
if(decl.type==VarDeclType.VAR) {
|
||||
when(val scope=decl.definingScope) {
|
||||
is Block -> {
|
||||
val blockVars = allBlockVars[scope] ?: mutableSetOf()
|
||||
blockVars.add(decl)
|
||||
allBlockVars[scope] = blockVars
|
||||
}
|
||||
is Subroutine -> {
|
||||
val subroutineVars = allSubroutineVars[scope] ?: mutableSetOf()
|
||||
subroutineVars.add(decl)
|
||||
allSubroutineVars[scope] = subroutineVars
|
||||
}
|
||||
else -> {
|
||||
throw FatalAstException("var can only occur in subroutine or block scope")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
@ -370,4 +396,29 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
||||
return modifications
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class VariableAllocation(
|
||||
override val blockVars: Map<Block, Set<VarDecl>>,
|
||||
override val subroutineVars: Map<Subroutine, Set<VarDecl>>) : IVariableAllocation
|
||||
{
|
||||
override fun dump(memsizer: IMemSizer) {
|
||||
println("ALL BLOCK VARS:")
|
||||
blockVars.forEach { (block, vars) ->
|
||||
val totalsize = vars.sumOf { memsizer.memorySize(it) }
|
||||
println("BLOCK: ${block.name} total size: $totalsize")
|
||||
vars.forEach {
|
||||
println(" ${it.datatype} ${it.name} ${it.position}")
|
||||
}
|
||||
}
|
||||
println("ALL SUBROUTINE VARS:")
|
||||
subroutineVars.forEach { (sub, vars) ->
|
||||
val totalsize = vars.sumOf { memsizer.memorySize(it) }
|
||||
println("SUBROUTINE: ${sub.name} total size: $totalsize")
|
||||
vars.forEach {
|
||||
println(" ${it.datatype} ${it.name} ${it.position}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -300,7 +300,7 @@ class TestOptimization: FunSpec({
|
||||
expr.right.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UWORD
|
||||
expr.inferType(result.program).getOrElse { fail("dt") } shouldBe DataType.UBYTE
|
||||
|
||||
val options = CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, true, C64Target)
|
||||
val options = CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), false, true, C64Target, outputDir= outputDir)
|
||||
result.program.processAstBeforeAsmGeneration(options, ErrorReporterForTests())
|
||||
|
||||
// assignment is now split into:
|
||||
|
@ -79,7 +79,7 @@ class TestAsmGenSymbols: StringSpec({
|
||||
val errors = ErrorReporterForTests()
|
||||
val options = CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target)
|
||||
options.compTarget.machine.zeropage = C64Zeropage(options)
|
||||
val asmgen = AsmGen6502(program, errors, options, Path.of(""))
|
||||
val asmgen = AsmGen6502(program, errors, options)
|
||||
return asmgen
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@ import prog8.ast.expressions.InferredTypes
|
||||
import prog8.ast.expressions.NumericLiteralValue
|
||||
import prog8.ast.statements.RegisterOrStatusflag
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.compilerinterface.*
|
||||
|
||||
internal val DummyFunctions = object : IBuiltinFunctions {
|
||||
@ -24,6 +25,7 @@ internal val DummyFunctions = object : IBuiltinFunctions {
|
||||
|
||||
internal val DummyMemsizer = object : IMemSizer {
|
||||
override fun memorySize(dt: DataType) = 0
|
||||
override fun memorySize(decl: VarDecl) = 0
|
||||
}
|
||||
|
||||
internal val DummyStringEncoder = object : IStringEncoding {
|
||||
@ -69,4 +71,8 @@ internal val DummyCompilationTarget = object : ICompilationTarget {
|
||||
override fun memorySize(dt: DataType): Int {
|
||||
throw NotImplementedError("dummy")
|
||||
}
|
||||
|
||||
override fun memorySize(decl: VarDecl): Int {
|
||||
throw NotImplementedError("dummy")
|
||||
}
|
||||
}
|
@ -85,8 +85,8 @@ internal fun generateAssembly(
|
||||
program: Program,
|
||||
options: CompilationOptions? = null
|
||||
): IAssemblyProgram? {
|
||||
val coptions = options ?: CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, true, C64Target)
|
||||
val coptions = options ?: CompilationOptions(OutputType.RAW, LauncherType.NONE, ZeropageType.DONTUSE, emptyList(), true, true, C64Target, outputDir = outputDir)
|
||||
coptions.compTarget.machine.zeropage = C64Zeropage(coptions)
|
||||
val asmgen = AsmGen6502(program, ErrorReporterForTests(), coptions, outputDir)
|
||||
val asmgen = AsmGen6502(program, ErrorReporterForTests(), coptions)
|
||||
return asmgen.compileToAssembly()
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package prog8.compilerinterface
|
||||
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.statements.VarDecl
|
||||
|
||||
|
||||
// note: this is a separate interface in the compilerAst module because
|
||||
@ -8,4 +9,5 @@ import prog8.ast.base.DataType
|
||||
|
||||
interface IMemSizer {
|
||||
fun memorySize(dt: DataType): Int
|
||||
fun memorySize(decl: VarDecl): Int
|
||||
}
|
||||
|
@ -1,5 +1,8 @@
|
||||
package prog8.compilerinterface
|
||||
|
||||
import java.nio.file.Path
|
||||
import kotlin.io.path.Path
|
||||
|
||||
enum class OutputType {
|
||||
RAW,
|
||||
PRG
|
||||
@ -32,5 +35,7 @@ class CompilationOptions(val output: OutputType,
|
||||
var dontReinitGlobals: Boolean = false,
|
||||
var asmQuiet: Boolean = false,
|
||||
var asmListfile: Boolean = false,
|
||||
var experimentalCodegen: Boolean = false
|
||||
)
|
||||
var experimentalCodegen: Boolean = false,
|
||||
var outputDir: Path = Path("")
|
||||
) {
|
||||
}
|
||||
|
@ -0,0 +1,12 @@
|
||||
package prog8.compilerinterface
|
||||
|
||||
import prog8.ast.statements.Block
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.ast.statements.VarDecl
|
||||
|
||||
interface IVariableAllocation {
|
||||
fun dump(memsizer: IMemSizer)
|
||||
|
||||
val blockVars: Map<Block, Set<VarDecl>>
|
||||
val subroutineVars: Map<Subroutine, Set<VarDecl>>
|
||||
}
|
@ -3,7 +3,7 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
...
|
||||
fix the concurrent modification issue on zeropage when running unit tests in parallel -> don't use static objects anymore
|
||||
|
||||
|
||||
Need help with
|
||||
@ -22,12 +22,11 @@ Blocked by an official Commander-x16 r39 release
|
||||
Future Things and Ideas
|
||||
^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Ast modifications done in AsmGen, that should be done BEFORE calling asmgen (so that it doesn't have to modify the Ast any longer):
|
||||
|
||||
- block2asm: removes init-assignments to no longer output the initialization assignments as regular statements (is done separately in block initialization routine)
|
||||
- block2asm: after vardecls2asm it clears the vardecl.value of all variables
|
||||
- Maybe don't rely on vardecls at all any longer but figure out the variable allocations (including ZP allocations) beforehand
|
||||
and pass that via a new datastructure to asmgen? So that asmgen is no longer tasked with doing the allocations.
|
||||
This could perhaps make it easer for the codegen as well to deal with sections, if any, in the future.
|
||||
- block2asm: removes init-assignments to no longer output the initialization assignments as regular statements (is done separately in block initialization routine)
|
||||
- block2asm: after vardecls2asm it clears the vardecl.value of all variables
|
||||
- Maybe don't rely on vardecls at all any longer but figure out the variable allocations (including ZP allocations) beforehand
|
||||
and pass that via a new datastructure to asmgen? So that asmgen is no longer tasked with doing the allocations.
|
||||
This could perhaps make it easer for the codegen as well to deal with sections, if any, in the future.
|
||||
|
||||
- remove support for old @"screencodes" string encoding syntax (parser+code+docs)
|
||||
- allow "xxx" * constexpr (where constexpr is not a number literal), now gives expression error not same type
|
||||
|
@ -22,13 +22,22 @@ main {
|
||||
foobar()
|
||||
startval1++
|
||||
mainglobal1++
|
||||
start2()
|
||||
|
||||
sub start2() {
|
||||
uword @shared startval1 = 2002
|
||||
ubyte[2] @shared barr
|
||||
uword[2] @shared warr
|
||||
uword[] @shared warr2 = [1,2]
|
||||
}
|
||||
}
|
||||
|
||||
asmsub derp() {
|
||||
|
||||
}
|
||||
|
||||
sub foobar() {
|
||||
uword @shared startval1 = 2002
|
||||
uword @shared mainglobal1 = 2002
|
||||
txt.print("foobar\n")
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user