mirror of
https://github.com/irmen/prog8.git
synced 2024-09-07 19:54:26 +00:00
improve bool params typecasting, fix compiler crash on abs(floatvar)
This commit is contained in:
parent
ff1fc28287
commit
edf12bec71
@ -23,10 +23,10 @@ enum class DataType {
|
|||||||
when(this) {
|
when(this) {
|
||||||
BOOL -> targetType.oneOf(BOOL, BYTE, UBYTE, WORD, UWORD, FLOAT)
|
BOOL -> targetType.oneOf(BOOL, BYTE, UBYTE, WORD, UWORD, FLOAT)
|
||||||
UBYTE -> targetType.oneOf(UBYTE, WORD, UWORD, FLOAT, BOOL)
|
UBYTE -> targetType.oneOf(UBYTE, WORD, UWORD, FLOAT, BOOL)
|
||||||
BYTE -> targetType.oneOf(BYTE, WORD, FLOAT, BOOL)
|
BYTE -> targetType.oneOf(BYTE, WORD, FLOAT)
|
||||||
UWORD -> targetType.oneOf(UWORD, FLOAT, BOOL)
|
UWORD -> targetType.oneOf(UWORD, FLOAT)
|
||||||
WORD -> targetType.oneOf(WORD, FLOAT, BOOL)
|
WORD -> targetType.oneOf(WORD, FLOAT)
|
||||||
FLOAT -> targetType.oneOf(FLOAT, BOOL)
|
FLOAT -> targetType.oneOf(FLOAT)
|
||||||
STR -> targetType.oneOf(STR, UWORD)
|
STR -> targetType.oneOf(STR, UWORD)
|
||||||
in ArrayDatatypes -> targetType == this
|
in ArrayDatatypes -> targetType == this
|
||||||
else -> false
|
else -> false
|
||||||
@ -115,7 +115,9 @@ enum class BranchCondition {
|
|||||||
val ByteDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.BOOL)
|
val ByteDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.BOOL)
|
||||||
val WordDatatypes = arrayOf(DataType.UWORD, DataType.WORD)
|
val WordDatatypes = arrayOf(DataType.UWORD, DataType.WORD)
|
||||||
val IntegerDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.BOOL)
|
val IntegerDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.BOOL)
|
||||||
|
val IntegerDatatypesNoBool = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD)
|
||||||
val NumericDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT, DataType.BOOL)
|
val NumericDatatypes = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT, DataType.BOOL)
|
||||||
|
val NumericDatatypesNoBool = arrayOf(DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT)
|
||||||
val SignedDatatypes = arrayOf(DataType.BYTE, DataType.WORD, DataType.FLOAT)
|
val SignedDatatypes = arrayOf(DataType.BYTE, DataType.WORD, DataType.FLOAT)
|
||||||
val ArrayDatatypes = arrayOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F, DataType.ARRAY_BOOL)
|
val ArrayDatatypes = arrayOf(DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_F, DataType.ARRAY_BOOL)
|
||||||
val StringlyDatatypes = arrayOf(DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.UWORD)
|
val StringlyDatatypes = arrayOf(DataType.STR, DataType.ARRAY_UB, DataType.ARRAY_B, DataType.UWORD)
|
||||||
|
@ -99,8 +99,9 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(ifElse: IfElse) {
|
override fun visit(ifElse: IfElse) {
|
||||||
if(!ifElse.condition.inferType(program).isInteger)
|
val dt = ifElse.condition.inferType(program)
|
||||||
errors.err("condition value should be an integer type", ifElse.condition.position)
|
if(!dt.isInteger && !dt.istype(DataType.BOOL))
|
||||||
|
errors.err("condition value should be an integer type or bool", ifElse.condition.position)
|
||||||
super.visit(ifElse)
|
super.visit(ifElse)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -435,14 +436,16 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(untilLoop: UntilLoop) {
|
override fun visit(untilLoop: UntilLoop) {
|
||||||
if(!untilLoop.condition.inferType(program).isInteger)
|
val dt = untilLoop.condition.inferType(program)
|
||||||
errors.err("condition value should be an integer type", untilLoop.condition.position)
|
if(!dt.isInteger && !dt.istype(DataType.BOOL))
|
||||||
|
errors.err("condition value should be an integer type or bool", untilLoop.condition.position)
|
||||||
super.visit(untilLoop)
|
super.visit(untilLoop)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(whileLoop: WhileLoop) {
|
override fun visit(whileLoop: WhileLoop) {
|
||||||
if(!whileLoop.condition.inferType(program).isInteger)
|
val dt = whileLoop.condition.inferType(program)
|
||||||
errors.err("condition value should be an integer type", whileLoop.condition.position)
|
if(!dt.isInteger && !dt.istype(DataType.BOOL))
|
||||||
|
errors.err("condition value should be an integer type or bool", whileLoop.condition.position)
|
||||||
super.visit(whileLoop)
|
super.visit(whileLoop)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -891,9 +894,9 @@ internal class AstChecker(private val program: Program,
|
|||||||
"in" -> throw FatalAstException("in expression should have been replaced by containmentcheck")
|
"in" -> throw FatalAstException("in expression should have been replaced by containmentcheck")
|
||||||
}
|
}
|
||||||
|
|
||||||
if(leftDt !in NumericDatatypes && leftDt != DataType.STR)
|
if(leftDt !in NumericDatatypes && leftDt != DataType.STR && leftDt != DataType.BOOL)
|
||||||
errors.err("left operand is not numeric or str", expr.left.position)
|
errors.err("left operand is not numeric or str", expr.left.position)
|
||||||
if(rightDt!in NumericDatatypes && rightDt != DataType.STR)
|
if(rightDt!in NumericDatatypes && rightDt != DataType.STR && rightDt != DataType.BOOL)
|
||||||
errors.err("right operand is not numeric or str", expr.right.position)
|
errors.err("right operand is not numeric or str", expr.right.position)
|
||||||
if(leftDt!=rightDt) {
|
if(leftDt!=rightDt) {
|
||||||
if(leftDt==DataType.STR && rightDt in IntegerDatatypes && expr.operator=="*") {
|
if(leftDt==DataType.STR && rightDt in IntegerDatatypes && expr.operator=="*") {
|
||||||
|
@ -93,6 +93,8 @@ internal class BoolRemover(val program: Program) : AstWalker() {
|
|||||||
fun isBoolean(expr: Expression): Boolean {
|
fun isBoolean(expr: Expression): Boolean {
|
||||||
return if(expr.inferType(program) istype DataType.BOOL)
|
return if(expr.inferType(program) istype DataType.BOOL)
|
||||||
true
|
true
|
||||||
|
else if(expr is NumericLiteral && expr.type in IntegerDatatypes && (expr.number==0.0 || expr.number==1.0))
|
||||||
|
true
|
||||||
else if(expr is BinaryExpression && expr.operator in ComparisonOperators + LogicalOperators)
|
else if(expr is BinaryExpression && expr.operator in ComparisonOperators + LogicalOperators)
|
||||||
true
|
true
|
||||||
else if(expr is PrefixExpression && expr.operator == "not")
|
else if(expr is PrefixExpression && expr.operator == "not")
|
||||||
|
@ -43,20 +43,24 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(expr: BinaryExpression, parent: Node): Iterable<IAstModification> {
|
||||||
val leftDt = expr.left.inferType(program)
|
val leftDt = expr.left.inferType(program)
|
||||||
val rightDt = expr.right.inferType(program)
|
val rightDt = expr.right.inferType(program)
|
||||||
|
val leftCv = expr.left.constValue(program)
|
||||||
|
val rightCv = expr.right.constValue(program)
|
||||||
|
|
||||||
if(leftDt.isKnown && rightDt.isKnown && leftDt!=rightDt) {
|
if(leftDt.isKnown && rightDt.isKnown && leftDt!=rightDt) {
|
||||||
|
|
||||||
// convert bool type to byte
|
// convert bool type to byte if needed
|
||||||
if(leftDt istype DataType.BOOL && rightDt.isBytes) {
|
if(leftDt istype DataType.BOOL && rightDt.isBytes && !rightDt.istype(DataType.BOOL)) {
|
||||||
|
if(rightCv==null || (rightCv.number!=1.0 && rightCv.number!=0.0))
|
||||||
return listOf(IAstModification.ReplaceNode(expr.left,
|
return listOf(IAstModification.ReplaceNode(expr.left,
|
||||||
TypecastExpression(expr.left, rightDt.getOr(DataType.UNDEFINED),true, expr.left.position), expr))
|
TypecastExpression(expr.left, rightDt.getOr(DataType.UNDEFINED),true, expr.left.position), expr))
|
||||||
} else if(leftDt.isBytes && rightDt istype DataType.BOOL) {
|
} else if(leftDt.isBytes && !leftDt.istype(DataType.BOOL) && rightDt istype DataType.BOOL) {
|
||||||
|
if(leftCv==null || (leftCv.number!=1.0 && leftCv.number!=0.0))
|
||||||
return listOf(IAstModification.ReplaceNode(expr.right,
|
return listOf(IAstModification.ReplaceNode(expr.right,
|
||||||
TypecastExpression(expr.right, leftDt.getOr(DataType.UNDEFINED),true, expr.right.position), expr))
|
TypecastExpression(expr.right, leftDt.getOr(DataType.UNDEFINED),true, expr.right.position), expr))
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert a negative operand for bitwise operator to the 2's complement positive number instead
|
// convert a negative operand for bitwise operator to the 2's complement positive number instead
|
||||||
if(expr.operator in BitwiseOperators && leftDt.isInteger && rightDt.isInteger) {
|
if(expr.operator in BitwiseOperators && leftDt.isInteger && rightDt.isInteger) {
|
||||||
val leftCv = expr.left.constValue(program)
|
|
||||||
if(leftCv!=null && leftCv.number<0) {
|
if(leftCv!=null && leftCv.number<0) {
|
||||||
val value = if(rightDt.isBytes) 256+leftCv.number else 65536+leftCv.number
|
val value = if(rightDt.isBytes) 256+leftCv.number else 65536+leftCv.number
|
||||||
return listOf(IAstModification.ReplaceNode(
|
return listOf(IAstModification.ReplaceNode(
|
||||||
@ -64,7 +68,6 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
NumericLiteral(rightDt.getOr(DataType.UNDEFINED), value, expr.left.position),
|
NumericLiteral(rightDt.getOr(DataType.UNDEFINED), value, expr.left.position),
|
||||||
expr))
|
expr))
|
||||||
}
|
}
|
||||||
val rightCv = expr.right.constValue(program)
|
|
||||||
if(rightCv!=null && rightCv.number<0) {
|
if(rightCv!=null && rightCv.number<0) {
|
||||||
val value = if(leftDt.isBytes) 256+rightCv.number else 65536+rightCv.number
|
val value = if(leftDt.isBytes) 256+rightCv.number else 65536+rightCv.number
|
||||||
return listOf(IAstModification.ReplaceNode(
|
return listOf(IAstModification.ReplaceNode(
|
||||||
@ -203,6 +206,9 @@ class TypecastsAdder(val program: Program, val options: CompilationOptions, val
|
|||||||
arg,
|
arg,
|
||||||
cast.valueOrZero(),
|
cast.valueOrZero(),
|
||||||
call as Node)
|
call as Node)
|
||||||
|
} else if(requiredType==DataType.BOOL && argtype!=DataType.BOOL) {
|
||||||
|
// cast to bool
|
||||||
|
addTypecastOrCastedValueModification(modifications, arg, requiredType, call as Node)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,8 @@ import io.kotest.core.spec.style.FunSpec
|
|||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.DataType
|
||||||
import prog8.code.core.NumericDatatypes
|
import prog8.code.core.NumericDatatypesNoBool
|
||||||
import prog8.code.core.RegisterOrPair
|
import prog8.code.core.RegisterOrPair
|
||||||
import prog8.code.target.C64Target
|
|
||||||
import prog8.code.target.Cx16Target
|
import prog8.code.target.Cx16Target
|
||||||
import prog8.compiler.BuiltinFunctions
|
import prog8.compiler.BuiltinFunctions
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
@ -31,7 +30,7 @@ class TestBuiltinFunctions: FunSpec({
|
|||||||
func.name shouldBe "sgn"
|
func.name shouldBe "sgn"
|
||||||
func.parameters.size shouldBe 1
|
func.parameters.size shouldBe 1
|
||||||
func.parameters[0].name shouldBe "value"
|
func.parameters[0].name shouldBe "value"
|
||||||
func.parameters[0].possibleDatatypes shouldBe NumericDatatypes
|
func.parameters[0].possibleDatatypes shouldBe NumericDatatypesNoBool
|
||||||
func.pure shouldBe true
|
func.pure shouldBe true
|
||||||
func.returnType shouldBe DataType.BYTE
|
func.returnType shouldBe DataType.BYTE
|
||||||
|
|
||||||
|
@ -20,6 +20,51 @@ import prog8tests.helpers.compileText
|
|||||||
|
|
||||||
|
|
||||||
class TestTypecasts: FunSpec({
|
class TestTypecasts: FunSpec({
|
||||||
|
|
||||||
|
test("integer args for builtin funcs") {
|
||||||
|
val text="""
|
||||||
|
%import floats
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
float fl
|
||||||
|
floats.print_f(abs(fl))
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
val result = compileText(VMTarget(), false, text, writeAssembly = false, errors=errors)
|
||||||
|
result shouldBe null
|
||||||
|
errors.errors.size shouldBe 1
|
||||||
|
errors.errors[0] shouldContain "type mismatch, was: FLOAT expected one of: [UBYTE, BYTE, UWORD, WORD]"
|
||||||
|
}
|
||||||
|
|
||||||
|
test("not casting bool operands to logical operators") {
|
||||||
|
val text="""
|
||||||
|
%import textio
|
||||||
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
bool bb2=true
|
||||||
|
bool @shared bb = bb2 and true
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val result = compileText(C64Target(), false, text, writeAssembly = false)!!
|
||||||
|
val stmts = result.program.entrypoint.statements
|
||||||
|
stmts.size shouldBe 4
|
||||||
|
val expr = (stmts[3] as Assignment).value as BinaryExpression
|
||||||
|
expr.operator shouldBe "and"
|
||||||
|
expr.right shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY)
|
||||||
|
(expr.left as IdentifierReference).nameInSource shouldBe listOf("bb2") // no cast
|
||||||
|
|
||||||
|
val result2 = compileText(C64Target(), true, text, writeAssembly = true)!!
|
||||||
|
val stmts2 = result2.program.entrypoint.statements
|
||||||
|
stmts2.size shouldBe 6
|
||||||
|
val expr2 = (stmts2[4] as Assignment).value as BinaryExpression
|
||||||
|
expr2.operator shouldBe "&"
|
||||||
|
expr2.right shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY)
|
||||||
|
(expr2.left as IdentifierReference).nameInSource shouldBe listOf("bb")
|
||||||
|
}
|
||||||
|
|
||||||
test("bool expressions with functioncalls") {
|
test("bool expressions with functioncalls") {
|
||||||
val text="""
|
val text="""
|
||||||
main {
|
main {
|
||||||
@ -50,7 +95,7 @@ main {
|
|||||||
ubyte ub3
|
ubyte ub3
|
||||||
ub3 = 1
|
ub3 = 1
|
||||||
ubyte @shared bvalue
|
ubyte @shared bvalue
|
||||||
bvalue = (((ub1^ub2)^ub3)^(1!=0))
|
bvalue = (((ub1^ub2)^ub3)^1)
|
||||||
bvalue = (((ub1^ub2)^ub3)^(ftrue(99)!=0))
|
bvalue = (((ub1^ub2)^ub3)^(ftrue(99)!=0))
|
||||||
bvalue = ((ub1&ub2)&(ftrue(99)!=0))
|
bvalue = ((ub1&ub2)&(ftrue(99)!=0))
|
||||||
return
|
return
|
||||||
@ -62,14 +107,12 @@ main {
|
|||||||
assignValue1.operator shouldBe "^"
|
assignValue1.operator shouldBe "^"
|
||||||
assignValue2.operator shouldBe "^"
|
assignValue2.operator shouldBe "^"
|
||||||
assignValue3.operator shouldBe "&"
|
assignValue3.operator shouldBe "&"
|
||||||
val right1 = assignValue1.right as BinaryExpression
|
val right1 = assignValue1.right as NumericLiteral
|
||||||
val right2 = assignValue2.right as BinaryExpression
|
val right2 = assignValue2.right as BinaryExpression
|
||||||
val right3 = assignValue3.right as BinaryExpression
|
val right3 = assignValue3.right as BinaryExpression
|
||||||
right1.operator shouldBe "!="
|
right1.number shouldBe 1.0
|
||||||
right2.operator shouldBe "!="
|
right2.operator shouldBe "!="
|
||||||
right3.operator shouldBe "!="
|
right3.operator shouldBe "!="
|
||||||
right1.left shouldBe NumericLiteral(DataType.UBYTE, 1.0, Position.DUMMY)
|
|
||||||
right1.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
|
||||||
right2.left shouldBe instanceOf<IFunctionCall>()
|
right2.left shouldBe instanceOf<IFunctionCall>()
|
||||||
right2.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
right2.right shouldBe NumericLiteral(DataType.UBYTE, 0.0, Position.DUMMY)
|
||||||
right3.left shouldBe instanceOf<IFunctionCall>()
|
right3.left shouldBe instanceOf<IFunctionCall>()
|
||||||
|
@ -94,12 +94,12 @@ private val functionSignatures: List<FSignature> = listOf(
|
|||||||
FSignature("sort" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
FSignature("sort" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
||||||
FSignature("reverse" , false, listOf(FParam("array", ArrayDatatypes)), null),
|
FSignature("reverse" , 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
|
||||||
FSignature("cmp" , false, listOf(FParam("value1", IntegerDatatypes), FParam("value2", NumericDatatypes)), null),
|
FSignature("cmp" , false, listOf(FParam("value1", IntegerDatatypesNoBool), FParam("value2", NumericDatatypesNoBool)), null),
|
||||||
FSignature("abs" , true, listOf(FParam("value", IntegerDatatypes)), DataType.UWORD, ::builtinAbs),
|
FSignature("abs" , true, listOf(FParam("value", IntegerDatatypesNoBool)), DataType.UWORD, ::builtinAbs),
|
||||||
FSignature("len" , true, listOf(FParam("values", IterableDatatypes)), DataType.UWORD, ::builtinLen),
|
FSignature("len" , true, listOf(FParam("values", IterableDatatypes)), DataType.UWORD, ::builtinLen),
|
||||||
// normal functions follow:
|
// normal functions follow:
|
||||||
FSignature("sizeof" , true, listOf(FParam("object", DataType.values())), DataType.UBYTE, ::builtinSizeof),
|
FSignature("sizeof" , true, listOf(FParam("object", DataType.values())), DataType.UBYTE, ::builtinSizeof),
|
||||||
FSignature("sgn" , true, listOf(FParam("value", NumericDatatypes)), DataType.BYTE, ::builtinSgn ),
|
FSignature("sgn" , true, listOf(FParam("value", NumericDatatypesNoBool)), DataType.BYTE, ::builtinSgn ),
|
||||||
FSignature("sqrt16" , true, listOf(FParam("value", arrayOf(DataType.UWORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { sqrt(it.toDouble()) } },
|
FSignature("sqrt16" , true, listOf(FParam("value", arrayOf(DataType.UWORD))), DataType.UBYTE) { a, p, prg -> oneIntArgOutputInt(a, p, prg) { sqrt(it.toDouble()) } },
|
||||||
FSignature("any" , true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAny) },
|
FSignature("any" , true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAny) },
|
||||||
FSignature("all" , true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAll) },
|
FSignature("all" , true, listOf(FParam("values", ArrayDatatypes)), DataType.UBYTE) { a, p, prg -> collectionArg(a, p, prg, ::builtinAll) },
|
||||||
@ -178,7 +178,7 @@ private fun builtinAbs(args: List<Expression>, position: Position, program: Prog
|
|||||||
|
|
||||||
val constval = args[0].constValue(program) ?: throw NotConstArgumentException()
|
val constval = args[0].constValue(program) ?: throw NotConstArgumentException()
|
||||||
return when (constval.type) {
|
return when (constval.type) {
|
||||||
in IntegerDatatypes -> NumericLiteral.optimalInteger(abs(constval.number.toInt()), args[0].position)
|
in IntegerDatatypesNoBool -> NumericLiteral.optimalInteger(abs(constval.number.toInt()), args[0].position)
|
||||||
else -> throw SyntaxError("abs requires one integer argument", position)
|
else -> throw SyntaxError("abs requires one integer argument", position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- fix compiler crash (abs(fl)) ; WHY IS THIS GETTING A BOOLEAN CAST???
|
- bool @shared bb = bb2 and true should not add typecast around bb2
|
||||||
- vm why is bb = bb2 and true generating so large code?
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,13 +1,10 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import floats
|
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
float fl
|
bool bb2=true
|
||||||
fl = -3.14
|
bool @shared bb = bb2 and true
|
||||||
floats.print_f(abs(fl)) ; WHY IS THIS GETTING A BOOLEAN CAST???
|
txt.print_ub(bb)
|
||||||
txt.nl()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user