From 69f4a4d4f89e937a880e0d695d70b7dcdd2f6714 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 11 Nov 2021 00:15:09 +0100 Subject: [PATCH] tweak expr.typecastTo() a bit --- .../compiler/BeforeAsmGenerationAstChanger.kt | 16 ++++++++++------ .../compiler/astprocessing/StatementReorderer.kt | 10 ++++++---- .../src/prog8/ast/expressions/AstExpressions.kt | 11 ++++------- docs/source/todo.rst | 1 - 4 files changed, 20 insertions(+), 18 deletions(-) diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index a40164589..aba12ff40 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -46,7 +46,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o if(binExpr.operator in associativeOperators) { // A = // use the other part of the expression to split. - val (_, right) = binExpr.right.typecastTo(assignment.target.inferType(program).getOr(DataType.UNDEFINED), program, implicit=true) + val sourceDt = binExpr.right.inferType(program).getOrElse { throw AssemblyError("invalid dt") } + val (_, right) = binExpr.right.typecastTo(assignment.target.inferType(program).getOr(DataType.UNDEFINED), sourceDt, implicit=true) val assignRight = Assignment(assignment.target, right, assignment.position) return listOf( IAstModification.InsertBefore(assignment, assignRight, parent as IStatementContainer), @@ -54,7 +55,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o IAstModification.ReplaceNode(binExpr.left, assignment.target.toExpression(), binExpr)) } } else { - val (_, left) = binExpr.left.typecastTo(assignment.target.inferType(program).getOr(DataType.UNDEFINED), program, implicit=true) + val sourceDt = binExpr.left.inferType(program).getOrElse { throw AssemblyError("invalid dt") } + val (_, left) = binExpr.left.typecastTo(assignment.target.inferType(program).getOr(DataType.UNDEFINED), sourceDt, implicit=true) val assignLeft = Assignment(assignment.target, left, assignment.position) return listOf( IAstModification.InsertBefore(assignment, assignLeft, parent as IStatementContainer), @@ -335,13 +337,15 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o if(dt1 in ByteDatatypes) { if(dt2 in ByteDatatypes) return noModifications - val cast1 = TypecastExpression(arg1, if(dt1==DataType.UBYTE) DataType.UWORD else DataType.WORD, true, functionCallStatement.position) - return listOf(IAstModification.ReplaceNode(arg1, cast1, functionCallStatement)) + val (replaced, cast) = arg1.typecastTo(if(dt1==DataType.UBYTE) DataType.UWORD else DataType.WORD, dt1, true) + if(replaced) + return listOf(IAstModification.ReplaceNode(arg1, cast, functionCallStatement)) } else { if(dt2 in WordDatatypes) return noModifications - val cast2 = TypecastExpression(arg2, if(dt2==DataType.UBYTE) DataType.UWORD else DataType.WORD, true, functionCallStatement.position) - return listOf(IAstModification.ReplaceNode(arg2, cast2, functionCallStatement)) + val (replaced, cast) = arg2.typecastTo(if(dt2==DataType.UBYTE) DataType.UWORD else DataType.WORD, dt2, true) + if(replaced) + return listOf(IAstModification.ReplaceNode(arg2, cast, functionCallStatement)) } } return noModifications diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 5c4e84dc6..7da0b1ed4 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -169,8 +169,9 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport is Subroutine -> { val paramType = callee.parameters[argnum].type if(leftDt isAssignableTo paramType) { - val cast = TypecastExpression(expr.left, paramType, true, parent.position) - return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) + val (replaced, cast) = expr.left.typecastTo(paramType, leftDt.getOr(DataType.UNDEFINED), true) + if(replaced) + return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) } } is BuiltinFunctionStatementPlaceholder -> { @@ -178,8 +179,9 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport val paramTypes = func.parameters[argnum].possibleDatatypes for(type in paramTypes) { if(leftDt isAssignableTo type) { - val cast = TypecastExpression(expr.left, type, true, parent.position) - return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) + val (replaced, cast) = expr.left.typecastTo(type, leftDt.getOr(DataType.UNDEFINED), true) + if(replaced) + return listOf(IAstModification.ReplaceNode(expr.left, cast, expr)) } } } diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index 034774543..8fc8d4159 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -63,17 +63,14 @@ sealed class Expression: Node { } } - fun typecastTo(targetDt: DataType, program: Program, sourceDt: DataType?=null, implicit: Boolean=false): Pair { - require(sourceDt==null || sourceDt!=DataType.UNDEFINED) - require(targetDt!=DataType.UNDEFINED) + fun typecastTo(targetDt: DataType, sourceDt: DataType, implicit: Boolean=false): Pair { + require(sourceDt!=DataType.UNDEFINED && targetDt!=DataType.UNDEFINED) + if(sourceDt==targetDt) + return Pair(false, this) if(this is TypecastExpression) { this.type = targetDt return Pair(false, this) } - val exprDt = sourceDt ?: this.inferType(program).getOr(DataType.UNDEFINED) - if(exprDt==targetDt) - return Pair(false, this) - val typecast = TypecastExpression(this, targetDt, implicit, this.position) return Pair(true, typecast) } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 060784348..8d2451948 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next compiler release (7.3) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- let typecasting code use expression.typecastTo() - add expression simplification to while and until loops as well.