assignments again

This commit is contained in:
Irmen de Jong 2018-10-27 23:03:46 +02:00
parent 1fea9e3bc4
commit 729d931ccb
5 changed files with 178 additions and 38 deletions

View File

@ -48,30 +48,115 @@ sub start() {
memory word[3] mwarr1 = $e100 memory word[3] mwarr1 = $e100
memory uword[3] muwarr1 = $e100 memory uword[3] muwarr1 = $e100
str string = "hello"
str_p stringp = "hello"
; all possible assignments to a BYTE VARIABLE
assignments: ; all possible assignments to a BYTE VARIABLE (not array)
byte_assignment_to_register:
A = 42 A = 42
A = Y
A = X A = X
Y = X
A = ub A = ub
X = ub
Y = ub
A = mubyte A = mubyte
X = mubyte
Y = mubyte
A = ubarr1[2] A = ubarr1[2]
X = ubarr1[2]
Y = ubarr1[2]
A = ubmatrix1[1,2] A = ubmatrix1[1,2]
X = ubmatrix1[1,2] A = string[4]
Y = ubmatrix1[1,2] A = AY[4]
byte_assignment_to_bytevar:
b = 42
b = b2
b = mbyte
b = barr1[2]
b = bmatrix1[1,2]
ub = 42
ub = X
ub = ub2
ub = mubyte
ub = ubarr1[2]
ub = ubmatrix1[1,2]
ub = string[4]
ub = AY[4]
; all possible assignments to a WORD VARIABLE (not array)
word_assignment_to_registerpair:
AY = 42
AY = 42.w
AY = 42555
AY = X
AY = XY
AY = ub
AY = mubyte
AY = ubarr1[2]
AY = ubmatrix1[1,2]
AY = string[4]
AY = uw
AY = muword
AY = uwarr1[2]
AY = string[4]
AY = XY[4]
;word_assignment_to_wordvar:
w = -42
w = -42.w
w = -12345
w = X
w = b2
w = ub2
w = w2
w = mbyte
w = mubyte
w = mword
w = barr1[2]
w = ubarr1[2]
w = warr1[2]
w = bmatrix1[1,2]
w = ubmatrix1[1,2]
w = string[4]
w = AY[4]
uw = 42
uw = 42.w
uw = 42555
uw = X
uw = AY
uw = ub2
uw = uw2
uw = mubyte
uw = muword
uw = ubarr1[2]
uw = uwarr1[2]
uw = ubmatrix1[1,2]
uw = string[4]
uw = AY[4]
; all possible assignments to a FLOAT VARIABLE
float_assignment_to_floatvar:
fl1 = 34
fl1 = 34555.w
fl1 = 3.33e22
fl1 = X
fl1 = AY
fl1 = b2
fl1 = ub2
fl1 = w2
fl1 = uw2
fl1 = mbyte
fl1 = mubyte
fl1 = mword
fl1 = muword
fl1 = barr1[2]
fl1 = ubarr1[2]
fl1 = warr1[2]
fl1 = uwarr1[2]
fl1 = bmatrix1[1,2]
fl1 = ubmatrix1[1,2]
fl1 = string[4]
return return
} }

View File

@ -67,7 +67,7 @@ enum class BranchCondition {
} }
val IterableDatatypes = setOf( val IterableDatatypes = setOf(
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS, DataType.STR, DataType.STR_S, // note: the STR_P/STR_PS types aren't iterable because they store their length as the first byte
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UB, DataType.ARRAY_B,
DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_UW, DataType.ARRAY_W,
DataType.ARRAY_F, DataType.MATRIX_UB, DataType.MATRIX_B) DataType.ARRAY_F, DataType.MATRIX_UB, DataType.MATRIX_B)

View File

