mirror of
https://github.com/irmen/prog8.git
synced 2024-10-07 15:57:03 +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)
|
||||
return when {
|
||||
fromDt==null || toDt==null -> null
|
||||
fromDt== DataType.UBYTE && toDt== DataType.UBYTE -> DataType.UBYTE
|
||||
fromDt== DataType.UWORD && toDt== DataType.UWORD -> DataType.UWORD
|
||||
fromDt== DataType.UBYTE && toDt== DataType.UBYTE -> DataType.ARRAY_UB
|
||||
fromDt== DataType.UWORD && toDt== DataType.UWORD -> DataType.ARRAY_UW
|
||||
fromDt== DataType.STR && toDt== DataType.STR -> DataType.STR
|
||||
fromDt== DataType.STR_S && toDt== DataType.STR_S -> DataType.STR_S
|
||||
fromDt== DataType.WORD || toDt== DataType.WORD -> DataType.WORD
|
||||
fromDt== DataType.BYTE || toDt== DataType.BYTE -> DataType.BYTE
|
||||
else -> DataType.UBYTE
|
||||
fromDt== DataType.WORD || toDt== DataType.WORD -> DataType.ARRAY_W
|
||||
fromDt== DataType.BYTE || toDt== DataType.BYTE -> DataType.ARRAY_B
|
||||
else -> DataType.ARRAY_UB
|
||||
}
|
||||
}
|
||||
override fun toString(): String {
|
||||
|
@ -120,7 +120,7 @@ internal class AstChecker(private val program: Program,
|
||||
} else {
|
||||
if (forLoop.loopRegister != null) {
|
||||
// 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))
|
||||
if(forLoop.loopRegister!=Register.A)
|
||||
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)
|
||||
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)
|
||||
|
@ -599,13 +599,16 @@ internal class AsmGen2(val program: Program,
|
||||
} else {
|
||||
translateSubroutineCall(stmt)
|
||||
// discard any results from the stack:
|
||||
val returns = stmt.target.targetSubroutine(program.namespace)!!.returntypes
|
||||
for(t in returns) {
|
||||
val sub = stmt.target.targetSubroutine(program.namespace)!!
|
||||
val returns = sub.returntypes.zip(sub.asmReturnvaluesRegisters)
|
||||
for((t, reg) in returns) {
|
||||
if(reg.stack) {
|
||||
if (t in IntegerDatatypes || t in PassByReferenceDatatypes) out(" inx")
|
||||
else if (t == DataType.FLOAT) out(" inx | inx | inx")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
is Assignment -> translate(stmt)
|
||||
is Jump -> translate(stmt)
|
||||
is PostIncrDecr -> translate(stmt)
|
||||
@ -1032,7 +1035,7 @@ $loopLabel lda ${65535.toHex()} ; modified
|
||||
$endLabel""")
|
||||
}
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
val length = decl.arraysize!!.size()
|
||||
val length = decl.arraysize!!.size()!!
|
||||
if(stmt.loopRegister!=null && stmt.loopRegister!=Register.A)
|
||||
throw AssemblyError("can only use A")
|
||||
val counterLabel = makeLabel("for_counter")
|
||||
@ -1044,8 +1047,6 @@ $endLabel""")
|
||||
sty $modifiedLabel+2
|
||||
ldy #0
|
||||
$loopLabel sty $counterLabel
|
||||
cpy #$length
|
||||
beq $endLabel
|
||||
$modifiedLabel lda ${65535.toHex()},y ; modified""")
|
||||
if(stmt.loopVar!=null)
|
||||
out(" sta ${asmIdentifierName(stmt.loopVar!!)}")
|
||||
@ -1053,6 +1054,8 @@ $modifiedLabel lda ${65535.toHex()},y ; modified""")
|
||||
out("""
|
||||
ldy $counterLabel
|
||||
iny
|
||||
cpy #${length and 255}
|
||||
beq $endLabel
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
$endLabel""")
|
||||
@ -1076,8 +1079,6 @@ $endLabel""")
|
||||
sty $modifiedLabel2+2
|
||||
ldy #0
|
||||
$loopLabel sty $counterLabel
|
||||
cpy #$length
|
||||
beq $endLabel
|
||||
$modifiedLabel lda ${65535.toHex()},y ; modified
|
||||
sta $loopvarName
|
||||
$modifiedLabel2 lda ${65535.toHex()},y ; modified
|
||||
@ -1087,6 +1088,8 @@ $modifiedLabel2 lda ${65535.toHex()},y ; modified
|
||||
ldy $counterLabel
|
||||
iny
|
||||
iny
|
||||
cpy #${length and 255}
|
||||
beq $endLabel
|
||||
jmp $loopLabel
|
||||
$counterLabel .byte 0
|
||||
$endLabel""")
|
||||
@ -1102,7 +1105,7 @@ $endLabel""")
|
||||
val loopLabel = makeLabel("for_loop")
|
||||
val endLabel = makeLabel("for_end")
|
||||
when(iterableDt) {
|
||||
in ByteDatatypes -> {
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||
if(stmt.loopRegister!=null) {
|
||||
|
||||
// loop register over range
|
||||
@ -1269,7 +1272,7 @@ $endLabel""")
|
||||
}
|
||||
}
|
||||
}
|
||||
in WordDatatypes -> {
|
||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||
// loop over word range via loopvar
|
||||
val counterLabel = makeLabel("for_counter")
|
||||
val varname = asmIdentifierName(stmt.loopVar!!)
|
||||
@ -1745,10 +1748,33 @@ $endLabel""")
|
||||
}
|
||||
|
||||
private fun translateExpression(expr: BinaryExpression) {
|
||||
translateExpression(expr.left)
|
||||
translateExpression(expr.right)
|
||||
val leftDt = expr.left.inferType(program)!!
|
||||
val rightDt = expr.right.inferType(program)!!
|
||||
when(expr.operator) {
|
||||
">>" -> {
|
||||
// bit-shifts are always by a constant number (for now)
|
||||
translateExpression(expr.left)
|
||||
val amount = expr.right.constValue(program)!!.number.toInt()
|
||||
when(leftDt) {
|
||||
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) {
|
||||
@ -1758,6 +1784,8 @@ $endLabel""")
|
||||
else -> throw AssemblyError("non-numerical datatype")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateExpression(expr: PrefixExpression) {
|
||||
translateExpression(expr.expression)
|
||||
@ -1819,8 +1847,7 @@ $endLabel""")
|
||||
inx
|
||||
sta $ESTACK_LO_PLUS1_HEX,x
|
||||
""")
|
||||
"<<" -> throw AssemblyError("<< should not operate via stack")
|
||||
">>" -> throw AssemblyError(">> should not operate via stack")
|
||||
"<<", ">>" -> throw AssemblyError("bit-shifts not 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.greater_ub" else " jsr prog8_lib.greater_b")
|
||||
"<=" -> out(if(types==DataType.UBYTE) " jsr prog8_lib.lesseq_ub" else " jsr prog8_lib.lesseq_b")
|
||||
|
@ -3,23 +3,34 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
c64.CHROUT('\n')
|
||||
%asm {{
|
||||
stx $0410
|
||||
}}
|
||||
c64.CHRIN()
|
||||
%asm {{
|
||||
stx $0411
|
||||
}}
|
||||
print_notes(80,35)
|
||||
%asm {{
|
||||
stx $0412
|
||||
}}
|
||||
return
|
||||
}
|
||||
|
||||
byte bb=10
|
||||
|
||||
while bb<15 {
|
||||
bb++
|
||||
c64scr.print_b(bb)
|
||||
sub print_notes(ubyte n1, ubyte n2) {
|
||||
c64scr.print_ub(n1/2)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(n1/3)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(n1/4)
|
||||
c64.CHROUT('\n')
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(n2/2)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(n2/3)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ub(n2/4)
|
||||
c64.CHROUT('\n')
|
||||
}
|
||||
|
||||
word ww=5
|
||||
|
||||
while ww > -5 {
|
||||
ww--
|
||||
c64scr.print_w(ww)
|
||||
c64.CHROUT('\n')
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user