1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-26 20:33:02 +00:00

Fix returning constant bools

This commit is contained in:
Karol Stasiak 2019-09-24 00:24:17 +02:00
parent 77a4324a12
commit 35bf4ba790
5 changed files with 60 additions and 10 deletions

View File

@ -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)

View File

@ -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) =>

View File

@ -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))

View File

@ -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

View File

@ -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)
}
}
}