mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
tweak some not optimizations
cleanup IR typestring
This commit is contained in:
parent
6d9fccacb1
commit
f2daa17b92
@ -66,7 +66,7 @@ class ExpressionSimplifier(private val program: Program,
|
||||
)
|
||||
}
|
||||
if(elsepart.statements.singleOrNull() is Jump) {
|
||||
val invertedCondition = invertCondition(ifElse.condition)
|
||||
val invertedCondition = invertCondition(ifElse.condition, program)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse),
|
||||
IAstModification.InsertAfter(ifElse, truepart, parent as IStatementContainer),
|
||||
@ -323,7 +323,7 @@ class ExpressionSimplifier(private val program: Program,
|
||||
return if (test) {
|
||||
listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
|
||||
} else {
|
||||
listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left), parent))
|
||||
listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left, program), parent))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -334,6 +334,22 @@ class ExpressionSimplifier(private val program: Program,
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(expr: PrefixExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(expr.operator=="not") {
|
||||
// not X <compare> Y -> X <invertedcompare> Y
|
||||
val binExpr = expr.expression as? BinaryExpression
|
||||
if(binExpr!=null) {
|
||||
val invertedOperator = invertedComparisonOperator(binExpr.operator)
|
||||
if(invertedOperator!=null) {
|
||||
val inverted = BinaryExpression(binExpr.left, invertedOperator, binExpr.right, binExpr.position)
|
||||
return listOf(IAstModification.ReplaceNode(expr, inverted, parent))
|
||||
}
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
||||
private fun applyAbsorptionLaws(expr: BinaryExpression): Expression? {
|
||||
val rightB = expr.right as? BinaryExpression
|
||||
if(rightB!=null) {
|
||||
|
@ -120,7 +120,7 @@ class StatementOptimizer(private val program: Program,
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(ifElse.elsepart, newElsePart, ifElse),
|
||||
IAstModification.ReplaceNode(ifElse.truepart, newTruePart, ifElse),
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertCondition(ifElse.condition), ifElse)
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertCondition(ifElse.condition, program), ifElse)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -90,6 +90,14 @@ internal class BoolRemover(val program: Program) : AstWalker() {
|
||||
|
||||
override fun after(expr: PrefixExpression, parent: Node): Iterable<IAstModification> {
|
||||
if(expr.operator=="not") {
|
||||
val binExpr = expr.expression as? BinaryExpression
|
||||
if(binExpr!=null) {
|
||||
val invertedOperator = invertedComparisonOperator(binExpr.operator)
|
||||
if(invertedOperator!=null) {
|
||||
val inverted = BinaryExpression(binExpr.left, invertedOperator, binExpr.right, binExpr.position)
|
||||
return listOf(IAstModification.ReplaceNode(expr, inverted, parent))
|
||||
}
|
||||
}
|
||||
val exprDt = expr.expression.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
|
||||
val nonBoolDt = if(exprDt==DataType.BOOL) DataType.UBYTE else exprDt
|
||||
val equalZero = BinaryExpression(expr.expression, "==", NumericLiteral(nonBoolDt, 0.0, expr.expression.position), expr.expression.position)
|
||||
|
@ -99,7 +99,7 @@ if not CONDITION
|
||||
val replacement = AnonymousScope(mutableListOf(
|
||||
loopLabel,
|
||||
untilLoop.body,
|
||||
IfElse(invertCondition(untilLoop.condition),
|
||||
IfElse(invertCondition(untilLoop.condition, program),
|
||||
AnonymousScope(mutableListOf(program.jumpLabel(loopLabel)), pos),
|
||||
AnonymousScope(mutableListOf(), pos),
|
||||
pos)
|
||||
@ -138,7 +138,7 @@ _after:
|
||||
val afterLabel = program.makeLabel("afterwhile", pos)
|
||||
val replacement = AnonymousScope(mutableListOf(
|
||||
loopLabel,
|
||||
IfElse(invertCondition(whileLoop.condition),
|
||||
IfElse(invertCondition(whileLoop.condition, program),
|
||||
AnonymousScope(mutableListOf(program.jumpLabel(afterLabel)), pos),
|
||||
AnonymousScope(mutableListOf(), pos),
|
||||
pos),
|
||||
|
@ -45,7 +45,7 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
|
||||
|
||||
if(expr.operator=="^" && expr.left.inferType(program) istype DataType.BOOL && expr.right.constValue(program)?.number == 1.0) {
|
||||
// boolean ^ 1 --> not boolean
|
||||
return listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left), parent))
|
||||
return listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left, program), parent))
|
||||
}
|
||||
|
||||
|
||||
@ -121,10 +121,11 @@ internal class NotExpressionAndIfComparisonExprChanger(val program: Program, val
|
||||
}
|
||||
}
|
||||
|
||||
// all other not(x) --> x==0
|
||||
// this means that "not" will never occur anywhere again in the ast after this
|
||||
val replacement = BinaryExpression(expr.expression, "==", NumericLiteral(DataType.UBYTE,0.0, expr.position), expr.position)
|
||||
return listOf(IAstModification.ReplaceNodeSafe(expr, replacement, parent))
|
||||
// not simpleX -> simpleX==0
|
||||
if(expr.expression.isSimple) {
|
||||
val replacement = BinaryExpression(expr.expression.copy(),"==", NumericLiteral(DataType.UBYTE, 0.0, expr.position), expr.position)
|
||||
return listOf(IAstModification.ReplaceNodeSafe(expr, replacement, parent))
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
@ -211,14 +211,12 @@ main {
|
||||
val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!!
|
||||
val stmts = result.compilerAst.entrypoint.statements
|
||||
stmts.size shouldBe 3
|
||||
val value1 = (stmts[1] as Assignment).value as BinaryExpression
|
||||
val value2 = (stmts[2] as Assignment).value as BinaryExpression
|
||||
value1.operator shouldBe "=="
|
||||
value1.left shouldBe instanceOf<ContainmentCheck>()
|
||||
(value1.right as NumericLiteral).number shouldBe 0.0
|
||||
value2.operator shouldBe "=="
|
||||
value2.left shouldBe instanceOf<ContainmentCheck>()
|
||||
(value2.right as NumericLiteral).number shouldBe 0.0
|
||||
val value1 = (stmts[1] as Assignment).value as PrefixExpression
|
||||
val value2 = (stmts[2] as Assignment).value as PrefixExpression
|
||||
value1.operator shouldBe "not"
|
||||
value2.operator shouldBe "not"
|
||||
value1.expression shouldBe instanceOf<ContainmentCheck>()
|
||||
value2.expression shouldBe instanceOf<ContainmentCheck>()
|
||||
}
|
||||
|
||||
test("const pointer variable indexing works") {
|
||||
|
@ -94,8 +94,13 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
|
||||
|
||||
private fun datatypeString(dt: DataType): String {
|
||||
return when (dt) {
|
||||
in NumericDatatypes -> dt.toString().lowercase()
|
||||
DataType.BOOL -> "bool"
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.LONG -> "long"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.STR -> "str"
|
||||
DataType.ARRAY_UB -> "ubyte["
|
||||
DataType.ARRAY_B -> "byte["
|
||||
@ -105,7 +110,7 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
|
||||
DataType.ARRAY_BOOL -> "bool["
|
||||
DataType.ARRAY_UW_SPLIT -> "@split uword["
|
||||
DataType.ARRAY_W_SPLIT -> "@split word["
|
||||
else -> throw IllegalArgumentException("weird dt: $dt")
|
||||
DataType.UNDEFINED -> throw IllegalArgumentException("wrong dt")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1257,12 +1257,15 @@ class BuiltinFunctionCall(override var target: IdentifierReference,
|
||||
override fun inferType(program: Program) = program.builtinFunctions.returnType(name)
|
||||
}
|
||||
|
||||
fun invertCondition(cond: Expression): Expression {
|
||||
fun invertCondition(cond: Expression, program: Program): Expression {
|
||||
if(cond is BinaryExpression) {
|
||||
val invertedOperator = invertedComparisonOperator(cond.operator)
|
||||
if (invertedOperator != null)
|
||||
return BinaryExpression(cond.left, invertedOperator, cond.right, cond.position)
|
||||
}
|
||||
|
||||
return PrefixExpression("not", cond, cond.position)
|
||||
return if(cond.inferType(program).isBool)
|
||||
PrefixExpression("not", cond, cond.position)
|
||||
else
|
||||
BinaryExpression(cond, "==", NumericLiteral(DataType.UBYTE, 0.0, cond.position), cond.position)
|
||||
}
|
||||
|
@ -1,12 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
consolidate the various type-to-string tables, look for: DataType.BOOL -> "bool"
|
||||
|
||||
"all other not(x) --> x==0" SOMETIMES if removed, improves code, sometimes it makes it worse.
|
||||
Find out what is what! (paint)
|
||||
ALSO: when adding a expr.issimple to that, it crashes with a parent node mismatch error. FIX THAT.
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -105,7 +105,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
xml.writeCharacters("\n")
|
||||
xml.writeStartElement("PARAMS")
|
||||
xml.writeCharacters("\n")
|
||||
child.parameters.forEach { param -> xml.writeCharacters("${getTypeString(param.dt)} ${param.name}\n") }
|
||||
child.parameters.forEach { param -> xml.writeCharacters("${param.dt.typeString(null)} ${param.name}\n") }
|
||||
xml.writeEndElement()
|
||||
xml.writeCharacters("\n")
|
||||
child.chunks.forEach { chunk ->
|
||||
|
@ -1,7 +1,10 @@
|
||||
package prog8.intermediate
|
||||
|
||||
import prog8.code.*
|
||||
import prog8.code.core.*
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.Encoding
|
||||
import prog8.code.core.ZeropageWish
|
||||
import prog8.code.core.internedStringsModuleName
|
||||
|
||||
|
||||
// In the Intermediate Representation, all nesting has been removed.
|
||||
@ -163,23 +166,7 @@ class IRStMemVar(name: String,
|
||||
}
|
||||
}
|
||||
|
||||
val typeString: String
|
||||
get() = when (dt) {
|
||||
DataType.BOOL -> "bool"
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.ARRAY_BOOL -> "bool[$length]"
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[$length]"
|
||||
DataType.ARRAY_B -> "byte[$length]"
|
||||
DataType.ARRAY_UW -> "uword[$length]"
|
||||
DataType.ARRAY_W -> "word[$length]"
|
||||
DataType.ARRAY_F -> "float[$length]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("@split can't be used on memory mapped arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
val typeString: String = dt.typeString(length)
|
||||
}
|
||||
|
||||
class IRStMemorySlab(
|
||||
@ -220,23 +207,7 @@ class IRStStaticVariable(name: String,
|
||||
|
||||
val uninitialized = onetimeInitializationArrayValue==null && onetimeInitializationStringValue==null && onetimeInitializationNumericValue==null
|
||||
|
||||
val typeString: String
|
||||
get() = when (dt) {
|
||||
DataType.BOOL -> "bool"
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.ARRAY_BOOL -> "bool[$length]"
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[$length]"
|
||||
DataType.ARRAY_B -> "byte[$length]"
|
||||
DataType.ARRAY_UW -> "uword[$length]"
|
||||
DataType.ARRAY_W -> "word[$length]"
|
||||
DataType.ARRAY_F -> "float[$length]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("split array should have been converted to 2 ubyte arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
val typeString: String = dt.typeString(length)
|
||||
}
|
||||
|
||||
class IRStArrayElement(val number: Double?, val addressOfSymbol: String?) {
|
||||
|
@ -6,21 +6,27 @@ import prog8.code.left
|
||||
import prog8.code.right
|
||||
|
||||
|
||||
fun getTypeString(dt : DataType): String = when(dt) {
|
||||
DataType.BOOL -> "bool"
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.ARRAY_BOOL -> "bool[]"
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[]"
|
||||
DataType.ARRAY_B -> "byte[]"
|
||||
DataType.ARRAY_UW -> "uword[]"
|
||||
DataType.ARRAY_W -> "word[]"
|
||||
DataType.ARRAY_F -> "float[]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("split array should have been converted to 2 ubyte arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
fun DataType.typeString(length: Int?): String {
|
||||
val lengthStr = if(length==0) "" else length.toString()
|
||||
return when (this) {
|
||||
DataType.BOOL -> "bool"
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.LONG -> "long"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.STR -> "ubyte[$lengthStr]" // here string doesn't exist as a seperate datatype anymore
|
||||
DataType.ARRAY_BOOL -> "bool[$lengthStr]"
|
||||
DataType.ARRAY_UB -> "ubyte[$lengthStr]"
|
||||
DataType.ARRAY_B -> "byte[$lengthStr]"
|
||||
DataType.ARRAY_UW -> "uword[$lengthStr]"
|
||||
DataType.ARRAY_W -> "word[$lengthStr]"
|
||||
DataType.ARRAY_F -> "float[$lengthStr]"
|
||||
DataType.ARRAY_UW_SPLIT -> "@split uword[$lengthStr]" // should be 2 separate byte arrays by now really
|
||||
DataType.ARRAY_W_SPLIT -> "@split word[$lengthStr]" // should be 2 separate byte arrays by now really
|
||||
DataType.UNDEFINED -> throw IllegalArgumentException("wrong dt")
|
||||
}
|
||||
}
|
||||
|
||||
fun convertIRType(typestr: String): IRDataType? {
|
||||
|
Loading…
Reference in New Issue
Block a user