implementing optimized comparisons

This commit is contained in:
Irmen de Jong 2023-03-22 22:00:21 +01:00
parent 04832f052a
commit 01461a196d
8 changed files with 482 additions and 149 deletions

View File

@ -51,11 +51,6 @@ class PtAugmentedAssign(val operator: String, position: Position) : PtNode(posit
get() = children[0] as PtAssignTarget
val value: PtExpression
get() = children[1] as PtExpression
init {
require(operator.endsWith('=') || operator in PrefixOperators) {
"invalid augmented assign operator $operator"
}
}
}

View File

@ -23,7 +23,7 @@ class AtariMachineDefinition: IMachineDefinition {
override lateinit var zeropage: Zeropage
override lateinit var golden: GoldenRam
override fun getFloatAsmBytes(num: Number) = TODO("float asm bytes from number")
override fun getFloatAsmBytes(num: Number) = TODO("atari float asm bytes from number")
override fun importLibs(compilerOptions: CompilationOptions, compilationTargetName: String): List<String> {
return if (compilerOptions.output == OutputType.XEX)

View File

@ -5,6 +5,7 @@ import prog8.code.SymbolTable
import prog8.code.ast.*
import prog8.code.core.*
import prog8.codegen.cpu6502.AsmGen6502Internal
import prog8.codegen.cpu6502.ExpressionsAsmGen
import prog8.codegen.cpu6502.VariableAllocator
import prog8.codegen.cpu6502.returnsWhatWhere
import java.util.*
@ -438,16 +439,84 @@ internal class AssignmentAsmGen(private val program: PtProgram,
val resultVarname = evalVarName(it.type, asmExtra.rpnDepth)
asmExtra.rpnDepth++
symbolTable.resetCachedFlat()
if(leftvar!=resultVarname) {
val scopeName = (scope as PtNamedNode).scopedName
val leftVarPt = PtIdentifier("$scopeName.$leftvar", it.leftType, it.position)
leftVarPt.parent=scope
assignExpressionToVariable(leftVarPt, resultVarname, it.type)
val scopeName = (scope as PtNamedNode).scopedName
val leftVarPt = PtIdentifier("$scopeName.$leftvar", it.leftType, it.position)
leftVarPt.parent = scope
if(it.rightType largerThan it.type) {
if(it.operator !in ComparisonOperators)
throw AssemblyError("only expected a boolean comparison, got ${it.operator}")
if(it.rightType !in WordDatatypes || it.type !in ByteDatatypes) {
when (it.rightType) {
DataType.STR -> {
val rightString = PtIdentifier("$scopeName.$rightvar", DataType.STR, it.position)
rightString.parent = scope
asmgen.assignExpressionToVariable(leftVarPt, "prog8_lib.strcmp_expression._arg_s1", DataType.UWORD)
asmgen.assignExpressionToVariable(rightString, "prog8_lib.strcmp_expression._arg_s2", DataType.UWORD)
asmgen.out(" jsr prog8_lib.strcmp_expression") // result of compare is in A
when(it.operator) {
"==" -> asmgen.out(" and #1 | eor #1")
"!=" -> asmgen.out(" and #1")
"<=" -> asmgen.out("""
bpl +
lda #1
bne ++
+ lda #0
+""")
">=" -> asmgen.out("""
bmi +
lda #1
bne ++
+ lda #0
+""")
"<" -> asmgen.out("""
bmi +
lda #0
beq ++
+ lda #1
+""")
">" -> asmgen.out("""
bpl +
lda #0
beq ++
+ lda #1
+""")
}
asmgen.out(" sta $resultVarname")
}
in NumericDatatypes -> {
val jumpIfFalseLabel = asmgen.makeLabel("cmp")
val rightVarPt = PtIdentifier("$scopeName.$rightvar", it.rightType, it.position)
rightVarPt.parent = scope
asmgen.testNonzeroComparisonAndJump(leftVarPt, it.operator, rightVarPt, jumpIfFalseLabel, null, null)
asmgen.out("""
lda #1
bne +
$jumpIfFalseLabel lda #0
+ sta $resultVarname""")
}
else -> throw AssemblyError("weird type for operator: ${it.rightType}")
}
} else {
// use in-place assignment with optional cast to the target variable
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, it.rightType, variableAsmName = rightvar)
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, it.leftType, scope, assign.position, variableAsmName = leftvar)
val operator = if(it.operator in ComparisonOperators) it.operator else it.operator+'='
val augAssign = AsmAugmentedAssignment(src, operator, target, program.memsizer, assign.position)
augmentableAsmGen.translate(augAssign, scope)
if(resultVarname!=leftvar)
assignTypeCastedIdentifier(resultVarname, it.type, leftvar, it.leftType)
}
} else {
// use in-place assignment with optional cast to the target variable
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, it.rightType, variableAsmName = rightvar)
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, it.leftType, scope, assign.position, variableAsmName = leftvar)
val operator = if(it.operator in ComparisonOperators) it.operator else it.operator+'='
val augAssign = AsmAugmentedAssignment(src, operator, target, program.memsizer, assign.position)
augmentableAsmGen.translate(augAssign, scope)
if(resultVarname!=leftvar)
assignTypeCastedIdentifier(resultVarname, it.type, leftvar, it.leftType)
}
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, it.rightType, variableAsmName = rightvar)
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, it.type, scope, assign.position, variableAsmName = resultVarname)
val augAssign = AsmAugmentedAssignment(src, it.operator+":=", target, program.memsizer, assign.position)
augmentableAsmGen.translate(augAssign, scope)
}
is PtExpression -> {
val varname = evalVarName(it.type, asmExtra.rpnDepth)

View File

@ -24,10 +24,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
"+" -> { /* is a nop */ }
else -> {
if(assign.operator.endsWith('='))
augmentedAssignExpr(assign)
else
throw AssemblyError("invalid augmented assign operator ${assign.operator}")
require(assign.operator in ComparisonOperators || assign.operator.length>=2) { "invalid aug assign operator ${assign.operator}" }
augmentedAssignExpr(assign)
}
}
}
@ -35,22 +33,22 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
private fun augmentedAssignExpr(assign: AsmAugmentedAssignment) {
val srcValue = assign.source.toAstExpression(assign.target.scope as PtNamedNode)
when (assign.operator) {
"+=", "+:=" -> inplaceModification(assign.target, "+", srcValue)
"-=", "-:=" -> inplaceModification(assign.target, "-", srcValue)
"*=", "*:=" -> inplaceModification(assign.target, "*", srcValue)
"/=", "/:=" -> inplaceModification(assign.target, "/", srcValue)
"|=", "|:=" -> inplaceModification(assign.target, "|", srcValue)
"&=", "&:=" -> inplaceModification(assign.target, "&", srcValue)
"^=", "^:=" -> inplaceModification(assign.target, "^", srcValue)
"<<=", "<<:=" -> inplaceModification(assign.target, "<<", srcValue)
">>=", ">>:=" -> inplaceModification(assign.target, ">>", srcValue)
"%=", "%:=" -> inplaceModification(assign.target, "%", srcValue)
"==:=" -> inplaceModification(assign.target, "==", srcValue)
"!=:=" -> inplaceModification(assign.target, "!=", srcValue)
"<:=" -> inplaceModification(assign.target, "<", srcValue)
">:=" -> inplaceModification(assign.target, ">", srcValue)
"<=:=" -> inplaceModification(assign.target, "<=", srcValue)
">=:=" -> inplaceModification(assign.target, ">=", srcValue)
"+=" -> inplaceModification(assign.target, "+", srcValue)
"-=" -> inplaceModification(assign.target, "-", srcValue)
"*=" -> inplaceModification(assign.target, "*", srcValue)
"/=" -> inplaceModification(assign.target, "/", srcValue)
"|=" -> inplaceModification(assign.target, "|", srcValue)
"&=" -> inplaceModification(assign.target, "&", srcValue)
"^=" -> inplaceModification(assign.target, "^", srcValue)
"<<=" -> inplaceModification(assign.target, "<<", srcValue)
">>=" -> inplaceModification(assign.target, ">>", srcValue)
"%=" -> inplaceModification(assign.target, "%", srcValue)
"==" -> inplaceModification(assign.target, "==", srcValue)
"!=" -> inplaceModification(assign.target, "!=", srcValue)
"<" -> inplaceModification(assign.target, "<", srcValue)
">" -> inplaceModification(assign.target, ">", srcValue)
"<=" -> inplaceModification(assign.target, "<=", srcValue)
">=" -> inplaceModification(assign.target, ">=", srcValue)
else -> throw AssemblyError("invalid augmented assign operator ${assign.operator}")
}
}
@ -339,12 +337,26 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
"&" -> asmgen.out(" and P8ZP_SCRATCH_B1")
"|" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
"^" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
"==" -> TODO("byte-value-to-pointer ==")
"!=" -> TODO("byte-value-to-pointer !=")
"<" -> TODO("byte-value-to-pointer <")
"<=" -> TODO("byte-value-to-pointer <=")
">" -> TODO("byte-value-to-pointer >")
">=" -> TODO("byte-value-to-pointer >=")
"==" -> {
asmgen.out("""
cmp P8ZP_SCRATCH_B1
beq +
lda #0
beq ++
+ lda #1
+""")
}
"!=" -> {
asmgen.out("""
cmp P8ZP_SCRATCH_B1
bne +
lda #0
beq ++
+ lda #1
+""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer:
"<", "<=", ">", ">=" -> TODO("byte-value-to-pointer comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
asmgen.storeAIntoZpPointerVar(sourceName)
@ -381,12 +393,26 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
"&" -> asmgen.out(" and $otherName")
"|" -> asmgen.out(" ora $otherName")
"^" -> asmgen.out(" eor $otherName")
"==" -> TODO("byte-var-to-pointer ==")
"!=" -> TODO("byte-var-to-pointer !=")
"<" -> TODO("byte-var-to-pointer <")
"<=" -> TODO("byte-var-to-pointer <=")
">" -> TODO("byte-var-to-pointer >")
">=" -> TODO("byte-var-to-pointer >=")
"==" -> {
asmgen.out("""
cmp $otherName
beq +
lda #0
beq ++
+ lda #1
+""")
}
"!=" -> {
asmgen.out("""
cmp $otherName
bne +
lda #0
beq ++
+ lda #1
+""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?
"<", "<=", ">", ">=" -> TODO("byte-var-to-pointer comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
asmgen.storeAIntoZpPointerVar(sourceName)
@ -455,12 +481,30 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.out(" eor #$value")
asmgen.storeAIntoZpPointerVar(sourceName)
}
"==" -> TODO("byte-litval-to-pointer ==")
"!=" -> TODO("byte-litval-to-pointer !=")
"<" -> TODO("byte-litval-to-pointer <")
"<=" -> TODO("byte-litval-to-pointer <=")
">" -> TODO("byte-litval-to-pointer >")
">=" -> TODO("byte-litval-to-pointer >=")
"==" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out("""
cmp #$value
beq +
lda #0
beq ++
+ lda #1
+""")
asmgen.storeAIntoZpPointerVar(sourceName)
}
"!=" -> {
val sourceName = asmgen.loadByteFromPointerIntoA(pointervar)
asmgen.out("""
cmp #$value
bne +
lda #0
beq ++
+ lda #1
+""")
asmgen.storeAIntoZpPointerVar(sourceName)
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a pointer?:
"<", "<=", ">", ">=" -> TODO("byte-litval-to-pointer comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -555,10 +599,46 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
+ lda #0
+ sta $name""")
}
"<" -> TODO("byte-value-to-var <")
"<=" -> TODO("byte-value-to-var <=")
">" -> TODO("byte-value-to-var >")
">=" -> TODO("byte-value-to-var >=")
"<" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out("""
cmp $name
bcc +
beq +
lda #1
bne ++
+ lda #0
+ sta $name""")
}
"<=" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out("""
cmp $name
lda #0
adc #0
sta $name""")
}
">" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out("""
cmp $name
bcc +
lda #0
beq ++
+ lda #1
+ sta $name""")
}
">=" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out("""
cmp $name
bcc +
beq +
lda #0
beq ++
+ lda #1
+ sta $name""")
}
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -635,10 +715,42 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
+ lda #0
+ sta $name""")
}
"<" -> TODO("byte-var-to-var <")
"<=" -> TODO("byte-var-to-var <=")
">" -> TODO("byte-var-to-var >")
">=" -> TODO("byte-var-to-var >=")
"<" -> {
asmgen.out("""
lda $name
cmp $otherName
bcs +
lda #1
bne ++
+ lda #0
+ sta $name""")
}
"<=" -> {
asmgen.out("""
lda $otherName
cmp $name
lda #0
adc #0
sta $name""")
}
">" -> {
asmgen.out("""
lda $otherName
cmp $name
bcc +
lda #0
beq ++
+ lda #1
+ sta $name""")
}
">=" -> {
asmgen.out("""
lda $name
cmp $otherName
lda #0
adc #0
sta $name""")
}
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -729,10 +841,42 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
+ lda #0
+ sta $name""")
}
"<" -> TODO("byte-litval-to-var <")
"<=" -> TODO("byte-litval-to-var <=")
">" -> TODO("byte-litval-to-var >")
">=" -> TODO("byte-litval-to-var >=")
"<" -> {
asmgen.out("""
lda $name
cmp #$value
bcs +
lda #1
bne ++
+ lda #0
+ sta $name""")
}
"<=" -> {
asmgen.out("""
lda #$value
cmp $name
lda #0
adc #0
sta $name""")
}
">" -> {
asmgen.out("""
lda #$value
cmp $name
bcc +
lda #0
beq ++
+ lda #1
+ sta $name""")
}
">=" -> {
asmgen.out("""
lda $name
cmp #$value
lda #0
adc #0
sta $name""")
}
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -767,13 +911,6 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.translateDirectMemReadExpressionToRegAorStack(memread, false)
asmgen.out(" eor $name | sta $name")
}
// TODO: tuned code for more operators
"==" -> TODO("byte-memread-to-var ==")
"!=" -> TODO("byte-memread-to-var !=")
"<" -> TODO("byte-memread-to-var <")
"<=" -> TODO("byte-memread-to-var <=")
">" -> TODO("byte-memread-to-var >")
">=" -> TODO("byte-memread-to-var >=")
else -> {
inplaceModification_byte_value_to_variable(name, dt, operator, memread)
}
@ -822,13 +959,6 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.translateDirectMemReadExpressionToRegAorStack(memread, false)
asmgen.out(" eor $name | sta $name")
}
// TODO: tuned code for more operators
"==" -> TODO("word-memread-to-var ==")
"!=" -> TODO("word-memread-to-var !=")
"<" -> TODO("word-memread-to-var <")
"<=" -> TODO("word-memread-to-var <=")
">" -> TODO("word-memread-to-var >")
">=" -> TODO("word-memread-to-var >=")
else -> {
inplaceModification_word_value_to_variable(name, dt, operator, memread)
}
@ -1093,12 +1223,38 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
else -> asmgen.out(" lda $name | eor #<$value | sta $name | lda $name+1 | eor #>$value | sta $name+1")
}
}
"==" -> TODO("word-litval-to-var ==")
"!=" -> TODO("word-litval-to-var !=")
"<" -> TODO("word-litval-to-var <")
"<=" -> TODO("word-litval-to-var <=")
">" -> TODO("word-litval-to-var >")
">=" -> TODO("word-litval-to-var >=")
"==" -> {
asmgen.out("""
lda $name
cmp #<$value
bne +
lda $name+1
cmp #>$value
bne +
lda #1
bne ++
+ lda #0
+ sta $name
lda #0
sta $name+1""")
}
"!=" -> {
asmgen.out("""
lda $name
cmp #<$value
bne +
lda $name+1
cmp #>$value
bne +
lda #0
beq ++
+ lda #1
+ sta $name
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
"<", "<=", ">", ">=" -> TODO("word-litval-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1265,12 +1421,36 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
}
"|" -> asmgen.out(" lda $otherName | ora $name | sta $name")
"^" -> asmgen.out(" lda $otherName | eor $name | sta $name")
"==" -> TODO("word-bytevar-to-var ==")
"!=" -> TODO("word-bytevar-to-var !=")
"<" -> TODO("word-bytevar-to-var <")
"<=" -> TODO("word-bytevar-to-var <=")
">" -> TODO("word-bytevar-to-var >")
">=" -> TODO("word-bytevar-to-var >=")
"==" -> {
asmgen.out("""
lda $name
cmp $otherName
bne +
lda $name+1
bne +
lda #1
bne ++
+ lda #0
+ sta $name
lda #0
sta $name+1""")
}
"!=" -> {
asmgen.out("""
lda $name
cmp $otherName
bne +
lda $name+1
bne +
lda #0
beq ++
+ lda #1
+ sta $name
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
"<", "<=", ">", ">=" -> TODO("word-bytevar-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1345,12 +1525,38 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
"&" -> asmgen.out(" lda $name | and $otherName | sta $name | lda $name+1 | and $otherName+1 | sta $name+1")
"|" -> asmgen.out(" lda $name | ora $otherName | sta $name | lda $name+1 | ora $otherName+1 | sta $name+1")
"^" -> asmgen.out(" lda $name | eor $otherName | sta $name | lda $name+1 | eor $otherName+1 | sta $name+1")
"==" -> TODO("word-var-to-var ==")
"!=" -> TODO("word-var-to-var !=")
"<" -> TODO("word-var-to-var <")
"<=" -> TODO("word-var-to-var <=")
">" -> TODO("word-var-to-var >")
">=" -> TODO("word-var-to-var >=")
"==" -> {
asmgen.out("""
lda $name
cmp $otherName
bne +
lda $name+1
cmp $otherName+1
bne +
lda #1
bne ++
+ lda #0
+ sta $name
lda #0
sta $name+1""")
}
"!=" -> {
asmgen.out("""
lda $name
cmp $otherName
bne +
lda $name+1
cmp $otherName+1
bne +
lda #0
beq ++
+ lda #1
+ sta $name
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?
"<", "<=", ">", ">=" -> TODO("word-var-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1535,12 +1741,36 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out(" eor $name | sta $name")
}
"==" -> TODO("word-bytevalue-to-var ==")
"!=" -> TODO("word-bytevalue-to-var !=")
"<" -> TODO("word-bytevalue-to-var <")
"<=" -> TODO("word-bytevalue-to-var <=")
">" -> TODO("word-bytevalue-to-var >")
">=" -> TODO("word-bytevalue-to-var >=")
"==" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out("""
cmp $name
bne +
lda $name+1
bne +
lda #1
bne ++
+ lda #0
+ sta $name
lda #0
sta $name+1""")
}
"!=" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
asmgen.out("""
cmp $name
bne +
lda $name+1
bne +
lda #0
beq ++
+ lda #1
+ sta $name
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
"<", "<=", ">", ">=" -> TODO("word-bytevalue-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1590,12 +1820,36 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
asmgen.out(" eor $name | sta $name | tya | eor $name+1 | sta $name+1")
}
"==" -> TODO("word-value-to-var ==")
"!=" -> TODO("word-value-to-var !=")
"<" -> TODO("word-value-to-var <")
"<=" -> TODO("word-value-to-var <=")
">" -> TODO("word-value-to-var >")
">=" -> TODO("word-value-to-var >=")
"==" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
asmgen.out("""
cmp $name
bne +
cpy $name+1
bne +
lda #1
bne ++
+ lda #0
+ sta $name
lda #0
sta $name+1""")
}
"!=" -> {
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
asmgen.out("""
cmp $name
bne +
cpy $name+1
bne +
lda #0
beq ++
+ lda #1
+ sta $name
lda #0
sta $name+1""")
}
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
"<", "<=", ">", ">=" -> TODO("word-value-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place modification $operator")
}
}
@ -1635,12 +1889,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
jsr floats.FDIV
""")
}
"==" -> TODO("float-value-to-var ==")
"!=" -> TODO("float-value-to-var !=")
"<" -> TODO("float-value-to-var <")
"<=" -> TODO("float-value-to-var <=")
">" -> TODO("float-value-to-var >")
">=" -> TODO("float-value-to-var >=")
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
"==", "!=", "<", "<=", ">", ">=" -> TODO("float-value-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
}
asmgen.out("""
@ -1699,12 +1949,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
jsr floats.FDIV
""")
}
"==" -> TODO("float-var-to-var ==")
"!=" -> TODO("float-var-to-var !=")
"<" -> TODO("float-var-to-var <")
"<=" -> TODO("float-var-to-var <=")
">" -> TODO("float-var-to-var >")
">=" -> TODO("float-var-to-var >=")
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
"==", "!=", "<", "<=", ">", ">=" -> TODO("float-var-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
}
// store Fac1 back into memory
@ -1767,12 +2013,8 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
jsr floats.FDIV
""")
}
"==" -> TODO("float-litval-to-var ==")
"!=" -> TODO("float-litval-to-var !=")
"<" -> TODO("float-litval-to-var <")
"<=" -> TODO("float-litval-to-var <=")
">" -> TODO("float-litval-to-var >")
">=" -> TODO("float-litval-to-var >=")
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
"==", "!=", "<", "<=", ">", ">=" -> TODO("float-litval-to-var comparisons")
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
}
// store Fac1 back into memory

View File

@ -119,10 +119,10 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
args.errors.report()
val intermediateAst = IntermediateAstMaker(program, compilationOptions).transform()
println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
printProgram(program)
println("*********** AST RIGHT BEFORE ASM GENERATION *************")
printAst(intermediateAst, true, ::println)
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
// printProgram(program)
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
// printAst(intermediateAst, true, ::println)
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
System.err.println("Error in codegeneration or assembler")

View File

@ -9,10 +9,7 @@ import prog8.ast.base.FatalAstException
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.code.ast.*
import prog8.code.core.BuiltinFunctions
import prog8.code.core.CompilationOptions
import prog8.code.core.DataType
import prog8.code.core.SourceCode
import prog8.code.core.*
import prog8.compiler.builtinFunctionReturnType
import java.io.File
import kotlin.io.path.Path
@ -95,14 +92,12 @@ class IntermediateAstMaker(private val program: Program, private val options: Co
val srcExpr = srcAssign.value
val (operator: String, augmentedValue: Expression?) = when(srcExpr) {
is BinaryExpression -> {
if(srcExpr.operator=="==" || srcExpr.operator=="%") {
// no special code possible for 'in-place comparison and result as boolean' or 'remainder'
Pair("", null)
}
else if(srcExpr.left isSameAs srcAssign.target) {
Pair(srcExpr.operator+'=', srcExpr.right)
if(srcExpr.left isSameAs srcAssign.target) {
val oper = if(srcExpr.operator in ComparisonOperators) srcExpr.operator else srcExpr.operator+'='
Pair(oper, srcExpr.right)
} else if(srcExpr.right isSameAs srcAssign.target) {
Pair(srcExpr.operator+'=', srcExpr.left)
val oper = if(srcExpr.operator in ComparisonOperators) srcExpr.operator else srcExpr.operator+'='
Pair(oper, srcExpr.left)
} else {
// either left or right is same as target, other combinations are not supported here
Pair("", null)

View File

@ -1,7 +1,10 @@
TODO
====
RPN: assembler fails selftest
RPN: examples/cx16/cobramk3-gfx.p8 crashes compiler
RPN: swirl is MUCH slower
RPN: wizzine is slower
RPN: wizzine is slightly slower
RPN: bsieve is much slower
then:
RPN: swirl is bigger

View File

@ -1,9 +1,38 @@
%import textio
%import floats
%zeropage basicsafe
; Draw a mandelbrot in graphics mode (the image will be 256 x 200 pixels).
; NOTE: this will take an eternity to draw on a real c64. A CommanderX16 is a bit faster.
; even in Vice in warp mode (700% speed on my machine) it's slow, but you can see progress
; Note: this program is compatible with C64 and CX16.
main {
sub start() {
ubyte x
ubyte y
if x<y
x++
;x = x+(x<y)+1
sub start() {
float xsquared = 2.0
float ysquared = 1.9
uword w = 1
ubyte h = 0
str name = ".tx2"
if name==".jpg" or name==".txt" or name==".gif" {
txt.print("yes")
}
; if w==0 or xsquared+ysquared<4.0 {
; txt.print("yes")
; }
; if w==0 {
; txt.print("w=0 ")
; }
; if h==0 {
; txt.print("h=0 ")
; }
; if w==0 or h==0 {
; txt.print(" w or h=0")
; }
}
}