From 5f337a0bd936ce83c6bce60c050155dbbac2953f Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 30 Oct 2020 21:45:37 +0100 Subject: [PATCH] fix typecheck of multiple returnvalues --- compiler/src/prog8/ast/processing/AstChecker.kt | 6 +++--- compiler/src/prog8/ast/processing/StatementReorderer.kt | 2 +- compiler/src/prog8/ast/processing/TypecastsAdder.kt | 2 +- compiler/src/prog8/ast/statements/AstStatements.kt | 4 ++-- .../prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt | 2 +- .../compiler/target/c64/codegen/assignment/AsmAssignment.kt | 2 +- .../target/c64/codegen/assignment/AssignmentAsmGen.kt | 5 +++-- compiler/src/prog8/optimizer/StatementOptimizer.kt | 2 +- 8 files changed, 13 insertions(+), 12 deletions(-) diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index b0cc39c7e..f92aa2b44 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -344,7 +344,7 @@ internal class AstChecker(private val program: Program, if(assignment.value is FunctionCall) { val stmt = (assignment.value as FunctionCall).target.targetStatement(program.namespace) if (stmt is Subroutine) { - val idt = assignment.target.inferType(program, assignment) + val idt = assignment.target.inferType(program) if(!idt.isKnown) { errors.err("return type mismatch", assignment.value.position) } @@ -378,7 +378,7 @@ internal class AstChecker(private val program: Program, } } - val targetDt = assignment.target.inferType(program, assignment) + val targetDt = assignment.target.inferType(program) val valueDt = assignment.value.inferType(program) if(valueDt.isKnown && !(valueDt isAssignableTo targetDt)) { if(targetDt.typeOrElse(DataType.STRUCT) in IterableDatatypes) @@ -433,7 +433,7 @@ internal class AstChecker(private val program: Program, if (assignment is Assignment) { - val targetDatatype = assignTarget.inferType(program, assignment) + val targetDatatype = assignTarget.inferType(program) if (targetDatatype.isKnown) { val constVal = assignment.value.constValue(program) if (constVal != null) { diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index 50a153fc8..70af20439 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -168,7 +168,7 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte override fun before(assignment: Assignment, parent: Node): Iterable { val valueType = assignment.value.inferType(program) - val targetType = assignment.target.inferType(program, assignment) + val targetType = assignment.target.inferType(program) var assignments = emptyList() if(targetType.istype(DataType.STRUCT) && (valueType.istype(DataType.STRUCT) || valueType.typeOrElse(DataType.STRUCT) in ArrayDatatypes )) { diff --git a/compiler/src/prog8/ast/processing/TypecastsAdder.kt b/compiler/src/prog8/ast/processing/TypecastsAdder.kt index a74199eb8..52d6a2dc3 100644 --- a/compiler/src/prog8/ast/processing/TypecastsAdder.kt +++ b/compiler/src/prog8/ast/processing/TypecastsAdder.kt @@ -60,7 +60,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke override fun after(assignment: Assignment, parent: Node): Iterable { // see if a typecast is needed to convert the value's type into the proper target type val valueItype = assignment.value.inferType(program) - val targetItype = assignment.target.inferType(program, assignment) + val targetItype = assignment.target.inferType(program) if(targetItype.isKnown && valueItype.isKnown) { val targettype = targetItype.typeOrElse(DataType.STRUCT) val valuetype = valueItype.typeOrElse(DataType.STRUCT) diff --git a/compiler/src/prog8/ast/statements/AstStatements.kt b/compiler/src/prog8/ast/statements/AstStatements.kt index 15dc3a9ad..f4157b0dd 100644 --- a/compiler/src/prog8/ast/statements/AstStatements.kt +++ b/compiler/src/prog8/ast/statements/AstStatements.kt @@ -449,9 +449,9 @@ data class AssignTarget(var identifier: IdentifierReference?, fun accept(visitor: IAstVisitor) = visitor.visit(this) fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) - fun inferType(program: Program, stmt: Statement): InferredTypes.InferredType { // TODO why does this have the extra 'stmt' scope parameter??? + fun inferType(program: Program): InferredTypes.InferredType { if (identifier != null) { - val symbol = program.namespace.lookup(identifier!!.nameInSource, stmt) ?: return InferredTypes.unknown() + val symbol = program.namespace.lookup(identifier!!.nameInSource, this) ?: return InferredTypes.unknown() if (symbol is VarDecl) return InferredTypes.knownFor(symbol.datatype) } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt index 4ed1f6258..eb941401d 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/PostIncrDecrAsmGen.kt @@ -19,7 +19,7 @@ internal class PostIncrDecrAsmGen(private val program: Program, private val asmg when { targetIdent!=null -> { val what = asmgen.asmVariableName(targetIdent) - when (stmt.target.inferType(program, stmt).typeOrElse(DataType.STRUCT)) { + when (stmt.target.inferType(program).typeOrElse(DataType.STRUCT)) { in ByteDatatypes -> asmgen.out(if (incr) " inc $what" else " dec $what") in WordDatatypes -> { if(incr) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt index 9917b464c..465cc2f38 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt @@ -55,7 +55,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, companion object { fun fromAstAssignment(assign: Assignment, program: Program, asmgen: AsmGen): AsmAssignTarget = with(assign.target) { - val idt = inferType(program, assign) + val idt = inferType(program) if(!idt.isKnown) throw AssemblyError("unknown dt") val dt = idt.typeOrElse(DataType.STRUCT) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt index 28ecfbe05..ec7014cdc 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AssignmentAsmGen.kt @@ -130,10 +130,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen is Subroutine -> { val preserveStatusRegisterAfterCall = sub.asmReturnvaluesRegisters.any { it.statusflag != null } asmgen.translateFunctionCall(value, preserveStatusRegisterAfterCall) - if(sub.returntypes.single()==DataType.STR) { + val returnValue = sub.returntypes.zip(sub.asmReturnvaluesRegisters).single { it.second.registerOrPair!=null } + if(returnValue.first==DataType.STR) { TODO("assignment of string => copy string ${assign.position}") } else { - when ((sub.asmReturnvaluesRegisters.single { it.registerOrPair != null }).registerOrPair) { + when (returnValue.second.registerOrPair) { RegisterOrPair.A -> assignRegisterByte(assign.target, CpuRegister.A) RegisterOrPair.X -> assignRegisterByte(assign.target, CpuRegister.X) RegisterOrPair.Y -> assignRegisterByte(assign.target, CpuRegister.Y) diff --git a/compiler/src/prog8/optimizer/StatementOptimizer.kt b/compiler/src/prog8/optimizer/StatementOptimizer.kt index cebcbf3f4..a4ba937c6 100644 --- a/compiler/src/prog8/optimizer/StatementOptimizer.kt +++ b/compiler/src/prog8/optimizer/StatementOptimizer.kt @@ -377,7 +377,7 @@ internal class StatementOptimizer(private val program: Program, return listOf(IAstModification.Remove(assignment, assignment.definingScope())) } - val targetIDt = assignment.target.inferType(program, assignment) + val targetIDt = assignment.target.inferType(program) if(!targetIDt.isKnown) throw FatalAstException("can't infer type of assignment target")