mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
working on doing comparison codegen differently
This commit is contained in:
parent
c8b2c8ae50
commit
04832f052a
@ -368,21 +368,22 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
if(oper.type != value.type)
|
if(oper.type != value.type)
|
||||||
throw AssemblyError("rpn node type error, expected ${value.type} got ${oper.type}")
|
throw AssemblyError("rpn node type error, expected ${value.type} got ${oper.type}")
|
||||||
|
|
||||||
if(oper.operator in ComparisonOperators) {
|
// TODO RPN optimizations for simple cases
|
||||||
assignRPNComparison(assign, value)
|
// if(oper.operator in ComparisonOperators) {
|
||||||
return true
|
// assignRPNComparison(assign, value)
|
||||||
}
|
// return true
|
||||||
|
// }
|
||||||
if(right is PtExpression) {
|
//
|
||||||
if (simpleEqualityExprRPN(value, oper, right, assign.target))
|
// if(right is PtExpression) {
|
||||||
return true
|
// if (simpleEqualityExprRPN(value, oper, right, assign.target))
|
||||||
if (simpleLogicalExprRPN(value, oper, right, assign.target))
|
// return true
|
||||||
return true
|
// if (simpleLogicalExprRPN(value, oper, right, assign.target))
|
||||||
if (simplePlusOrMinusExprRPN(value, oper, right, assign.target))
|
// return true
|
||||||
return true
|
// if (simplePlusOrMinusExprRPN(value, oper, right, assign.target))
|
||||||
if (simpleBitshiftExprRPN(value, oper, right, assign.target))
|
// return true
|
||||||
return true
|
// if (simpleBitshiftExprRPN(value, oper, right, assign.target))
|
||||||
}
|
// return true
|
||||||
|
// }
|
||||||
|
|
||||||
val asmExtra = asmgen.subroutineExtra(scope)
|
val asmExtra = asmgen.subroutineExtra(scope)
|
||||||
val evalVars = mutableMapOf (
|
val evalVars = mutableMapOf (
|
||||||
@ -437,19 +438,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
val resultVarname = evalVarName(it.type, asmExtra.rpnDepth)
|
val resultVarname = evalVarName(it.type, asmExtra.rpnDepth)
|
||||||
asmExtra.rpnDepth++
|
asmExtra.rpnDepth++
|
||||||
symbolTable.resetCachedFlat()
|
symbolTable.resetCachedFlat()
|
||||||
if(it.operator in ComparisonOperators) {
|
|
||||||
require(it.type == DataType.UBYTE)
|
|
||||||
val scopeName = (scope as PtNamedNode).scopedName
|
|
||||||
val comparison = PtRpn(DataType.UBYTE, assign.position)
|
|
||||||
comparison.addRpnNode(PtIdentifier("$scopeName.$leftvar", it.leftType, value.position))
|
|
||||||
comparison.addRpnNode(PtIdentifier("$scopeName.$rightvar", it.rightType, value.position))
|
|
||||||
comparison.addRpnNode(PtRpnOperator(it.operator, it.type, it.leftType, it.rightType, it.position))
|
|
||||||
comparison.parent = scope
|
|
||||||
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = comparison)
|
|
||||||
val target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UBYTE, scope, assign.position, variableAsmName = resultVarname)
|
|
||||||
val normalAssign = AsmAssignment(src, target, program.memsizer, assign.position)
|
|
||||||
assignRPNComparison(normalAssign, comparison)
|
|
||||||
} else {
|
|
||||||
if(leftvar!=resultVarname) {
|
if(leftvar!=resultVarname) {
|
||||||
val scopeName = (scope as PtNamedNode).scopedName
|
val scopeName = (scope as PtNamedNode).scopedName
|
||||||
val leftVarPt = PtIdentifier("$scopeName.$leftvar", it.leftType, it.position)
|
val leftVarPt = PtIdentifier("$scopeName.$leftvar", it.leftType, it.position)
|
||||||
@ -458,10 +446,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, it.rightType, variableAsmName = rightvar)
|
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 target = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, it.type, scope, assign.position, variableAsmName = resultVarname)
|
||||||
val augAssign = AsmAugmentedAssignment(src, it.operator+"=", target, program.memsizer, assign.position)
|
val augAssign = AsmAugmentedAssignment(src, it.operator+":=", target, program.memsizer, assign.position)
|
||||||
augmentableAsmGen.translate(augAssign, scope)
|
augmentableAsmGen.translate(augAssign, scope)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
is PtExpression -> {
|
is PtExpression -> {
|
||||||
val varname = evalVarName(it.type, asmExtra.rpnDepth)
|
val varname = evalVarName(it.type, asmExtra.rpnDepth)
|
||||||
assignExpressionToVariable(it, varname, it.type)
|
assignExpressionToVariable(it, varname, it.type)
|
||||||
@ -499,406 +486,6 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun simpleLogicalExprRPN(expr: PtRpn, oper: PtRpnOperator, right: PtExpression, target: AsmAssignTarget): Boolean {
|
|
||||||
fun simpleLogicalBytesExpr(left: PtExpression, operand: String) {
|
|
||||||
// both left and right expression operands are simple.
|
|
||||||
if (right is PtNumber || right is PtIdentifier)
|
|
||||||
assignLogicalWithSimpleRightOperandByte(target, left, operand, right)
|
|
||||||
else if (left is PtNumber || left is PtIdentifier)
|
|
||||||
assignLogicalWithSimpleRightOperandByte(target, right, operand, left)
|
|
||||||
else {
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.A, false)
|
|
||||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
|
||||||
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
|
||||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
|
||||||
when (operand) {
|
|
||||||
"&", "and" -> asmgen.out(" and P8ZP_SCRATCH_B1")
|
|
||||||
"|", "or" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
|
|
||||||
"^", "xor" -> asmgen.out(" eor P8ZP_SCRATCH_B1")
|
|
||||||
else -> throw AssemblyError("invalid operator")
|
|
||||||
}
|
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun simpleLogicalWordsExpr(left: PtExpression, operand: String) {
|
|
||||||
// both left and right expression operands are simple.
|
|
||||||
if (right is PtNumber || right is PtIdentifier)
|
|
||||||
assignLogicalWithSimpleRightOperandWord(target, left, operand, right)
|
|
||||||
else if (left is PtNumber || left is PtIdentifier)
|
|
||||||
assignLogicalWithSimpleRightOperandWord(target, right, operand, left)
|
|
||||||
else {
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, false)
|
|
||||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
|
||||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
|
||||||
assignExpressionToVariable(right, "P8ZP_SCRATCH_W1", DataType.UWORD)
|
|
||||||
when (operand) {
|
|
||||||
"&", "and" -> asmgen.out(" pla | and P8ZP_SCRATCH_W1+1 | tay | pla | and P8ZP_SCRATCH_W1")
|
|
||||||
"|", "or" -> asmgen.out(" pla | ora P8ZP_SCRATCH_W1+1 | tay | pla | ora P8ZP_SCRATCH_W1")
|
|
||||||
"^", "xor" -> asmgen.out(" pla | eor P8ZP_SCRATCH_W1+1 | tay | pla | eor P8ZP_SCRATCH_W1")
|
|
||||||
else -> throw AssemblyError("invalid operator")
|
|
||||||
}
|
|
||||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(oper.operator in setOf("&", "|", "^", "and", "or", "xor")) {
|
|
||||||
if (oper.leftType in ByteDatatypes && right.type in ByteDatatypes) {
|
|
||||||
if (right.isSimple()) {
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
simpleLogicalBytesExpr(left, oper.operator)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (oper.leftType in WordDatatypes && right.type in WordDatatypes) {
|
|
||||||
if (right.isSimple()) {
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
simpleLogicalWordsExpr(left, oper.operator)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun simpleEqualityExprRPN(expr: PtRpn, oper: PtRpnOperator, right: PtExpression, target: AsmAssignTarget): Boolean {
|
|
||||||
if(oper.operator!="==" && oper.operator!="!=")
|
|
||||||
return false
|
|
||||||
|
|
||||||
// expression datatype is BOOL (ubyte) but operands can be anything
|
|
||||||
if(oper.leftType in ByteDatatypes && oper.rightType in ByteDatatypes && right.isSimple()) { // TODO && left.isSimple??
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.A, false)
|
|
||||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
|
||||||
assignExpressionToVariable(right, "P8ZP_SCRATCH_B1", DataType.UBYTE)
|
|
||||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
|
||||||
if(oper.operator=="==") {
|
|
||||||
asmgen.out("""
|
|
||||||
cmp P8ZP_SCRATCH_B1
|
|
||||||
bne +
|
|
||||||
lda #1
|
|
||||||
bne ++
|
|
||||||
+ lda #0
|
|
||||||
+""")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
cmp P8ZP_SCRATCH_B1
|
|
||||||
beq +
|
|
||||||
lda #1
|
|
||||||
bne ++
|
|
||||||
+ lda #0
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
|
||||||
return true
|
|
||||||
} else if(oper.leftType in WordDatatypes && oper.rightType in WordDatatypes && right.isSimple()) { // TODO && left.isSimple?
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, false)
|
|
||||||
asmgen.saveRegisterStack(CpuRegister.A, false)
|
|
||||||
asmgen.saveRegisterStack(CpuRegister.Y, false)
|
|
||||||
assignExpressionToVariable(right, "P8ZP_SCRATCH_W1", DataType.UWORD)
|
|
||||||
asmgen.restoreRegisterStack(CpuRegister.Y, false)
|
|
||||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
|
||||||
if(oper.operator=="==") {
|
|
||||||
asmgen.out("""
|
|
||||||
cmp P8ZP_SCRATCH_W1
|
|
||||||
bne +
|
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
|
||||||
bne +
|
|
||||||
lda #1
|
|
||||||
bne ++
|
|
||||||
+ lda #0
|
|
||||||
+""")
|
|
||||||
} else {
|
|
||||||
asmgen.out("""
|
|
||||||
cmp P8ZP_SCRATCH_W1
|
|
||||||
bne +
|
|
||||||
cpy P8ZP_SCRATCH_W1+1
|
|
||||||
bne +
|
|
||||||
lda #0
|
|
||||||
bne ++
|
|
||||||
+ lda #1
|
|
||||||
+""")
|
|
||||||
}
|
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun simplePlusOrMinusExprRPN(expr: PtRpn, oper: PtRpnOperator, right: PtExpression, target: AsmAssignTarget): Boolean {
|
|
||||||
if(oper.operator!="+" && oper.operator!="!-")
|
|
||||||
return false
|
|
||||||
|
|
||||||
val dt = target.datatype
|
|
||||||
if(dt in ByteDatatypes) {
|
|
||||||
when (right) {
|
|
||||||
is PtIdentifier -> {
|
|
||||||
val left=expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.A, dt==DataType.BYTE)
|
|
||||||
val symname = asmgen.asmVariableName(right)
|
|
||||||
if(oper.operator=="+")
|
|
||||||
asmgen.out(" clc | adc $symname")
|
|
||||||
else
|
|
||||||
asmgen.out(" sec | sbc $symname")
|
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
is PtNumber -> {
|
|
||||||
val left=expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.A, dt==DataType.BYTE)
|
|
||||||
if(oper.operator=="+")
|
|
||||||
asmgen.out(" clc | adc #${right.number.toHex()}")
|
|
||||||
else
|
|
||||||
asmgen.out(" sec | sbc #${right.number.toHex()}")
|
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
else -> return false
|
|
||||||
}
|
|
||||||
} else if(dt in WordDatatypes) {
|
|
||||||
when (right) {
|
|
||||||
is PtAddressOf -> {
|
|
||||||
val left=expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
|
||||||
val symbol = asmgen.asmVariableName(right.identifier)
|
|
||||||
if(oper.operator=="+")
|
|
||||||
asmgen.out("""
|
|
||||||
clc
|
|
||||||
adc #<$symbol
|
|
||||||
pha
|
|
||||||
tya
|
|
||||||
adc #>$symbol
|
|
||||||
tay
|
|
||||||
pla""")
|
|
||||||
else
|
|
||||||
asmgen.out("""
|
|
||||||
sec
|
|
||||||
sbc #<$symbol
|
|
||||||
pha
|
|
||||||
tya
|
|
||||||
sbc #>$symbol
|
|
||||||
tay
|
|
||||||
pla""")
|
|
||||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
is PtIdentifier -> {
|
|
||||||
val left=expr.truncateLastOperator()
|
|
||||||
val symname = asmgen.asmVariableName(right)
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
|
||||||
if(oper.operator=="+")
|
|
||||||
asmgen.out("""
|
|
||||||
clc
|
|
||||||
adc $symname
|
|
||||||
pha
|
|
||||||
tya
|
|
||||||
adc $symname+1
|
|
||||||
tay
|
|
||||||
pla""")
|
|
||||||
else
|
|
||||||
asmgen.out("""
|
|
||||||
sec
|
|
||||||
sbc $symname
|
|
||||||
pha
|
|
||||||
tya
|
|
||||||
sbc $symname+1
|
|
||||||
tay
|
|
||||||
pla""")
|
|
||||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
is PtNumber -> {
|
|
||||||
val left=expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
|
||||||
if(oper.operator=="+") {
|
|
||||||
asmgen.out("""
|
|
||||||
clc
|
|
||||||
adc #<${right.number.toHex()}
|
|
||||||
pha
|
|
||||||
tya
|
|
||||||
adc #>${right.number.toHex()}
|
|
||||||
tay
|
|
||||||
pla""")
|
|
||||||
} else if(oper.operator=="-") {
|
|
||||||
asmgen.out("""
|
|
||||||
sec
|
|
||||||
sbc #<${right.number.toHex()}
|
|
||||||
pha
|
|
||||||
tya
|
|
||||||
sbc #>${right.number.toHex()}
|
|
||||||
tay
|
|
||||||
pla""")
|
|
||||||
}
|
|
||||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
is PtTypeCast -> {
|
|
||||||
val castedValue = right.value
|
|
||||||
if(right.type in WordDatatypes && castedValue.type in ByteDatatypes) {
|
|
||||||
if(castedValue is PtIdentifier) {
|
|
||||||
val castedSymname = asmgen.asmVariableName(castedValue)
|
|
||||||
val left=expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, dt==DataType.WORD)
|
|
||||||
if(oper.operator=="+")
|
|
||||||
asmgen.out("""
|
|
||||||
clc
|
|
||||||
adc $castedSymname
|
|
||||||
bcc +
|
|
||||||
iny
|
|
||||||
+""")
|
|
||||||
else
|
|
||||||
asmgen.out("""
|
|
||||||
sec
|
|
||||||
sbc $castedSymname
|
|
||||||
bcs +
|
|
||||||
dey
|
|
||||||
+""")
|
|
||||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun simpleBitshiftExprRPN(expr: PtRpn, oper: PtRpnOperator, right: PtExpression, target: AsmAssignTarget): Boolean {
|
|
||||||
if(oper.operator!="<<" && oper.operator!=">>")
|
|
||||||
return false
|
|
||||||
val shifts = right.asConstInteger()
|
|
||||||
if(shifts==null || shifts !in 0..7 || oper.leftType !in IntegerDatatypes)
|
|
||||||
return false
|
|
||||||
|
|
||||||
if(oper.leftType in ByteDatatypes) {
|
|
||||||
val signed = oper.leftType == DataType.BYTE
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.A, signed)
|
|
||||||
if(oper.operator=="<<") {
|
|
||||||
repeat(shifts) {
|
|
||||||
asmgen.out(" asl a")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(signed && shifts>0) {
|
|
||||||
asmgen.out(" ldy #$shifts | jsr math.lsr_byte_A")
|
|
||||||
} else {
|
|
||||||
repeat(shifts) {
|
|
||||||
asmgen.out(" lsr a")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assignRegisterByte(target, CpuRegister.A)
|
|
||||||
return true
|
|
||||||
} else if(oper.leftType in WordDatatypes) {
|
|
||||||
val signed = oper.leftType == DataType.WORD
|
|
||||||
if(oper.operator=="<<") {
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, signed)
|
|
||||||
if(shifts>0) {
|
|
||||||
asmgen.out(" sty P8ZP_SCRATCH_B1")
|
|
||||||
repeat(shifts) {
|
|
||||||
asmgen.out(" asl a | rol P8ZP_SCRATCH_B1")
|
|
||||||
}
|
|
||||||
asmgen.out(" ldy P8ZP_SCRATCH_B1")
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if(signed) {
|
|
||||||
return false // TODO("shift AY >> $shifts signed")
|
|
||||||
} else {
|
|
||||||
val left = expr.truncateLastOperator()
|
|
||||||
assignExpressionToRegister(left, RegisterOrPair.AY, false)
|
|
||||||
if(shifts>0) {
|
|
||||||
asmgen.out(" sty P8ZP_SCRATCH_B1")
|
|
||||||
repeat(shifts) {
|
|
||||||
asmgen.out(" lsr P8ZP_SCRATCH_B1 | ror a")
|
|
||||||
}
|
|
||||||
asmgen.out(" ldy P8ZP_SCRATCH_B1")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
assignRegisterpairWord(target, RegisterOrPair.AY)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun assignRPNComparison(assign: AsmAssignment, comparison: PtRpn) {
|
|
||||||
val (leftRpn, oper, right) = comparison.finalOperation()
|
|
||||||
val constRight = (right as PtExpression).asConstInteger()
|
|
||||||
if(constRight == 0) {
|
|
||||||
if(oper.operator == "==" || oper.operator == "!=") {
|
|
||||||
when(assign.target.datatype) {
|
|
||||||
in ByteDatatypes -> {
|
|
||||||
if(attemptAssignToByteCompareZeroRPN(comparison, assign))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
in WordDatatypes -> {
|
|
||||||
assignConstantWord(assign.target, 0)
|
|
||||||
if(attemptAssignToByteCompareZeroRPN(comparison, assign))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
// do nothing, this is handled by a type cast.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val left: PtExpression = if(comparison.children.size>3 || leftRpn !is PtExpression)
|
|
||||||
comparison.truncateLastOperator()
|
|
||||||
else
|
|
||||||
leftRpn
|
|
||||||
|
|
||||||
val leftNum = left as? PtNumber
|
|
||||||
val rightNum = right as? PtNumber
|
|
||||||
val jumpIfFalseLabel = asmgen.makeLabel("cmp")
|
|
||||||
|
|
||||||
if(assign.target.isSameAs(left)) {
|
|
||||||
// In-place comparison Target = Target <compare> Right
|
|
||||||
val targetDt = assign.target.datatype
|
|
||||||
val tempVar = asmgen.getTempVarName(assign.target.datatype)
|
|
||||||
val tempTarget = AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, targetDt, comparison.definingISub(), comparison.position, variableAsmName = tempVar)
|
|
||||||
when (assign.target.datatype) {
|
|
||||||
in ByteDatatypes -> assignConstantByte(tempTarget, 0)
|
|
||||||
in WordDatatypes -> assignConstantWord(tempTarget, 0)
|
|
||||||
DataType.FLOAT -> assignConstantFloat(tempTarget, 0.0)
|
|
||||||
else -> throw AssemblyError("invalid dt")
|
|
||||||
}
|
|
||||||
asmgen.testNonzeroComparisonAndJump(left, oper.operator, right, jumpIfFalseLabel, leftNum, rightNum)
|
|
||||||
when (assign.target.datatype) {
|
|
||||||
in ByteDatatypes -> assignConstantByte(tempTarget, 1)
|
|
||||||
in WordDatatypes -> assignConstantWord(tempTarget, 1)
|
|
||||||
DataType.FLOAT -> assignConstantFloat(tempTarget, 1.0)
|
|
||||||
else -> throw AssemblyError("invalid dt")
|
|
||||||
}
|
|
||||||
asmgen.out(jumpIfFalseLabel)
|
|
||||||
val tempLeft = PtIdentifier(tempVar, targetDt, comparison.position)
|
|
||||||
tempLeft.parent=comparison
|
|
||||||
asmgen.assignExpressionTo(tempLeft, assign.target)
|
|
||||||
} else {
|
|
||||||
// Normal comparison Target = Left <compare> Right
|
|
||||||
when (assign.target.datatype) {
|
|
||||||
in ByteDatatypes -> assignConstantByte(assign.target, 0)
|
|
||||||
in WordDatatypes -> assignConstantWord(assign.target, 0)
|
|
||||||
DataType.FLOAT -> assignConstantFloat(assign.target, 0.0)
|
|
||||||
else -> throw AssemblyError("invalid dt")
|
|
||||||
}
|
|
||||||
asmgen.testNonzeroComparisonAndJump(left, oper.operator, right, jumpIfFalseLabel, leftNum, rightNum)
|
|
||||||
when (assign.target.datatype) {
|
|
||||||
in ByteDatatypes -> assignConstantByte(assign.target, 1)
|
|
||||||
in WordDatatypes -> assignConstantWord(assign.target, 1)
|
|
||||||
DataType.FLOAT -> assignConstantFloat(assign.target, 1.0)
|
|
||||||
else -> throw AssemblyError("invalid dt")
|
|
||||||
}
|
|
||||||
asmgen.out(jumpIfFalseLabel)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
if(expr.operator in ComparisonOperators) {
|
if(expr.operator in ComparisonOperators) {
|
||||||
if(expr.right.asConstInteger() == 0) {
|
if(expr.right.asConstInteger() == 0) {
|
||||||
|
@ -35,16 +35,22 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
private fun augmentedAssignExpr(assign: AsmAugmentedAssignment) {
|
private fun augmentedAssignExpr(assign: AsmAugmentedAssignment) {
|
||||||
val srcValue = assign.source.toAstExpression(assign.target.scope as PtNamedNode)
|
val srcValue = assign.source.toAstExpression(assign.target.scope as PtNamedNode)
|
||||||
when (assign.operator) {
|
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)
|
||||||
else -> throw AssemblyError("invalid augmented assign operator ${assign.operator}")
|
else -> throw AssemblyError("invalid augmented assign operator ${assign.operator}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -333,6 +339,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
"&" -> asmgen.out(" and P8ZP_SCRATCH_B1")
|
"&" -> asmgen.out(" and P8ZP_SCRATCH_B1")
|
||||||
"|" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
|
"|" -> asmgen.out(" ora P8ZP_SCRATCH_B1")
|
||||||
"^" -> asmgen.out(" eor 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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
asmgen.storeAIntoZpPointerVar(sourceName)
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
@ -369,6 +381,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
"&" -> asmgen.out(" and $otherName")
|
"&" -> asmgen.out(" and $otherName")
|
||||||
"|" -> asmgen.out(" ora $otherName")
|
"|" -> asmgen.out(" ora $otherName")
|
||||||
"^" -> asmgen.out(" eor $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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
asmgen.storeAIntoZpPointerVar(sourceName)
|
asmgen.storeAIntoZpPointerVar(sourceName)
|
||||||
@ -437,6 +455,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" eor #$value")
|
asmgen.out(" eor #$value")
|
||||||
asmgen.storeAIntoZpPointerVar(sourceName)
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -531,6 +555,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ lda #0
|
+ lda #0
|
||||||
+ sta $name""")
|
+ sta $name""")
|
||||||
}
|
}
|
||||||
|
"<" -> TODO("byte-value-to-var <")
|
||||||
|
"<=" -> TODO("byte-value-to-var <=")
|
||||||
|
">" -> TODO("byte-value-to-var >")
|
||||||
|
">=" -> TODO("byte-value-to-var >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -607,6 +635,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ lda #0
|
+ lda #0
|
||||||
+ sta $name""")
|
+ sta $name""")
|
||||||
}
|
}
|
||||||
|
"<" -> TODO("byte-var-to-var <")
|
||||||
|
"<=" -> TODO("byte-var-to-var <=")
|
||||||
|
">" -> TODO("byte-var-to-var >")
|
||||||
|
">=" -> TODO("byte-var-to-var >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -697,6 +729,10 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ lda #0
|
+ lda #0
|
||||||
+ sta $name""")
|
+ sta $name""")
|
||||||
}
|
}
|
||||||
|
"<" -> TODO("byte-litval-to-var <")
|
||||||
|
"<=" -> TODO("byte-litval-to-var <=")
|
||||||
|
">" -> TODO("byte-litval-to-var >")
|
||||||
|
">=" -> TODO("byte-litval-to-var >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,6 +768,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" eor $name | sta $name")
|
asmgen.out(" eor $name | sta $name")
|
||||||
}
|
}
|
||||||
// TODO: tuned code for more operators
|
// 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 -> {
|
else -> {
|
||||||
inplaceModification_byte_value_to_variable(name, dt, operator, memread)
|
inplaceModification_byte_value_to_variable(name, dt, operator, memread)
|
||||||
}
|
}
|
||||||
@ -781,6 +823,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.out(" eor $name | sta $name")
|
asmgen.out(" eor $name | sta $name")
|
||||||
}
|
}
|
||||||
// TODO: tuned code for more operators
|
// 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 -> {
|
else -> {
|
||||||
inplaceModification_word_value_to_variable(name, dt, operator, memread)
|
inplaceModification_word_value_to_variable(name, dt, operator, memread)
|
||||||
}
|
}
|
||||||
@ -1045,6 +1093,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
else -> asmgen.out(" lda $name | eor #<$value | sta $name | lda $name+1 | eor #>$value | sta $name+1")
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1211,6 +1265,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
"|" -> asmgen.out(" lda $otherName | ora $name | sta $name")
|
"|" -> asmgen.out(" lda $otherName | ora $name | sta $name")
|
||||||
"^" -> asmgen.out(" lda $otherName | eor $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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1285,6 +1345,12 @@ 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 | 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 | 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")
|
"^" -> 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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1469,6 +1535,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.out(" eor $name | sta $name")
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1518,6 +1590,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.AY)
|
||||||
asmgen.out(" eor $name | sta $name | tya | eor $name+1 | sta $name+1")
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1557,6 +1635,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
jsr floats.FDIV
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
|
||||||
}
|
}
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -1615,6 +1699,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
jsr floats.FDIV
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
|
||||||
}
|
}
|
||||||
// store Fac1 back into memory
|
// store Fac1 back into memory
|
||||||
@ -1677,6 +1767,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
jsr floats.FDIV
|
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 >=")
|
||||||
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place float modification $operator")
|
||||||
}
|
}
|
||||||
// store Fac1 back into memory
|
// store Fac1 back into memory
|
||||||
|
@ -6,9 +6,11 @@ import prog8.ast.Program
|
|||||||
import prog8.ast.base.AstException
|
import prog8.ast.base.AstException
|
||||||
import prog8.ast.expressions.Expression
|
import prog8.ast.expressions.Expression
|
||||||
import prog8.ast.expressions.NumericLiteral
|
import prog8.ast.expressions.NumericLiteral
|
||||||
|
import prog8.ast.printProgram
|
||||||
import prog8.ast.statements.Directive
|
import prog8.ast.statements.Directive
|
||||||
import prog8.code.SymbolTableMaker
|
import prog8.code.SymbolTableMaker
|
||||||
import prog8.code.ast.PtProgram
|
import prog8.code.ast.PtProgram
|
||||||
|
import prog8.code.ast.printAst
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
import prog8.code.target.*
|
import prog8.code.target.*
|
||||||
import prog8.codegen.vm.VmCodeGen
|
import prog8.codegen.vm.VmCodeGen
|
||||||
@ -117,10 +119,10 @@ fun compileProgram(args: CompilerArguments): CompilationResult? {
|
|||||||
args.errors.report()
|
args.errors.report()
|
||||||
|
|
||||||
val intermediateAst = IntermediateAstMaker(program, compilationOptions).transform()
|
val intermediateAst = IntermediateAstMaker(program, compilationOptions).transform()
|
||||||
// println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
|
println("*********** COMPILER AST RIGHT BEFORE ASM GENERATION *************")
|
||||||
// printProgram(program)
|
printProgram(program)
|
||||||
// println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
println("*********** AST RIGHT BEFORE ASM GENERATION *************")
|
||||||
// printAst(intermediateAst, true, ::println)
|
printAst(intermediateAst, true, ::println)
|
||||||
|
|
||||||
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
|
if(!createAssemblyAndAssemble(intermediateAst, args.errors, compilationOptions)) {
|
||||||
System.err.println("Error in codegeneration or assembler")
|
System.err.println("Error in codegeneration or assembler")
|
||||||
|
@ -1,54 +1,9 @@
|
|||||||
%import textio
|
|
||||||
%import floats
|
|
||||||
%zeropage basicsafe
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const uword width = 256
|
|
||||||
const uword height = 240
|
|
||||||
const ubyte max_iter = 16 ; 32 actually looks pretty nice but takes longer
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
void cx16.screen_mode($80, false)
|
ubyte x
|
||||||
cx16.r0=0
|
ubyte y
|
||||||
cx16.FB_init()
|
if x<y
|
||||||
mandel()
|
x++
|
||||||
}
|
;x = x+(x<y)+1
|
||||||
|
|
||||||
sub mandel() {
|
|
||||||
const float XL=-2.200
|
|
||||||
const float XU=0.800
|
|
||||||
const float YL=-1.300
|
|
||||||
const float YU=1.300
|
|
||||||
float dx = (XU-XL)/width
|
|
||||||
float dy = (YU-YL)/height
|
|
||||||
ubyte pixelx
|
|
||||||
ubyte pixely
|
|
||||||
|
|
||||||
for pixely in 0 to height-1 {
|
|
||||||
float yy = YL+dy*(pixely as float)
|
|
||||||
|
|
||||||
cx16.FB_cursor_position(0, pixely)
|
|
||||||
|
|
||||||
for pixelx in 0 to width-1 {
|
|
||||||
float xx = XL+dx*(pixelx as float)
|
|
||||||
|
|
||||||
float xsquared = 0.0
|
|
||||||
float ysquared = 0.0
|
|
||||||
float x = 0.0
|
|
||||||
float y = 0.0
|
|
||||||
ubyte iter = 0
|
|
||||||
|
|
||||||
while xsquared+ysquared<4.0 {
|
|
||||||
y = x*y*2.0 + yy
|
|
||||||
x = xsquared - ysquared + xx
|
|
||||||
xsquared = x*x
|
|
||||||
ysquared = y*y
|
|
||||||
iter++
|
|
||||||
if iter>16
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cx16.FB_set_pixel(iter)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user