fix typecheck of multiple returnvalues

This commit is contained in:
Irmen de Jong 2020-10-30 21:45:37 +01:00
parent 87862f772a
commit 5f337a0bd9
8 changed files with 13 additions and 12 deletions

View File

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

View File

@ -168,7 +168,7 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte
override fun before(assignment: Assignment, parent: Node): Iterable<IAstModification> {
val valueType = assignment.value.inferType(program)
val targetType = assignment.target.inferType(program, assignment)
val targetType = assignment.target.inferType(program)
var assignments = emptyList<Assignment>()
if(targetType.istype(DataType.STRUCT) && (valueType.istype(DataType.STRUCT) || valueType.typeOrElse(DataType.STRUCT) in ArrayDatatypes )) {

View File

@ -60,7 +60,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
// 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)

View File

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

View File

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

View File

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

View File

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

View File

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