mirror of
https://github.com/irmen/prog8.git
synced 2024-07-12 05:30:11 +00:00
Merge branch 'new-expr-codegen'
# Conflicts: # codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt # codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt # examples/test.p8
This commit is contained in:
commit
2d85fd093e
@ -180,7 +180,13 @@ class PtFunctionCall(val name: String,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class PtIdentifier(val name: String, type: DataType, position: Position) : PtExpression(type, position)
|
class PtIdentifier(val name: String, type: DataType, position: Position) : PtExpression(type, position) {
|
||||||
|
override fun toString(): String {
|
||||||
|
return "[PtIdentifier:$name $type $position]"
|
||||||
|
}
|
||||||
|
|
||||||
|
fun copy() = PtIdentifier(name, type, position)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class PtMemoryByte(position: Position) : PtExpression(DataType.UBYTE, position) {
|
class PtMemoryByte(position: Position) : PtExpression(DataType.UBYTE, position) {
|
||||||
|
@ -38,20 +38,17 @@ class PtSub(
|
|||||||
class PtSubroutineParameter(name: String, val type: DataType, position: Position): PtNamedNode(name, position)
|
class PtSubroutineParameter(name: String, val type: DataType, position: Position): PtNamedNode(name, position)
|
||||||
|
|
||||||
|
|
||||||
class PtAssignment(position: Position) : PtNode(position) {
|
sealed interface IPtAssignment {
|
||||||
|
val children: MutableList<PtNode>
|
||||||
val target: PtAssignTarget
|
val target: PtAssignTarget
|
||||||
get() = children[0] as PtAssignTarget
|
get() = children[0] as PtAssignTarget
|
||||||
val value: PtExpression
|
val value: PtExpression
|
||||||
get() = children[1] as PtExpression
|
get() = children[1] as PtExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class PtAssignment(position: Position) : PtNode(position), IPtAssignment
|
||||||
|
|
||||||
class PtAugmentedAssign(val operator: String, position: Position) : PtNode(position) {
|
class PtAugmentedAssign(val operator: String, position: Position) : PtNode(position), IPtAssignment
|
||||||
val target: PtAssignTarget
|
|
||||||
get() = children[0] as PtAssignTarget
|
|
||||||
val value: PtExpression
|
|
||||||
get() = children[1] as PtExpression
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class PtAssignTarget(position: Position) : PtNode(position) {
|
class PtAssignTarget(position: Position) : PtNode(position) {
|
||||||
@ -95,7 +92,7 @@ class PtForLoop(position: Position) : PtNode(position) {
|
|||||||
|
|
||||||
|
|
||||||
class PtIfElse(position: Position) : PtNode(position) {
|
class PtIfElse(position: Position) : PtNode(position) {
|
||||||
val condition: PtExpression // either PtRpn or PtBinaryExpression
|
val condition: PtExpression
|
||||||
get() = children[0] as PtExpression
|
get() = children[0] as PtExpression
|
||||||
val ifScope: PtNodeGroup
|
val ifScope: PtNodeGroup
|
||||||
get() = children[1] as PtNodeGroup
|
get() = children[1] as PtNodeGroup
|
||||||
|
@ -79,6 +79,7 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
|
|||||||
"reverse" to FSignature(false, listOf(FParam("array", ArrayDatatypes)), null),
|
"reverse" to FSignature(false, listOf(FParam("array", ArrayDatatypes)), null),
|
||||||
// cmp returns a status in the carry flag, but not a proper return value
|
// cmp returns a status in the carry flag, but not a proper return value
|
||||||
"cmp" to FSignature(false, listOf(FParam("value1", IntegerDatatypesNoBool), FParam("value2", NumericDatatypesNoBool)), null),
|
"cmp" to FSignature(false, listOf(FParam("value1", IntegerDatatypesNoBool), FParam("value2", NumericDatatypesNoBool)), null),
|
||||||
|
"prog8_lib_stringcompare" to FSignature(true, listOf(FParam("str1", arrayOf(DataType.STR)), FParam("str2", arrayOf(DataType.STR))), DataType.BYTE),
|
||||||
"abs" to FSignature(true, listOf(FParam("value", IntegerDatatypesNoBool)), DataType.UWORD),
|
"abs" to FSignature(true, listOf(FParam("value", IntegerDatatypesNoBool)), DataType.UWORD),
|
||||||
"len" to FSignature(true, listOf(FParam("values", IterableDatatypes)), DataType.UWORD),
|
"len" to FSignature(true, listOf(FParam("values", IterableDatatypes)), DataType.UWORD),
|
||||||
// normal functions follow:
|
// normal functions follow:
|
||||||
|
@ -21,13 +21,6 @@ class AsmGen6502: ICodeGeneratorBackend {
|
|||||||
options: CompilationOptions,
|
options: CompilationOptions,
|
||||||
errors: IErrorReporter
|
errors: IErrorReporter
|
||||||
): IAssemblyProgram? {
|
): IAssemblyProgram? {
|
||||||
if(options.useNewExprCode) {
|
|
||||||
// TODO("transform BinExprs?")
|
|
||||||
// errors.warn("EXPERIMENTAL NEW EXPRESSION CODEGEN IS USED. CODE SIZE+SPEED POSSIBLY SUFFERS.", Position.DUMMY)
|
|
||||||
}
|
|
||||||
|
|
||||||
// printAst(program, true) { println(it) }
|
|
||||||
|
|
||||||
val asmgen = AsmGen6502Internal(program, symbolTable, options, errors)
|
val asmgen = AsmGen6502Internal(program, symbolTable, options, errors)
|
||||||
return asmgen.compileToAssembly()
|
return asmgen.compileToAssembly()
|
||||||
}
|
}
|
||||||
@ -551,28 +544,76 @@ class AsmGen6502Internal (
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(stmt: PtIfElse) {
|
private fun translate(stmt: PtIfElse) {
|
||||||
val condition = stmt.condition as PtBinaryExpression
|
val condition = stmt.condition as? PtBinaryExpression
|
||||||
requireComparisonExpression(condition) // IfStatement: condition must be of form 'x <comparison> <value>'
|
if(condition!=null) {
|
||||||
if (stmt.elseScope.children.isEmpty()) {
|
require(!options.useNewExprCode)
|
||||||
val jump = stmt.ifScope.children.singleOrNull()
|
requireComparisonExpression(condition) // IfStatement: condition must be of form 'x <comparison> <value>'
|
||||||
if (jump is PtJump) {
|
if (stmt.elseScope.children.isEmpty()) {
|
||||||
translateCompareAndJumpIfTrue(condition, jump)
|
val jump = stmt.ifScope.children.singleOrNull()
|
||||||
|
if (jump is PtJump) {
|
||||||
|
translateCompareAndJumpIfTrue(condition, jump)
|
||||||
|
} else {
|
||||||
|
val endLabel = makeLabel("if_end")
|
||||||
|
translateCompareOrJumpIfFalse(condition, endLabel)
|
||||||
|
translate(stmt.ifScope)
|
||||||
|
out(endLabel)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
// both true and else parts
|
||||||
|
val elseLabel = makeLabel("if_else")
|
||||||
val endLabel = makeLabel("if_end")
|
val endLabel = makeLabel("if_end")
|
||||||
translateCompareAndJumpIfFalse(condition, endLabel)
|
translateCompareOrJumpIfFalse(condition, elseLabel)
|
||||||
translate(stmt.ifScope)
|
translate(stmt.ifScope)
|
||||||
|
jmp(endLabel)
|
||||||
|
out(elseLabel)
|
||||||
|
translate(stmt.elseScope)
|
||||||
out(endLabel)
|
out(endLabel)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// both true and else parts
|
// condition is a simple expression "if X" --> "if X!=0"
|
||||||
val elseLabel = makeLabel("if_else")
|
val zero = PtNumber(DataType.UBYTE,0.0, stmt.position)
|
||||||
val endLabel = makeLabel("if_end")
|
val leftConst = stmt.condition as? PtNumber
|
||||||
translateCompareAndJumpIfFalse(condition, elseLabel)
|
if (stmt.elseScope.children.isEmpty()) {
|
||||||
translate(stmt.ifScope)
|
val jump = stmt.ifScope.children.singleOrNull()
|
||||||
jmp(endLabel)
|
if (jump is PtJump) {
|
||||||
out(elseLabel)
|
// jump somewhere if X!=0
|
||||||
translate(stmt.elseScope)
|
val label = when {
|
||||||
out(endLabel)
|
jump.generatedLabel!=null -> jump.generatedLabel!!
|
||||||
|
jump.identifier!=null -> asmSymbolName(jump.identifier!!)
|
||||||
|
jump.address!=null -> jump.address!!.toHex()
|
||||||
|
else -> throw AssemblyError("weird jump")
|
||||||
|
}
|
||||||
|
when(stmt.condition.type) {
|
||||||
|
in WordDatatypes -> translateWordEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label)
|
||||||
|
in ByteDatatypes -> translateByteEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, label)
|
||||||
|
else -> throw AssemblyError("weird condition dt")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// skip the true block (=jump to end label) if X==0
|
||||||
|
val endLabel = makeLabel("if_end")
|
||||||
|
when(stmt.condition.type) {
|
||||||
|
in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel)
|
||||||
|
in ByteDatatypes -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, endLabel)
|
||||||
|
else -> throw AssemblyError("weird condition dt")
|
||||||
|
}
|
||||||
|
translate(stmt.ifScope)
|
||||||
|
out(endLabel)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// both true and else parts
|
||||||
|
val elseLabel = makeLabel("if_else")
|
||||||
|
val endLabel = makeLabel("if_end")
|
||||||
|
when(stmt.condition.type) {
|
||||||
|
in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel)
|
||||||
|
in ByteDatatypes -> translateByteNotEqualsOrJumpElsewhere(stmt.condition, zero, leftConst, zero, elseLabel)
|
||||||
|
else -> throw AssemblyError("weird condition dt")
|
||||||
|
}
|
||||||
|
translate(stmt.ifScope)
|
||||||
|
jmp(endLabel)
|
||||||
|
out(elseLabel)
|
||||||
|
translate(stmt.elseScope)
|
||||||
|
out(endLabel)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -740,7 +781,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
val isNested = parent is PtRepeatLoop
|
val isNested = parent is PtRepeatLoop
|
||||||
|
|
||||||
if(!isNested && !options.useNewExprCode) {
|
if(!isNested) {
|
||||||
// we can re-use a counter var from the subroutine if it already has one for that datatype
|
// we can re-use a counter var from the subroutine if it already has one for that datatype
|
||||||
val existingVar = asmInfo.extraVars.firstOrNull { it.first==dt && it.second.endsWith("counter") }
|
val existingVar = asmInfo.extraVars.firstOrNull { it.first==dt && it.second.endsWith("counter") }
|
||||||
if(existingVar!=null) {
|
if(existingVar!=null) {
|
||||||
@ -987,6 +1028,7 @@ $repeatLabel lda $counterVar
|
|||||||
val operator: String
|
val operator: String
|
||||||
|
|
||||||
if (pointerOffsetExpr is PtBinaryExpression) {
|
if (pointerOffsetExpr is PtBinaryExpression) {
|
||||||
|
require(!options.useNewExprCode)
|
||||||
operator = pointerOffsetExpr.operator
|
operator = pointerOffsetExpr.operator
|
||||||
left = pointerOffsetExpr.left
|
left = pointerOffsetExpr.left
|
||||||
right = pointerOffsetExpr.right
|
right = pointerOffsetExpr.right
|
||||||
@ -1132,15 +1174,16 @@ $repeatLabel lda $counterVar
|
|||||||
jump.address!=null -> jump.address!!.toHex()
|
jump.address!=null -> jump.address!!.toHex()
|
||||||
else -> throw AssemblyError("weird jump")
|
else -> throw AssemblyError("weird jump")
|
||||||
}
|
}
|
||||||
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
if (rightConstVal!=null && rightConstVal.number == 0.0) {
|
||||||
testZeroAndJump(left, invertedComparisonOperator, label)
|
testZeroOrJumpElsewhere(left, invertedComparisonOperator, label)
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
val leftConstVal = left as? PtNumber
|
val leftConstVal = left as? PtNumber
|
||||||
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
testNonzeroComparisonOrJumpElsewhere(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateCompareAndJumpIfFalse(expr: PtBinaryExpression, jumpIfFalseLabel: String) {
|
private fun translateCompareOrJumpIfFalse(expr: PtBinaryExpression, jumpIfFalseLabel: String) {
|
||||||
val left = expr.left
|
val left = expr.left
|
||||||
val right = expr.right
|
val right = expr.right
|
||||||
val operator = expr.operator
|
val operator = expr.operator
|
||||||
@ -1148,19 +1191,19 @@ $repeatLabel lda $counterVar
|
|||||||
val rightConstVal = right as? PtNumber
|
val rightConstVal = right as? PtNumber
|
||||||
|
|
||||||
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
||||||
testZeroAndJump(left, operator, jumpIfFalseLabel)
|
testZeroOrJumpElsewhere(left, operator, jumpIfFalseLabel)
|
||||||
else
|
else
|
||||||
testNonzeroComparisonAndJump(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
testNonzeroComparisonOrJumpElsewhere(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testZeroAndJump(
|
private fun testZeroOrJumpElsewhere(
|
||||||
left: PtExpression,
|
left: PtExpression,
|
||||||
operator: String,
|
operator: String,
|
||||||
jumpIfFalseLabel: String
|
jumpIfFalseLabel: String
|
||||||
) {
|
) {
|
||||||
val dt = left.type
|
val dt = left.type
|
||||||
if(dt in IntegerDatatypes && left is PtIdentifier)
|
if(dt in IntegerDatatypes && left is PtIdentifier)
|
||||||
return testVariableZeroAndJump(left, dt, operator, jumpIfFalseLabel)
|
return testVariableZeroOrJumpElsewhere(left, dt, operator, jumpIfFalseLabel)
|
||||||
|
|
||||||
when(dt) {
|
when(dt) {
|
||||||
DataType.BOOL, DataType.UBYTE, DataType.UWORD -> {
|
DataType.BOOL, DataType.UBYTE, DataType.UWORD -> {
|
||||||
@ -1246,7 +1289,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testVariableZeroAndJump(variable: PtIdentifier, dt: DataType, operator: String, jumpIfFalseLabel: String) {
|
private fun testVariableZeroOrJumpElsewhere(variable: PtIdentifier, dt: DataType, operator: String, jumpIfFalseLabel: String) {
|
||||||
// optimized code if the expression is just an identifier (variable)
|
// optimized code if the expression is just an identifier (variable)
|
||||||
val varname = asmVariableName(variable)
|
val varname = asmVariableName(variable)
|
||||||
when(dt) {
|
when(dt) {
|
||||||
@ -1306,7 +1349,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun testNonzeroComparisonAndJump(
|
internal fun testNonzeroComparisonOrJumpElsewhere(
|
||||||
left: PtExpression,
|
left: PtExpression,
|
||||||
operator: String,
|
operator: String,
|
||||||
right: PtExpression,
|
right: PtExpression,
|
||||||
@ -1319,70 +1362,70 @@ $repeatLabel lda $counterVar
|
|||||||
when (operator) {
|
when (operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
when (dt) {
|
when (dt) {
|
||||||
in ByteDatatypes -> translateByteEqualsJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
in ByteDatatypes -> translateByteEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
in WordDatatypes -> translateWordEqualsJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
in WordDatatypes -> translateWordEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.FLOAT -> translateFloatEqualsJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.FLOAT -> translateFloatEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.STR -> translateStringEqualsJump(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
DataType.STR -> translateStringEqualsOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
||||||
else -> throw AssemblyError("weird operand datatype")
|
else -> throw AssemblyError("weird operand datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"!=" -> {
|
"!=" -> {
|
||||||
when (dt) {
|
when (dt) {
|
||||||
in ByteDatatypes -> translateByteNotEqualsJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
in ByteDatatypes -> translateByteNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
in WordDatatypes -> translateWordNotEqualsJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
in WordDatatypes -> translateWordNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.FLOAT -> translateFloatNotEqualsJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.FLOAT -> translateFloatNotEqualsOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.STR -> translateStringNotEqualsJump(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
DataType.STR -> translateStringNotEqualsOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
||||||
else -> throw AssemblyError("weird operand datatype")
|
else -> throw AssemblyError("weird operand datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
when(dt) {
|
when(dt) {
|
||||||
DataType.UBYTE -> translateUbyteLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UBYTE -> translateUbyteLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.BYTE -> translateByteLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.BYTE -> translateByteLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.UWORD -> translateUwordLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UWORD -> translateUwordLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.WORD -> translateWordLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.WORD -> translateWordLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.FLOAT -> translateFloatLessJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.FLOAT -> translateFloatLessOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.STR -> translateStringLessJump(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
DataType.STR -> translateStringLessOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
||||||
else -> throw AssemblyError("weird operand datatype")
|
else -> throw AssemblyError("weird operand datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
when(dt) {
|
when(dt) {
|
||||||
DataType.UBYTE -> translateUbyteLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UBYTE -> translateUbyteLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.BYTE -> translateByteLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.BYTE -> translateByteLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.UWORD -> translateUwordLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UWORD -> translateUwordLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.WORD -> translateWordLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.WORD -> translateWordLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.FLOAT -> translateFloatLessOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.FLOAT -> translateFloatLessOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.STR -> translateStringLessOrEqualJump(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
DataType.STR -> translateStringLessOrEqualOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
||||||
else -> throw AssemblyError("weird operand datatype")
|
else -> throw AssemblyError("weird operand datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
when(dt) {
|
when(dt) {
|
||||||
DataType.UBYTE -> translateUbyteGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UBYTE -> translateUbyteGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.BYTE -> translateByteGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.BYTE -> translateByteGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.UWORD -> translateUwordGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UWORD -> translateUwordGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.WORD -> translateWordGreaterJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.WORD -> translateWordGreaterOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.FLOAT -> translateFloatGreaterJump(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
DataType.FLOAT -> translateFloatGreaterOrJumpElsewhere(left, right, leftConstVal,rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.STR -> translateStringGreaterJump(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
DataType.STR -> translateStringGreaterOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
||||||
else -> throw AssemblyError("weird operand datatype")
|
else -> throw AssemblyError("weird operand datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
when(dt) {
|
when(dt) {
|
||||||
DataType.UBYTE -> translateUbyteGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UBYTE -> translateUbyteGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.BYTE -> translateByteGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.BYTE -> translateByteGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.UWORD -> translateUwordGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.UWORD -> translateUwordGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.WORD -> translateWordGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.WORD -> translateWordGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.FLOAT -> translateFloatGreaterOrEqualJump(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
DataType.FLOAT -> translateFloatGreaterOrEqualOrJumpElsewhere(left, right, leftConstVal, rightConstVal, jumpIfFalseLabel)
|
||||||
DataType.STR -> translateStringGreaterOrEqualJump(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
DataType.STR -> translateStringGreaterOrEqualOrJumpElsewhere(left as PtIdentifier, right as PtIdentifier, jumpIfFalseLabel)
|
||||||
else -> throw AssemblyError("weird operand datatype")
|
else -> throw AssemblyError("weird operand datatype")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFloatLessJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateFloatLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(leftConstVal!=null && rightConstVal!=null) {
|
if(leftConstVal!=null && rightConstVal!=null) {
|
||||||
throw AssemblyError("const-compare should have been optimized away")
|
throw AssemblyError("const-compare should have been optimized away")
|
||||||
}
|
}
|
||||||
@ -1427,7 +1470,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFloatLessOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateFloatLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(leftConstVal!=null && rightConstVal!=null) {
|
if(leftConstVal!=null && rightConstVal!=null) {
|
||||||
throw AssemblyError("const-compare should have been optimized away")
|
throw AssemblyError("const-compare should have been optimized away")
|
||||||
}
|
}
|
||||||
@ -1472,7 +1515,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFloatGreaterJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateFloatGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(leftConstVal!=null && rightConstVal!=null) {
|
if(leftConstVal!=null && rightConstVal!=null) {
|
||||||
throw AssemblyError("const-compare should have been optimized away")
|
throw AssemblyError("const-compare should have been optimized away")
|
||||||
}
|
}
|
||||||
@ -1517,7 +1560,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFloatGreaterOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateFloatGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(leftConstVal!=null && rightConstVal!=null) {
|
if(leftConstVal!=null && rightConstVal!=null) {
|
||||||
throw AssemblyError("const-compare should have been optimized away")
|
throw AssemblyError("const-compare should have been optimized away")
|
||||||
}
|
}
|
||||||
@ -1562,7 +1605,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUbyteLessJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUbyteLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(cmpOperand: String) {
|
fun code(cmpOperand: String) {
|
||||||
out(" cmp $cmpOperand | bcs $jumpIfFalseLabel")
|
out(" cmp $cmpOperand | bcs $jumpIfFalseLabel")
|
||||||
@ -1607,7 +1650,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateByteLessJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateByteLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(sbcOperand: String) {
|
fun code(sbcOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1648,7 +1691,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUwordLessJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUwordLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1692,7 +1735,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_less_uw | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateWordLessJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateWordLessOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1738,7 +1781,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUbyteGreaterJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUbyteGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(cmpOperand: String) {
|
fun code(cmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1784,7 +1827,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateByteGreaterJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateByteGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(sbcOperand: String) {
|
fun code(sbcOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1827,7 +1870,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUwordGreaterJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUwordGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1877,7 +1920,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_W2+1", "P8ZP_SCRATCH_W2")
|
return code("P8ZP_SCRATCH_W2+1", "P8ZP_SCRATCH_W2")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateWordGreaterJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateWordGreaterOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCmpOperand: String, lsbCmpOperand: String) {
|
fun code(msbCmpOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1928,7 +1971,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_less_w | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUbyteLessOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUbyteLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(cmpOperand: String) {
|
fun code(cmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -1975,7 +2018,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateByteLessOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateByteLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
fun code(sbcOperand: String) {
|
fun code(sbcOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
clc
|
clc
|
||||||
@ -2018,7 +2061,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUwordLessOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUwordLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -2070,7 +2113,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateWordLessOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateWordLessOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(leftName: String) {
|
fun code(leftName: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -2125,7 +2168,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUbyteGreaterOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUbyteGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(cmpOperand: String) {
|
fun code(cmpOperand: String) {
|
||||||
out(" cmp $cmpOperand | bcc $jumpIfFalseLabel")
|
out(" cmp $cmpOperand | bcc $jumpIfFalseLabel")
|
||||||
@ -2168,7 +2211,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateByteGreaterOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateByteGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
fun code(sbcOperand: String) {
|
fun code(sbcOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
sec
|
sec
|
||||||
@ -2208,7 +2251,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateUwordGreaterOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateUwordGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -2251,7 +2294,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_lesseq_uw | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateWordGreaterOrEqualJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateWordGreaterOrEqualOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
fun code(msbCpyOperand: String, lsbCmpOperand: String) {
|
||||||
out("""
|
out("""
|
||||||
@ -2297,7 +2340,7 @@ $repeatLabel lda $counterVar
|
|||||||
return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel")
|
return out(" jsr prog8_lib.reg_lesseq_w | beq $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateByteEqualsJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateByteEqualsOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
fun code(cmpOperand: String) {
|
fun code(cmpOperand: String) {
|
||||||
out(" cmp $cmpOperand | bne $jumpIfFalseLabel")
|
out(" cmp $cmpOperand | bne $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
@ -2342,7 +2385,7 @@ $repeatLabel lda $counterVar
|
|||||||
out(" cmp P8ZP_SCRATCH_B1 | bne $jumpIfFalseLabel")
|
out(" cmp P8ZP_SCRATCH_B1 | bne $jumpIfFalseLabel")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateByteNotEqualsJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateByteNotEqualsOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
fun code(cmpOperand: String) {
|
fun code(cmpOperand: String) {
|
||||||
out(" cmp $cmpOperand | beq $jumpIfFalseLabel")
|
out(" cmp $cmpOperand | beq $jumpIfFalseLabel")
|
||||||
@ -2388,7 +2431,7 @@ $repeatLabel lda $counterVar
|
|||||||
return code("P8ZP_SCRATCH_B1")
|
return code("P8ZP_SCRATCH_B1")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateWordEqualsJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateWordEqualsOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(rightConstVal!=null) {
|
if(rightConstVal!=null) {
|
||||||
if(leftConstVal!=null) {
|
if(leftConstVal!=null) {
|
||||||
if(rightConstVal!=leftConstVal)
|
if(rightConstVal!=leftConstVal)
|
||||||
@ -2472,7 +2515,7 @@ $repeatLabel lda $counterVar
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateWordNotEqualsJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateWordNotEqualsOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
|
|
||||||
if(rightConstVal!=null) {
|
if(rightConstVal!=null) {
|
||||||
if(leftConstVal!=null) {
|
if(leftConstVal!=null) {
|
||||||
@ -2560,7 +2603,7 @@ $repeatLabel lda $counterVar
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFloatEqualsJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateFloatEqualsOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(rightConstVal!=null) {
|
if(rightConstVal!=null) {
|
||||||
if(leftConstVal!=null) {
|
if(leftConstVal!=null) {
|
||||||
if(rightConstVal!=leftConstVal)
|
if(rightConstVal!=leftConstVal)
|
||||||
@ -2644,7 +2687,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateFloatNotEqualsJump(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
private fun translateFloatNotEqualsOrJumpElsewhere(left: PtExpression, right: PtExpression, leftConstVal: PtNumber?, rightConstVal: PtNumber?, jumpIfFalseLabel: String) {
|
||||||
if(rightConstVal!=null) {
|
if(rightConstVal!=null) {
|
||||||
if(leftConstVal!=null) {
|
if(leftConstVal!=null) {
|
||||||
if(rightConstVal==leftConstVal)
|
if(rightConstVal==leftConstVal)
|
||||||
@ -2729,7 +2772,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateStringEqualsJump(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
private fun translateStringEqualsOrJumpElsewhere(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
||||||
val leftNam = asmVariableName(left)
|
val leftNam = asmVariableName(left)
|
||||||
val rightNam = asmVariableName(right)
|
val rightNam = asmVariableName(right)
|
||||||
out("""
|
out("""
|
||||||
@ -2740,11 +2783,10 @@ $repeatLabel lda $counterVar
|
|||||||
lda #<$leftNam
|
lda #<$leftNam
|
||||||
ldy #>$leftNam
|
ldy #>$leftNam
|
||||||
jsr prog8_lib.strcmp_mem
|
jsr prog8_lib.strcmp_mem
|
||||||
cmp #0
|
|
||||||
bne $jumpIfFalseLabel""")
|
bne $jumpIfFalseLabel""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateStringNotEqualsJump(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
private fun translateStringNotEqualsOrJumpElsewhere(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
||||||
val leftNam = asmVariableName(left)
|
val leftNam = asmVariableName(left)
|
||||||
val rightNam = asmVariableName(right)
|
val rightNam = asmVariableName(right)
|
||||||
out("""
|
out("""
|
||||||
@ -2755,11 +2797,10 @@ $repeatLabel lda $counterVar
|
|||||||
lda #<$leftNam
|
lda #<$leftNam
|
||||||
ldy #>$leftNam
|
ldy #>$leftNam
|
||||||
jsr prog8_lib.strcmp_mem
|
jsr prog8_lib.strcmp_mem
|
||||||
cmp #0
|
|
||||||
beq $jumpIfFalseLabel""")
|
beq $jumpIfFalseLabel""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateStringLessJump(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
private fun translateStringLessOrJumpElsewhere(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
||||||
val leftNam = asmVariableName(left)
|
val leftNam = asmVariableName(left)
|
||||||
val rightNam = asmVariableName(right)
|
val rightNam = asmVariableName(right)
|
||||||
out("""
|
out("""
|
||||||
@ -2773,7 +2814,7 @@ $repeatLabel lda $counterVar
|
|||||||
bpl $jumpIfFalseLabel""")
|
bpl $jumpIfFalseLabel""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateStringGreaterJump(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
private fun translateStringGreaterOrJumpElsewhere(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
||||||
val leftNam = asmVariableName(left)
|
val leftNam = asmVariableName(left)
|
||||||
val rightNam = asmVariableName(right)
|
val rightNam = asmVariableName(right)
|
||||||
out("""
|
out("""
|
||||||
@ -2788,7 +2829,7 @@ $repeatLabel lda $counterVar
|
|||||||
bmi $jumpIfFalseLabel""")
|
bmi $jumpIfFalseLabel""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateStringLessOrEqualJump(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
private fun translateStringLessOrEqualOrJumpElsewhere(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
||||||
val leftNam = asmVariableName(left)
|
val leftNam = asmVariableName(left)
|
||||||
val rightNam = asmVariableName(right)
|
val rightNam = asmVariableName(right)
|
||||||
out("""
|
out("""
|
||||||
@ -2804,7 +2845,7 @@ $repeatLabel lda $counterVar
|
|||||||
+""")
|
+""")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateStringGreaterOrEqualJump(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
private fun translateStringGreaterOrEqualOrJumpElsewhere(left: PtIdentifier, right: PtIdentifier, jumpIfFalseLabel: String) {
|
||||||
val leftNam = asmVariableName(left)
|
val leftNam = asmVariableName(left)
|
||||||
val rightNam = asmVariableName(right)
|
val rightNam = asmVariableName(right)
|
||||||
out("""
|
out("""
|
||||||
@ -2853,6 +2894,7 @@ $repeatLabel lda $counterVar
|
|||||||
out(" sta P8ESTACK_LO,x | dex")
|
out(" sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!options.useNewExprCode)
|
||||||
val addrExpr = expr.address as PtBinaryExpression
|
val addrExpr = expr.address as PtBinaryExpression
|
||||||
if(tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
if(tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
||||||
if(pushResultOnEstack)
|
if(pushResultOnEstack)
|
||||||
|
@ -72,6 +72,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
"rrestorex" -> funcRrestoreX()
|
"rrestorex" -> funcRrestoreX()
|
||||||
"cmp" -> funcCmp(fcall)
|
"cmp" -> funcCmp(fcall)
|
||||||
"callfar" -> funcCallFar(fcall)
|
"callfar" -> funcCallFar(fcall)
|
||||||
|
"prog8_lib_stringcompare" -> funcStringCompare(fcall, resultToStack)
|
||||||
else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}")
|
else -> throw AssemblyError("missing asmgen for builtin func ${fcall.name}")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,6 +112,14 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
sty $remainderVar+1""")
|
sty $remainderVar+1""")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcStringCompare(fcall: PtBuiltinFunctionCall, resultToStack: Boolean) {
|
||||||
|
assignAsmGen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", DataType.UWORD)
|
||||||
|
assignAsmGen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY, false)
|
||||||
|
asmgen.out(" jsr prog8_lib.strcmp_mem")
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
|
}
|
||||||
|
|
||||||
private fun funcRsave() {
|
private fun funcRsave() {
|
||||||
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
if (asmgen.isTargetCpu(CpuType.CPU65c02))
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
@ -697,6 +706,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
val result = asmgen.pointerViaIndexRegisterPossible(addrExpr)
|
val result = asmgen.pointerViaIndexRegisterPossible(addrExpr)
|
||||||
val pointer = result?.first as? PtIdentifier
|
val pointer = result?.first as? PtIdentifier
|
||||||
if(result!=null && pointer!=null && asmgen.isZpVar(pointer)) {
|
if(result!=null && pointer!=null && asmgen.isZpVar(pointer)) {
|
||||||
@ -759,6 +769,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
|||||||
} else fallback()
|
} else fallback()
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
val result = asmgen.pointerViaIndexRegisterPossible(addrExpr)
|
val result = asmgen.pointerViaIndexRegisterPossible(addrExpr)
|
||||||
val pointer = result?.first as? PtIdentifier
|
val pointer = result?.first as? PtIdentifier
|
||||||
if(result!=null && pointer!=null && asmgen.isZpVar(pointer)) {
|
if(result!=null && pointer!=null && asmgen.isZpVar(pointer)) {
|
||||||
|
@ -245,6 +245,8 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateExpression(expr: PtBinaryExpression) {
|
private fun translateExpression(expr: PtBinaryExpression) {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
|
|
||||||
// Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED!
|
// Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED!
|
||||||
if(translateSomewhatOptimized(expr.left, expr.operator, expr.right))
|
if(translateSomewhatOptimized(expr.left, expr.operator, expr.right))
|
||||||
return
|
return
|
||||||
|
@ -147,6 +147,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
assignMemoryByte(assign.target, null, value.address as PtIdentifier)
|
assignMemoryByte(assign.target, null, value.address as PtIdentifier)
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
val addrExpr = value.address as PtBinaryExpression
|
val addrExpr = value.address as PtBinaryExpression
|
||||||
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
@ -301,6 +302,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
assignRegisterByte(assign.target, CpuRegister.A)
|
assignRegisterByte(assign.target, CpuRegister.A)
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
if(!attemptAssignOptimizedBinexpr(value, assign)) {
|
if(!attemptAssignOptimizedBinexpr(value, assign)) {
|
||||||
// All remaining binary expressions just evaluate via the stack for now.
|
// All remaining binary expressions just evaluate via the stack for now.
|
||||||
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
|
||||||
@ -346,6 +348,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
if(expr.operator in ComparisonOperators) {
|
if(expr.operator in ComparisonOperators) {
|
||||||
if(expr.right.asConstInteger() == 0) {
|
if(expr.right.asConstInteger() == 0) {
|
||||||
if(expr.operator == "==" || expr.operator=="!=") {
|
if(expr.operator == "==" || expr.operator=="!=") {
|
||||||
@ -728,6 +731,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun attemptAssignToByteCompareZero(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
private fun attemptAssignToByteCompareZero(expr: PtBinaryExpression, assign: AsmAssignment): Boolean {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
when (expr.operator) {
|
when (expr.operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
when(val dt = expr.left.type) {
|
when(val dt = expr.left.type) {
|
||||||
@ -907,6 +911,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
assignMemoryByteIntoWord(target, null, value.address as PtIdentifier)
|
assignMemoryByteIntoWord(target, null, value.address as PtIdentifier)
|
||||||
}
|
}
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
val addrExpr = value.address as PtBinaryExpression
|
val addrExpr = value.address as PtBinaryExpression
|
||||||
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.operator, false)) {
|
||||||
asmgen.out(" ldy #0")
|
asmgen.out(" ldy #0")
|
||||||
@ -2519,7 +2524,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun assignConstantFloat(target: AsmAssignTarget, float: Double) {
|
internal fun assignConstantFloat(target: AsmAssignTarget, float: Double) {
|
||||||
if (float == 0.0) {
|
if (float == 0.0) {
|
||||||
// optimized case for float zero
|
// optimized case for float zero
|
||||||
when(target.kind) {
|
when(target.kind) {
|
||||||
@ -2829,6 +2834,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
|||||||
asmgen.storeAIntoPointerVar(addressExpr)
|
asmgen.storeAIntoPointerVar(addressExpr)
|
||||||
}
|
}
|
||||||
addressExpr is PtBinaryExpression -> {
|
addressExpr is PtBinaryExpression -> {
|
||||||
|
require(!asmgen.options.useNewExprCode)
|
||||||
if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.operator, true))
|
if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.operator, true))
|
||||||
storeViaExprEval()
|
storeViaExprEval()
|
||||||
}
|
}
|
||||||
|
@ -668,43 +668,31 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE)
|
||||||
cmp $name
|
TODO("ubyte <")
|
||||||
bcc +
|
else
|
||||||
beq +
|
TODO("byte <")
|
||||||
lda #1
|
|
||||||
bne ++
|
|
||||||
+ lda #0
|
|
||||||
+ sta $name""")
|
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE)
|
||||||
cmp $name
|
TODO("ubyte <=")
|
||||||
lda #0
|
else
|
||||||
adc #0
|
TODO("byte <=")
|
||||||
sta $name""")
|
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE)
|
||||||
cmp $name
|
TODO("ubyte >")
|
||||||
bcc +
|
else
|
||||||
lda #0
|
TODO("byte >")
|
||||||
beq ++
|
|
||||||
+ lda #1
|
|
||||||
+ sta $name""")
|
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
asmgen.assignExpressionToRegister(value, RegisterOrPair.A)
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE)
|
||||||
cmp $name
|
TODO("ubyte >=")
|
||||||
bcc +
|
else
|
||||||
beq +
|
TODO("byte >=")
|
||||||
lda #0
|
|
||||||
beq ++
|
|
||||||
+ lda #1
|
|
||||||
+ sta $name""")
|
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -782,41 +770,106 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ sta $name""")
|
+ sta $name""")
|
||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda $name
|
asmgen.out("""
|
||||||
cmp $otherName
|
lda $name
|
||||||
bcs +
|
cmp $otherName
|
||||||
lda #1
|
bcc +
|
||||||
bne ++
|
lda #0
|
||||||
+ lda #0
|
beq ++
|
||||||
+ sta $name""")
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
sec
|
||||||
|
sbc $otherName
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bmi +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda $otherName
|
asmgen.out("""
|
||||||
cmp $name
|
lda $otherName
|
||||||
lda #0
|
cmp $name
|
||||||
adc #0
|
bcs +
|
||||||
sta $name""")
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
clc
|
||||||
|
sbc $otherName
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bmi +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda $otherName
|
asmgen.out("""
|
||||||
cmp $name
|
lda $name
|
||||||
bcc +
|
cmp $otherName
|
||||||
lda #0
|
beq +
|
||||||
beq ++
|
bcs ++
|
||||||
+ lda #1
|
+ lda #0
|
||||||
+ sta $name""")
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
clc
|
||||||
|
sbc $otherName
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bpl +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda $name
|
asmgen.out("""
|
||||||
cmp $otherName
|
lda $name
|
||||||
lda #0
|
cmp $otherName
|
||||||
adc #0
|
bcs +
|
||||||
sta $name""")
|
lda #0
|
||||||
}
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
sec
|
||||||
|
sbc $otherName
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bpl +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} }
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -908,40 +961,106 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
+ sta $name""")
|
+ sta $name""")
|
||||||
}
|
}
|
||||||
"<" -> {
|
"<" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda $name
|
asmgen.out("""
|
||||||
cmp #$value
|
lda $name
|
||||||
bcs +
|
cmp #$value
|
||||||
lda #1
|
bcc +
|
||||||
bne ++
|
lda #0
|
||||||
+ lda #0
|
beq ++
|
||||||
+ sta $name""")
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
sec
|
||||||
|
sbc #$value
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bmi +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda #$value
|
asmgen.out("""
|
||||||
cmp $name
|
lda #$value
|
||||||
lda #0
|
cmp $name
|
||||||
adc #0
|
bcs +
|
||||||
sta $name""")
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
clc
|
||||||
|
sbc #$value
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bmi +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
">" -> {
|
">" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda #$value
|
asmgen.out("""
|
||||||
cmp $name
|
lda $name
|
||||||
bcc +
|
cmp #$value
|
||||||
lda #0
|
beq +
|
||||||
beq ++
|
bcs ++
|
||||||
+ lda #1
|
+ lda #0
|
||||||
+ sta $name""")
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
clc
|
||||||
|
sbc #$value
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bpl +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
asmgen.out("""
|
if(dt==DataType.UBYTE) {
|
||||||
lda $name
|
asmgen.out("""
|
||||||
cmp #$value
|
lda $name
|
||||||
lda #0
|
cmp #$value
|
||||||
adc #0
|
bcs +
|
||||||
sta $name""")
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
} else {
|
||||||
|
// see http://www.6502.org/tutorials/compare_beyond.html
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
sec
|
||||||
|
sbc #$value
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bpl +
|
||||||
|
lda #0
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
+ sta $name""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -1319,8 +1438,174 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
lda #0
|
lda #0
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
}
|
}
|
||||||
// pretty uncommon, who's going to assign a comparison boolean expresion to a word var?:
|
"<" -> {
|
||||||
"<", "<=", ">", ">=" -> TODO("word-litval-to-var comparisons")
|
if(dt==DataType.UWORD) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name+1
|
||||||
|
cmp #>$value
|
||||||
|
bcc ++
|
||||||
|
bne +
|
||||||
|
lda $name
|
||||||
|
cmp #<$value
|
||||||
|
bcc ++
|
||||||
|
+ lda #0 ; false
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq ++
|
||||||
|
+ lda #1 ; true
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// signed
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
cmp #<$value
|
||||||
|
lda $name+1
|
||||||
|
sbc #>$value
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bmi +
|
||||||
|
lda #0
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq ++
|
||||||
|
+ lda #1 ; true
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
if(dt==DataType.UWORD) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name+1
|
||||||
|
cmp #>$value
|
||||||
|
beq +
|
||||||
|
bcc ++
|
||||||
|
- lda #0 ; false
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq +++
|
||||||
|
+ lda $name ; next
|
||||||
|
cmp #<$value
|
||||||
|
bcc +
|
||||||
|
bne -
|
||||||
|
+ lda #1 ; true
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// signed
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$value
|
||||||
|
cmp $name
|
||||||
|
lda #>$value
|
||||||
|
sbc $name+1
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bpl +
|
||||||
|
lda #0
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
// word > value --> value < word
|
||||||
|
if(dt==DataType.UWORD) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #>$value
|
||||||
|
cmp $name+1
|
||||||
|
bcc ++
|
||||||
|
bne +
|
||||||
|
lda #<$value
|
||||||
|
cmp $name
|
||||||
|
bcc ++
|
||||||
|
+ lda #0 ; false
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq ++
|
||||||
|
+ lda #1 ; true
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// signed
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$value
|
||||||
|
cmp $name
|
||||||
|
lda #>$value
|
||||||
|
sbc $name+1
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bmi +
|
||||||
|
lda #0
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq ++
|
||||||
|
+ lda #1 ; true
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
// word >= value --> value <= word
|
||||||
|
if(dt==DataType.UWORD) {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #>$value
|
||||||
|
cmp $name+1
|
||||||
|
beq +
|
||||||
|
bcc ++
|
||||||
|
- lda #0 ; false
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq +++
|
||||||
|
+ lda #<$value ; next
|
||||||
|
cmp $name
|
||||||
|
bcc +
|
||||||
|
bne -
|
||||||
|
+ lda #1 ; true
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// signed
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
cmp #<$value
|
||||||
|
lda $name+1
|
||||||
|
sbc #>$value
|
||||||
|
bvc +
|
||||||
|
eor #$80
|
||||||
|
+ bpl +
|
||||||
|
lda #0
|
||||||
|
sta $name
|
||||||
|
sta $name+1
|
||||||
|
beq ++
|
||||||
|
+ lda #1
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1
|
||||||
|
+""")
|
||||||
|
}
|
||||||
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1650,33 +1935,63 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
}
|
}
|
||||||
"<=" -> {
|
"<=" -> {
|
||||||
val compareRoutine = if(dt==DataType.UWORD) "reg_lesseq_uw" else "reg_lesseq_w"
|
if(dt==DataType.UWORD) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $otherName
|
lda $otherName
|
||||||
ldy $otherName+1
|
ldy $otherName+1
|
||||||
sta P8ZP_SCRATCH_W2
|
sta P8ZP_SCRATCH_W2
|
||||||
sty P8ZP_SCRATCH_W2+1
|
sty P8ZP_SCRATCH_W2+1
|
||||||
lda $name
|
lda $name
|
||||||
ldy $name+1
|
ldy $name+1
|
||||||
jsr prog8_lib.$compareRoutine
|
jsr prog8_lib.reg_lesseq_uw
|
||||||
sta $name
|
sta $name
|
||||||
lda #0
|
lda #0
|
||||||
sta $name+1""")
|
sta $name+1""")
|
||||||
|
} else {
|
||||||
|
// note: reg_lesseq_w routine takes the arguments in reverse order
|
||||||
|
asmgen.out("""
|
||||||
|
lda $name
|
||||||
|
ldy $name+1
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
lda $otherName
|
||||||
|
ldy $otherName+1
|
||||||
|
jsr prog8_lib.reg_lesseq_w
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1""")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
">=" -> {
|
">=" -> {
|
||||||
// a>=b --> b<=a
|
// a>=b --> b<=a
|
||||||
val compareRoutine = if(dt==DataType.UWORD) "reg_lesseq_uw" else "reg_lesseq_w"
|
if(dt==DataType.UWORD) {
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
lda $name
|
lda $name
|
||||||
ldy $name+1
|
ldy $name+1
|
||||||
sta P8ZP_SCRATCH_W2
|
sta P8ZP_SCRATCH_W2
|
||||||
sty P8ZP_SCRATCH_W2+1
|
sty P8ZP_SCRATCH_W2+1
|
||||||
lda $otherName
|
lda $otherName
|
||||||
ldy $otherName+1
|
ldy $otherName+1
|
||||||
jsr prog8_lib.$compareRoutine
|
jsr prog8_lib.reg_lesseq_uw
|
||||||
sta $name
|
sta $name
|
||||||
lda #0
|
lda #0
|
||||||
sta $name+1""")
|
sta $name+1"""
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
// note: reg_lesseq_w routine takes the arguments in reverse order
|
||||||
|
asmgen.out("""
|
||||||
|
lda $otherName
|
||||||
|
ldy $otherName+1
|
||||||
|
sta P8ZP_SCRATCH_W2
|
||||||
|
sty P8ZP_SCRATCH_W2+1
|
||||||
|
lda $name
|
||||||
|
ldy $name+1
|
||||||
|
jsr prog8_lib.reg_lesseq_w
|
||||||
|
sta $name
|
||||||
|
lda #0
|
||||||
|
sta $name+1"""
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
else -> throw AssemblyError("invalid operator for in-place modification $operator")
|
||||||
}
|
}
|
||||||
@ -2011,9 +2326,12 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
|
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
|
||||||
"==", "!=", "<", "<=", ">", ">=" -> TODO("float-value-to-var comparisons")
|
"==" -> TODO("float-value-to-var comparison ==")
|
||||||
|
"!=" -> TODO("float-value-to-var comparison !=")
|
||||||
|
"<", "<=", ">", ">=" -> TODO("float-value-to-var comparisons")
|
||||||
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
|
||||||
asmgen.out("""
|
asmgen.out("""
|
||||||
ldx #<$name
|
ldx #<$name
|
||||||
ldy #>$name
|
ldy #>$name
|
||||||
@ -2066,7 +2384,67 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
|
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
|
||||||
"==", "!=", "<", "<=", ">", ">=" -> TODO("float-var-to-var comparisons")
|
"==" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$otherName
|
||||||
|
ldy #>$otherName
|
||||||
|
jsr floats.var_fac1_notequal_f
|
||||||
|
eor #1
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$otherName
|
||||||
|
ldy #>$otherName
|
||||||
|
jsr floats.var_fac1_notequal_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$otherName
|
||||||
|
ldy #>$otherName
|
||||||
|
jsr floats.var_fac1_less_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$otherName
|
||||||
|
ldy #>$otherName
|
||||||
|
jsr floats.var_fac1_lesseq_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$otherName
|
||||||
|
ldy #>$otherName
|
||||||
|
jsr floats.var_fac1_greater_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$otherName
|
||||||
|
ldy #>$otherName
|
||||||
|
jsr floats.var_fac1_greatereq_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
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
|
||||||
@ -2129,8 +2507,67 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
|||||||
jsr floats.FDIV
|
jsr floats.FDIV
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
// pretty uncommon, who's going to assign a comparison boolean expresion to a float var:
|
"==" -> {
|
||||||
"==", "!=", "<", "<=", ">", ">=" -> TODO("float-litval-to-var comparisons")
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr floats.var_fac1_notequal_f
|
||||||
|
eor #1
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
"!=" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr floats.var_fac1_notequal_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
"<" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr floats.var_fac1_less_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
"<=" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr floats.var_fac1_lesseq_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
">" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr floats.var_fac1_greater_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
|
">=" -> {
|
||||||
|
asmgen.out("""
|
||||||
|
lda #<$name
|
||||||
|
ldy #>$name
|
||||||
|
jsr floats.MOVFM
|
||||||
|
lda #<$constValueName
|
||||||
|
ldy #>$constValueName
|
||||||
|
jsr floats.var_fac1_greatereq_f
|
||||||
|
jsr floats.FREADSA""")
|
||||||
|
}
|
||||||
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
|
||||||
|
@ -14,11 +14,6 @@ class ExperiCodeGen: ICodeGeneratorBackend {
|
|||||||
errors: IErrorReporter
|
errors: IErrorReporter
|
||||||
): IAssemblyProgram? {
|
): IAssemblyProgram? {
|
||||||
|
|
||||||
if(options.useNewExprCode) {
|
|
||||||
// TODO("transform BinExprs?")
|
|
||||||
// errors.warn("EXPERIMENTAL NEW EXPRESSION CODEGEN IS USED. CODE SIZE+SPEED POSSIBLY SUFFERS.", Position.DUMMY)
|
|
||||||
}
|
|
||||||
|
|
||||||
// you could write a code generator directly on the PtProgram AST,
|
// you could write a code generator directly on the PtProgram AST,
|
||||||
// but you can also use the Intermediate Representation to build a codegen on:
|
// but you can also use the Intermediate Representation to build a codegen on:
|
||||||
val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
|
val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
|
||||||
|
@ -93,7 +93,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
} else {
|
} else {
|
||||||
require(origAssign.operator.endsWith('='))
|
require(origAssign.operator.endsWith('='))
|
||||||
if(codeGen.options.useNewExprCode) {
|
if(codeGen.options.useNewExprCode) {
|
||||||
TODO("use something else than a BinExpr?")
|
TODO("use something else than a BinExpr")
|
||||||
} else {
|
} else {
|
||||||
value = PtBinaryExpression(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position)
|
value = PtBinaryExpression(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position)
|
||||||
val left: PtExpression = origAssign.target.children.single() as PtExpression
|
val left: PtExpression = origAssign.target.children.single() as PtExpression
|
||||||
@ -268,7 +268,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
|
|||||||
} else {
|
} else {
|
||||||
val mult : PtExpression
|
val mult : PtExpression
|
||||||
if(codeGen.options.useNewExprCode) {
|
if(codeGen.options.useNewExprCode) {
|
||||||
TODO("use something else than a BinExpr?")
|
TODO("use something else than a BinExpr")
|
||||||
} else {
|
} else {
|
||||||
mult = PtBinaryExpression("*", DataType.UBYTE, array.position)
|
mult = PtBinaryExpression("*", DataType.UBYTE, array.position)
|
||||||
mult.children += array.index
|
mult.children += array.index
|
||||||
|
@ -43,6 +43,7 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
"ror" -> funcRolRor(Opcode.ROXR, call)
|
"ror" -> funcRolRor(Opcode.ROXR, call)
|
||||||
"rol2" -> funcRolRor(Opcode.ROL, call)
|
"rol2" -> funcRolRor(Opcode.ROL, call)
|
||||||
"ror2" -> funcRolRor(Opcode.ROR, call)
|
"ror2" -> funcRolRor(Opcode.ROR, call)
|
||||||
|
"prog8_lib_stringcompare" -> funcStringCompare(call)
|
||||||
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
|
else -> throw AssemblyError("missing builtinfunc for ${call.name}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,6 +69,18 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
|||||||
return ExpressionCodeResult(result, type, -1, -1)
|
return ExpressionCodeResult(result, type, -1, -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun funcStringCompare(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
|
val left = exprGen.translateExpression(call.args[0])
|
||||||
|
val right = exprGen.translateExpression(call.args[1])
|
||||||
|
val targetReg = codeGen.registers.nextFree()
|
||||||
|
addToResult(result, left, 65500, -1)
|
||||||
|
addToResult(result, right, 65501, -1)
|
||||||
|
addInstr(result, IRInstruction(Opcode.SYSCALL, value=IMSyscall.COMPARE_STRINGS.number), null)
|
||||||
|
addInstr(result, IRInstruction(Opcode.LOADR, IRDataType.BYTE, reg1=targetReg, reg2=0), null)
|
||||||
|
return ExpressionCodeResult(result, IRDataType.BYTE, targetReg, -1)
|
||||||
|
}
|
||||||
|
|
||||||
private fun funcCmp(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
private fun funcCmp(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
val leftTr = exprGen.translateExpression(call.args[0])
|
val leftTr = exprGen.translateExpression(call.args[0])
|
||||||
|
@ -320,6 +320,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(binExpr: PtBinaryExpression): ExpressionCodeResult {
|
private fun translate(binExpr: PtBinaryExpression): ExpressionCodeResult {
|
||||||
|
require(!codeGen.options.useNewExprCode)
|
||||||
val vmDt = codeGen.irType(binExpr.left.type)
|
val vmDt = codeGen.irType(binExpr.left.type)
|
||||||
val signed = binExpr.left.type in SignedDatatypes
|
val signed = binExpr.left.type in SignedDatatypes
|
||||||
return when(binExpr.operator) {
|
return when(binExpr.operator) {
|
||||||
|
@ -899,6 +899,7 @@ class IRCodeGen(
|
|||||||
val goto = ifElse.ifScope.children.firstOrNull() as? PtJump
|
val goto = ifElse.ifScope.children.firstOrNull() as? PtJump
|
||||||
when (condition) {
|
when (condition) {
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
|
require(!options.useNewExprCode)
|
||||||
if(condition.operator !in ComparisonOperators)
|
if(condition.operator !in ComparisonOperators)
|
||||||
throw AssemblyError("if condition should only be a binary comparison expression")
|
throw AssemblyError("if condition should only be a binary comparison expression")
|
||||||
|
|
||||||
|
@ -14,13 +14,6 @@ class VmCodeGen: ICodeGeneratorBackend {
|
|||||||
options: CompilationOptions,
|
options: CompilationOptions,
|
||||||
errors: IErrorReporter
|
errors: IErrorReporter
|
||||||
): IAssemblyProgram? {
|
): IAssemblyProgram? {
|
||||||
|
|
||||||
if(options.useNewExprCode) {
|
|
||||||
// TODO("transform BinExprs?")
|
|
||||||
// errors.warn("EXPERIMENTAL NEW EXPRESSION CODEGEN IS USED. CODE SIZE+SPEED POSSIBLY SUFFERS.", Position.DUMMY)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
|
val irCodeGen = IRCodeGen(program, symbolTable, options, errors)
|
||||||
val irProgram = irCodeGen.generate()
|
val irProgram = irCodeGen.generate()
|
||||||
return VmAssemblyProgram(irProgram.name, irProgram)
|
return VmAssemblyProgram(irProgram.name, irProgram)
|
||||||
|
@ -251,7 +251,7 @@ pop_float_fac1 .proc
|
|||||||
.pend
|
.pend
|
||||||
|
|
||||||
copy_float .proc
|
copy_float .proc
|
||||||
; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_ZPWORD1,
|
; -- copies the 5 bytes of the mflt value pointed to by SCRATCH_W1,
|
||||||
; into the 5 bytes pointed to by A/Y. Clobbers A,Y.
|
; into the 5 bytes pointed to by A/Y. Clobbers A,Y.
|
||||||
sta _target+1
|
sta _target+1
|
||||||
sty _target+2
|
sty _target+2
|
||||||
|
@ -4,11 +4,12 @@ import com.github.michaelbull.result.onFailure
|
|||||||
import prog8.ast.IBuiltinFunctions
|
import prog8.ast.IBuiltinFunctions
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.base.AstException
|
import prog8.ast.base.AstException
|
||||||
|
import prog8.ast.base.FatalAstException
|
||||||
import prog8.ast.expressions.Expression
|
import prog8.ast.expressions.Expression
|
||||||
import prog8.ast.expressions.NumericLiteral
|
import prog8.ast.expressions.NumericLiteral
|
||||||
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.*
|
||||||
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
|
||||||
@ -409,6 +410,11 @@ private fun createAssemblyAndAssemble(program: PtProgram,
|
|||||||
else
|
else
|
||||||
throw NotImplementedError("no code generator for cpu ${compilerOptions.compTarget.machine.cpu}")
|
throw NotImplementedError("no code generator for cpu ${compilerOptions.compTarget.machine.cpu}")
|
||||||
|
|
||||||
|
if(compilerOptions.useNewExprCode)
|
||||||
|
transformNewExpressions(program)
|
||||||
|
|
||||||
|
// printAst(program, true) { println(it) }
|
||||||
|
|
||||||
val stMaker = SymbolTableMaker(program, compilerOptions)
|
val stMaker = SymbolTableMaker(program, compilerOptions)
|
||||||
val symbolTable = stMaker.make()
|
val symbolTable = stMaker.make()
|
||||||
val assembly = asmgen.generate(program, symbolTable, compilerOptions, errors)
|
val assembly = asmgen.generate(program, symbolTable, compilerOptions, errors)
|
||||||
@ -420,3 +426,188 @@ private fun createAssemblyAndAssemble(program: PtProgram,
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun transformNewExpressions(program: PtProgram) {
|
||||||
|
val newVariables = mutableMapOf<PtSub, MutableList<PtVariable>>()
|
||||||
|
var countByteVars = 0
|
||||||
|
var countWordVars = 0
|
||||||
|
var countFloatVars = 0
|
||||||
|
// TODO: find a reliable way to reuse the temp vars across expressions
|
||||||
|
|
||||||
|
fun getExprVar(type: DataType, pos: Position, scope: PtSub): PtIdentifier {
|
||||||
|
val count = when(type) {
|
||||||
|
in ByteDatatypes -> {
|
||||||
|
countByteVars++
|
||||||
|
countByteVars
|
||||||
|
}
|
||||||
|
in WordDatatypes -> {
|
||||||
|
countWordVars++
|
||||||
|
countWordVars
|
||||||
|
}
|
||||||
|
DataType.FLOAT -> {
|
||||||
|
countFloatVars++
|
||||||
|
countFloatVars
|
||||||
|
}
|
||||||
|
else -> throw FatalAstException("weird dt")
|
||||||
|
}
|
||||||
|
val name = "p8p_exprvar_${count}_${type.toString().lowercase()}"
|
||||||
|
var subVars = newVariables[scope]
|
||||||
|
if(subVars==null) {
|
||||||
|
subVars = mutableListOf()
|
||||||
|
newVariables[scope] = subVars
|
||||||
|
}
|
||||||
|
if(subVars.all { it.name!=name }) {
|
||||||
|
subVars.add(PtVariable(name, type, ZeropageWish.DONTCARE, null, null, pos))
|
||||||
|
}
|
||||||
|
return PtIdentifier("${scope.scopedName}.$name", type, pos)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun transformExpr(expr: PtBinaryExpression): Pair<PtExpression, List<IPtAssignment>> {
|
||||||
|
// depth first process the expression tree
|
||||||
|
val scope = expr.definingSub()!!
|
||||||
|
val assignments = mutableListOf<IPtAssignment>()
|
||||||
|
|
||||||
|
fun transformOperand(node: PtExpression): PtNode {
|
||||||
|
return when(node) {
|
||||||
|
is PtNumber, is PtIdentifier, is PtArray, is PtString, is PtMachineRegister -> node
|
||||||
|
is PtBinaryExpression -> {
|
||||||
|
val (replacement, subAssigns) = transformExpr(node)
|
||||||
|
assignments.addAll(subAssigns)
|
||||||
|
replacement
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
val variable = getExprVar(node.type, node.position, scope)
|
||||||
|
val assign = PtAssignment(node.position)
|
||||||
|
val target = PtAssignTarget(variable.position)
|
||||||
|
target.add(variable)
|
||||||
|
assign.add(target)
|
||||||
|
assign.add(node)
|
||||||
|
assignments.add(assign)
|
||||||
|
variable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newLeft = transformOperand(expr.left)
|
||||||
|
val newRight = transformOperand(expr.right)
|
||||||
|
|
||||||
|
// process the binexpr
|
||||||
|
|
||||||
|
val resultVar =
|
||||||
|
if(expr.type == expr.left.type) {
|
||||||
|
getExprVar(expr.type, expr.position, scope)
|
||||||
|
} else {
|
||||||
|
if(expr.operator in ComparisonOperators && expr.type in ByteDatatypes) {
|
||||||
|
// this is very common and should be dealth with correctly; byte==0, word>42
|
||||||
|
val varType = if(expr.left.type in PassByReferenceDatatypes) DataType.UWORD else expr.left.type
|
||||||
|
getExprVar(varType, expr.position, scope)
|
||||||
|
}
|
||||||
|
else if(expr.left.type in PassByReferenceDatatypes && expr.type==DataType.UBYTE) {
|
||||||
|
// this is common and should be dealth with correctly; for instance "name"=="john"
|
||||||
|
val varType = if (expr.left.type in PassByReferenceDatatypes) DataType.UWORD else expr.left.type
|
||||||
|
getExprVar(varType, expr.position, scope)
|
||||||
|
} else if(expr.left.type equalsSize expr.type) {
|
||||||
|
getExprVar(expr.type, expr.position, scope)
|
||||||
|
} else {
|
||||||
|
TODO("expression type differs from left operand type! got ${expr.left.type} expected ${expr.type} ${expr.position}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(resultVar.name!=(newLeft as? PtIdentifier)?.name) {
|
||||||
|
// resultvar = left
|
||||||
|
val assign1 = PtAssignment(newLeft.position)
|
||||||
|
val target1 = PtAssignTarget(resultVar.position)
|
||||||
|
target1.add(resultVar)
|
||||||
|
assign1.add(target1)
|
||||||
|
assign1.add(newLeft)
|
||||||
|
assignments.add(assign1)
|
||||||
|
}
|
||||||
|
// resultvar {oper}= right
|
||||||
|
val operator = if(expr.operator in ComparisonOperators) expr.operator else expr.operator+'='
|
||||||
|
val assign2 = PtAugmentedAssign(operator, newRight.position)
|
||||||
|
val target2 = PtAssignTarget(resultVar.position)
|
||||||
|
target2.add(resultVar.copy())
|
||||||
|
assign2.add(target2)
|
||||||
|
assign2.add(newRight)
|
||||||
|
assignments.add(assign2)
|
||||||
|
return Pair(resultVar, assignments)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun isProperStatement(node: PtNode): Boolean {
|
||||||
|
return when(node) {
|
||||||
|
is PtAssignment -> true
|
||||||
|
is PtAugmentedAssign -> true
|
||||||
|
is PtBreakpoint -> true
|
||||||
|
is PtConditionalBranch -> true
|
||||||
|
is PtForLoop -> true
|
||||||
|
is PtIfElse -> true
|
||||||
|
is PtIncludeBinary -> true
|
||||||
|
is PtInlineAssembly -> true
|
||||||
|
is PtJump -> true
|
||||||
|
is PtAsmSub -> true
|
||||||
|
is PtLabel -> true
|
||||||
|
is PtSub -> true
|
||||||
|
is PtVariable -> true
|
||||||
|
is PtNop -> true
|
||||||
|
is PtPostIncrDecr -> true
|
||||||
|
is PtRepeatLoop -> true
|
||||||
|
is PtReturn -> true
|
||||||
|
is PtWhen -> true
|
||||||
|
is PtBuiltinFunctionCall -> node.void
|
||||||
|
is PtFunctionCall -> node.void
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun transform(node: PtNode, parent: PtNode) {
|
||||||
|
if(node is PtBinaryExpression) {
|
||||||
|
node.children.toTypedArray().forEach {
|
||||||
|
transform(it, node)
|
||||||
|
}
|
||||||
|
val (rep, assignments) = transformExpr(node)
|
||||||
|
var replacement = rep
|
||||||
|
if(!(rep.type equalsSize node.type)) {
|
||||||
|
if(rep.type in NumericDatatypes && node.type in ByteDatatypes) {
|
||||||
|
replacement = PtTypeCast(node.type, node.position)
|
||||||
|
replacement.add(rep)
|
||||||
|
} else
|
||||||
|
TODO("cast replacement type ${rep.type} -> ${node.type}")
|
||||||
|
}
|
||||||
|
var idx = parent.children.indexOf(node)
|
||||||
|
parent.children[idx] = replacement
|
||||||
|
replacement.parent = parent
|
||||||
|
// find the statement above which we should insert the assignments
|
||||||
|
var stmt = node
|
||||||
|
while(!isProperStatement(stmt))
|
||||||
|
stmt = stmt.parent
|
||||||
|
idx = stmt.parent.children.indexOf(stmt)
|
||||||
|
assignments.reversed().forEach {
|
||||||
|
stmt.parent.add(idx, it as PtNode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
node.children.toTypedArray().forEach { child -> transform(child, node) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
program.allBlocks().forEach { block ->
|
||||||
|
block.children.toTypedArray().forEach {
|
||||||
|
transform(it, block)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the new variables
|
||||||
|
newVariables.forEach { (sub, vars) ->
|
||||||
|
vars.forEach {
|
||||||
|
sub.add(0, it)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// extra check to see that all PtBinaryExpressions have been transformed
|
||||||
|
fun binExprCheck(node: PtNode) {
|
||||||
|
if(node is PtBinaryExpression)
|
||||||
|
throw IllegalArgumentException("still got binexpr $node ${node.position}")
|
||||||
|
node.children.forEach { binExprCheck(it) }
|
||||||
|
}
|
||||||
|
binExprCheck(program)
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -958,7 +958,11 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(expr.operator !in ComparisonOperators) {
|
if(expr.operator in ComparisonOperators) {
|
||||||
|
if(leftDt!=rightDt && !(leftDt in ByteDatatypes && rightDt in ByteDatatypes)) {
|
||||||
|
throw FatalAstException("got comparison with different operand types: $leftDt ${expr.operator} $rightDt ${expr.position}")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
if (leftDt == DataType.STR && rightDt == DataType.STR || leftDt in ArrayDatatypes && rightDt in ArrayDatatypes) {
|
if (leftDt == DataType.STR && rightDt == DataType.STR || leftDt in ArrayDatatypes && rightDt in ArrayDatatypes) {
|
||||||
// str+str and str*number have already been const evaluated before we get here.
|
// str+str and str*number have already been const evaluated before we get here.
|
||||||
errors.err("no computational or logical expressions with strings or arrays are possible", expr.position)
|
errors.err("no computational or logical expressions with strings or arrays are possible", expr.position)
|
||||||
|
@ -36,6 +36,19 @@ internal class BeforeAsmAstChanger(val program: Program,
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
||||||
|
if(expr.operator in ComparisonOperators && expr.left.inferType(program) istype DataType.STR && expr.right.inferType(program) istype DataType.STR) {
|
||||||
|
// replace string comparison expressions with calls to string.compare()
|
||||||
|
val stringCompare = BuiltinFunctionCall(
|
||||||
|
IdentifierReference(listOf("prog8_lib_stringcompare"), expr.position),
|
||||||
|
mutableListOf(expr.left.copy(), expr.right.copy()), expr.position)
|
||||||
|
val zero = NumericLiteral.optimalInteger(0, expr.position)
|
||||||
|
val comparison = BinaryExpression(stringCompare, expr.operator, zero, expr.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(expr, comparison, parent))
|
||||||
|
}
|
||||||
|
return noModifications
|
||||||
|
}
|
||||||
|
|
||||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||||
if (decl.type == VarDeclType.VAR && decl.value != null && decl.datatype in NumericDatatypes)
|
if (decl.type == VarDeclType.VAR && decl.value != null && decl.datatype in NumericDatatypes)
|
||||||
throw InternalCompilerException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
throw InternalCompilerException("vardecls for variables, with initial numerical value, should have been rewritten as plain vardecl + assignment $decl")
|
||||||
|
@ -79,7 +79,7 @@ if CONDITION==0
|
|||||||
while CONDITION { STUFF }
|
while CONDITION { STUFF }
|
||||||
==>
|
==>
|
||||||
_whileloop:
|
_whileloop:
|
||||||
if CONDITION==0 goto _after
|
if INVERTED-CONDITION goto _after
|
||||||
STUFF
|
STUFF
|
||||||
goto _whileloop
|
goto _whileloop
|
||||||
_after:
|
_after:
|
||||||
|
@ -109,6 +109,8 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
|
|||||||
if(binExpr==null || binExpr.operator !in ComparisonOperators)
|
if(binExpr==null || binExpr.operator !in ComparisonOperators)
|
||||||
return noModifications
|
return noModifications
|
||||||
|
|
||||||
|
return noModifications // TODO tijdelijk geen simplify
|
||||||
|
|
||||||
// Simplify the conditional expression, introduce simple assignments if required.
|
// Simplify the conditional expression, introduce simple assignments if required.
|
||||||
// This is REQUIRED for correct code generation on 6502 because evaluating certain expressions
|
// This is REQUIRED for correct code generation on 6502 because evaluating certain expressions
|
||||||
// clobber the handful of temporary variables in the zeropage and leaving everything in one
|
// clobber the handful of temporary variables in the zeropage and leaving everything in one
|
||||||
|
@ -1,12 +1,40 @@
|
|||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%import textio
|
%import textio
|
||||||
|
%import floats
|
||||||
|
%import string
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
|
test_string()
|
||||||
|
txt.nl()
|
||||||
|
test_compare_variable()
|
||||||
|
txt.nl()
|
||||||
|
test_compare_literal()
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_string() {
|
||||||
|
str name="john"
|
||||||
|
|
||||||
|
if (string.compare(name, "aaa")==0) or (string.compare(name, "john")==0) or (string.compare(name, "bbb")==0) {
|
||||||
|
txt.print("name1 ok\n")
|
||||||
|
}
|
||||||
|
if (string.compare(name, "aaa")==0) or (string.compare(name, "zzz")==0) or (string.compare(name, "bbb")==0) {
|
||||||
|
txt.print("name2 fail!\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
if name=="aaa" or name=="john" or name=="bbb"
|
||||||
|
txt.print("name1b ok\n")
|
||||||
|
if name=="aaa" or name=="zzz" or name=="bbb"
|
||||||
|
txt.print("name2b fail!\n")
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_compare_literal() {
|
||||||
byte b = -100
|
byte b = -100
|
||||||
ubyte ub = 20
|
ubyte ub = 20
|
||||||
word w = -20000
|
word w = -20000
|
||||||
uword uw = 2000
|
uword uw = 2000
|
||||||
|
float f = -100
|
||||||
|
|
||||||
txt.print("all 1: ")
|
txt.print("all 1: ")
|
||||||
txt.print_ub(b == -100)
|
txt.print_ub(b == -100)
|
||||||
@ -34,7 +62,15 @@ main {
|
|||||||
txt.print_ub(uw <= 2000)
|
txt.print_ub(uw <= 2000)
|
||||||
txt.print_ub(uw > 1999)
|
txt.print_ub(uw > 1999)
|
||||||
txt.print_ub(uw >= 2000)
|
txt.print_ub(uw >= 2000)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(f == -100.0)
|
||||||
|
txt.print_ub(f != -99.0)
|
||||||
|
txt.print_ub(f < -99.0)
|
||||||
|
txt.print_ub(f <= -100.0)
|
||||||
|
txt.print_ub(f > -101.0)
|
||||||
|
txt.print_ub(f >= -100.0)
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
txt.print("all 0: ")
|
txt.print("all 0: ")
|
||||||
txt.print_ub(b == -99)
|
txt.print_ub(b == -99)
|
||||||
txt.print_ub(b != -100)
|
txt.print_ub(b != -100)
|
||||||
@ -61,6 +97,153 @@ main {
|
|||||||
txt.print_ub(uw <= 1999)
|
txt.print_ub(uw <= 1999)
|
||||||
txt.print_ub(uw > 2000)
|
txt.print_ub(uw > 2000)
|
||||||
txt.print_ub(uw >= 2001)
|
txt.print_ub(uw >= 2001)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(f == -99.0)
|
||||||
|
txt.print_ub(f != -100.0)
|
||||||
|
txt.print_ub(f < -100.0)
|
||||||
|
txt.print_ub(f <= -101.0)
|
||||||
|
txt.print_ub(f > -100.0)
|
||||||
|
txt.print_ub(f >= -99.0)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all .: ")
|
||||||
|
if b == -100 txt.chrout('.')
|
||||||
|
if b != -99 txt.chrout('.')
|
||||||
|
if b < -99 txt.chrout('.')
|
||||||
|
if b <= -100 txt.chrout('.')
|
||||||
|
if b > -101 txt.chrout('.')
|
||||||
|
if b >= -100 txt.chrout('.')
|
||||||
|
if ub ==20 txt.chrout('.')
|
||||||
|
if ub !=19 txt.chrout('.')
|
||||||
|
if ub <21 txt.chrout('.')
|
||||||
|
if ub <=20 txt.chrout('.')
|
||||||
|
if ub>19 txt.chrout('.')
|
||||||
|
if ub>=20 txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if w == -20000 txt.chrout('.')
|
||||||
|
if w != -19999 txt.chrout('.')
|
||||||
|
if w < -19999 txt.chrout('.')
|
||||||
|
if w <= -20000 txt.chrout('.')
|
||||||
|
if w > -20001 txt.chrout('.')
|
||||||
|
if w >= -20000 txt.chrout('.')
|
||||||
|
if uw == 2000 txt.chrout('.')
|
||||||
|
if uw != 2001 txt.chrout('.')
|
||||||
|
if uw < 2001 txt.chrout('.')
|
||||||
|
if uw <= 2000 txt.chrout('.')
|
||||||
|
if uw > 1999 txt.chrout('.')
|
||||||
|
if uw >= 2000 txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if f == -100.0 txt.chrout('.')
|
||||||
|
if f != -99.0 txt.chrout('.')
|
||||||
|
if f < -99.0 txt.chrout('.')
|
||||||
|
if f <= -100.0 txt.chrout('.')
|
||||||
|
if f > -101.0 txt.chrout('.')
|
||||||
|
if f >= -100.0 txt.chrout('.')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print(" no !: ")
|
||||||
|
if b == -99 txt.chrout('!')
|
||||||
|
if b != -100 txt.chrout('!')
|
||||||
|
if b < -100 txt.chrout('!')
|
||||||
|
if b <= -101 txt.chrout('!')
|
||||||
|
if b > -100 txt.chrout('!')
|
||||||
|
if b >= -99 txt.chrout('!')
|
||||||
|
if ub ==21 txt.chrout('!')
|
||||||
|
if ub !=20 txt.chrout('!')
|
||||||
|
if ub <20 txt.chrout('!')
|
||||||
|
if ub <=19 txt.chrout('!')
|
||||||
|
if ub>20 txt.chrout('!')
|
||||||
|
if ub>=21 txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if w == -20001 txt.chrout('!')
|
||||||
|
if w != -20000 txt.chrout('!')
|
||||||
|
if w < -20000 txt.chrout('!')
|
||||||
|
if w <= -20001 txt.chrout('!')
|
||||||
|
if w > -20000 txt.chrout('!')
|
||||||
|
if w >= -19999 txt.chrout('!')
|
||||||
|
if uw == 1999 txt.chrout('!')
|
||||||
|
if uw != 2000 txt.chrout('!')
|
||||||
|
if uw < 2000 txt.chrout('!')
|
||||||
|
if uw <= 1999 txt.chrout('!')
|
||||||
|
if uw > 2000 txt.chrout('!')
|
||||||
|
if uw >= 2001 txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if f == -99.0 txt.chrout('!')
|
||||||
|
if f != -100.0 txt.chrout('!')
|
||||||
|
if f < -100.0 txt.chrout('!')
|
||||||
|
if f <= -101.0 txt.chrout('!')
|
||||||
|
if f > -100.0 txt.chrout('!')
|
||||||
|
if f >= -99.0 txt.chrout('!')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all .: ")
|
||||||
|
if b == -100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b != -99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b < -99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b <= -100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b > -101 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b >= -100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub ==20 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub !=19 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub <21 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub <=20 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub>19 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub>=20 txt.chrout('.') else txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if w == -20000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w != -19999 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w < -19999 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w <= -20000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w > -20001 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w >= -20000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw == 2000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw != 2001 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw < 2001 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw <= 2000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw > 1999 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw >= 2000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if f == -100.0 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f != -99.0 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f < -99.0 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f <= -100.0 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f > -101.0 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f >= -100.0 txt.chrout('.') else txt.chrout('!')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all .: ")
|
||||||
|
if b == -99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b != -100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b < -100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b <= -101 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b > -100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b >= -99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub ==21 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub !=20 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub <20 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub <=19 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub>20 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub>=21 txt.chrout('!') else txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if w == -20001 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w != -20000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w < -20000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w <= -20001 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w > -20000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w >= -19999 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw == 1999 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw != 2000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw < 2000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw <= 1999 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw > 2000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw >= 2001 txt.chrout('!') else txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if f == -99.0 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f != -100.0 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f < -100.0 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f <= -101.0 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f > -100.0 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f >= -99.0 txt.chrout('!') else txt.chrout('.')
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
|
|
||||||
@ -112,9 +295,311 @@ main {
|
|||||||
txt.print_uw(uw)
|
txt.print_uw(uw)
|
||||||
txt.print(" 8000\n")
|
txt.print(" 8000\n")
|
||||||
|
|
||||||
; float f
|
f = 0.0
|
||||||
; while f<2.2 {
|
floats.print_f(f)
|
||||||
; f+=0.1
|
while f<2.2 {
|
||||||
; }
|
f+=0.1
|
||||||
|
floats.print_f(f)
|
||||||
|
}
|
||||||
|
floats.print_f(f)
|
||||||
|
txt.print(" 2.2\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
sub test_compare_variable() {
|
||||||
|
byte b = -100
|
||||||
|
ubyte ub = 20
|
||||||
|
word w = -20000
|
||||||
|
uword uw = 2000
|
||||||
|
float f = -100
|
||||||
|
|
||||||
|
byte minus_100 = -100
|
||||||
|
byte minus_99 = -99
|
||||||
|
byte minus_20 = -20
|
||||||
|
byte minus_101 = -101
|
||||||
|
ubyte nineteen = 19
|
||||||
|
ubyte twenty = 20
|
||||||
|
ubyte twenty1 = 21
|
||||||
|
ubyte twohundred = 200
|
||||||
|
float f_minus_100 = -100.0
|
||||||
|
float f_minus_101 = -101.0
|
||||||
|
float f_minus_99 = -99.0
|
||||||
|
float twodottwo = 2.2
|
||||||
|
word minus8000 = -8000
|
||||||
|
word eightthousand = 8000
|
||||||
|
word w_min_20000 = -20000
|
||||||
|
word w_min_19999 = -19999
|
||||||
|
word w_min_20001 = -20001
|
||||||
|
uword twothousand = 2000
|
||||||
|
uword twothousand1 = 2001
|
||||||
|
uword nineteen99 = 1999
|
||||||
|
|
||||||
|
|
||||||
|
txt.print("all 1: ")
|
||||||
|
txt.print_ub(b == minus_100)
|
||||||
|
txt.print_ub(b != minus_99)
|
||||||
|
txt.print_ub(b < minus_99)
|
||||||
|
txt.print_ub(b <= minus_100)
|
||||||
|
txt.print_ub(b > minus_101)
|
||||||
|
txt.print_ub(b >= minus_100)
|
||||||
|
txt.print_ub(ub ==twenty)
|
||||||
|
txt.print_ub(ub !=nineteen)
|
||||||
|
txt.print_ub(ub <twenty1)
|
||||||
|
txt.print_ub(ub <=twenty)
|
||||||
|
txt.print_ub(ub>nineteen)
|
||||||
|
txt.print_ub(ub>=twenty)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(w == w_min_20000)
|
||||||
|
txt.print_ub(w != w_min_19999)
|
||||||
|
txt.print_ub(w < w_min_19999)
|
||||||
|
txt.print_ub(w <= w_min_20000)
|
||||||
|
txt.print_ub(w > w_min_20001)
|
||||||
|
txt.print_ub(w >= w_min_20000)
|
||||||
|
txt.print_ub(uw == twothousand)
|
||||||
|
txt.print_ub(uw != twothousand1)
|
||||||
|
txt.print_ub(uw < twothousand1)
|
||||||
|
txt.print_ub(uw <= twothousand)
|
||||||
|
txt.print_ub(uw > nineteen99)
|
||||||
|
txt.print_ub(uw >= twothousand)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(f == f_minus_100)
|
||||||
|
txt.print_ub(f != f_minus_99)
|
||||||
|
txt.print_ub(f < f_minus_99)
|
||||||
|
txt.print_ub(f <= f_minus_100)
|
||||||
|
txt.print_ub(f > f_minus_101)
|
||||||
|
txt.print_ub(f >= f_minus_100)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all 0: ")
|
||||||
|
txt.print_ub(b == minus_99)
|
||||||
|
txt.print_ub(b != minus_100)
|
||||||
|
txt.print_ub(b < minus_100)
|
||||||
|
txt.print_ub(b <= minus_101)
|
||||||
|
txt.print_ub(b > minus_100)
|
||||||
|
txt.print_ub(b >= minus_99)
|
||||||
|
txt.print_ub(ub ==twenty1)
|
||||||
|
txt.print_ub(ub !=twenty)
|
||||||
|
txt.print_ub(ub <twenty)
|
||||||
|
txt.print_ub(ub <=nineteen)
|
||||||
|
txt.print_ub(ub>twenty)
|
||||||
|
txt.print_ub(ub>=twenty1)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(w == w_min_20001)
|
||||||
|
txt.print_ub(w != w_min_20000)
|
||||||
|
txt.print_ub(w < w_min_20000)
|
||||||
|
txt.print_ub(w <= w_min_20001)
|
||||||
|
txt.print_ub(w > w_min_20000)
|
||||||
|
txt.print_ub(w >= w_min_19999)
|
||||||
|
txt.print_ub(uw == nineteen99)
|
||||||
|
txt.print_ub(uw != twothousand)
|
||||||
|
txt.print_ub(uw < twothousand)
|
||||||
|
txt.print_ub(uw <= nineteen99)
|
||||||
|
txt.print_ub(uw > twothousand)
|
||||||
|
txt.print_ub(uw >= twothousand1)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_ub(f == f_minus_99)
|
||||||
|
txt.print_ub(f != f_minus_100)
|
||||||
|
txt.print_ub(f < f_minus_100)
|
||||||
|
txt.print_ub(f <= f_minus_101)
|
||||||
|
txt.print_ub(f > f_minus_100)
|
||||||
|
txt.print_ub(f >= f_minus_99)
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all .: ")
|
||||||
|
if b == minus_100 txt.chrout('.')
|
||||||
|
if b != minus_99 txt.chrout('.')
|
||||||
|
if b < minus_99 txt.chrout('.')
|
||||||
|
if b <= minus_100 txt.chrout('.')
|
||||||
|
if b > minus_101 txt.chrout('.')
|
||||||
|
if b >= minus_100 txt.chrout('.')
|
||||||
|
if ub == twenty txt.chrout('.')
|
||||||
|
if ub != nineteen txt.chrout('.')
|
||||||
|
if ub < twenty1 txt.chrout('.')
|
||||||
|
if ub <= twenty txt.chrout('.')
|
||||||
|
if ub> nineteen txt.chrout('.')
|
||||||
|
if ub>= twenty txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if w == w_min_20000 txt.chrout('.')
|
||||||
|
if w != w_min_19999 txt.chrout('.')
|
||||||
|
if w < w_min_19999 txt.chrout('.')
|
||||||
|
if w <= w_min_20000 txt.chrout('.')
|
||||||
|
if w > w_min_20001 txt.chrout('.')
|
||||||
|
if w >= w_min_20000 txt.chrout('.')
|
||||||
|
if uw == twothousand txt.chrout('.')
|
||||||
|
if uw != twothousand1 txt.chrout('.')
|
||||||
|
if uw < twothousand1 txt.chrout('.')
|
||||||
|
if uw <= twothousand txt.chrout('.')
|
||||||
|
if uw > nineteen99 txt.chrout('.')
|
||||||
|
if uw >= twothousand txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if f == f_minus_100 txt.chrout('.')
|
||||||
|
if f != f_minus_99 txt.chrout('.')
|
||||||
|
if f < f_minus_99 txt.chrout('.')
|
||||||
|
if f <= f_minus_100 txt.chrout('.')
|
||||||
|
if f > f_minus_101 txt.chrout('.')
|
||||||
|
if f >= f_minus_100 txt.chrout('.')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print(" no !: ")
|
||||||
|
if b == minus_99 txt.chrout('!')
|
||||||
|
if b != minus_100 txt.chrout('!')
|
||||||
|
if b < minus_100 txt.chrout('!')
|
||||||
|
if b <= minus_101 txt.chrout('!')
|
||||||
|
if b > minus_100 txt.chrout('!')
|
||||||
|
if b >= minus_99 txt.chrout('!')
|
||||||
|
if ub == twenty1 txt.chrout('!')
|
||||||
|
if ub != twenty txt.chrout('!')
|
||||||
|
if ub < twenty txt.chrout('!')
|
||||||
|
if ub <= nineteen txt.chrout('!')
|
||||||
|
if ub> twenty txt.chrout('!')
|
||||||
|
if ub>= twenty1 txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if w == w_min_20001 txt.chrout('!')
|
||||||
|
if w != w_min_20000 txt.chrout('!')
|
||||||
|
if w < w_min_20000 txt.chrout('!')
|
||||||
|
if w <= w_min_20001 txt.chrout('!')
|
||||||
|
if w > w_min_20000 txt.chrout('!')
|
||||||
|
if w >= w_min_19999 txt.chrout('!')
|
||||||
|
if uw == nineteen99 txt.chrout('!')
|
||||||
|
if uw != twothousand txt.chrout('!')
|
||||||
|
if uw < twothousand txt.chrout('!')
|
||||||
|
if uw <= nineteen99 txt.chrout('!')
|
||||||
|
if uw > twothousand txt.chrout('!')
|
||||||
|
if uw >= twothousand1 txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if f == f_minus_99 txt.chrout('!')
|
||||||
|
if f != f_minus_100 txt.chrout('!')
|
||||||
|
if f < f_minus_100 txt.chrout('!')
|
||||||
|
if f <= f_minus_101 txt.chrout('!')
|
||||||
|
if f > f_minus_100 txt.chrout('!')
|
||||||
|
if f >= f_minus_99 txt.chrout('!')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all .: ")
|
||||||
|
if b == minus_100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b != minus_99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b < minus_99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b <= minus_100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b > minus_101 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if b >= minus_100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub == twenty txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub != nineteen txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub < twenty1 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub <= twenty txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub> nineteen txt.chrout('.') else txt.chrout('!')
|
||||||
|
if ub>=twenty txt.chrout('.') else txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if w == w_min_20000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w != w_min_19999 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w < w_min_19999 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w <= w_min_20000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w > w_min_20001 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if w >= w_min_20000 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw == twothousand txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw != twothousand1 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw < twothousand1 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw <= twothousand txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw > nineteen99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if uw >= twothousand txt.chrout('.') else txt.chrout('!')
|
||||||
|
txt.spc()
|
||||||
|
if f == f_minus_100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f != f_minus_99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f < f_minus_99 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f <= f_minus_100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f > f_minus_101 txt.chrout('.') else txt.chrout('!')
|
||||||
|
if f >= f_minus_100 txt.chrout('.') else txt.chrout('!')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
txt.print("all .: ")
|
||||||
|
if b == minus_99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b != minus_100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b < minus_100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b <= minus_101 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b > minus_100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if b >= minus_99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub == twenty1 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub !=twenty txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub <twenty txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub <=nineteen txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub>twenty txt.chrout('!') else txt.chrout('.')
|
||||||
|
if ub>= twenty1 txt.chrout('!') else txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if w == w_min_20001 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w != w_min_20000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w < w_min_20000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w <= w_min_20001 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w > w_min_20000 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if w >= w_min_19999 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw == nineteen99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw != twothousand txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw < twothousand txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw <= nineteen99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw > twothousand txt.chrout('!') else txt.chrout('.')
|
||||||
|
if uw >= twothousand1 txt.chrout('!') else txt.chrout('.')
|
||||||
|
txt.spc()
|
||||||
|
if f == f_minus_99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f != f_minus_100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f < f_minus_100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f <= f_minus_101 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f > f_minus_100 txt.chrout('!') else txt.chrout('.')
|
||||||
|
if f >= f_minus_99 txt.chrout('!') else txt.chrout('.')
|
||||||
|
txt.nl()
|
||||||
|
|
||||||
|
|
||||||
|
b = minus_100
|
||||||
|
while b <= minus_20
|
||||||
|
b++
|
||||||
|
txt.print_b(b)
|
||||||
|
txt.print(" -19\n")
|
||||||
|
b = minus_100
|
||||||
|
while b < -minus_20
|
||||||
|
b++
|
||||||
|
txt.print_b(b)
|
||||||
|
txt.print(" -20\n")
|
||||||
|
|
||||||
|
ub = 20
|
||||||
|
while ub <= twohundred
|
||||||
|
ub++
|
||||||
|
txt.print_ub(ub)
|
||||||
|
txt.print(" 201\n")
|
||||||
|
ub = 20
|
||||||
|
while ub < twohundred
|
||||||
|
ub++
|
||||||
|
txt.print_ub(ub)
|
||||||
|
txt.print(" 200\n")
|
||||||
|
|
||||||
|
w = w_min_20000
|
||||||
|
while w <= minus8000 {
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
txt.print_w(w)
|
||||||
|
txt.print(" -7999\n")
|
||||||
|
w = w_min_20000
|
||||||
|
while w < minus8000 {
|
||||||
|
w++
|
||||||
|
}
|
||||||
|
txt.print_w(w)
|
||||||
|
txt.print(" -8000\n")
|
||||||
|
|
||||||
|
uw = 2000
|
||||||
|
while uw <= eightthousand {
|
||||||
|
uw++
|
||||||
|
}
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.print(" 8001\n")
|
||||||
|
uw = 2000
|
||||||
|
while uw < eightthousand {
|
||||||
|
uw++
|
||||||
|
}
|
||||||
|
txt.print_uw(uw)
|
||||||
|
txt.print(" 8000\n")
|
||||||
|
|
||||||
|
f = 0.0
|
||||||
|
floats.print_f(f)
|
||||||
|
while f<twodottwo {
|
||||||
|
f+=0.1
|
||||||
|
floats.print_f(f)
|
||||||
|
}
|
||||||
|
floats.print_f(f)
|
||||||
|
txt.print(" 2.2\n")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
replace RPN by something that actually works and is efficient...
|
|
||||||
|
|
||||||
|
|
||||||
For next minor release
|
For next minor release
|
||||||
^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^
|
||||||
- ubyte fits = cx<numCellsHoriz-1 much larger code than when declared as bool ????
|
|
||||||
- if fits and @(celladdr(cx+1)) much larger code than if fits and not @(celladdr(cx+1)) ????
|
|
||||||
- @($5000 + c<<$0003) = 22 why is 22 pushed on the stack first and then popped after the address is calculated
|
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user