1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-10-03 20:55:36 +00:00

Type casting

This commit is contained in:
Karol Stasiak 2018-01-20 01:54:10 +01:00
parent 013bcd63f1
commit ba9e1b6475
3 changed files with 56 additions and 1 deletions

View File

@ -98,6 +98,8 @@ object BuiltIns {
}
calculateIndex -> List(AssemblyLine.absoluteY(opcode, baseAddress))
}
case FunctionCallExpression(name, List(param)) if env.maybeGet[Type](name).isDefined =>
return simpleOperation(opcode, ctx, param, indexChoice, preserveA, commutative, decimal)
case _: FunctionCallExpression | _:SumExpression if commutative =>
// TODO: is it ok?
return List(AssemblyLine.implied(PHA)) ++ MfCompiler.compile(ctx.addStack(1), source, Some(b -> RegisterVariable(Register.A, b)), NoBranching) ++ wrapInSedCldIfNeeded(decimal, List(

View File

@ -137,7 +137,12 @@ object MfCompiler {
case FunctionCallExpression("<<'=", params) => v
case FunctionCallExpression(">>'=", params) => v
case f@FunctionCallExpression(name, params) =>
lookupFunction(ctx, f).returnType
ctx.env.maybeGet[Type](name) match {
case Some(typ) =>
typ
case None =>
lookupFunction(ctx, f).returnType
}
}
}
@ -1095,6 +1100,27 @@ object MfCompiler {
}
}
case _ =>
env.maybeGet[Type](f.functionName) match {
case Some(typ) =>
var failed = false
if (typ.name == "pointer") {
ErrorReporting.error("Cannot cast into pointer")
failed = true
}
if (params.length != 1) {
ErrorReporting.error("Type casting should have exactly one argument")
failed = true
}
val sourceType = getExpressionType(ctx, params.head)
if (typ.size != sourceType.size){
ErrorReporting.error("Cannot cast a type to a type of different size")
failed = true
}
val newExprTypeAndVariable = exprTypeAndVariable.map(i => sourceType -> i._2)
return if (failed) Nil else compile(ctx, params.head, newExprTypeAndVariable, branches)
case None =>
// fallthrough to the lookup below
}
lookupFunction(ctx, f) match {
case function: InlinedFunction =>
inlineFunction(function, params, Some(ctx)).map {

View File

@ -0,0 +1,27 @@
package millfork.test
import millfork.test.emu.EmuBenchmarkRun
import org.scalatest.{FunSuite, Matchers}
/**
* @author Karol Stasiak
*/
class TypeSuite extends FunSuite with Matchers {
test("Word to word") {
EmuBenchmarkRun("""
| word output @$c000
| void main () {
| output = word(0x203)
| }
""".stripMargin)(_.readWord(0xc000) should equal(0x203))
}
test("Byte to sbyte") {
EmuBenchmarkRun("""
| word output @$c000
| void main () {
| if sbyte(0) > sbyte(255) { output = word(0x203) }
| }
""".stripMargin)(_.readWord(0xc000) should equal(0x203))
}
}