mirror of
https://github.com/irmen/prog8.git
synced 2024-08-11 21:29:03 +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.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import io.kotest.matchers.string.shouldContain
|
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.InternalCompilerException
|
||||||
|
import prog8.code.core.Position
|
||||||
import prog8.code.core.toHex
|
import prog8.code.core.toHex
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
import prog8.code.target.cbm.Mflpt5
|
import prog8.code.target.cbm.Mflpt5
|
||||||
|
import prog8.compiler.printProgram
|
||||||
import prog8tests.helpers.ErrorReporterForTests
|
import prog8tests.helpers.ErrorReporterForTests
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
|
|
||||||
@ -180,4 +185,27 @@ class TestNumbers: FunSpec({
|
|||||||
"""
|
"""
|
||||||
compileText(C64Target(), true, src, writeAssembly = false) shouldNotBe null
|
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="""
|
val src="""
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
ubyte @shared z1 = - 1
|
ubyte @shared z1 = - 200
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
val errors = ErrorReporterForTests()
|
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.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"
|
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") {
|
test("test augmented expression asmgen") {
|
||||||
val src = """
|
val src = """
|
||||||
main {
|
main {
|
||||||
|
@ -541,10 +541,18 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
|||||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||||
}
|
}
|
||||||
DataType.BYTE -> {
|
DataType.BYTE -> {
|
||||||
if(targettype== DataType.UBYTE && number >= 0)
|
if(targettype== DataType.UBYTE) {
|
||||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
if(number in -128.0..0.0)
|
||||||
if(targettype== DataType.UWORD && number >= 0)
|
return CastValue(true, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||||
return CastValue(true, NumericLiteral(targettype, number, 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)
|
if(targettype== DataType.WORD)
|
||||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||||
if(targettype== DataType.FLOAT)
|
if(targettype== DataType.FLOAT)
|
||||||
@ -563,10 +571,18 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
|
|||||||
DataType.WORD -> {
|
DataType.WORD -> {
|
||||||
if(targettype== DataType.BYTE && number >= -128 && number <=127)
|
if(targettype== DataType.BYTE && number >= -128 && number <=127)
|
||||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||||
if(targettype== DataType.UBYTE && number >= 0 && number <= 255)
|
if(targettype== DataType.UBYTE) {
|
||||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
if(number in -128.0..0.0)
|
||||||
if(targettype== DataType.UWORD && number >=0)
|
return CastValue(true, NumericLiteral(targettype, number.toInt().toUByte().toDouble(), position))
|
||||||
return CastValue(true, NumericLiteral(targettype, number, 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)
|
if(targettype== DataType.FLOAT)
|
||||||
return CastValue(true, NumericLiteral(targettype, number, position))
|
return CastValue(true, NumericLiteral(targettype, number, position))
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import test_stack
|
;%import test_stack
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
|
|
||||||
|
|
||||||
@ -31,8 +31,16 @@ main {
|
|||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
; mcCarthy()
|
; 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 value = 0
|
||||||
ubyte one = 1
|
ubyte one = 1
|
||||||
@ -93,7 +101,7 @@ main {
|
|||||||
}
|
}
|
||||||
txt.nl()
|
txt.nl()
|
||||||
|
|
||||||
test_stack.test()
|
;test_stack.test()
|
||||||
|
|
||||||
|
|
||||||
; ; a "pixelshader":
|
; ; a "pixelshader":
|
||||||
|
Loading…
Reference in New Issue
Block a user