From 35bf4ba790aa5185f56acfcfe40a4c1b467cdd43 Mon Sep 17 00:00:00 2001 From: Karol Stasiak Date: Tue, 24 Sep 2019 00:24:17 +0200 Subject: [PATCH] Fix returning constant bools --- .../m6809/M6809ExpressionCompiler.scala | 25 ++++++++++++++++++- .../m6809/M6809StatementCompiler.scala | 19 ++++++++------ .../compiler/mos/MosExpressionCompiler.scala | 4 ++- .../compiler/z80/Z80ExpressionCompiler.scala | 4 ++- .../scala/millfork/test/BooleanSuite.scala | 18 +++++++++++++ 5 files changed, 60 insertions(+), 10 deletions(-) diff --git a/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala b/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala index b512678e..21de60cb 100644 --- a/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/m6809/M6809ExpressionCompiler.scala @@ -4,7 +4,7 @@ import millfork.assembly.m6809.{DAccumulatorIndexed, Indexed, MLine, MOpcode, Tw import millfork.compiler.{AbstractExpressionCompiler, BranchIfFalse, BranchIfTrue, BranchSpec, ComparisonType, CompilationContext, NoBranching} import millfork.node.{DerefExpression, Expression, FunctionCallExpression, GeneratedConstantExpression, IndexedExpression, LhsExpression, LiteralExpression, M6809Register, SumExpression, VariableExpression} import millfork.assembly.m6809.MOpcode._ -import millfork.env.{AssemblyParamSignature, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, M6809RegisterVariable, MathOperator, MemoryVariable, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, Variable, VariablePointy} +import millfork.env.{AssemblyParamSignature, Constant, ConstantBooleanType, ConstantPointy, ExternFunction, FatBooleanType, M6809RegisterVariable, MathOperator, MemoryVariable, NormalFunction, NormalParamSignature, NumericConstant, StackVariablePointy, Type, Variable, VariablePointy} import scala.collection.GenTraversableOnce @@ -282,6 +282,17 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] { case ">>'=" => ??? case ">>>>=" => ??? case _ => + env.maybeGet[Type](fce.functionName) match { + case Some(typ) => + val sourceType = validateTypeCastAndGetSourceExpressionType(ctx, typ, params) + return sourceType.size match { + case 1 => compileToB(ctx, params.head) ++ targetifyB(ctx, target, isSigned = sourceType.isSigned) + case 2 => compileToD(ctx, params.head) ++ targetifyD(ctx, target) + case _ => ??? + } + case None => + // fallthrough to the lookup below + } val f = lookupFunction(ctx, fce) val prepareParams: List[MLine] = f.params match { case NormalParamSignature(List(param)) if param.typ.size == 1 => @@ -333,6 +344,18 @@ object M6809ExpressionCompiler extends AbstractExpressionCompiler[MLine] { def compileToB(ctx: CompilationContext, expr: Expression): List[MLine] = compile(ctx, expr, MExpressionTarget.B) + def compileToFatBooleanInB(ctx: CompilationContext, expr: Expression): List[MLine] = { + val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, expr) + sourceType match { + case FatBooleanType => compileToB(ctx, expr) + case t: ConstantBooleanType => + List(MLine.immediate(MOpcode.LDB, if (t.value) 1 else 0)) + case _ => + println(sourceType) + ??? + } + } + def compileToD(ctx: CompilationContext, expr: Expression): List[MLine] = compile(ctx, expr, MExpressionTarget.D) def compileToX(ctx: CompilationContext, expr: Expression): List[MLine] = compile(ctx, expr, MExpressionTarget.X) diff --git a/src/main/scala/millfork/compiler/m6809/M6809StatementCompiler.scala b/src/main/scala/millfork/compiler/m6809/M6809StatementCompiler.scala index 5f948725..c1d37215 100644 --- a/src/main/scala/millfork/compiler/m6809/M6809StatementCompiler.scala +++ b/src/main/scala/millfork/compiler/m6809/M6809StatementCompiler.scala @@ -5,7 +5,7 @@ import millfork.assembly.m6809.{MLine, NonExistent} import millfork.compiler.{AbstractCompiler, AbstractExpressionCompiler, AbstractStatementCompiler, BranchSpec, CompilationContext} import millfork.node.{Assignment, DoWhileStatement, ExecutableStatement, Expression, ExpressionStatement, ForEachStatement, ForStatement, IfStatement, M6809AssemblyStatement, ReturnDispatchStatement, ReturnStatement, VariableExpression, WhileStatement} import millfork.assembly.m6809.MOpcode._ -import millfork.env.{Label, ThingInMemory} +import millfork.env.{FatBooleanType, Label, ThingInMemory} /** * @author Karol Stasiak @@ -21,12 +21,17 @@ object M6809StatementCompiler extends AbstractStatementCompiler[MLine] { // TODO: clean stack // TODO: RTI val rts = List(MLine.inherent(RTS)) - val eval = ctx.function.returnType.size match { - case 0 => - ctx.log.error("Cannot return anything from a void function", statement.position) - M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING) - case 1 => M6809ExpressionCompiler.compileToB(ctx, e) - case 2 => M6809ExpressionCompiler.compileToD(ctx, e) + val eval = ctx.function.returnType match { + case FatBooleanType => + M6809ExpressionCompiler.compileToFatBooleanInB(ctx, e) + case _ => + ctx.function.returnType.size match { + case 0 => + ctx.log.error("Cannot return anything from a void function", statement.position) + M6809ExpressionCompiler.compile(ctx, e, MExpressionTarget.NOTHING) + case 1 => M6809ExpressionCompiler.compileToB(ctx, e) + case 2 => M6809ExpressionCompiler.compileToD(ctx, e) + } } (eval ++ rts) -> Nil case M6809AssemblyStatement(opcode, addrMode, expression, elidability) => diff --git a/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala b/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala index 9008df91..374f3cd5 100644 --- a/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/mos/MosExpressionCompiler.scala @@ -440,8 +440,10 @@ object MosExpressionCompiler extends AbstractExpressionCompiler[AssemblyLine] { val env = ctx.env val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, expr) sourceType match { - case FatBooleanType | _:ConstantBooleanType => + case FatBooleanType => compileToA(ctx, expr) + case t: ConstantBooleanType => + List(AssemblyLine.immediate(LDA, if (t.value) 1 else 0)) case _: FlagBooleanType | BuiltInBooleanType => val label = env.nextLabel("bo") val condition = compile(ctx, expr, None, BranchIfFalse(label)) diff --git a/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala b/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala index c354db02..494ad7eb 100644 --- a/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala +++ b/src/main/scala/millfork/compiler/z80/Z80ExpressionCompiler.scala @@ -24,7 +24,9 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] { def compileToFatBooleanInA(ctx: CompilationContext, expression: Expression): List[ZLine] = { val sourceType = AbstractExpressionCompiler.getExpressionType(ctx, expression) sourceType match { - case FatBooleanType | _: ConstantBooleanType => compileToA(ctx, expression) + case FatBooleanType => compileToA(ctx, expression) + case t: ConstantBooleanType => + List(ZLine.ldImm8(ZRegister.A, if (t.value) 1 else 0)) case BuiltInBooleanType | _: FlagBooleanType => // TODO optimize if using CARRY // TODO: helper functions to convert flags to booleans, to make code smaller diff --git a/src/test/scala/millfork/test/BooleanSuite.scala b/src/test/scala/millfork/test/BooleanSuite.scala index 91a4f99e..486e538a 100644 --- a/src/test/scala/millfork/test/BooleanSuite.scala +++ b/src/test/scala/millfork/test/BooleanSuite.scala @@ -228,4 +228,22 @@ class BooleanSuite extends FunSuite with Matchers { m.readByte(0xc000) should equal(1) } } + + test("Returning const bools") { + val code =""" + | byte outputF @$c000 + | byte outputT @$c001 + | noinline bool f(byte x) = 1==2 + | noinline bool t(byte x) = 1==1 + | void main () { + | outputF = byte(f(7)) + | outputT = byte(t(7)) + | } + | + """.stripMargin + EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Motorola6809)(code){ m => + m.readByte(0xc000) should equal(0) + m.readByte(0xc001) should equal(1) + } + } }