mirror of
https://github.com/irmen/prog8.git
synced 2025-02-08 00:31:01 +00:00
fix many split array issues
This commit is contained in:
parent
d2827a7431
commit
80d88b3c61
@ -64,14 +64,14 @@ rotate3d {
|
||||
|
||||
matrix_math {
|
||||
; vertices
|
||||
word[] @split xcoor = [ -40, -40, -40, -40, 40, 40, 40, 40 ]
|
||||
word[] @split ycoor = [ -40, -40, 40, 40, -40, -40, 40, 40 ]
|
||||
word[] @split zcoor = [ -40, 40, -40, 40, -40, 40, -40, 40 ]
|
||||
word[] xcoor = [ -40, -40, -40, -40, 40, 40, 40, 40 ]
|
||||
word[] ycoor = [ -40, -40, 40, 40, -40, -40, 40, 40 ]
|
||||
word[] zcoor = [ -40, 40, -40, 40, -40, 40, -40, 40 ]
|
||||
|
||||
; storage for rotated coordinates
|
||||
word[len(xcoor)] @split rotatedx
|
||||
word[len(ycoor)] @split rotatedy
|
||||
word[len(zcoor)] @split rotatedz
|
||||
word[len(xcoor)] rotatedx
|
||||
word[len(ycoor)] rotatedy
|
||||
word[len(zcoor)] rotatedz
|
||||
|
||||
sub rotate_vertices(ubyte ax, ubyte ay, ubyte az) {
|
||||
; rotate around origin (0,0,0)
|
||||
|
@ -25,8 +25,8 @@ adpcm {
|
||||
|
||||
; IMA ADPCM decoder. Supports mono and stereo streams.
|
||||
|
||||
ubyte[] t_index = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8]
|
||||
uword[] @split t_step = [
|
||||
byte[] t_index = [ -1, -1, -1, -1, 2, 4, 6, 8, -1, -1, -1, -1, 2, 4, 6, 8]
|
||||
uword[] t_step = [
|
||||
7, 8, 9, 10, 11, 12, 13, 14,
|
||||
16, 17, 19, 21, 23, 25, 28, 31,
|
||||
34, 37, 41, 45, 50, 55, 60, 66,
|
||||
@ -79,7 +79,7 @@ adpcm {
|
||||
; elif predicted < -32767:
|
||||
; predicted = - 32767
|
||||
|
||||
index += t_index[nibble]
|
||||
index += t_index[nibble] as ubyte
|
||||
if_neg
|
||||
index = 0
|
||||
else if index >= len(t_step)-1
|
||||
|
@ -4,8 +4,8 @@
|
||||
circles {
|
||||
const ubyte MAX_NUM_CIRCLES = 80
|
||||
const ubyte GROWTH_RATE = 4
|
||||
uword[MAX_NUM_CIRCLES] @split circle_x
|
||||
uword[MAX_NUM_CIRCLES] @split circle_y
|
||||
uword[MAX_NUM_CIRCLES] circle_x
|
||||
uword[MAX_NUM_CIRCLES] circle_y
|
||||
ubyte[MAX_NUM_CIRCLES] circle_radius
|
||||
ubyte color
|
||||
uword total_num_circles
|
||||
|
@ -1,7 +1,6 @@
|
||||
%import textio
|
||||
%import conv
|
||||
%import string
|
||||
%import string
|
||||
%import strings
|
||||
|
||||
|
||||
textelite {
|
||||
@ -172,7 +171,7 @@ textelite {
|
||||
|
||||
sub next_input(str buffer) -> ubyte {
|
||||
input_index++
|
||||
return string.copy(inputs[input_index], buffer)
|
||||
return strings.copy(inputs[input_index], buffer)
|
||||
}
|
||||
}
|
||||
|
||||
@ -571,7 +570,7 @@ elite_galaxy {
|
||||
ubyte distance = elite_planet.distance(px, py)
|
||||
if distance <= max_distance {
|
||||
elite_planet.name = make_current_planet_name()
|
||||
elite_planet.name[0] = string.upperchar(elite_planet.name[0])
|
||||
elite_planet.name[0] = strings.upperchar(elite_planet.name[0])
|
||||
uword tx = elite_planet.x
|
||||
uword ty = elite_planet.y
|
||||
if local {
|
||||
@ -840,7 +839,7 @@ elite_planet {
|
||||
}
|
||||
}
|
||||
randname[nx] = 0
|
||||
randname[0] = string.upperchar(randname[0])
|
||||
randname[0] = strings.upperchar(randname[0])
|
||||
return randname
|
||||
}
|
||||
|
||||
@ -912,12 +911,12 @@ elite_planet {
|
||||
source_ptr = source_stack[stack_ptr]
|
||||
} else {
|
||||
if c == $b0 {
|
||||
@(result_ptr) = string.upperchar(name[0])
|
||||
@(result_ptr) = strings.upperchar(name[0])
|
||||
result_ptr++
|
||||
concat_string(&name + 1)
|
||||
}
|
||||
else if c == $b1 {
|
||||
@(result_ptr) = string.upperchar(name[0])
|
||||
@(result_ptr) = strings.upperchar(name[0])
|
||||
result_ptr++
|
||||
ubyte ni
|
||||
for ni in 1 to len(name) {
|
||||
@ -981,7 +980,7 @@ elite_util {
|
||||
if pc == 0
|
||||
return true
|
||||
; to lowercase for case insensitive compare:
|
||||
if string.lowerchar(pc)!=string.lowerchar(sc)
|
||||
if strings.lowerchar(pc)!=strings.lowerchar(sc)
|
||||
return false
|
||||
prefixptr++
|
||||
stringptr++
|
||||
|
@ -136,7 +136,10 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
|
||||
is PtAddressOf -> {
|
||||
if(it.isFromArrayElement)
|
||||
TODO("address-of array element $it in initial array value")
|
||||
StArrayElement(null, it.identifier.name, null)
|
||||
if(it.identifier.type.isSplitWordArray)
|
||||
StArrayElement(null, it.identifier.name + "_lsb", null) // the _lsb split array comes first in memory
|
||||
else
|
||||
StArrayElement(null, it.identifier.name, null)
|
||||
}
|
||||
is PtNumber -> StArrayElement(it.number, null, null)
|
||||
is PtBool -> StArrayElement(null, null, it.value)
|
||||
|
@ -72,12 +72,12 @@ sealed class SubType(val dt: BaseDataType) {
|
||||
}
|
||||
}
|
||||
|
||||
private data object SubUnsignedByte: SubType(BaseDataType.UBYTE)
|
||||
private data object SubSignedByte: SubType(BaseDataType.BYTE)
|
||||
private data object SubUnsignedWord: SubType(BaseDataType.UWORD)
|
||||
private data object SubSignedWord: SubType(BaseDataType.WORD)
|
||||
private data object SubBool: SubType(BaseDataType.BOOL)
|
||||
private data object SubFloat: SubType(BaseDataType.FLOAT)
|
||||
data object SubUnsignedByte: SubType(BaseDataType.UBYTE)
|
||||
data object SubSignedByte: SubType(BaseDataType.BYTE)
|
||||
data object SubUnsignedWord: SubType(BaseDataType.UWORD)
|
||||
data object SubSignedWord: SubType(BaseDataType.WORD)
|
||||
data object SubBool: SubType(BaseDataType.BOOL)
|
||||
data object SubFloat: SubType(BaseDataType.FLOAT)
|
||||
|
||||
|
||||
class DataType private constructor(val base: BaseDataType, val sub: SubType?) {
|
||||
|
@ -651,18 +651,24 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
target = AsmAssignTarget(TargetStorageKind.MEMORY, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingSub(), fcall.position, memory = mem)
|
||||
}
|
||||
is PtAddressOf -> {
|
||||
val mem = PtMemoryByte(fcall.position)
|
||||
if((fcall.args[0] as PtAddressOf).isFromArrayElement)
|
||||
TODO("address-of arrayelement")
|
||||
if(msb) {
|
||||
val address = PtBinaryExpression("+", DataType.forDt(BaseDataType.UWORD), fcall.args[0].position)
|
||||
address.add(fcall.args[0])
|
||||
address.add(PtNumber(address.type.base, 1.0, fcall.args[0].position))
|
||||
mem.add(address)
|
||||
val addrof = fcall.args[0] as PtAddressOf
|
||||
if(addrof.identifier.type.isSplitWordArray) {
|
||||
TODO("address of split word array")
|
||||
} else {
|
||||
mem.add(fcall.args[0])
|
||||
val mem = PtMemoryByte(fcall.position)
|
||||
if(addrof.isFromArrayElement)
|
||||
TODO("address-of arrayelement")
|
||||
if(msb) {
|
||||
val address = PtBinaryExpression("+", DataType.forDt(BaseDataType.UWORD), addrof.position)
|
||||
address.add(addrof)
|
||||
address.add(PtNumber(address.type.base, 1.0, addrof.position))
|
||||
mem.add(address)
|
||||
} else {
|
||||
mem.add(addrof)
|
||||
}
|
||||
target = AsmAssignTarget(TargetStorageKind.MEMORY, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingSub(), fcall.position, memory = mem)
|
||||
}
|
||||
target = AsmAssignTarget(TargetStorageKind.MEMORY, asmgen, DataType.forDt(BaseDataType.UBYTE), fcall.definingSub(), fcall.position, memory = mem)
|
||||
|
||||
}
|
||||
is PtArrayIndexer -> {
|
||||
val indexer = fcall.args[0] as PtArrayIndexer
|
||||
|
@ -808,7 +808,11 @@ _jump jmp (${target.asmLabel})
|
||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY, true)
|
||||
asmgen.out(" cpy #0")
|
||||
} else {
|
||||
asmgen.out(" lda #>${asmgen.asmVariableName(value.identifier)}")
|
||||
if(value.identifier.type.isSplitWordArray) {
|
||||
TODO("address of split word array")
|
||||
} else {
|
||||
asmgen.out(" lda #>${asmgen.asmVariableName(value.identifier)}")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
@ -1603,9 +1607,13 @@ _jump jmp (${target.asmLabel})
|
||||
if(left.isFromArrayElement)
|
||||
fallbackTranslateForSimpleCondition(stmt)
|
||||
else {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
val varname = left.identifier.name
|
||||
translateAYNotEquals("#<$varname", "#>$varname")
|
||||
if(left.identifier.type.isSplitWordArray) {
|
||||
TODO("address of split word array")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
val varname = left.identifier.name
|
||||
translateAYNotEquals("#<$varname", "#>$varname")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
@ -1651,9 +1659,13 @@ _jump jmp (${target.asmLabel})
|
||||
if(left.isFromArrayElement)
|
||||
fallbackTranslateForSimpleCondition(stmt)
|
||||
else {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
val varname = left.identifier.name
|
||||
translateAYEquals("#<$varname", "#>$varname")
|
||||
if(left.identifier.type.isSplitWordArray) {
|
||||
TODO("address of split word array")
|
||||
} else {
|
||||
asmgen.assignExpressionToRegister(right, RegisterOrPair.AY, signed)
|
||||
val varname = left.identifier.name
|
||||
translateAYEquals("#<$varname", "#>$varname")
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
|
@ -439,8 +439,11 @@ internal class AssignmentAsmGen(
|
||||
private fun assignExpression(assign: AsmAssignment, scope: IPtSubroutine?) {
|
||||
when(val value = assign.source.expression!!) {
|
||||
is PtAddressOf -> {
|
||||
val sourceName = asmgen.asmSymbolName(value.identifier)
|
||||
val arrayDt = value.identifier.type
|
||||
val sourceName = if(arrayDt.isSplitWordArray)
|
||||
asmgen.asmSymbolName(value.identifier) + "_lsb" // the _lsb split array comes first in memory
|
||||
else
|
||||
asmgen.asmSymbolName(value.identifier)
|
||||
assignAddressOf(assign.target, sourceName, arrayDt, value.arrayIndexExpr)
|
||||
}
|
||||
is PtBool -> throw AssemblyError("source kind should have been literalboolean")
|
||||
@ -1339,6 +1342,10 @@ internal class AssignmentAsmGen(
|
||||
if(right.isFromArrayElement) {
|
||||
TODO("address-of array element $symbol at ${right.position}")
|
||||
} else {
|
||||
if(right.identifier.type.isSplitWordArray) {
|
||||
TODO("address of split word array")
|
||||
return true
|
||||
}
|
||||
assignExpressionToRegister(left, RegisterOrPair.AY, dt.isSigned)
|
||||
if(expr.operator=="+")
|
||||
asmgen.out("""
|
||||
|
@ -154,7 +154,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
||||
}
|
||||
}
|
||||
} else {
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||
if(expr.identifier.type.isSplitWordArray) {
|
||||
// the _lsb split array comes first in memory
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol+"_lsb"), null)
|
||||
} else
|
||||
addInstr(result, IRInstruction(Opcode.LOAD, vmDt, reg1 = resultRegister, labelSymbol = symbol), null)
|
||||
}
|
||||
return ExpressionCodeResult(result, vmDt, resultRegister, -1)
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ anyall {
|
||||
|
||||
sub anyw(uword arrayptr, uword num_elements) -> bool {
|
||||
; -- returns true if any word in the array is not zero.
|
||||
; TODO FIX: doesn't work on @split arrays.
|
||||
; TODO FIX: doesn't work on split arrays. Just always test every byte !
|
||||
cx16.r1 = arrayptr
|
||||
if msb(num_elements)==0 {
|
||||
repeat lsb(num_elements) {
|
||||
@ -62,7 +62,7 @@ anyall {
|
||||
|
||||
sub allw(uword arrayptr, uword num_elements) -> bool {
|
||||
; -- returns true if all words in the array are not zero.
|
||||
; TODO FIX: doesn't work on @split arrays.
|
||||
; TODO FIX: doesn't work on split arrays. Just always test every byte !
|
||||
cx16.r1 = arrayptr
|
||||
if msb(num_elements)==0 {
|
||||
repeat lsb(num_elements) {
|
||||
|
@ -83,7 +83,7 @@ sprites {
|
||||
}
|
||||
|
||||
sub pos_batch(ubyte first_spritenum, ubyte num_sprites, uword xpositions_ptr, uword ypositions_ptr) {
|
||||
; -- note: the x and y positions word arrays must be regular arrays, they cannot be @split arrays!
|
||||
; -- note: the x and y positions word arrays must be regular arrays, they cannot be split arrays! TODO FIX THIS
|
||||
sprite_reg = VERA_SPRITEREGS + 2 + first_spritenum*$0008
|
||||
cx16.vaddr_autoincr(1, sprite_reg, 0, 8)
|
||||
cx16.vaddr_autoincr(1, sprite_reg+1, 1, 8)
|
||||
|
@ -223,9 +223,9 @@ internal class AstChecker(private val program: Program,
|
||||
errors.err("byte loop variable can only loop over bytes", forLoop.position)
|
||||
}
|
||||
BaseDataType.WORD -> {
|
||||
if(!iterableDt.isSignedByte && !iterableDt.isSignedWord && // TODO remove byte and word check?
|
||||
if(!iterableDt.isSignedByte && !iterableDt.isSignedWord &&
|
||||
!iterableDt.isSignedByteArray && !iterableDt.isUnsignedByteArray &&
|
||||
!iterableDt.isSignedWordArray && !iterableDt.isSplitWordArray)
|
||||
!iterableDt.isSignedWordArray && !iterableDt.isUnsignedWordArray)
|
||||
errors.err("word loop variable can only loop over bytes or words", forLoop.position)
|
||||
}
|
||||
BaseDataType.FLOAT -> {
|
||||
@ -703,8 +703,6 @@ internal class AstChecker(private val program: Program,
|
||||
if (variable!=null) {
|
||||
if (variable.type == VarDeclType.CONST && addressOf.arrayIndex == null)
|
||||
errors.err("invalid pointer-of operand type",addressOf.position)
|
||||
if (variable.datatype.isSplitWordArray)
|
||||
errors.err("cannot take address of split word array",addressOf.position)
|
||||
}
|
||||
super.visit(addressOf)
|
||||
}
|
||||
|
@ -730,7 +730,15 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
||||
|
||||
private fun transform(srcRange: RangeExpression): PtRange {
|
||||
require(srcRange.from.inferType(program)==srcRange.to.inferType(program))
|
||||
val type = srcRange.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
var type = srcRange.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
if(type.isSplitWordArray) {
|
||||
// ranges are never a split word array!
|
||||
when(type.sub) {
|
||||
is SubSignedWord -> type = DataType.arrayFor(BaseDataType.WORD, false)
|
||||
is SubUnsignedWord -> type = DataType.arrayFor(BaseDataType.UWORD, false)
|
||||
else -> { }
|
||||
}
|
||||
}
|
||||
val range=PtRange(type, srcRange.position)
|
||||
range.add(transformExpression(srcRange.from))
|
||||
range.add(transformExpression(srcRange.to))
|
||||
|
@ -77,18 +77,6 @@ internal class LiteralsToAutoVars(private val program: Program, private val erro
|
||||
}
|
||||
}
|
||||
|
||||
if(array.type.isArray) {
|
||||
val mods = mutableListOf<IAstModification>()
|
||||
for(elt in array.value.filterIsInstance<IdentifierReference>()) {
|
||||
val decl = elt.targetVarDecl(program)
|
||||
if(decl!=null && decl.datatype.isSplitWordArray) {
|
||||
// you can't take the adress of a split-word array.
|
||||
errors.err("cannot take address of split word array", decl.position)
|
||||
}
|
||||
}
|
||||
return mods
|
||||
}
|
||||
|
||||
return noModifications
|
||||
}
|
||||
|
||||
@ -151,15 +139,4 @@ internal class LiteralsToAutoVars(private val program: Program, private val erro
|
||||
// }
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(addressOf: AddressOf, parent: Node): Iterable<IAstModification> {
|
||||
val variable=addressOf.identifier.targetVarDecl(program)
|
||||
if (variable!=null) {
|
||||
if (variable.datatype.isSplitWordArray) {
|
||||
// you can't take the adress of a split-word array.
|
||||
errors.err("cannot take address of split word array", addressOf.position)
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
|
@ -385,7 +385,7 @@ main {
|
||||
compileText(C64Target(), false, src, writeAssembly = true) shouldNotBe null
|
||||
}
|
||||
|
||||
test("taking address of split arrays") {
|
||||
test("taking address of split arrays works") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
@ -404,11 +404,7 @@ main {
|
||||
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
|
||||
compileText(C64Target(), optimize=false, src, writeAssembly=true, errors=errors) shouldNotBe null
|
||||
errors.errors.size shouldBe 0
|
||||
errors.warnings.size shouldBe 2
|
||||
errors.warnings[0] shouldContain("address")
|
||||
errors.warnings[1] shouldContain("address")
|
||||
errors.warnings[0] shouldContain("split")
|
||||
errors.warnings[1] shouldContain("split")
|
||||
errors.warnings.size shouldBe 0
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -16,11 +16,32 @@ import prog8.intermediate.IRFileReader
|
||||
import prog8.intermediate.IRSubroutine
|
||||
import prog8.intermediate.Opcode
|
||||
import prog8.vm.VmRunner
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
import prog8tests.helpers.compileText
|
||||
import kotlin.io.path.readText
|
||||
|
||||
class TestCompilerVirtual: FunSpec({
|
||||
test("compile virtual: array with pointers") {
|
||||
test("linear words array with pointers") {
|
||||
val src = """
|
||||
main {
|
||||
sub start() {
|
||||
str localstr = "hello"
|
||||
ubyte[] otherarray = [1,2,3]
|
||||
uword[] @nosplit words = [1111,2222,"three",&localstr,&otherarray]
|
||||
uword @shared zz = &words
|
||||
bool result = 2222 in words
|
||||
zz = words[2]
|
||||
zz++
|
||||
zz = words[3]
|
||||
}
|
||||
}"""
|
||||
val target = VMTarget()
|
||||
val result = compileText(target, false, src, writeAssembly = true)!!
|
||||
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
|
||||
VmRunner().runProgram(virtfile.readText())
|
||||
}
|
||||
|
||||
test("split words array with pointers") {
|
||||
val src = """
|
||||
main {
|
||||
sub start() {
|
||||
@ -35,11 +56,33 @@ main {
|
||||
}
|
||||
}"""
|
||||
val target = VMTarget()
|
||||
val result = compileText(target, true, src, writeAssembly = true)!!
|
||||
val result = compileText(target, false, src, writeAssembly = true)!!
|
||||
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
|
||||
VmRunner().runProgram(virtfile.readText())
|
||||
}
|
||||
|
||||
test("taking address of split arrays works") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
cx16.r0L=0
|
||||
if cx16.r0L==0 {
|
||||
uword[] addresses = [scores2, start]
|
||||
uword[] scores1 = [10, 25, 50, 100]
|
||||
uword[] scores2 = [100, 250, 500, 1000]
|
||||
|
||||
cx16.r0 = &scores1
|
||||
cx16.r1 = &scores2
|
||||
cx16.r2 = &addresses
|
||||
}
|
||||
}
|
||||
}"""
|
||||
val errors = ErrorReporterForTests(keepMessagesAfterReporting = true)
|
||||
compileText(VMTarget(), optimize=false, src, writeAssembly=true, errors=errors) shouldNotBe null
|
||||
errors.errors.size shouldBe 0
|
||||
errors.warnings.size shouldBe 0
|
||||
}
|
||||
|
||||
test("compile virtual: str args and return type, and global var init") {
|
||||
val src = """
|
||||
main {
|
||||
|
@ -758,6 +758,8 @@ private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl
|
||||
val identifiername = identifiers[0].NAME() ?: identifiers[0].UNDERSCORENAME()
|
||||
val name = if(identifiers.size==1) identifiername.text else "<multiple>"
|
||||
val isArray = ARRAYSIG() != null || arrayindex() != null
|
||||
if(options.SPLIT().isNotEmpty())
|
||||
throw SyntaxError("@split is now the default for word arrays. Use @nosplit if you don't want to split it.", toPosition())
|
||||
val nosplit = options.NOSPLIT().isNotEmpty()
|
||||
val alignword = options.ALIGNWORD().isNotEmpty()
|
||||
val align64 = options.ALIGN64().isNotEmpty()
|
||||
|
@ -280,7 +280,15 @@ class VarDecl(val type: VarDeclType,
|
||||
|
||||
fun createAuto(array: ArrayLiteral): VarDecl {
|
||||
val autoVarName = "auto_heap_value_${++autoHeapValueSequenceNumber}"
|
||||
val arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") }
|
||||
var arrayDt = array.type.getOrElse { throw FatalAstException("unknown dt") }
|
||||
if(arrayDt.isSplitWordArray) {
|
||||
// autovars for array literals are NOT stored as a split word array!
|
||||
when(arrayDt.sub) {
|
||||
is SubSignedWord -> arrayDt = DataType.arrayFor(BaseDataType.WORD, false)
|
||||
is SubUnsignedWord -> arrayDt = DataType.arrayFor(BaseDataType.UWORD, false)
|
||||
else -> { }
|
||||
}
|
||||
}
|
||||
val arraysize = ArrayIndex.forArray(array)
|
||||
return VarDecl(VarDeclType.VAR, VarDeclOrigin.ARRAYLITERAL, arrayDt, ZeropageWish.NOT_IN_ZEROPAGE, arraysize, autoVarName, emptyList(), array,
|
||||
sharedWithAsm = false, alignment = 0u, dirty = false, position = array.position)
|
||||
|
@ -3,12 +3,16 @@ TODO
|
||||
|
||||
- DONE: make word arrays split by default (remove @split tag) and use new @nosplit tag to make an array use the old storage format? Also invert -splitarrays command line option.
|
||||
- DONE: remove "splitarrays" %option switch
|
||||
- Regular & will just return the start of the split array in memory whatever byte comes first. Search "cannot take address of split word array"
|
||||
- fix anyall.anyw/allw , optimize any/all in asm? make sure it still works for virtual
|
||||
- fix IR compilation errors
|
||||
- Regular & will just return the start of the split array in memory whatever byte comes first. Search TODO("address of split word array")
|
||||
- check this for 6502 codegen: split word arrays, both _msb and _lsb arrays are tagged with an alignment. This is not what's intended; only the one put in memory first should be aligned (the other one should follow straight after it)
|
||||
- add &< and &> operators to get the address of the lsb-array and msb-array, respectively.
|
||||
- fix sprites.pos_batch
|
||||
- fix anyall.anyw/allw
|
||||
- update Syntax files + Document all of this (also that word arrays can then have length 256 by default as well, and that @linear will reduce it to half.)
|
||||
- test all examples
|
||||
- test all examples and projects (paint has wrong palette colors)
|
||||
- benchmark program became slower!? (did get smaller, just slower????)
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
@ -269,13 +269,13 @@ stereo {
|
||||
%asm {{
|
||||
; copy to vera PSG fifo buffer
|
||||
ldy #0
|
||||
- lda p8v_left,y
|
||||
- lda p8v_left_lsb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
lda p8v_left+1,y
|
||||
lda p8v_left_msb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
lda p8v_right,y
|
||||
lda p8v_right_lsb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
lda p8v_right+1,y
|
||||
lda p8v_right_msb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
iny
|
||||
iny
|
||||
|
@ -382,13 +382,13 @@ _lp2 lda $ffff,y
|
||||
%asm {{
|
||||
; copy to vera PSG fifo buffer
|
||||
ldy #0
|
||||
- lda p8v_left,y
|
||||
- lda p8v_left_lsb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
lda p8v_left+1,y
|
||||
lda p8v_left_msb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
lda p8v_right,y
|
||||
lda p8v_right_lsb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
lda p8v_right+1,y
|
||||
lda p8v_right_msb,y
|
||||
sta cx16.VERA_AUDIO_DATA
|
||||
iny
|
||||
iny
|
||||
|
@ -2,13 +2,11 @@
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword[] addresses = [scores2, start]
|
||||
uword[] scores1 = [10, 25, 50, 100]
|
||||
uword[] scores2 = [100, 250, 500, 1000]
|
||||
uword large = memory("large", 20000, 256)
|
||||
|
||||
cx16.r0 = &scores1
|
||||
cx16.r1 = &scores2
|
||||
cx16.r2 = &addresses
|
||||
sub start() {
|
||||
for cx16.r1 in large to large+20000-1 {
|
||||
cx16.r0++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ class IRSymbolTable {
|
||||
val newArray = mutableListOf<IRStArrayElement>()
|
||||
array.forEach {
|
||||
if(it.addressOfSymbol!=null) {
|
||||
val target = variable.lookup(it.addressOfSymbol!!)!!
|
||||
val target = variable.lookup(it.addressOfSymbol!!) ?: throw NoSuchElementException("can't find variable ${it.addressOfSymbol}")
|
||||
newArray.add(IRStArrayElement(null, null, target.scopedName))
|
||||
} else {
|
||||
newArray.add(IRStArrayElement.from(it))
|
||||
|
@ -61,6 +61,8 @@ ZEROPAGENOT: '@nozp' ;
|
||||
|
||||
SHARED : '@shared' ;
|
||||
|
||||
SPLIT: '@split' ;
|
||||
|
||||
NOSPLIT: '@nosplit' ;
|
||||
|
||||
ALIGNWORD: '@alignword' ;
|
||||
@ -159,7 +161,7 @@ directivearg : stringliteral | identifier | integerliteral ;
|
||||
|
||||
vardecl: datatype (arrayindex | ARRAYSIG)? decloptions identifier (',' identifier)* ;
|
||||
|
||||
decloptions: (SHARED | ZEROPAGE | ZEROPAGEREQUIRE | ZEROPAGENOT | NOSPLIT | ALIGNWORD | ALIGN64 | ALIGNPAGE | DIRTY)* ;
|
||||
decloptions: (SHARED | ZEROPAGE | ZEROPAGEREQUIRE | ZEROPAGENOT | NOSPLIT | SPLIT | ALIGNWORD | ALIGN64 | ALIGNPAGE | DIRTY)* ;
|
||||
|
||||
varinitializer : vardecl '=' expression ;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user