mirror of
https://github.com/irmen/prog8.git
synced 2025-02-24 13:29:10 +00:00
implementing optimized comparisons
This commit is contained in:
parent
04832f052a
commit
01461a196d
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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")
|
||||
; }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user