@ -702,7 +702,7 @@ class AstChecker(private val namespace: INameScope,
val indexedRegister = postIncrDecr.target.arrayindexed?.register val indexedRegister = postIncrDecr.target.arrayindexed?.register
if(indexedRegister!=null) { if(indexedRegister!=null) {
if(indexedRegister==Register.A || indexedRegister==Register.X || indexedRegister==Register.Y) if(indexedRegister==Register.A || indexedRegister==Register.X || indexedRegister==Register.Y)
checkResult.add(SyntaxError("arrayspec indexing on registers requires register pair variable", postIncrDecr.position)) checkResult.add(SyntaxError("indexing on registers requires register pair variable", postIncrDecr.position))
} else { } else {
val target = postIncrDecr.target.arrayindexed?.identifier?.targetStatement(namespace) val target = postIncrDecr.target.arrayindexed?.identifier?.targetStatement(namespace)
if(target==null) { if(target==null) {
@ -724,7 +724,7 @@ class AstChecker(private val namespace: INameScope,
val target = arrayIndexedExpression.identifier!!.targetStatement(namespace) val target = arrayIndexedExpression.identifier!!.targetStatement(namespace)
if(target is VarDecl) { if(target is VarDecl) {
if(target.datatype !in IterableDatatypes) if(target.datatype !in IterableDatatypes)
checkResult.add(SyntaxError("arrayspec indexing requires an iterable variable", arrayIndexedExpression.position)) checkResult.add(SyntaxError("indexing requires an iterable variable", arrayIndexedExpression.position))
val arraysize = target.arrayspec?.size() val arraysize = target.arrayspec?.size()
if(arraysize!=null) { if(arraysize!=null) {
// check out of bounds // check out of bounds
@ -734,13 +734,21 @@ class AstChecker(private val namespace: INameScope,
val index = (arrayIndexedExpression.arrayspec.x as? LiteralValue)?.asIntegerValue val index = (arrayIndexedExpression.arrayspec.x as? LiteralValue)?.asIntegerValue
if(index!=null && (index<0 || index>=arraysize)) if(index!=null && (index<0 || index>=arraysize))
checkResult.add(ExpressionError("arrayspec index out of bounds", arrayIndexedExpression.arrayspec.position)) checkResult.add(ExpressionError("arrayspec index out of bounds", arrayIndexedExpression.arrayspec.position))
} else if(target.datatype in StringDatatypes) {
// check string lengths
(arrayIndexedExpression.arrayspec.y as? LiteralValue)?.asIntegerValue
val heapId = (target.value as LiteralValue).heapId!!
val stringLen = heap.get(heapId).str!!.length
val index = (arrayIndexedExpression.arrayspec.x as? LiteralValue)?.asIntegerValue
if(index!=null && (index<0 || index>=stringLen))
checkResult.add(ExpressionError("index out of bounds", arrayIndexedExpression.arrayspec.position))
} }
} else } else
checkResult.add(SyntaxError("arrayspec indexing requires a variable to act upon", arrayIndexedExpression.position)) checkResult.add(SyntaxError("indexing requires a variable to act upon", arrayIndexedExpression.position))
} else if(reg==Register.A || reg==Register.X || reg==Register.Y) { } else if(reg==Register.A || reg==Register.X || reg==Register.Y) {
checkResult.add(SyntaxError("arrayspec indexing on registers requires register pair variable", arrayIndexedExpression.position)) checkResult.add(SyntaxError("indexing on registers requires register pair variable", arrayIndexedExpression.position))
} else if(arrayIndexedExpression.arrayspec.y!=null) { } else if(arrayIndexedExpression.arrayspec.y!=null) {
checkResult.add(SyntaxError("arrayspec indexing on registers can only use one index dimension", arrayIndexedExpression.position)) checkResult.add(SyntaxError("indexing on registers can only use one index dimension", arrayIndexedExpression.position))
} }
// check index value 0..255 // check index value 0..255

View File

@ -312,7 +312,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.ARRAY_UW, DataType.ARRAY_W -> Opcode.READ_INDEXED_VAR_WORD DataType.ARRAY_UW, DataType.ARRAY_W -> Opcode.READ_INDEXED_VAR_WORD
DataType.ARRAY_F -> Opcode.READ_INDEXED_VAR_FLOAT DataType.ARRAY_F -> Opcode.READ_INDEXED_VAR_FLOAT
DataType.MATRIX_UB, DataType.MATRIX_B -> Opcode.READ_INDEXED_VAR_BYTE DataType.MATRIX_UB, DataType.MATRIX_B -> Opcode.READ_INDEXED_VAR_BYTE
else -> throw CompilerException("invalid dt for indexed $dt") DataType.STR, DataType.STR_S -> Opcode.READ_INDEXED_VAR_BYTE
DataType.STR_P, DataType.STR_PS -> throw CompilerException("cannot access pascal-string type $dt with index")
else -> throw CompilerException("invalid dt for indexed access $dt")
} }
} }
@ -322,7 +324,9 @@ private class StatementTranslator(private val prog: IntermediateProgram,
DataType.ARRAY_UW, DataType.ARRAY_W -> Opcode.WRITE_INDEXED_VAR_WORD DataType.ARRAY_UW, DataType.ARRAY_W -> Opcode.WRITE_INDEXED_VAR_WORD
DataType.ARRAY_F -> Opcode.WRITE_INDEXED_VAR_FLOAT DataType.ARRAY_F -> Opcode.WRITE_INDEXED_VAR_FLOAT
DataType.MATRIX_UB, DataType.MATRIX_B -> Opcode.WRITE_INDEXED_VAR_BYTE DataType.MATRIX_UB, DataType.MATRIX_B -> Opcode.WRITE_INDEXED_VAR_BYTE
else -> throw CompilerException("invalid dt for indexed $dt") DataType.STR, DataType.STR_S -> Opcode.WRITE_INDEXED_VAR_BYTE
DataType.STR_P, DataType.STR_PS -> throw CompilerException("cannot access pascal-string type $dt with index")
else -> throw CompilerException("invalid dt for indexed access $dt")
} }
} }

