mirror of
https://github.com/irmen/prog8.git
synced 2025-01-26 19:30:59 +00:00
allow casting negative numbers to unsigned, result = 2's complement
This commit is contained in:
parent
8f1c86f550
commit
031f647952
@ -6,10 +6,15 @@ import io.kotest.matchers.doubles.plusOrMinus
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.InternalCompilerException
|
||||
import prog8.code.core.Position
|
||||
import prog8.code.core.toHex
|
||||
import prog8.code.target.C64Target
|
||||
import prog8.code.target.cbm.Mflpt5
|
||||
import prog8.compiler.printProgram
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
import prog8tests.helpers.compileText
|
||||
|
||||
@ -180,4 +185,27 @@ class TestNumbers: FunSpec({
|
||||
"""
|
||||
compileText(C64Target(), true, src, writeAssembly = false) shouldNotBe null
|
||||
}
|
||||
|
||||
test("signed negative numbers cast to unsigned allowed") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
uword uw1 = -32768
|
||||
uword uw = -1
|
||||
ubyte ub = -1
|
||||
uw = -2 as uword
|
||||
ub = -2 as ubyte
|
||||
}
|
||||
}
|
||||
"""
|
||||
val result = compileText(C64Target(), false, src, writeAssembly = false)!!
|
||||
val statements = result.program.entrypoint.statements
|
||||
statements.size shouldBe 8
|
||||
printProgram(result.program)
|
||||
(statements[1] as Assignment).value shouldBe NumericLiteral(DataType.UWORD, 32768.0, Position.DUMMY)
|
||||
(statements[3] as Assignment).value shouldBe NumericLiteral(DataType.UWORD, 65535.0, Position.DUMMY)
|
||||
(statements[5] as Assignment).value shouldBe NumericLiteral(DataType.UBYTE, 255.0, Position.DUMMY)
|
||||
(statements[6] as Assignment).value shouldBe NumericLiteral(DataType.UWORD, 65534.0, Position.DUMMY)
|
||||
(statements[7] as Assignment).value shouldBe NumericLiteral(DataType.UBYTE, 254.0, Position.DUMMY)
|
||||
}
|
||||
})
|
||||
|
@ -565,17 +565,31 @@ class TestOptimization: FunSpec({
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
ubyte @shared z1 = - 1
|
||||
ubyte @shared z1 = - 200
|
||||
}
|
||||
}
|
||||
"""
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(C64Target(), optimize=true, src, writeAssembly=false, errors = errors) shouldBe null
|
||||
compileText(C64Target(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null
|
||||
errors.errors.size shouldBe 2
|
||||
errors.errors[0] shouldContain "type of value BYTE doesn't match target UBYTE"
|
||||
errors.errors[0] shouldContain "type of value WORD doesn't match target UBYTE"
|
||||
errors.errors[1] shouldContain "out of range"
|
||||
}
|
||||
|
||||
test("out of range cast should give error") {
|
||||
val src="""
|
||||
main {
|
||||
sub start() {
|
||||
ubyte @shared z1 = - 200 as ubyte
|
||||
}
|
||||
}
|
||||
"""
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(C64Target(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null
|
||||
errors.errors.size shouldBe 1
|
||||
errors.errors[0] shouldContain "can't cast"
|
||||
}
|
||||
|
||||
test("test augmented expression asmgen") {
|
||||
val src = """
|
||||
main {
|
||||
|
@ -541,10 +541,18 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
DataType.BYTE -> {
|
||||
if(targettype== DataType.UBYTE && number >= 0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
if(targettype== DataType.UWORD && number >= 0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
if(targettype== DataType.UBYTE) {
|
||||
if(number in -128.0..0.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||
else if(number in 0.0..255.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype== DataType.UWORD) {
|
||||
if(number in -32768.0..0.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number.toInt().toUShort().toDouble(), position))
|
||||
else if(number in 0.0..65535.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype== DataType.WORD)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
if(targettype== DataType.FLOAT)
|
||||
@ -563,10 +571,18 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
||||
DataType.WORD -> {
|
||||
if(targettype== DataType.BYTE && number >= -128 && number <=127)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
if(targettype== DataType.UBYTE && number >= 0 && number <= 255)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
if(targettype== DataType.UWORD && number >=0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
if(targettype== DataType.UBYTE) {
|
||||
if(number in -128.0..0.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||
else if(number in 0.0..255.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype== DataType.UWORD) {
|
||||
if(number in -32768.0 .. 0.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number.toInt().toUShort().toDouble(), position))
|
||||
else if(number in 0.0..65535.0)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
if(targettype== DataType.FLOAT)
|
||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
%import textio
|
||||
%import test_stack
|
||||
;%import test_stack
|
||||
%zeropage basicsafe
|
||||
|
||||
|
||||
@ -31,8 +31,16 @@ main {
|
||||
|
||||
sub start() {
|
||||
; mcCarthy()
|
||||
test_stack.test()
|
||||
uword uw = -2
|
||||
ubyte ub = -2
|
||||
uw = -2 as uword
|
||||
ub = -2 as ubyte
|
||||
txt.print_uw(uw)
|
||||
txt.spc()
|
||||
txt.print_ub(ub)
|
||||
txt.nl()
|
||||
|
||||
;test_stack.test()
|
||||
|
||||
ubyte value = 0
|
||||
ubyte one = 1
|
||||
@ -93,7 +101,7 @@ main {
|
||||
}
|
||||
txt.nl()
|
||||
|
||||
test_stack.test()
|
||||
;test_stack.test()
|
||||
|
||||
|
||||
; ; a "pixelshader":
|
||||
|
Loading…
x
Reference in New Issue
Block a user