mirror of
https://github.com/KarolS/millfork.git
synced 2025-02-24 10:28:57 +00:00
Allow casting to wider types
This commit is contained in:
parent
9581891d66
commit
34b7107d27
@ -225,8 +225,17 @@ Other kinds of expressions than the above (even `nonet(byte + byte + byte)`) wil
|
|||||||
* `hi`, `lo`: most/least significant byte of a word
|
* `hi`, `lo`: most/least significant byte of a word
|
||||||
`hi(word)`
|
`hi(word)`
|
||||||
|
|
||||||
Furthermore, any type that can be assigned to a variable
|
Furthermore, any type that can be assigned to a variable can be used to convert
|
||||||
can be used to convert from one type to another of the same size.
|
either from one type either to another type of the same size,
|
||||||
|
or from a 1-byte integer type to a compatible 2-byte integer type.
|
||||||
|
|
||||||
|
`byte` → `word`
|
||||||
|
`word` → `pointer`
|
||||||
|
some enum → `byte`
|
||||||
|
`byte` → some enum
|
||||||
|
but not
|
||||||
|
`word` → `byte`
|
||||||
|
some enum → `word`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -130,6 +130,24 @@ class AbstractExpressionCompiler[T <: AbstractCode] {
|
|||||||
}
|
}
|
||||||
count <= 1
|
count <= 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def validateTypeCastAndGetSourceExpressionType(ctx: CompilationContext, typ: Type, params: List[Expression]): Type = {
|
||||||
|
var failed = false
|
||||||
|
if (typ.name == "pointer") {
|
||||||
|
ctx.log.error("Cannot cast into pointer")
|
||||||
|
failed = true
|
||||||
|
}
|
||||||
|
if (params.length != 1) {
|
||||||
|
ctx.log.error("Type casting should have exactly one argument")
|
||||||
|
failed = true
|
||||||
|
}
|
||||||
|
val sourceType = getExpressionType(ctx, params.head)
|
||||||
|
if (typ.size != sourceType.size && !sourceType.isAssignableTo(typ)) {
|
||||||
|
ctx.log.error("Cannot cast a type to an incompatible type of different size")
|
||||||
|
failed = true
|
||||||
|
}
|
||||||
|
sourceType
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object AbstractExpressionCompiler {
|
object AbstractExpressionCompiler {
|
||||||
|
@ -1066,22 +1066,9 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] {
|
|||||||
case _ =>
|
case _ =>
|
||||||
env.maybeGet[Type](f.functionName) match {
|
env.maybeGet[Type](f.functionName) match {
|
||||||
case Some(typ) =>
|
case Some(typ) =>
|
||||||
var failed = false
|
val sourceType = validateTypeCastAndGetSourceExpressionType(ctx, typ, params)
|
||||||
if (typ.name == "pointer") {
|
|
||||||
ctx.log.error("Cannot cast into pointer")
|
|
||||||
failed = true
|
|
||||||
}
|
|
||||||
if (params.length != 1) {
|
|
||||||
ctx.log.error("Type casting should have exactly one argument")
|
|
||||||
failed = true
|
|
||||||
}
|
|
||||||
val sourceType = getExpressionType(ctx, params.head)
|
|
||||||
if (typ.size != sourceType.size){
|
|
||||||
ctx.log.error("Cannot cast a type to a type of different size")
|
|
||||||
failed = true
|
|
||||||
}
|
|
||||||
val newExprTypeAndVariable = exprTypeAndVariable.map(i => sourceType -> i._2)
|
val newExprTypeAndVariable = exprTypeAndVariable.map(i => sourceType -> i._2)
|
||||||
return if (failed) Nil else compile(ctx, params.head, newExprTypeAndVariable, branches)
|
return compile(ctx, params.head, newExprTypeAndVariable, branches)
|
||||||
case None =>
|
case None =>
|
||||||
// fallthrough to the lookup below
|
// fallthrough to the lookup below
|
||||||
}
|
}
|
||||||
|
@ -782,20 +782,7 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
|
|||||||
case _ =>
|
case _ =>
|
||||||
env.maybeGet[Type](f.functionName) match {
|
env.maybeGet[Type](f.functionName) match {
|
||||||
case Some(typ) =>
|
case Some(typ) =>
|
||||||
var failed = false
|
val sourceType = validateTypeCastAndGetSourceExpressionType(ctx, typ, params)
|
||||||
if (typ.name == "pointer") {
|
|
||||||
ctx.log.error("Cannot cast into pointer")
|
|
||||||
failed = true
|
|
||||||
}
|
|
||||||
if (params.length != 1) {
|
|
||||||
ctx.log.error("Type casting should have exactly one argument")
|
|
||||||
failed = true
|
|
||||||
}
|
|
||||||
val sourceType = getExpressionType(ctx, params.head)
|
|
||||||
if (typ.size != sourceType.size) {
|
|
||||||
ctx.log.error("Cannot cast a type to a type of different size")
|
|
||||||
failed = true
|
|
||||||
}
|
|
||||||
return sourceType.size match {
|
return sourceType.size match {
|
||||||
case 1 => targetifyA(ctx, target, compileToA(ctx, params.head), isSigned = sourceType.isSigned)
|
case 1 => targetifyA(ctx, target, compileToA(ctx, params.head), isSigned = sourceType.isSigned)
|
||||||
case 2 => targetifyHL(ctx, target, compileToHL(ctx, params.head))
|
case 2 => targetifyHL(ctx, target, compileToHL(ctx, params.head))
|
||||||
|
@ -20,6 +20,19 @@ class WordMathSuite extends FunSuite with Matchers {
|
|||||||
""".stripMargin)(_.readWord(0xc000) should equal(1280))
|
""".stripMargin)(_.readWord(0xc000) should equal(1280))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("Cast word addition") {
|
||||||
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)("""
|
||||||
|
| byte output @$c000
|
||||||
|
| word a
|
||||||
|
| void main () {
|
||||||
|
| output = add(155, 166)
|
||||||
|
| }
|
||||||
|
| byte add(byte a, byte b) {
|
||||||
|
| return hi(word(a) + word(b))
|
||||||
|
| }
|
||||||
|
""".stripMargin)(_.readByte(0xc000) should equal(1))
|
||||||
|
}
|
||||||
|
|
||||||
test("Word subtraction") {
|
test("Word subtraction") {
|
||||||
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)("""
|
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)("""
|
||||||
| word output @$c000
|
| word output @$c000
|
||||||
@ -132,7 +145,7 @@ class WordMathSuite extends FunSuite with Matchers {
|
|||||||
| output = get(5, 6)
|
| output = get(5, 6)
|
||||||
| }
|
| }
|
||||||
| byte get(byte mx, byte my) {
|
| byte get(byte mx, byte my) {
|
||||||
| return map[((mx + 00000) << 5) + my]
|
| return map[(word(mx) << 5) + my]
|
||||||
| }
|
| }
|
||||||
""".stripMargin){ m =>
|
""".stripMargin){ m =>
|
||||||
m.readByte(0xc3a6) should equal(77)
|
m.readByte(0xc3a6) should equal(77)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user