mirror of
https://github.com/irmen/prog8.git
synced 2024-08-11 05:29:18 +00:00
fix string compare and ifelse
This commit is contained in:
parent
07fde7f6cc
commit
f4bf00ad31
@ -583,15 +583,15 @@ class AsmGen6502Internal (
|
|||||||
else -> throw AssemblyError("weird jump")
|
else -> throw AssemblyError("weird jump")
|
||||||
}
|
}
|
||||||
when(stmt.condition.type) {
|
when(stmt.condition.type) {
|
||||||
in WordDatatypes -> translateWordEqualsJump(stmt.condition, zero, leftConst, zero, label)
|
in WordDatatypes -> translateWordNotEqualsJump(stmt.condition, zero, leftConst, zero, label)
|
||||||
in ByteDatatypes -> translateByteEqualsJump(stmt.condition, zero, leftConst, zero, label)
|
in ByteDatatypes -> translateByteNotEqualsJump(stmt.condition, zero, leftConst, zero, label)
|
||||||
else -> throw AssemblyError("weird condition dt")
|
else -> throw AssemblyError("weird condition dt")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val endLabel = makeLabel("if_end")
|
val endLabel = makeLabel("if_end")
|
||||||
when(stmt.condition.type) {
|
when(stmt.condition.type) {
|
||||||
in WordDatatypes -> translateWordEqualsJump(stmt.condition, zero, leftConst, zero, endLabel)
|
in WordDatatypes -> translateWordNotEqualsJump(stmt.condition, zero, leftConst, zero, endLabel)
|
||||||
in ByteDatatypes -> translateByteEqualsJump(stmt.condition, zero, leftConst, zero, endLabel)
|
in ByteDatatypes -> translateByteNotEqualsJump(stmt.condition, zero, leftConst, zero, endLabel)
|
||||||
else -> throw AssemblyError("weird condition dt")
|
else -> throw AssemblyError("weird condition dt")
|
||||||
}
|
}
|
||||||
translate(stmt.ifScope)
|
translate(stmt.ifScope)
|
||||||
|
@ -70,17 +70,19 @@ 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)
|
"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}")
|
||||||
}
|
}
|
||||||
|
|
||||||
return BuiltinFunctions.getValue(fcall.name).returnType
|
return BuiltinFunctions.getValue(fcall.name).returnType
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcStringCompare(fcall: PtBuiltinFunctionCall) {
|
private fun funcStringCompare(fcall: PtBuiltinFunctionCall, resultToStack: Boolean) {
|
||||||
assignAsmGen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", DataType.UWORD)
|
assignAsmGen.assignExpressionToVariable(fcall.args[1], "P8ZP_SCRATCH_W2", DataType.UWORD)
|
||||||
assignAsmGen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY, false)
|
assignAsmGen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY, false)
|
||||||
asmgen.out(" jsr prog8_lib.strcmp_mem")
|
asmgen.out(" jsr prog8_lib.strcmp_mem")
|
||||||
|
if(resultToStack)
|
||||||
|
asmgen.out(" sta P8ESTACK_LO,x | dex")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun funcRsave() {
|
private fun funcRsave() {
|
||||||
|
@ -4,6 +4,7 @@ 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
|
||||||
@ -428,9 +429,28 @@ private fun createAssemblyAndAssemble(program: PtProgram,
|
|||||||
|
|
||||||
private fun transformNewExpressions(program: PtProgram) {
|
private fun transformNewExpressions(program: PtProgram) {
|
||||||
val newVariables = mutableMapOf<PtSub, MutableList<PtVariable>>()
|
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(what: String, type: DataType, count: Int, pos: Position, scope: PtSub): PtIdentifier {
|
fun getExprVar(type: DataType, pos: Position, scope: PtSub): PtIdentifier {
|
||||||
val name = "p8p_exprvar_${what}_${count}_${type.toString().lowercase()}"
|
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]
|
var subVars = newVariables[scope]
|
||||||
if(subVars==null) {
|
if(subVars==null) {
|
||||||
subVars = mutableListOf()
|
subVars = mutableListOf()
|
||||||
@ -442,21 +462,21 @@ private fun transformNewExpressions(program: PtProgram) {
|
|||||||
return PtIdentifier("${scope.scopedName}.$name", type, pos)
|
return PtIdentifier("${scope.scopedName}.$name", type, pos)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transformExpr(expr: PtBinaryExpression, postfix: String, depth: Int): Pair<PtExpression, List<IPtAssignment>> {
|
fun transformExpr(expr: PtBinaryExpression): Pair<PtExpression, List<IPtAssignment>> {
|
||||||
// depth first process the expression tree
|
// depth first process the expression tree
|
||||||
val scope = expr.definingSub()!!
|
val scope = expr.definingSub()!!
|
||||||
val assignments = mutableListOf<IPtAssignment>()
|
val assignments = mutableListOf<IPtAssignment>()
|
||||||
|
|
||||||
fun transformOperand(node: PtExpression, kind: String): PtNode {
|
fun transformOperand(node: PtExpression): PtNode {
|
||||||
return when(node) {
|
return when(node) {
|
||||||
is PtNumber, is PtIdentifier, is PtArray, is PtString, is PtMachineRegister -> node
|
is PtNumber, is PtIdentifier, is PtArray, is PtString, is PtMachineRegister -> node
|
||||||
is PtBinaryExpression -> {
|
is PtBinaryExpression -> {
|
||||||
val (replacement, subAssigns) = transformExpr(node, kind, depth+1)
|
val (replacement, subAssigns) = transformExpr(node)
|
||||||
assignments.addAll(subAssigns)
|
assignments.addAll(subAssigns)
|
||||||
replacement
|
replacement
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val variable = getExprVar(kind, node.type, depth, node.position, scope)
|
val variable = getExprVar(node.type, node.position, scope)
|
||||||
val assign = PtAssignment(node.position)
|
val assign = PtAssignment(node.position)
|
||||||
val target = PtAssignTarget(variable.position)
|
val target = PtAssignTarget(variable.position)
|
||||||
target.add(variable)
|
target.add(variable)
|
||||||
@ -468,26 +488,26 @@ private fun transformNewExpressions(program: PtProgram) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newLeft = transformOperand(expr.left,"l")
|
val newLeft = transformOperand(expr.left)
|
||||||
val newRight = transformOperand(expr.right, "r")
|
val newRight = transformOperand(expr.right)
|
||||||
|
|
||||||
// process the binexpr
|
// process the binexpr
|
||||||
|
|
||||||
val resultVar =
|
val resultVar =
|
||||||
if(expr.type == expr.left.type) {
|
if(expr.type == expr.left.type) {
|
||||||
getExprVar(postfix, expr.type, depth, expr.position, scope)
|
getExprVar(expr.type, expr.position, scope)
|
||||||
} else {
|
} else {
|
||||||
if(expr.operator in ComparisonOperators && expr.type in ByteDatatypes) {
|
if(expr.operator in ComparisonOperators && expr.type in ByteDatatypes) {
|
||||||
// this is very common and should be dealth with correctly; byte==0, word>42
|
// 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
|
val varType = if(expr.left.type in PassByReferenceDatatypes) DataType.UWORD else expr.left.type
|
||||||
getExprVar(postfix, varType, depth, expr.position, scope)
|
getExprVar(varType, expr.position, scope)
|
||||||
}
|
}
|
||||||
else if(expr.left.type in PassByReferenceDatatypes && expr.type==DataType.UBYTE) {
|
else if(expr.left.type in PassByReferenceDatatypes && expr.type==DataType.UBYTE) {
|
||||||
// this is common and should be dealth with correctly; for instance "name"=="john"
|
// 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
|
val varType = if (expr.left.type in PassByReferenceDatatypes) DataType.UWORD else expr.left.type
|
||||||
getExprVar(postfix, varType, depth, expr.position, scope)
|
getExprVar(varType, expr.position, scope)
|
||||||
} else if(expr.left.type equalsSize expr.type) {
|
} else if(expr.left.type equalsSize expr.type) {
|
||||||
getExprVar(postfix, expr.type, depth, expr.position, scope)
|
getExprVar(expr.type, expr.position, scope)
|
||||||
} else {
|
} else {
|
||||||
TODO("expression type differs from left operand type! got ${expr.left.type} expected ${expr.type} ${expr.position}")
|
TODO("expression type differs from left operand type! got ${expr.left.type} expected ${expr.type} ${expr.position}")
|
||||||
}
|
}
|
||||||
@ -539,12 +559,13 @@ private fun transformNewExpressions(program: PtProgram) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transform(node: PtNode, parent: PtNode, depth: Int) {
|
fun transform(node: PtNode, parent: PtNode) {
|
||||||
if(node is PtBinaryExpression) {
|
if(node is PtBinaryExpression) {
|
||||||
|
println("BINEXPR AT ${node.position}")
|
||||||
node.children.toTypedArray().forEach {
|
node.children.toTypedArray().forEach {
|
||||||
transform(it, node, depth+1)
|
transform(it, node)
|
||||||
}
|
}
|
||||||
val (rep, assignments) = transformExpr(node, "l", depth)
|
val (rep, assignments) = transformExpr(node)
|
||||||
var replacement = rep
|
var replacement = rep
|
||||||
if(!(rep.type equalsSize node.type)) {
|
if(!(rep.type equalsSize node.type)) {
|
||||||
if(rep.type in NumericDatatypes && node.type in ByteDatatypes) {
|
if(rep.type in NumericDatatypes && node.type in ByteDatatypes) {
|
||||||
@ -565,13 +586,13 @@ private fun transformNewExpressions(program: PtProgram) {
|
|||||||
stmt.parent.add(idx, it as PtNode)
|
stmt.parent.add(idx, it as PtNode)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
node.children.toTypedArray().forEach { child -> transform(child, node, depth+1) }
|
node.children.toTypedArray().forEach { child -> transform(child, node) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
program.allBlocks().forEach { block ->
|
program.allBlocks().forEach { block ->
|
||||||
block.children.toTypedArray().forEach {
|
block.children.toTypedArray().forEach {
|
||||||
transform(it, block, 0)
|
transform(it, block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -19,9 +19,9 @@ main {
|
|||||||
txt.print("name2 fail!\n")
|
txt.print("name2 fail!\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if name=="aaa" or name=="john" or name=="bbb" ; TODO fix this result on C64 target, no newexpr!
|
if name=="aaa" or name=="john" or name=="bbb"
|
||||||
txt.print("name1b ok\n")
|
txt.print("name1b ok\n")
|
||||||
if name=="aaa" or name=="zzz" or name=="bbb" ; TODO fix this result on C64 target, no newexpr!
|
if name=="aaa" or name=="zzz" or name=="bbb"
|
||||||
txt.print("name2b fail!\n")
|
txt.print("name2b fail!\n")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user