From ba9e1b647500614145a788fdbf13d18d97685bc6 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Sat, 20 Jan 2018 01:54:10 +0100 Subject: [PATCH] Type casting --- .../scala/millfork/compiler/BuiltIns.scala | 2 ++ .../scala/millfork/compiler/MfCompiler.scala | 28 ++++++++++++++++++- src/test/scala/millfork/test/TypeSuite.scala | 27 ++++++++++++++++++ 3 files changed, 56 insertions(+), 1 deletion(-) create mode 100644 src/test/scala/millfork/test/TypeSuite.scala diff --git a/src/main/scala/millfork/compiler/BuiltIns.scala b/src/main/scala/millfork/compiler/BuiltIns.scala index 200e5a2a..26c16f7b 100644 --- a/src/main/scala/millfork/compiler/BuiltIns.scala +++ b/src/main/scala/millfork/compiler/BuiltIns.scala @@ -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( diff --git a/src/main/scala/millfork/compiler/MfCompiler.scala b/src/main/scala/millfork/compiler/MfCompiler.scala index a03ea581..011facc6 100644 --- a/src/main/scala/millfork/compiler/MfCompiler.scala +++ b/src/main/scala/millfork/compiler/MfCompiler.scala @@ -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 { diff --git a/src/test/scala/millfork/test/TypeSuite.scala b/src/test/scala/millfork/test/TypeSuite.scala new file mode 100644 index 00000000..776a4797 --- /dev/null +++ b/src/test/scala/millfork/test/TypeSuite.scala @@ -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)) + } +}