tweak expr.typecastTo() a bit

This commit is contained in:
Irmen de Jong 2021-11-11 00:15:09 +01:00
parent 222bcb808f
commit 69f4a4d4f8
4 changed files with 20 additions and 18 deletions

View File

@ -46,7 +46,8 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
if(binExpr.operator in associativeOperators) {
// A = <something-without-A> <associativeoperator> <otherthing-with-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

View File

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

View File

@ -63,17 +63,14 @@ sealed class Expression: Node {
}
}
fun typecastTo(targetDt: DataType, program: Program, sourceDt: DataType?=null, implicit: Boolean=false): Pair<Boolean, Expression> {
require(sourceDt==null || sourceDt!=DataType.UNDEFINED)
require(targetDt!=DataType.UNDEFINED)
fun typecastTo(targetDt: DataType, sourceDt: DataType, implicit: Boolean=false): Pair<Boolean, Expression> {
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)
}

View File

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