From bf9d12008145302d188875ccc6e090ec515c09b0 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 13 Jun 2022 01:37:16 +0200 Subject: [PATCH] logical operators now always return a boolean byte result, instead of sometimes word type as well (preparing for codegen simplifications for these) --- .../prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt | 3 ++- .../src/prog8/compiler/astprocessing/StatementReorderer.kt | 1 + compiler/test/TestOptimization.kt | 7 ++++--- compilerAst/src/prog8/ast/expressions/AstExpressions.kt | 2 +- docs/source/todo.rst | 4 +++- 5 files changed, 11 insertions(+), 6 deletions(-) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 1e55f3b27..1af8850fe 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -321,7 +321,8 @@ internal class AssignmentAsmGen(private val program: Program, if(!expr.inferType(program).isInteger) return false -/* TODO re-add these optimizations? after we improved the unneeded addition of !=0 expressions +/* +TODO re-add these optimizations? after we improved the unneeded addition of !=0 expressions if(expr.operator=="and") { val dt = expr.left.inferType(program).getOrElse { throw AssemblyError("weird dt") } if (dt in ByteDatatypes) { diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 8c2448592..89bffa02c 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -252,6 +252,7 @@ internal class StatementReorderer(val program: Program, // is rewritten as "var!=0 and other-logical-expression", to avoid bitwise boolean and // generating the wrong results later + // TODO use bool(expr) instead of expr!=0 rewriting fun wrapped(expr: Expression): Expression = BinaryExpression(expr, "!=", NumericLiteral(DataType.UBYTE, 0.0, expr.position), expr.position) diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 8f91cae85..40eae2453 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -253,7 +253,7 @@ class TestOptimization: FunSpec({ (initY2.value as NumericLiteral).number shouldBe 11.0 } - test("not-typecasted assignment from ubyte logical expression to uword var") { + test("not-typecasted assignment from ubyte logical expression to uword var should be auto upcasted") { val src = """ main { sub start() { @@ -266,10 +266,11 @@ class TestOptimization: FunSpec({ val result = compileText(C64Target(), false, src, writeAssembly = false)!! val wwAssign = result.program.entrypoint.statements.last() as Assignment - val expr = wwAssign.value as BinaryExpression + val expr = wwAssign.value as TypecastExpression + expr.type shouldBe DataType.UWORD wwAssign.target.identifier?.nameInSource shouldBe listOf("ww") - expr.inferType(result.program) istype DataType.UWORD shouldBe true + expr.expression.inferType(result.program) istype DataType.UBYTE shouldBe true } test("intermediate assignment steps have correct types for codegen phase (BeforeAsmGenerationAstChanger)") { diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 139267e4c..5444ced32 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -215,7 +215,7 @@ class BinaryExpression(var left: Expression, var operator: String, var right: Ex "&" -> leftDt "|" -> leftDt "^" -> leftDt - "and", "or", "xor", + "and", "or", "xor" -> InferredTypes.knownFor(DataType.UBYTE) "<", ">", "<=", ">=", "==", "!=" -> dynamicBooleanType() diff --git a/docs/source/todo.rst b/docs/source/todo.rst index a4ac11a5a..e79423b52 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,9 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- get rid of unneeded !=0 added to logical expressions +- add a builtin function 'bool' that takes a numeric value and returns ubyte false if it was zero and true otherwise +- statementreorderer: after(expr: BinaryExpression): get rid of unneeded !=0 added to logical expressions + by using this bool() function instead for the operand if it is not a byte type - optimize logical expressions in attemptAssignOptimizedBinexpr() - add McCarthy evaluation to shortcircuit and/or expressions. First do ifs by splitting them up? Then do expressions that compute a value? ...