Merge branch 'v8_maintenance'

# Conflicts:
#	examples/test.p8
This commit is contained in:
Irmen de Jong 2023-05-28 13:26:05 +02:00
commit a99d38fdaa
5 changed files with 64 additions and 15 deletions

View File

@ -157,6 +157,12 @@ class UnusedCodeRemover(private val program: Program,
return noModifications return noModifications
} }
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
if(assignment.target isSameAs assignment.value)
return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
return noModifications
}
private fun deduplicateAssignments(statements: List<Statement>, scope: IStatementContainer): List<IAstModification> { private fun deduplicateAssignments(statements: List<Statement>, scope: IStatementContainer): List<IAstModification> {
// removes 'duplicate' assignments that assign the same target directly after another, unless it is a function call // removes 'duplicate' assignments that assign the same target directly after another, unless it is a function call
val linesToRemove = mutableListOf<Assignment>() val linesToRemove = mutableListOf<Assignment>()

View File

@ -479,6 +479,8 @@ internal class AstChecker(private val program: Program,
errors.err("target datatype is unknown", assignment.target.position) errors.err("target datatype is unknown", assignment.target.position)
// otherwise, another error about missing symbol is already reported. // otherwise, another error about missing symbol is already reported.
} else { } else {
// allow bitwise operations on different types as long as the size is the same
if (!((assignment.value as? BinaryExpression)?.operator in BitwiseOperators && targetDt.isBytes && valueDt.isBytes || targetDt.isWords && valueDt.isWords))
errors.err("type of value $valueDt doesn't match target $targetDt", assignment.value.position) errors.err("type of value $valueDt doesn't match target $targetDt", assignment.value.position)
} }
} }
@ -1598,9 +1600,12 @@ internal class AstChecker(private val program: Program,
else if(sourceDatatype== DataType.FLOAT && targetDatatype in IntegerDatatypes) else if(sourceDatatype== DataType.FLOAT && targetDatatype in IntegerDatatypes)
errors.err("cannot assign float to ${targetDatatype.name.lowercase()}; possible loss of precision. Suggestion: round the value or revert to integer arithmetic", position) errors.err("cannot assign float to ${targetDatatype.name.lowercase()}; possible loss of precision. Suggestion: round the value or revert to integer arithmetic", position)
else { else {
if(targetDatatype!=DataType.UWORD && sourceDatatype !in PassByReferenceDatatypes) if(targetDatatype!=DataType.UWORD && sourceDatatype !in PassByReferenceDatatypes) {
// allow bitwise operations on different types as long as the size is the same
if (!((sourceValue as? BinaryExpression)?.operator in BitwiseOperators && targetDatatype.equalsSize(sourceDatatype)))
errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position) errors.err("type of value $sourceDatatype doesn't match target $targetDatatype", position)
} }
}
return false return false
} }

View File

@ -93,6 +93,11 @@ internal class BeforeAsmAstChanger(val program: Program,
) )
} }
} else { } else {
if(binExpr.left isSameAs assignment.target)
return noModifications
val typeCast = binExpr.left as? TypecastExpression
if(typeCast!=null && typeCast.expression isSameAs assignment.target)
return noModifications
val sourceDt = binExpr.left.inferType(program).getOrElse { throw AssemblyError("unknown dt") } val sourceDt = binExpr.left.inferType(program).getOrElse { throw AssemblyError("unknown dt") }
val (_, left) = binExpr.left.typecastTo(assignment.target.inferType(program).getOrElse { throw AssemblyError( val (_, left) = binExpr.left.typecastTo(assignment.target.inferType(program).getOrElse { throw AssemblyError(
"unknown dt" "unknown dt"

View File

@ -133,9 +133,16 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) return listOf(IAstModification.ReplaceNode(expr.left, cast, expr))
} }
if(leftDt istype DataType.WORD && rightDt.oneOf(DataType.UBYTE, DataType.UWORD)) { if(leftDt istype DataType.WORD && rightDt.oneOf(DataType.UBYTE, DataType.UWORD)) {
// cast left to unsigned // cast left to unsigned word. Cast right to unsigned word if it is ubyte
val cast = TypecastExpression(expr.left, rightDt.getOr(DataType.UNDEFINED), true, expr.left.position) val mods = mutableListOf<IAstModification>()
return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) val cast = TypecastExpression(expr.left, DataType.UWORD, true, expr.left.position)
mods += IAstModification.ReplaceNode(expr.left, cast, expr)
if(rightDt istype DataType.UBYTE) {
mods += IAstModification.ReplaceNode(expr.right,
TypecastExpression(expr.right, DataType.UWORD, true, expr.right.position),
expr)
}
return mods
} }
if(rightDt istype DataType.BYTE && leftDt.oneOf(DataType.UBYTE, DataType.UWORD)) { if(rightDt istype DataType.BYTE && leftDt.oneOf(DataType.UBYTE, DataType.UWORD)) {
// cast right to unsigned // cast right to unsigned
@ -143,9 +150,16 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
return listOf(IAstModification.ReplaceNode(expr.right, cast, expr)) return listOf(IAstModification.ReplaceNode(expr.right, cast, expr))
} }
if(rightDt istype DataType.WORD && leftDt.oneOf(DataType.UBYTE, DataType.UWORD)) { if(rightDt istype DataType.WORD && leftDt.oneOf(DataType.UBYTE, DataType.UWORD)) {
// cast right to unsigned // cast right to unsigned word. Cast left to unsigned word if it is ubyte
val cast = TypecastExpression(expr.right, leftDt.getOr(DataType.UNDEFINED), true, expr.right.position) val mods = mutableListOf<IAstModification>()
return listOf(IAstModification.ReplaceNode(expr.right, cast, expr)) val cast = TypecastExpression(expr.right, DataType.UWORD, true, expr.right.position)
mods += IAstModification.ReplaceNode(expr.right, cast, expr)
if(leftDt istype DataType.UBYTE) {
mods += IAstModification.ReplaceNode(expr.left,
TypecastExpression(expr.left, DataType.UWORD, true, expr.left.position),
expr)
}
return mods
} }
} }

View File

@ -1,16 +1,35 @@
%import floats
%import textio %import textio
%zeropage basicsafe %zeropage basicsafe
main { main {
sub start() { sub start() {
ubyte[] array = [ $00, $11, $22, $33, $44, $55, $66, $77, $88, $99, $aa, $bb] ubyte ub = 123
byte bb = -100
uword uw = 12345
word ww = -12345
ubyte x = 2 ub |= 63 ; vm/c64 ok (127)
ubyte y = 3 bb |= 63 ; vm/c64 ok (-65)
txt.print_uwhex(mkword(array[9], array[8]), true) uw |= 63 ; vm/c64 ok (12351)
txt.print_uwhex(mkword(array[x*y+y], array[y*x+x]), true) ww |= 63 ; vm/c64 ok (-12289)
txt.print_ub(ub)
txt.spc()
txt.print_b(bb)
txt.spc()
txt.print_uw(uw)
txt.spc()
txt.print_w(ww)
txt.nl()
uw |= 16384 ; vm/c64 ok (28735)
ww |= 8192 ; vm/c64 ok (-4097)
txt.print_uw(uw)
txt.spc()
txt.print_w(ww)
txt.nl()
} }
} }