mirror of
https://github.com/irmen/prog8.git
synced 2024-07-28 18:29:40 +00:00
fix range typing issues and function call param cleanup bug for asmsub
This commit is contained in:
parent
fb00ff74d1
commit
e9c357a885
@ -637,13 +637,13 @@ class RangeExpr(var from: Expression,
|
|||||||
val toDt=to.inferType(program)
|
val toDt=to.inferType(program)
|
||||||
return when {
|
return when {
|
||||||
fromDt==null || toDt==null -> null
|
fromDt==null || toDt==null -> null
|
||||||
fromDt== DataType.UBYTE && toDt== DataType.UBYTE -> DataType.UBYTE
|
fromDt== DataType.UBYTE && toDt== DataType.UBYTE -> DataType.ARRAY_UB
|
||||||
fromDt== DataType.UWORD && toDt== DataType.UWORD -> DataType.UWORD
|
fromDt== DataType.UWORD && toDt== DataType.UWORD -> DataType.ARRAY_UW
|
||||||
fromDt== DataType.STR && toDt== DataType.STR -> DataType.STR
|
fromDt== DataType.STR && toDt== DataType.STR -> DataType.STR
|
||||||
fromDt== DataType.STR_S && toDt== DataType.STR_S -> DataType.STR_S
|
fromDt== DataType.STR_S && toDt== DataType.STR_S -> DataType.STR_S
|
||||||
fromDt== DataType.WORD || toDt== DataType.WORD -> DataType.WORD
|
fromDt== DataType.WORD || toDt== DataType.WORD -> DataType.ARRAY_W
|
||||||
fromDt== DataType.BYTE || toDt== DataType.BYTE -> DataType.BYTE
|
fromDt== DataType.BYTE || toDt== DataType.BYTE -> DataType.ARRAY_B
|
||||||
else -> DataType.UBYTE
|
else -> DataType.ARRAY_UB
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
|
@ -120,7 +120,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
} else {
|
} else {
|
||||||
if (forLoop.loopRegister != null) {
|
if (forLoop.loopRegister != null) {
|
||||||
// loop register
|
// loop register
|
||||||
if (iterableDt != DataType.UBYTE && iterableDt!= DataType.ARRAY_UB && iterableDt !in StringDatatypes)
|
if (iterableDt != DataType.ARRAY_UB && iterableDt != DataType.ARRAY_B && iterableDt !in StringDatatypes)
|
||||||
checkResult.add(ExpressionError("register can only loop over bytes", forLoop.position))
|
checkResult.add(ExpressionError("register can only loop over bytes", forLoop.position))
|
||||||
if(forLoop.loopRegister!=Register.A)
|
if(forLoop.loopRegister!=Register.A)
|
||||||
checkResult.add(ExpressionError("it's only possible to use A as a loop register", forLoop.position))
|
checkResult.add(ExpressionError("it's only possible to use A as a loop register", forLoop.position))
|
||||||
@ -750,6 +750,12 @@ internal class AstChecker(private val program: Program,
|
|||||||
if(leftDt !in IntegerDatatypes || rightDt !in IntegerDatatypes)
|
if(leftDt !in IntegerDatatypes || rightDt !in IntegerDatatypes)
|
||||||
checkResult.add(ExpressionError("bitwise operator can only be used on integer operands", expr.right.position))
|
checkResult.add(ExpressionError("bitwise operator can only be used on integer operands", expr.right.position))
|
||||||
}
|
}
|
||||||
|
"<<", ">>" -> {
|
||||||
|
// for now, bit-shifts can only shift by a constant number
|
||||||
|
val constRight = expr.right.constValue(program)
|
||||||
|
if(constRight==null)
|
||||||
|
checkResult.add(ExpressionError("bit-shift can only be done by a constant number (for now)", expr.right.position))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(leftDt !in NumericDatatypes)
|
if(leftDt !in NumericDatatypes)
|
||||||
|
@ -599,10 +599,13 @@ internal class AsmGen2(val program: Program,
|
|||||||
} else {
|
} else {
|
||||||
translateSubroutineCall(stmt)
|
translateSubroutineCall(stmt)
|
||||||
// discard any results from the stack:
|
// discard any results from the stack:
|
||||||
val returns = stmt.target.targetSubroutine(program.namespace)!!.returntypes
|
val sub = stmt.target.targetSubroutine(program.namespace)!!
|
||||||
for(t in returns) {
|
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
|
||||||
if (t in IntegerDatatypes || t in PassByReferenceDatatypes) out(" inx")
|
for((t, reg) in returns) {
|
||||||
else if (t == DataType.FLOAT) out(" inx | inx | inx")
|
if(reg.stack) {
|
||||||
|
if (t in IntegerDatatypes || t in PassByReferenceDatatypes) out(" inx")
|
||||||
|
else if (t == DataType.FLOAT) out(" inx | inx | inx")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1032,7 +1035,7 @@ $loopLabel lda ${65535.toHex()} ; modified
|
|||||||
$endLabel""")
|
$endLabel""")
|
||||||
}
|
}
|
||||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||||
val length = decl.arraysize!!.size()
|
val length = decl.arraysize!!.size()!!
|
||||||
if(stmt.loopRegister!=null && stmt.loopRegister!=Register.A)
|
if(stmt.loopRegister!=null && stmt.loopRegister!=Register.A)
|
||||||
throw AssemblyError("can only use A")
|
throw AssemblyError("can only use A")
|
||||||
val counterLabel = makeLabel("for_counter")
|
val counterLabel = makeLabel("for_counter")
|
||||||
@ -1044,8 +1047,6 @@ $endLabel""")
|
|||||||
sty $modifiedLabel+2
|
sty $modifiedLabel+2
|
||||||
ldy #0
|
ldy #0
|
||||||
$loopLabel sty $counterLabel
|
$loopLabel sty $counterLabel
|
||||||
cpy #$length
|
|
||||||
beq $endLabel
|
|
||||||
$modifiedLabel lda ${65535.toHex()},y ; modified""")
|
$modifiedLabel lda ${65535.toHex()},y ; modified""")
|
||||||
if(stmt.loopVar!=null)
|
if(stmt.loopVar!=null)
|
||||||
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
|
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
|
||||||
@ -1053,6 +1054,8 @@ $modifiedLabel lda ${65535.toHex()},y ; modified""")
|
|||||||
out("""
|
out("""
|
||||||
ldy $counterLabel
|
ldy $counterLabel
|
||||||
iny
|
iny
|
||||||
|
cpy #${length and 255}
|
||||||
|
beq $endLabel
|
||||||
jmp $loopLabel
|
jmp $loopLabel
|
||||||
$counterLabel .byte 0
|
$counterLabel .byte 0
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
@ -1076,8 +1079,6 @@ $endLabel""")
|
|||||||
sty $modifiedLabel2+2
|
sty $modifiedLabel2+2
|
||||||
ldy #0
|
ldy #0
|
||||||
$loopLabel sty $counterLabel
|
$loopLabel sty $counterLabel
|
||||||
cpy #$length
|
|
||||||
beq $endLabel
|
|
||||||
$modifiedLabel lda ${65535.toHex()},y ; modified
|
$modifiedLabel lda ${65535.toHex()},y ; modified
|
||||||
sta $loopvarName
|
sta $loopvarName
|
||||||
$modifiedLabel2 lda ${65535.toHex()},y ; modified
|
$modifiedLabel2 lda ${65535.toHex()},y ; modified
|
||||||
@ -1087,6 +1088,8 @@ $modifiedLabel2 lda ${65535.toHex()},y ; modified
|
|||||||
ldy $counterLabel
|
ldy $counterLabel
|
||||||
iny
|
iny
|
||||||
iny
|
iny
|
||||||
|
cpy #${length and 255}
|
||||||
|
beq $endLabel
|
||||||
jmp $loopLabel
|
jmp $loopLabel
|
||||||
$counterLabel .byte 0
|
$counterLabel .byte 0
|
||||||
$endLabel""")
|
$endLabel""")
|
||||||
@ -1102,7 +1105,7 @@ $endLabel""")
|
|||||||
val loopLabel = makeLabel("for_loop")
|
val loopLabel = makeLabel("for_loop")
|
||||||
val endLabel = makeLabel("for_end")
|
val endLabel = makeLabel("for_end")
|
||||||
when(iterableDt) {
|
when(iterableDt) {
|
||||||
in ByteDatatypes -> {
|
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||||
if(stmt.loopRegister!=null) {
|
if(stmt.loopRegister!=null) {
|
||||||
|
|
||||||
// loop register over range
|
// loop register over range
|
||||||
@ -1269,7 +1272,7 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in WordDatatypes -> {
|
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||||
// loop over word range via loopvar
|
// loop over word range via loopvar
|
||||||
val counterLabel = makeLabel("for_counter")
|
val counterLabel = makeLabel("for_counter")
|
||||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||||
@ -1745,17 +1748,42 @@ $endLabel""")
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateExpression(expr: BinaryExpression) {
|
private fun translateExpression(expr: BinaryExpression) {
|
||||||
translateExpression(expr.left)
|
|
||||||
translateExpression(expr.right)
|
|
||||||
val leftDt = expr.left.inferType(program)!!
|
val leftDt = expr.left.inferType(program)!!
|
||||||
val rightDt = expr.right.inferType(program)!!
|
val rightDt = expr.right.inferType(program)!!
|
||||||
if(leftDt!=rightDt)
|
when(expr.operator) {
|
||||||
throw AssemblyError("binary operator ${expr.operator} left/right dt not identical") // is this strictly required always?
|
">>" -> {
|
||||||
when (leftDt) {
|
// bit-shifts are always by a constant number (for now)
|
||||||
in ByteDatatypes -> translateBinaryOperatorBytes(expr.operator, leftDt)
|
translateExpression(expr.left)
|
||||||
in WordDatatypes -> translateBinaryOperatorWords(expr.operator, leftDt)
|
val amount = expr.right.constValue(program)!!.number.toInt()
|
||||||
DataType.FLOAT -> translateBinaryOperatorFloats(expr.operator)
|
when(leftDt) {
|
||||||
else -> throw AssemblyError("non-numerical datatype")
|
DataType.UBYTE -> repeat(amount) { out(" lsr $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
|
DataType.BYTE -> repeat(amount) { out(" lda $ESTACK_LO_PLUS1_HEX,x | asl a | ror $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
|
DataType.UWORD -> repeat(amount) { out(" lsr $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
|
DataType.WORD -> repeat(amount) { out( " lda $ESTACK_HI_PLUS1_HEX,x | asl a | ror $ESTACK_HI_PLUS1_HEX,x | ror $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
|
else -> throw AssemblyError("weird type")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"<<" -> {
|
||||||
|
// bit-shifts are always by a constant number (for now)
|
||||||
|
translateExpression(expr.left)
|
||||||
|
val amount = expr.right.constValue(program)!!.number.toInt()
|
||||||
|
if(leftDt in ByteDatatypes)
|
||||||
|
repeat(amount) { out(" asl $ESTACK_LO_PLUS1_HEX,x") }
|
||||||
|
else
|
||||||
|
repeat(amount) { out(" asl $ESTACK_LO_PLUS1_HEX,x | rol $ESTACK_HI_PLUS1_HEX,x") }
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
translateExpression(expr.left)
|
||||||
|
translateExpression(expr.right)
|
||||||
|
if(leftDt!=rightDt)
|
||||||
|
throw AssemblyError("binary operator ${expr.operator} left/right dt not identical") // is this strictly required always?
|
||||||
|
when (leftDt) {
|
||||||
|
in ByteDatatypes -> translateBinaryOperatorBytes(expr.operator, leftDt)
|
||||||
|
in WordDatatypes -> translateBinaryOperatorWords(expr.operator, leftDt)
|
||||||
|
DataType.FLOAT -> translateBinaryOperatorFloats(expr.operator)
|
||||||
|
else -> throw AssemblyError("non-numerical datatype")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1819,8 +1847,7 @@ $endLabel""")
|
|||||||
inx
|
inx
|
||||||
sta $ESTACK_LO_PLUS1_HEX,x
|
sta $ESTACK_LO_PLUS1_HEX,x
|
||||||
""")
|
""")
|
||||||
"<<" -> throw AssemblyError("<< should not operate via stack")
|
"<<", ">>" -> throw AssemblyError("bit-shifts not via stack")
|
||||||
">>" -> throw AssemblyError(">> should not operate via stack")
|
|
||||||
"<" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.less_ub" else " jsr prog8_lib.less_b")
|
"<" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.less_ub" else " jsr prog8_lib.less_b")
|
||||||
">" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.greater_ub" else " jsr prog8_lib.greater_b")
|
">" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.greater_ub" else " jsr prog8_lib.greater_b")
|
||||||
"<=" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.lesseq_ub" else " jsr prog8_lib.lesseq_b")
|
"<=" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.lesseq_ub" else " jsr prog8_lib.lesseq_b")
|
||||||
|
@ -3,23 +3,34 @@
|
|||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
c64.CHROUT('\n')
|
||||||
|
%asm {{
|
||||||
|
stx $0410
|
||||||
|
}}
|
||||||
|
c64.CHRIN()
|
||||||
|
%asm {{
|
||||||
|
stx $0411
|
||||||
|
}}
|
||||||
|
print_notes(80,35)
|
||||||
|
%asm {{
|
||||||
|
stx $0412
|
||||||
|
}}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
byte bb=10
|
sub print_notes(ubyte n1, ubyte n2) {
|
||||||
|
c64scr.print_ub(n1/2)
|
||||||
while bb<15 {
|
c64.CHROUT('\n')
|
||||||
bb++
|
c64scr.print_ub(n1/3)
|
||||||
c64scr.print_b(bb)
|
c64.CHROUT('\n')
|
||||||
c64.CHROUT('\n')
|
c64scr.print_ub(n1/4)
|
||||||
}
|
c64.CHROUT('\n')
|
||||||
|
c64.CHROUT('\n')
|
||||||
word ww=5
|
c64scr.print_ub(n2/2)
|
||||||
|
c64.CHROUT('\n')
|
||||||
while ww > -5 {
|
c64scr.print_ub(n2/3)
|
||||||
ww--
|
c64.CHROUT('\n')
|
||||||
c64scr.print_w(ww)
|
c64scr.print_ub(n2/4)
|
||||||
c64.CHROUT('\n')
|
c64.CHROUT('\n')
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user