mirror of
https://github.com/irmen/prog8.git
synced 2024-11-25 19:31:36 +00:00
fixed arrayliteral regression
This commit is contained in:
parent
5a54066f81
commit
7d20458e82
@ -439,7 +439,7 @@ internal class ProgramAndVarsGen(
|
||||
private class ZpArrayWithInitial(
|
||||
val name: List<String>,
|
||||
val alloc: Zeropage.ZpAllocation,
|
||||
val value: DoubleArray
|
||||
val value: StArray
|
||||
)
|
||||
|
||||
private fun getZpStringVarsWithInitvalue(): Collection<ZpStringWithInitial> {
|
||||
@ -518,7 +518,7 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
}
|
||||
|
||||
private fun arrayVariable2asm(varname: String, dt: DataType, value: DoubleArray?, orNumberOfZeros: Int?) {
|
||||
private fun arrayVariable2asm(varname: String, dt: DataType, value: StArray?, orNumberOfZeros: Int?) {
|
||||
when(dt) {
|
||||
DataType.ARRAY_UB -> {
|
||||
val data = makeArrayFillDataUnsigned(dt, value, orNumberOfZeros)
|
||||
@ -561,9 +561,9 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
val array = value ?: DoubleArray(orNumberOfZeros!!)
|
||||
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
|
||||
val floatFills = array.map {
|
||||
compTarget.machine.getFloat(it).makeFloatFillAsm()
|
||||
compTarget.machine.getFloat(it.number!!).makeFloatFillAsm()
|
||||
}
|
||||
asmgen.out(varname)
|
||||
for (f in array.zip(floatFills))
|
||||
@ -573,6 +573,14 @@ internal class ProgramAndVarsGen(
|
||||
}
|
||||
}
|
||||
|
||||
private fun zeroFilledArray(numElts: Int): StArray {
|
||||
val values = mutableListOf<StArrayElement>()
|
||||
repeat(numElts) {
|
||||
values.add(StArrayElement(0.0, null))
|
||||
}
|
||||
return values
|
||||
}
|
||||
|
||||
private fun memdefsAndConsts2asm(memvars: Collection<StMemVar>, consts: Collection<StConstant>) {
|
||||
memvars.forEach {
|
||||
asmgen.out(" ${it.name} = ${it.address.toHex()}")
|
||||
@ -602,48 +610,41 @@ internal class ProgramAndVarsGen(
|
||||
asmgen.out(" .byte " + chunk.joinToString())
|
||||
}
|
||||
|
||||
private fun makeArrayFillDataUnsigned(dt: DataType, value: DoubleArray?, orNumberOfZeros: Int?): List<String> {
|
||||
val array = value ?: DoubleArray(orNumberOfZeros!!)
|
||||
private fun makeArrayFillDataUnsigned(dt: DataType, value: StArray?, orNumberOfZeros: Int?): List<String> {
|
||||
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
|
||||
return when (dt) {
|
||||
DataType.ARRAY_UB ->
|
||||
// byte array can never contain pointer-to types, so treat values as all integers
|
||||
array.map {
|
||||
val number = it.toInt()
|
||||
val number = it.number!!.toInt()
|
||||
"$"+number.toString(16).padStart(2, '0')
|
||||
}
|
||||
DataType.ARRAY_UW -> array.map {
|
||||
"$" + it.toInt().toString(16).padStart(4, '0')
|
||||
// TODO: initial array literals with address-of, or just variable references, are no longer possible at this time
|
||||
// when (it) {
|
||||
// is NumericLiteral -> {
|
||||
// "$" + it.number.toInt().toString(16).padStart(4, '0')
|
||||
// }
|
||||
// is AddressOf -> {
|
||||
// asmgen.asmSymbolName(it.identifier)
|
||||
// }
|
||||
// is IdentifierReference -> {
|
||||
// asmgen.asmSymbolName(it)
|
||||
// }
|
||||
// else -> throw AssemblyError("weird array elt dt")
|
||||
// }
|
||||
if(it.number!=null) {
|
||||
"$" + it.number!!.toInt().toString(16).padStart(4, '0')
|
||||
}
|
||||
else if(it.addressOf!=null) {
|
||||
asmgen.asmSymbolName(it.addressOf!!)
|
||||
}
|
||||
else
|
||||
throw AssemblyError("weird array elt")
|
||||
}
|
||||
else -> throw AssemblyError("invalid dt")
|
||||
}
|
||||
}
|
||||
|
||||
private fun makeArrayFillDataSigned(dt: DataType, value: DoubleArray?, orNumberOfZeros: Int?): List<String> {
|
||||
val array = value ?: DoubleArray(orNumberOfZeros!!)
|
||||
private fun makeArrayFillDataSigned(dt: DataType, value: StArray?, orNumberOfZeros: Int?): List<String> {
|
||||
val array = value ?: zeroFilledArray(orNumberOfZeros!!)
|
||||
return when (dt) {
|
||||
// byte array can never contain pointer-to types, so treat values as all integers
|
||||
DataType.ARRAY_UB ->
|
||||
// byte array can never contain pointer-to types, so treat values as all integers
|
||||
array.map {
|
||||
val number = it.toInt()
|
||||
val number = it.number!!.toInt()
|
||||
"$"+number.toString(16).padStart(2, '0')
|
||||
}
|
||||
DataType.ARRAY_B ->
|
||||
// byte array can never contain pointer-to types, so treat values as all integers
|
||||
array.map {
|
||||
val number = it.toInt()
|
||||
val number = it.number!!.toInt()
|
||||
val hexnum = number.absoluteValue.toString(16).padStart(2, '0')
|
||||
if(number>=0)
|
||||
"$$hexnum"
|
||||
@ -651,11 +652,11 @@ internal class ProgramAndVarsGen(
|
||||
"-$$hexnum"
|
||||
}
|
||||
DataType.ARRAY_UW -> array.map {
|
||||
val number = it.toInt()
|
||||
val number = it.number!!.toInt()
|
||||
"$" + number.toString(16).padStart(4, '0')
|
||||
}
|
||||
DataType.ARRAY_W -> array.map {
|
||||
val number = it.toInt()
|
||||
val number = it.number!!.toInt()
|
||||
val hexnum = number.absoluteValue.toString(16).padStart(4, '0')
|
||||
if(number>=0)
|
||||
"$$hexnum"
|
||||
|
@ -1,11 +1,10 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.base.Position
|
||||
import prog8.ast.base.VarDeclType
|
||||
import prog8.ast.expressions.ArrayLiteral
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.expressions.StringLiteral
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.Block
|
||||
import prog8.ast.statements.Label
|
||||
import prog8.ast.statements.Subroutine
|
||||
@ -66,15 +65,17 @@ internal class SymbolTableMaker: IAstVisitor {
|
||||
st.origAstLinks[decl] = node
|
||||
}
|
||||
|
||||
private fun makeInitialArray(arrayLit: ArrayLiteral?): DoubleArray? {
|
||||
private fun makeInitialArray(arrayLit: ArrayLiteral?): StArray? {
|
||||
if(arrayLit==null)
|
||||
return null
|
||||
return arrayLit.value.map {
|
||||
if(it !is NumericLiteral)
|
||||
TODO("ability to have addressof or variables inside array literal currently not possible @ ${arrayLit.position}")
|
||||
else
|
||||
it.number
|
||||
}.toDoubleArray()
|
||||
when(it){
|
||||
is AddressOf -> StArrayElement(null, it.identifier.nameInSource)
|
||||
is IdentifierReference -> StArrayElement(null, it.nameInSource)
|
||||
is NumericLiteral -> StArrayElement(it.number, null)
|
||||
else -> throw FatalAstException("weird element dt in array literal")
|
||||
}
|
||||
}.toList()
|
||||
}
|
||||
|
||||
override fun visit(label: Label) {
|
||||
@ -82,4 +83,4 @@ internal class SymbolTableMaker: IAstVisitor {
|
||||
scopestack.peek().add(node)
|
||||
st.origAstLinks[label] = node
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,8 +2,12 @@ package prog8tests.ast
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import prog8.ast.base.Position
|
||||
import prog8.ast.statements.InlineAssembly
|
||||
import prog8.codegen.target.C64Target
|
||||
import prog8.compiler.compileProgram
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
class TestVarious: FunSpec({
|
||||
test("symbol names in inline assembly blocks") {
|
||||
@ -25,5 +29,26 @@ label2:
|
||||
|
||||
names2 shouldBe setOf("label", "lda", "sta", "ea", "value", "label2", "othervalue", "valid", "words")
|
||||
}
|
||||
|
||||
test("array literals") {
|
||||
val text="""
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
ubyte b1
|
||||
ubyte b2
|
||||
ubyte[] array1 = [1,2,3]
|
||||
ubyte[] array2 = [9,8,7]
|
||||
|
||||
uword[] @shared addresses1 = [&b1, &b2]
|
||||
uword[] @shared addresses2 = [array1, array2]
|
||||
uword[] @shared addresses3 = [&array1, &array2]
|
||||
uword[] @shared addresses4 = ["string1", "string2"]
|
||||
uword[] @shared addresses5 = [1111, 2222]
|
||||
}
|
||||
}"""
|
||||
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -4,7 +4,6 @@ import prog8.ast.Node
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.Position
|
||||
import prog8.ast.statements.ZeropageWish
|
||||
import prog8.ast.toHex
|
||||
|
||||
|
||||
/**
|
||||
@ -123,8 +122,8 @@ open class StNode(val name: String,
|
||||
class StStaticVariable(name: String,
|
||||
val dt: DataType,
|
||||
val initialNumericValue: Double?,
|
||||
val initialStringValue: Pair<String, Encoding>?,
|
||||
val initialArrayValue: DoubleArray?,
|
||||
val initialStringValue: StString?,
|
||||
val initialArrayValue: StArray?,
|
||||
val arraysize: Int?,
|
||||
val zpw: ZeropageWish,
|
||||
position: Position) : StNode(name, StNodeType.STATICVAR, position) {
|
||||
@ -153,6 +152,12 @@ class StMemVar(name: String, val dt: DataType, val address: UInt, position: Posi
|
||||
StNode(name, StNodeType.MEMVAR, position
|
||||
) {
|
||||
override fun printProperties() {
|
||||
print("$name dt=$dt address=${address.toHex()}")
|
||||
print("$name dt=$dt address=${address.toString(16).padStart(4,'0')}")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class StArrayElement(val number: Double?, val addressOf: List<String>?)
|
||||
|
||||
typealias StString = Pair<String, Encoding>
|
||||
typealias StArray = List<StArrayElement>
|
||||
|
@ -260,8 +260,10 @@ The largest 5-byte MFLPT float that can be stored is: **1.7014118345e+38** (ne
|
||||
|
||||
Arrays
|
||||
^^^^^^
|
||||
Array types are also supported. They can be made of bytes, words or floats, strings, and other arrays
|
||||
(although the usefulness of the latter is very limited for now)::
|
||||
Array types are also supported. They can be formed from a list of bytes, words, floats, or addresses of other variables
|
||||
(such as explicit address-of expressions, strings, or other array variables) - values in an array literal
|
||||
always have to be constants. Putting variables inside an array has to be done on a value-by-value basis.
|
||||
Here are some examples of arrays::
|
||||
|
||||
byte[10] array ; array of 10 bytes, initially set to 0
|
||||
byte[] array = [1, 2, 3, 4] ; initialize the array, size taken from value
|
||||
|
@ -3,13 +3,10 @@ TODO
|
||||
|
||||
For next release
|
||||
^^^^^^^^^^^^^^^^
|
||||
- make 'intermediate' module containing the SymbolTable and dumbed down version of the Ast.
|
||||
- make an intermediate representation containing the SymbolTable and dumbed down version of the Ast.
|
||||
no vardecls in it anymore (these are part of the symboltable) and baked types, so no inferType too.
|
||||
no name lookup in the Ast, always do this in the symbol table.
|
||||
|
||||
- codegen makeInitialArray()/makeArrayFillDataUnsigned():
|
||||
initial array literals with address-of, or just variable references, are no longer possible at this time!!
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user