mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
boolean vs byte cast fixing, and pointervar error
This commit is contained in:
parent
a5ca08f33d
commit
201b77d5b6
@ -113,10 +113,10 @@ class AsmGen(
|
||||
out(" lda $sourceName")
|
||||
return sourceName
|
||||
}
|
||||
is PtVariable -> {
|
||||
is PtVariable, is PtMemMapped -> {
|
||||
val sourceName = asmVariableName(pointervar)
|
||||
if (isTargetCpu(CpuType.CPU65c02)) {
|
||||
return if (allocator.isZpVar(target.scopedName.split('.'))) { // TODO dotted string
|
||||
return if (allocator.isZpVar((target as PtNamedNode).scopedName.split('.'))) { // TODO dotted string
|
||||
// pointervar is already in the zero page, no need to copy
|
||||
out(" lda ($sourceName)")
|
||||
sourceName
|
||||
@ -130,7 +130,7 @@ class AsmGen(
|
||||
"P8ZP_SCRATCH_W1"
|
||||
}
|
||||
} else {
|
||||
return if (allocator.isZpVar(target.scopedName.split('.'))) { // TODO dotted string
|
||||
return if (allocator.isZpVar((target as PtNamedNode).scopedName.split('.'))) { // TODO dotted string
|
||||
// pointervar is already in the zero page, no need to copy
|
||||
out(" ldy #0 | lda ($sourceName),y")
|
||||
sourceName
|
||||
@ -146,7 +146,7 @@ class AsmGen(
|
||||
}
|
||||
}
|
||||
}
|
||||
else -> throw AssemblyError("invalid pointervar")
|
||||
else -> throw AssemblyError("invalid pointervar $target")
|
||||
}
|
||||
}
|
||||
|
||||
@ -995,7 +995,7 @@ $repeatLabel lda $counterVar
|
||||
out(" lda ${asmSymbolName(pointervar)},y")
|
||||
return true
|
||||
}
|
||||
is PtVariable, null -> {
|
||||
is IPtVariable, null -> {
|
||||
if(write) {
|
||||
if(pointervar!=null && isZpVar(pointervar)) {
|
||||
val saveA = evalBytevalueWillClobberA(ptrAndIndex.second)
|
||||
@ -1045,7 +1045,7 @@ $repeatLabel lda $counterVar
|
||||
}
|
||||
return true
|
||||
}
|
||||
else -> throw AssemblyError("invalid pointervar")
|
||||
else -> throw AssemblyError("invalid pointervar $pointervar")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -162,3 +162,27 @@ internal fun IPtSubroutine.returnsWhatWhere(): List<Pair<DataType, RegisterOrSta
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun PtExpression.clone(): PtExpression {
|
||||
fun withClonedChildrenFrom(orig: PtExpression, clone: PtExpression): PtExpression {
|
||||
orig.children.forEach { clone.add((it as PtExpression).clone()) }
|
||||
return clone
|
||||
}
|
||||
when(this) {
|
||||
is PtAddressOf -> return withClonedChildrenFrom(this, PtAddressOf(position))
|
||||
is PtArray -> return withClonedChildrenFrom(this, PtArray(type, position))
|
||||
is PtArrayIndexer -> return withClonedChildrenFrom(this, PtArrayIndexer(type, position))
|
||||
is PtBinaryExpression -> return withClonedChildrenFrom(this, PtBinaryExpression(operator, type, position))
|
||||
is PtBuiltinFunctionCall -> return withClonedChildrenFrom(this, PtBuiltinFunctionCall(name, void, hasNoSideEffects, type, position))
|
||||
is PtContainmentCheck -> return withClonedChildrenFrom(this, PtContainmentCheck(position))
|
||||
is PtFunctionCall -> return withClonedChildrenFrom(this, PtFunctionCall(name, void, type, position))
|
||||
is PtIdentifier -> return withClonedChildrenFrom(this, PtIdentifier(name, type, position))
|
||||
is PtMachineRegister -> return withClonedChildrenFrom(this, PtMachineRegister(register, type, position))
|
||||
is PtMemoryByte -> return withClonedChildrenFrom(this, PtMemoryByte(position))
|
||||
is PtNumber -> return withClonedChildrenFrom(this, PtNumber(type, number, position))
|
||||
is PtPrefix -> return withClonedChildrenFrom(this, PtPrefix(operator, type, position))
|
||||
is PtRange -> return withClonedChildrenFrom(this, PtRange(type, position))
|
||||
is PtString -> return withClonedChildrenFrom(this, PtString(value, encoding, position))
|
||||
is PtTypeCast -> return withClonedChildrenFrom(this, PtTypeCast(type, position))
|
||||
}
|
||||
}
|
@ -363,11 +363,12 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
assignTrue.add(assignment)
|
||||
val assignFalse = PtNodeGroup()
|
||||
val ifelse = PtIfElse(assign.position)
|
||||
val exprClone = arrayOf(expr).clone()[0]
|
||||
require(exprClone !== expr) // TODO remove check if it works
|
||||
ifelse.add(expr)
|
||||
val exprClone = PtBinaryExpression(expr.operator, expr.type, expr.position)
|
||||
expr.children.forEach { exprClone.children.add(it) } // doesn't seem to need a deep clone
|
||||
ifelse.add(exprClone)
|
||||
ifelse.add(assignTrue)
|
||||
ifelse.add(assignFalse)
|
||||
ifelse.parent = expr.parent
|
||||
asmgen.translate(ifelse)
|
||||
return true
|
||||
}
|
||||
|
@ -136,12 +136,8 @@ internal fun Program.checkIdentifiers(errors: IErrorReporter, options: Compilati
|
||||
internal fun Program.variousCleanups(errors: IErrorReporter, options: CompilationOptions) {
|
||||
val process = VariousCleanups(this, errors, options)
|
||||
process.visit(this)
|
||||
if(errors.noErrors()) {
|
||||
if(process.applyModifications()>0) {
|
||||
process.visit(this)
|
||||
if(errors.noErrors())
|
||||
process.applyModifications()
|
||||
}
|
||||
while(errors.noErrors() && process.applyModifications()>0) { // TODO limit the number of cycles here?
|
||||
process.visit(this)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,6 +62,11 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
||||
}
|
||||
|
||||
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
||||
if(assignment.target isSameAs assignment.value) {
|
||||
// remove assignment to self
|
||||
return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
}
|
||||
|
||||
// remove duplicated assignments, but not if it's a memory mapped IO register
|
||||
val isIO = try {
|
||||
assignment.target.isIOAddress(options.compTarget.machine)
|
||||
|
@ -120,6 +120,42 @@ main {
|
||||
right3.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||
}
|
||||
|
||||
test("simple logical with bool no typecast") {
|
||||
val text="""
|
||||
main {
|
||||
bool bb
|
||||
|
||||
sub start() {
|
||||
bb = bb and 123
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
|
||||
val stmts = result.program.entrypoint.statements
|
||||
stmts.size shouldBe 2
|
||||
val assignValue = (stmts[0] as Assignment).value as BinaryExpression
|
||||
assignValue.left shouldBe instanceOf<IdentifierReference>()
|
||||
assignValue.operator shouldBe "&"
|
||||
(assignValue.right as NumericLiteral).number shouldBe 1.0
|
||||
}
|
||||
|
||||
test("simple logical with byte instead of bool ok with typecasting") {
|
||||
val text="""
|
||||
main {
|
||||
ubyte ubb
|
||||
|
||||
sub start() {
|
||||
ubb = ubb and 123
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), true, text, writeAssembly = true)!!
|
||||
val stmts = result.program.entrypoint.statements
|
||||
stmts.size shouldBe 2
|
||||
val assignValue = (stmts[0] as Assignment).value as BinaryExpression
|
||||
assignValue.left shouldBe instanceOf<BinaryExpression>() // as a result of the cast to boolean
|
||||
assignValue.operator shouldBe "&"
|
||||
(assignValue.right as NumericLiteral).number shouldBe 1.0
|
||||
}
|
||||
|
||||
test("logical with byte instead of bool") {
|
||||
val text="""
|
||||
%import textio
|
||||
|
Loading…
Reference in New Issue
Block a user