mirror of
https://github.com/irmen/prog8.git
synced 2025-01-10 20:30:23 +00:00
boolean not expression tweaks and optimizations
This commit is contained in:
parent
37638e7ed0
commit
6d9fccacb1
@ -18,7 +18,7 @@ class AtariTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> machine.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
else -> throw IllegalArgumentException("invalid datatype")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ class VMTarget: ICompilationTarget, IStringEncoding by Encoder, IMemSizer {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> machine.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
else -> throw IllegalArgumentException("invalid datatype")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9,7 +9,7 @@ internal object CbmMemorySizer: IMemSizer {
|
||||
in ByteDatatypes -> 1
|
||||
in WordDatatypes, in PassByReferenceDatatypes -> 2
|
||||
DataType.FLOAT -> Mflpt5.FLOAT_MEM_SIZE
|
||||
else -> Int.MIN_VALUE
|
||||
else -> throw IllegalArgumentException("invalid datatype")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -67,14 +67,12 @@ class ExpressionSimplifier(private val program: Program,
|
||||
}
|
||||
if(elsepart.statements.singleOrNull() is Jump) {
|
||||
val invertedCondition = invertCondition(ifElse.condition)
|
||||
if(invertedCondition!=null) {
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse),
|
||||
IAstModification.InsertAfter(ifElse, truepart, parent as IStatementContainer),
|
||||
IAstModification.ReplaceNode(elsepart, AnonymousScope(mutableListOf(), elsepart.position), ifElse),
|
||||
IAstModification.ReplaceNode(truepart, elsepart, ifElse)
|
||||
)
|
||||
}
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse),
|
||||
IAstModification.InsertAfter(ifElse, truepart, parent as IStatementContainer),
|
||||
IAstModification.ReplaceNode(elsepart, AnonymousScope(mutableListOf(), elsepart.position), ifElse),
|
||||
IAstModification.ReplaceNode(truepart, elsepart, ifElse)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,23 +317,13 @@ class ExpressionSimplifier(private val program: Program,
|
||||
}
|
||||
|
||||
if(rightVal!=null && leftDt==DataType.BOOL) {
|
||||
// see if we can replace comparison against true/1 with simpler comparison against zero
|
||||
if (expr.operator == "==") {
|
||||
if (rightVal.number == 1.0) {
|
||||
val zero = NumericLiteral(DataType.UBYTE, 0.0, expr.right.position)
|
||||
return listOf(
|
||||
IAstModification.SetExpression({expr.operator="!="}, expr, parent),
|
||||
IAstModification.ReplaceNode(expr.right, zero, expr)
|
||||
)
|
||||
}
|
||||
}
|
||||
if (expr.operator == "!=") {
|
||||
if (rightVal.number == 1.0) {
|
||||
val zero = NumericLiteral(DataType.UBYTE, 0.0, expr.right.position)
|
||||
return listOf(
|
||||
IAstModification.SetExpression({expr.operator="=="}, expr, parent),
|
||||
IAstModification.ReplaceNode(expr.right, zero, expr)
|
||||
)
|
||||
// boolean compare against a number -> just keep the boolean, no compare
|
||||
if(expr.operator=="==" || expr.operator=="!=") {
|
||||
val test = if (expr.operator == "==") rightVal.asBooleanValue else !rightVal.asBooleanValue
|
||||
return if (test) {
|
||||
listOf(IAstModification.ReplaceNode(expr, expr.left, parent))
|
||||
} else {
|
||||
listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left), parent))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -117,11 +117,10 @@ class StatementOptimizer(private val program: Program,
|
||||
if(jump is Jump) {
|
||||
val newTruePart = AnonymousScope(mutableListOf(jump), ifElse.elsepart.position)
|
||||
val newElsePart = AnonymousScope(ifElse.truepart.statements, ifElse.truepart.position)
|
||||
val invertedCondition = PrefixExpression("not", ifElse.condition, ifElse.condition.position)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(ifElse.elsepart, newElsePart, ifElse),
|
||||
IAstModification.ReplaceNode(ifElse.truepart, newTruePart, ifElse),
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertedCondition, ifElse)
|
||||
IAstModification.ReplaceNode(ifElse.condition, invertCondition(ifElse.condition), ifElse)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -91,17 +91,15 @@ do { STUFF } until CONDITION
|
||||
===>
|
||||
_loop:
|
||||
STUFF
|
||||
if CONDITION==0
|
||||
if not CONDITION
|
||||
goto _loop
|
||||
*/
|
||||
val pos = untilLoop.position
|
||||
val loopLabel = program.makeLabel("untilloop", pos)
|
||||
val ifCondition = invertCondition(untilLoop.condition)
|
||||
?: BinaryExpression(untilLoop.condition, "==", NumericLiteral(DataType.UBYTE, 0.0, pos), pos)
|
||||
val replacement = AnonymousScope(mutableListOf(
|
||||
loopLabel,
|
||||
untilLoop.body,
|
||||
IfElse(ifCondition,
|
||||
IfElse(invertCondition(untilLoop.condition),
|
||||
AnonymousScope(mutableListOf(program.jumpLabel(loopLabel)), pos),
|
||||
AnonymousScope(mutableListOf(), pos),
|
||||
pos)
|
||||
@ -130,7 +128,7 @@ if CONDITION==0
|
||||
while CONDITION { STUFF }
|
||||
==>
|
||||
_whileloop:
|
||||
if INVERTED-CONDITION goto _after
|
||||
if not CONDITION goto _after
|
||||
STUFF
|
||||
goto _whileloop
|
||||
_after:
|
||||
@ -138,11 +136,9 @@ _after:
|
||||
val pos = whileLoop.position
|
||||
val loopLabel = program.makeLabel("whileloop", pos)
|
||||
val afterLabel = program.makeLabel("afterwhile", pos)
|
||||
val ifCondition = invertCondition(whileLoop.condition)
|
||||
?: BinaryExpression(whileLoop.condition, "==", NumericLiteral(DataType.UBYTE, 0.0, pos), pos)
|
||||
val replacement = AnonymousScope(mutableListOf(
|
||||
loopLabel,
|
||||
IfElse(ifCondition,
|
||||
IfElse(invertCondition(whileLoop.condition),
|
||||
AnonymousScope(mutableListOf(program.jumpLabel(afterLabel)), pos),
|
||||
AnonymousScope(mutableListOf(), pos),
|
||||
pos),
|
||||
|
@ -6,6 +6,7 @@ import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.expressions.BinaryExpression
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.expressions.PrefixExpression
|
||||
import prog8.ast.expressions.invertCondition
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.DataType
|
||||
@ -44,8 +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
|
||||
val notExpr = PrefixExpression("not", expr.left, expr.position)
|
||||
return listOf(IAstModification.ReplaceNode(expr, notExpr, parent))
|
||||
return listOf(IAstModification.ReplaceNode(expr, invertCondition(expr.left), parent))
|
||||
}
|
||||
|
||||
|
||||
|
@ -987,22 +987,18 @@ main {
|
||||
val result = compileText(Cx16Target(), true, src, writeAssembly = false)!!
|
||||
val st = result.compilerAst.entrypoint.statements
|
||||
st.size shouldBe 8
|
||||
val if1c = (st[4] as IfElse).condition as BinaryExpression
|
||||
val if2c = (st[5] as IfElse).condition as BinaryExpression
|
||||
val if3c = (st[6] as IfElse).condition as BinaryExpression
|
||||
val if4c = (st[7] as IfElse).condition as BinaryExpression
|
||||
if1c.operator shouldBe "=="
|
||||
(if1c.right as NumericLiteral).number shouldBe 0.0
|
||||
(if1c.left as BinaryExpression).operator shouldBe "or"
|
||||
if2c.operator shouldBe "=="
|
||||
(if2c.right as NumericLiteral).number shouldBe 0.0
|
||||
(if2c.left as BinaryExpression).operator shouldBe "and"
|
||||
if3c.operator shouldBe "=="
|
||||
(if3c.right as NumericLiteral).number shouldBe 0.0
|
||||
(if3c.left as BinaryExpression).operator shouldBe "and"
|
||||
if4c.operator shouldBe "=="
|
||||
(if4c.right as NumericLiteral).number shouldBe 0.0
|
||||
(if4c.left as BinaryExpression).operator shouldBe "or"
|
||||
val if1c = (st[4] as IfElse).condition as PrefixExpression
|
||||
val if2c = (st[5] as IfElse).condition as PrefixExpression
|
||||
val if3c = (st[6] as IfElse).condition as PrefixExpression
|
||||
val if4c = (st[7] as IfElse).condition as PrefixExpression
|
||||
if1c.operator shouldBe "not"
|
||||
if2c.operator shouldBe "not"
|
||||
if3c.operator shouldBe "not"
|
||||
if4c.operator shouldBe "not"
|
||||
(if1c.expression as BinaryExpression).operator shouldBe "or"
|
||||
(if2c.expression as BinaryExpression).operator shouldBe "and"
|
||||
(if3c.expression as BinaryExpression).operator shouldBe "and"
|
||||
(if4c.expression as BinaryExpression).operator shouldBe "or"
|
||||
}
|
||||
|
||||
test("absorption laws") {
|
||||
|
@ -475,17 +475,17 @@ main {
|
||||
st.size shouldBe 7
|
||||
|
||||
val ifCond = (st[4] as IfElse).condition as BinaryExpression
|
||||
ifCond.operator shouldBe "=="
|
||||
(ifCond.right as NumericLiteral).number shouldBe 0.0
|
||||
(ifCond.left as BinaryExpression).operator shouldBe "<"
|
||||
ifCond.operator shouldBe ">="
|
||||
(ifCond.left as IdentifierReference).nameInSource shouldBe listOf("n")
|
||||
(ifCond.right as IdentifierReference).nameInSource shouldBe listOf("x")
|
||||
val assign1 = (st[5] as Assignment).value as BinaryExpression
|
||||
val assign2 = (st[6] as Assignment).value as BinaryExpression
|
||||
assign1.operator shouldBe "=="
|
||||
(assign1.right as NumericLiteral).number shouldBe 0.0
|
||||
(assign1.left as BinaryExpression).operator shouldBe "<"
|
||||
assign2.operator shouldBe "=="
|
||||
(assign2.right as NumericLiteral).number shouldBe 0.0
|
||||
(assign2.left as BinaryExpression).operator shouldBe "<"
|
||||
assign1.operator shouldBe ">="
|
||||
(assign1.left as IdentifierReference).nameInSource shouldBe listOf("n")
|
||||
(assign1.right as IdentifierReference).nameInSource shouldBe listOf("x")
|
||||
assign2.operator shouldBe ">="
|
||||
(assign1.left as IdentifierReference).nameInSource shouldBe listOf("n")
|
||||
(assign1.right as IdentifierReference).nameInSource shouldBe listOf("x")
|
||||
}
|
||||
|
||||
test("modulo is not directive") {
|
||||
|
@ -95,7 +95,8 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
|
||||
private fun datatypeString(dt: DataType): String {
|
||||
return when (dt) {
|
||||
in NumericDatatypes -> dt.toString().lowercase()
|
||||
DataType.STR -> dt.toString().lowercase()
|
||||
DataType.BOOL -> "bool"
|
||||
DataType.STR -> "str"
|
||||
DataType.ARRAY_UB -> "ubyte["
|
||||
DataType.ARRAY_B -> "byte["
|
||||
DataType.ARRAY_UW -> "uword["
|
||||
|
@ -226,10 +226,10 @@ class BinaryExpression(
|
||||
}
|
||||
}
|
||||
"&", "|", "^" -> if(leftDt istype DataType.BOOL) InferredTypes.knownFor(DataType.UBYTE) else leftDt
|
||||
"and", "or", "xor", "not" -> InferredTypes.knownFor(DataType.BOOL)
|
||||
"and", "or", "xor", "not", "in", "not in",
|
||||
"<", ">",
|
||||
"<=", ">=",
|
||||
"==", "!=", "in", "not in" -> InferredTypes.knownFor(DataType.BOOL)
|
||||
"==", "!=" -> InferredTypes.knownFor(DataType.BOOL)
|
||||
"<<", ">>" -> leftDt
|
||||
else -> throw FatalAstException("resulting datatype check for invalid operator $operator")
|
||||
}
|
||||
@ -550,137 +550,137 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
||||
|
||||
operator fun compareTo(other: NumericLiteral): Int = number.compareTo(other.number)
|
||||
|
||||
class CastValue(val isValid: Boolean, val whyFailed: String?, private val value: NumericLiteral?) {
|
||||
class ValueAfterCast(val isValid: Boolean, val whyFailed: String?, private val value: NumericLiteral?) {
|
||||
fun valueOrZero() = if(isValid) value!! else NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||
fun linkParent(parent: Node) {
|
||||
value?.linkParents(parent)
|
||||
}
|
||||
}
|
||||
|
||||
fun cast(targettype: DataType): CastValue {
|
||||
fun cast(targettype: DataType): ValueAfterCast {
|
||||
val result = internalCast(targettype)
|
||||
result.linkParent(this.parent)
|
||||
return result
|
||||
}
|
||||
|
||||
private fun internalCast(targettype: DataType): CastValue {
|
||||
private fun internalCast(targettype: DataType): ValueAfterCast {
|
||||
if(type==targettype)
|
||||
return CastValue(true, null, this)
|
||||
return ValueAfterCast(true, null, this)
|
||||
when(type) {
|
||||
DataType.UBYTE -> {
|
||||
if(targettype==DataType.BYTE)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number.toInt().toByte().toDouble(), position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number.toInt().toByte().toDouble(), position))
|
||||
if(targettype==DataType.WORD || targettype==DataType.UWORD)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.FLOAT)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.LONG)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.BOOL)
|
||||
return CastValue(true, null, fromBoolean(number!=0.0, position))
|
||||
return ValueAfterCast(true, null, fromBoolean(number!=0.0, position))
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
if(targettype==DataType.UBYTE) {
|
||||
if(number in -128.0..0.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||
else if(number in 0.0..255.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype==DataType.UWORD) {
|
||||
if(number in -32768.0..0.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number.toInt().toUShort().toDouble(), position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number.toInt().toUShort().toDouble(), position))
|
||||
else if(number in 0.0..65535.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype==DataType.WORD)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.FLOAT)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.BOOL)
|
||||
return CastValue(true, null, fromBoolean(number!=0.0, position))
|
||||
return ValueAfterCast(true, null, fromBoolean(number!=0.0, position))
|
||||
if(targettype==DataType.LONG)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
DataType.UWORD -> {
|
||||
if(targettype==DataType.BYTE && number <= 127)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.UBYTE && number <= 255)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.WORD)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number.toInt().toShort().toDouble(), position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number.toInt().toShort().toDouble(), position))
|
||||
if(targettype==DataType.FLOAT)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.BOOL)
|
||||
return CastValue(true, null, fromBoolean(number!=0.0, position))
|
||||
return ValueAfterCast(true, null, fromBoolean(number!=0.0, position))
|
||||
if(targettype==DataType.LONG)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
DataType.WORD -> {
|
||||
if(targettype==DataType.BYTE && number >= -128 && number <=127)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.UBYTE) {
|
||||
if(number in -128.0..0.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||
else if(number in 0.0..255.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype==DataType.UWORD) {
|
||||
if(number in -32768.0 .. 0.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number.toInt().toUShort().toDouble(), position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number.toInt().toUShort().toDouble(), position))
|
||||
else if(number in 0.0..65535.0)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype==DataType.FLOAT)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.BOOL)
|
||||
return CastValue(true, null, fromBoolean(number!=0.0, position))
|
||||
return ValueAfterCast(true, null, fromBoolean(number!=0.0, position))
|
||||
if(targettype==DataType.LONG)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
DataType.FLOAT -> {
|
||||
try {
|
||||
if (targettype == DataType.BYTE && number >= -128 && number <= 127)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if (targettype == DataType.UBYTE && number >= 0 && number <= 255)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if (targettype == DataType.WORD && number >= -32768 && number <= 32767)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if (targettype == DataType.UWORD && number >= 0 && number <= 65535)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.LONG && number >=0 && number <= 2147483647)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.BOOL)
|
||||
return CastValue(true, null, fromBoolean(number!=0.0, position))
|
||||
return ValueAfterCast(true, null, fromBoolean(number!=0.0, position))
|
||||
} catch (x: ExpressionError) {
|
||||
return CastValue(false, x.message,null)
|
||||
return ValueAfterCast(false, x.message,null)
|
||||
}
|
||||
}
|
||||
DataType.BOOL -> {
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
DataType.LONG -> {
|
||||
try {
|
||||
if (targettype == DataType.BYTE && number >= -128 && number <= 127)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if (targettype == DataType.UBYTE && number >= 0 && number <= 255)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if (targettype == DataType.WORD && number >= -32768 && number <= 32767)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if (targettype == DataType.UWORD && number >= 0 && number <= 65535)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
if(targettype==DataType.BOOL)
|
||||
return CastValue(true, null, fromBoolean(number!=0.0, position))
|
||||
return ValueAfterCast(true, null, fromBoolean(number!=0.0, position))
|
||||
if(targettype==DataType.FLOAT)
|
||||
return CastValue(true, null, NumericLiteral(targettype, number, position))
|
||||
return ValueAfterCast(true, null, NumericLiteral(targettype, number, position))
|
||||
} catch (x: ExpressionError) {
|
||||
return CastValue(false, x.message, null)
|
||||
return ValueAfterCast(false, x.message, null)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
throw FatalAstException("type cast of weird type $type")
|
||||
}
|
||||
}
|
||||
return CastValue(false, "no cast available between these types", null)
|
||||
return ValueAfterCast(false, "no cast available between these types", null)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1257,11 +1257,12 @@ class BuiltinFunctionCall(override var target: IdentifierReference,
|
||||
override fun inferType(program: Program) = program.builtinFunctions.returnType(name)
|
||||
}
|
||||
|
||||
fun invertCondition(cond: Expression): BinaryExpression? {
|
||||
fun invertCondition(cond: Expression): Expression {
|
||||
if(cond is BinaryExpression) {
|
||||
val invertedOperator = invertedComparisonOperator(cond.operator)
|
||||
if (invertedOperator != null)
|
||||
return BinaryExpression(cond.left, invertedOperator, cond.right, cond.position)
|
||||
}
|
||||
return null
|
||||
|
||||
return PrefixExpression("not", cond, cond.position)
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
[on branch 'booleans']: keep Bool alive longer until codegen? (don't replace by UBYTE so quickly?)
|
||||
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.
|
||||
|
||||
...
|
||||
|
||||
|
@ -683,7 +683,13 @@ class FunctionCallArgs(
|
||||
val returns: RegSpec?
|
||||
) {
|
||||
class RegSpec(val dt: IRDataType, val registerNum: Int, val cpuRegister: RegisterOrStatusflag?)
|
||||
class ArgumentSpec(val name: String, val address: Int?, val reg: RegSpec)
|
||||
class ArgumentSpec(val name: String, val address: Int?, val reg: RegSpec) {
|
||||
init {
|
||||
require(address==null || address>=0) {
|
||||
"address must be >=0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data class IRInstruction(
|
||||
@ -759,6 +765,9 @@ data class IRInstruction(
|
||||
else
|
||||
require(immediate != null || immediateFp != null) { "missing immediate value" }
|
||||
}
|
||||
require(address==null || address>=0) {
|
||||
"address must be >=0"
|
||||
}
|
||||
|
||||
reg1direction = format.reg1
|
||||
reg2direction = format.reg2
|
||||
|
@ -165,17 +165,18 @@ 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.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
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}]"
|
||||
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")
|
||||
}
|
||||
@ -221,17 +222,18 @@ class IRStStaticVariable(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.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
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}]"
|
||||
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")
|
||||
}
|
||||
|
@ -7,12 +7,13 @@ 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.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
DataType.ARRAY_BOOL -> "bool[]"
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[]"
|
||||
DataType.ARRAY_B -> "byte[]"
|
||||
DataType.ARRAY_UW -> "uword[]"
|
||||
|
Loading…
x
Reference in New Issue
Block a user