View File

@ -910,7 +910,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
private val patterns = listOf( private val patterns = listOf(
// ----------- assignment to BYTE VARIABLE ---------------- // ----------- assignment to BYTE VARIABLE ----------------
// @todo var=var
// var = bytevalue // var = bytevalue
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.POP_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.POP_VAR_BYTE)) { segment ->
when (segment[1].callLabel) { when (segment[1].callLabel) {
@ -999,7 +998,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
}, },
// var = bytearray[indexvar] // var = bytearray[indexvar]
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.POP_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
@ -1050,6 +1049,45 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
""" """
} }
}, },
// var = other var
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.POP_VAR_WORD)) { segment ->
when(segment[1].callLabel) {
"AX" ->
when(segment[0].callLabel) {
"AX" -> null
"AY" -> " stx ${C64Zeropage.SCRATCH_B1} | ldy ${C64Zeropage.SCRATCH_B1}"
"XY" -> " stx ${C64Zeropage.SCRATCH_B1} | tax | ldy ${C64Zeropage.SCRATCH_B1}"
else -> " lda ${segment[0].callLabel} | ldx ${segment[0].callLabel}+1"
}
"AY" ->
when(segment[0].callLabel) {
"AX" -> " sty ${C64Zeropage.SCRATCH_B1} | ldx ${C64Zeropage.SCRATCH_B1}"
"AY" -> null
"XY" -> " tax"
else -> " lda ${segment[0].callLabel} | ldy ${segment[0].callLabel}+1"
}
"XY" ->
when(segment[0].callLabel) {
"AX" -> " txa | sty ${C64Zeropage.SCRATCH_B1} | ldx ${C64Zeropage.SCRATCH_B1}"
"AY" -> " txa"
"XY" -> null
else -> " ldx ${segment[0].callLabel} | ldy ${segment[0].callLabel}+1"
}
else ->
when(segment[0].callLabel) {
"AX" -> " sta ${segment[1].callLabel} | stx ${segment[1].callLabel}+1"
"AY" -> " sta ${segment[1].callLabel} | sty ${segment[1].callLabel}+1"
"XY" -> " stx ${segment[1].callLabel} | sty ${segment[1].callLabel}+1"
else ->
"""
lda ${segment[0].callLabel}
ldy ${segment[0].callLabel}+1
sta ${segment[1].callLabel}
sty ${segment[1].callLabel}+1
"""
}
}
},
// var = mem (u)word // var = mem (u)word
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.POP_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.POP_VAR_WORD)) { segment ->
when(segment[1].callLabel) { when(segment[1].callLabel) {
@ -1156,6 +1194,11 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
} }
} }
}, },
// var = bytearray[index_byte] (sign extended)
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.B2WORD, Opcode.POP_VAR_WORD)) { segment ->
val index = segment[0].arg!!.integerValue().toHex()
TODO("$segment (sign extended)")
},
// var = (u)wordarray[index_byte] // var = (u)wordarray[index_byte]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment ->
val index = segment[0].arg!!.integerValue()*2 val index = segment[0].arg!!.integerValue()*2
@ -1168,11 +1211,11 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
}, },
// var = bytearray[indexvar] (sign extended) // var = bytearray[indexvar] (sign extended)
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_BYTE, Opcode.UB2UWORD, Opcode.POP_VAR_WORD)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// var = (u)wordarray[indexvar] // var = (u)wordarray[indexvar]
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_WORD, Opcode.POP_VAR_WORD)) { segment ->
"nop" // TODO TODO("$segment")
}, },
@ -1413,18 +1456,18 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
}, },
// floatvar = floatarray[index] // floatvar = floatarray[index]
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// floatvar = floatarray[indexvar] // floatvar = floatarray[indexvar]
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// floatvar = floatarray[mem index (u)byte] // floatvar = floatarray[mem index (u)byte]
AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> AsmPattern(listOf(Opcode.PUSH_MEM_B, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
"nop" // TODO TODO("$segment")
}, },
AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment -> AsmPattern(listOf(Opcode.PUSH_MEM_UB, Opcode.READ_INDEXED_VAR_FLOAT, Opcode.POP_VAR_FLOAT)) { segment ->
"nop" // TODO TODO("$segment")
}, },
@ -1506,27 +1549,27 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// assignment: bytearray[memory (u)byte] = byte // assignment: bytearray[memory (u)byte] = byte
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: bytearray[idxvar] = byte // assignment: bytearray[idxvar] = byte
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: bytearray[idxvar] = bytevar // assignment: bytearray[idxvar] = bytevar
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: bytearray[mem (u)byte] = bytevar // assignment: bytearray[mem (u)byte] = bytevar
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_BYTE, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_BYTE)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: bytearray[idxbyte] = membyte // assignment: bytearray[idxbyte] = membyte
@ -1557,15 +1600,15 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
// assignment: wordarray[memory (u)byte] = word // assignment: wordarray[memory (u)byte] = word
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_B, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
"nop" // TODO TODO("$segment")
}, },
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_MEM_UB, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: wordarray[indexvar] = word // assignment: wordarray[indexvar] = word
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: wordarray[idxbyte] = wordvar // assignment: wordarray[idxbyte] = wordvar
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
@ -1585,7 +1628,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
}, },
// assignment: wordarray[indexvar] = wordvar // assignment: wordarray[indexvar] = wordvar
AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_VAR_WORD, Opcode.PUSH_VAR_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->
"nop" // TODO TODO("$segment")
}, },
// assignment: wordarray[idxbyte] = memword // assignment: wordarray[idxbyte] = memword
AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment -> AsmPattern(listOf(Opcode.PUSH_MEM_W, Opcode.PUSH_BYTE, Opcode.WRITE_INDEXED_VAR_WORD)) { segment ->