From b428343c2a0f4537ae9827109d530f0c5f112a5f Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 28 Dec 2023 02:31:39 +0100 Subject: [PATCH] tweak chained comparisons --- .../compiler/astprocessing/AstExtensions.kt | 10 ++++---- .../compiler/astprocessing/CodeDesugarer.kt | 24 +++++++++++++++++++ .../astprocessing/StatementReorderer.kt | 24 ------------------- .../prog8/ast/expressions/AstExpressions.kt | 2 +- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt index 259f2c49c..157cc93a0 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstExtensions.kt @@ -96,10 +96,11 @@ internal fun Program.addTypecasts(errors: IErrorReporter, options: CompilationOp caster.applyModifications() } -fun Program.desugaring(errors: IErrorReporter): Int { +fun Program.desugaring(errors: IErrorReporter) { val desugar = CodeDesugarer(this, errors) desugar.visit(this) - return desugar.applyModifications() + while(errors.noErrors() && desugar.applyModifications()>0) + desugar.visit(this) } internal fun Program.verifyFunctionArgTypes(errors: IErrorReporter) { @@ -110,9 +111,8 @@ internal fun Program.verifyFunctionArgTypes(errors: IErrorReporter) { internal fun Program.preprocessAst(errors: IErrorReporter, options: CompilationOptions) { val transforms = AstPreprocessor(this, errors, options) transforms.visit(this) - var mods = transforms.applyModifications() - while(mods>0) - mods = transforms.applyModifications() + while(errors.noErrors() && transforms.applyModifications()>0) + transforms.visit(this) } internal fun Program.checkIdentifiers(errors: IErrorReporter, options: CompilationOptions) { diff --git a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt index f12e2d91f..7503ca797 100644 --- a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt +++ b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt @@ -26,6 +26,7 @@ internal class CodeDesugarer(val program: Program, private val errors: IErrorRep // - pointer[word] replaced by @(pointer+word) // - @(&var) and @(&var+1) replaced by lsb(var) and msb(var) if var is a word // - flatten chained assignments + // - rewrite chained comparisons like i { fun jumpAfter(stmt: Statement): Iterable { @@ -259,6 +260,29 @@ _after: return listOf(IAstModification.ReplaceNode(expr, squareCall, parent)) } + // desugar chained comparisons: i < x < j ---> i leave untouched + if(expr.operator in ComparisonOperators) { + val leftBinExpr = expr.left as? BinaryExpression + val rightBinExpr = expr.right as? BinaryExpression + if(leftBinExpr!=null && !leftBinExpr.insideParentheses && leftBinExpr.operator in ComparisonOperators) { + if(!leftBinExpr.right.isSimple) { + errors.warn("possible multiple evaluation of subexpression in chained comparison, consider using a temporary variable", leftBinExpr.right.position) + } + val right = BinaryExpression(leftBinExpr.right.copy(), expr.operator, expr.right, leftBinExpr.right.position) + val desugar = BinaryExpression(leftBinExpr, "and", right, expr.position) + return listOf(IAstModification.ReplaceNode(expr, desugar, parent)) + } + else if(rightBinExpr!=null && !rightBinExpr.insideParentheses && rightBinExpr.operator in ComparisonOperators) { + if(!rightBinExpr.left.isSimple) { + errors.warn("possible multiple evaluation of subexpression in chained comparison, consider using a temporary variable", rightBinExpr.left.position) + } + val left = BinaryExpression(expr.left, expr.operator, rightBinExpr.left.copy(), rightBinExpr.left.position) + val desugar = BinaryExpression(left, "and", rightBinExpr, expr.position) + return listOf(IAstModification.ReplaceNode(expr, desugar, parent)) + } + } + return noModifications } diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 5cf620232..4b732ccdf 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -171,30 +171,6 @@ internal class StatementReorderer( } override fun after(expr: BinaryExpression, parent: Node): Iterable { - // desugar chained comparisons: i < x < j ---> i leave untouched - if(expr.operator in ComparisonOperators) { - val leftBinExpr = expr.left as? BinaryExpression - val rightBinExpr = expr.right as? BinaryExpression - if(leftBinExpr!=null && !leftBinExpr.insideParentheses && leftBinExpr.operator in ComparisonOperators) { - if(!leftBinExpr.right.isSimple) { - errors.warn("possible multiple evaluation of subexpression in chained comparison, consider using a temporary variable", leftBinExpr.right.position) - } - val right = BinaryExpression(leftBinExpr.right.copy(), expr.operator, expr.right, leftBinExpr.right.position) - val desugar = BinaryExpression(leftBinExpr, "and", right, expr.position) - return listOf(IAstModification.ReplaceNode(expr, desugar, parent)) - } - else if(rightBinExpr!=null && !rightBinExpr.insideParentheses && rightBinExpr.operator in ComparisonOperators) { - if(!rightBinExpr.left.isSimple) { - errors.warn("possible multiple evaluation of subexpression in chained comparison, consider using a temporary variable", rightBinExpr.left.position) - } - val left = BinaryExpression(expr.left, expr.operator, rightBinExpr.left.copy(), rightBinExpr.left.position) - val desugar = BinaryExpression(left, "and", rightBinExpr, expr.position) - return listOf(IAstModification.ReplaceNode(expr, desugar, parent)) - } - } - - // ConstValue X --> X ConstValue // (this should be done by the ExpressionSimplifier when optimizing is enabled, // but the current assembly code generator for IF statements now also depends on it, so we do it here regardless of optimization.) diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index ba8c53ba2..d70ffe0fe 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -173,7 +173,7 @@ class BinaryExpression( replacement.parent = this } - override fun copy() = BinaryExpression(left.copy(), operator, right.copy(), position) + override fun copy() = BinaryExpression(left.copy(), operator, right.copy(), position, insideParentheses) override fun toString() = "[$left $operator $right]" override val isSimple = false