improved call arguments type check

This commit is contained in:
Irmen de Jong
2020-07-27 00:28:48 +02:00
parent 1c16bbb742
commit fdfbb7bdf0
3 changed files with 41 additions and 23 deletions

View File

@@ -810,6 +810,10 @@ internal class AstChecker(private val program: Program,
errors.warn("sgn() of unsigned type is always 0 or 1, this is perhaps not what was intended", functionCall.args.first().position) errors.warn("sgn() of unsigned type is always 0 or 1, this is perhaps not what was intended", functionCall.args.first().position)
} }
val error = VerifyFunctionArgTypes.checkTypes(functionCall, functionCall.definingScope(), program)
if(error!=null)
errors.err(error, functionCall.args.first().position)
super.visit(functionCall) super.visit(functionCall)
} }
@@ -838,6 +842,11 @@ internal class AstChecker(private val program: Program,
errors.err("invalid argument to a in-place modifying function", functionCallStatement.args.first().position) errors.err("invalid argument to a in-place modifying function", functionCallStatement.args.first().position)
} }
} }
val error = VerifyFunctionArgTypes.checkTypes(functionCallStatement, functionCallStatement.definingScope(), program)
if(error!=null)
errors.err(error, functionCallStatement.args.first().position)
super.visit(functionCallStatement) super.visit(functionCallStatement)
} }

View File

@@ -13,30 +13,41 @@ import prog8.functions.BuiltinFunctions
class VerifyFunctionArgTypes(val program: Program) : IAstVisitor { class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
override fun visit(functionCall: FunctionCall) override fun visit(functionCall: FunctionCall) {
= checkTypes(functionCall as IFunctionCall, functionCall.definingScope()) val error = checkTypes(functionCall as IFunctionCall, functionCall.definingScope(), program)
if(error!=null)
throw CompilerException(error)
}
override fun visit(functionCallStatement: FunctionCallStatement) override fun visit(functionCallStatement: FunctionCallStatement) {
= checkTypes(functionCallStatement as IFunctionCall, functionCallStatement.definingScope()) val error = checkTypes(functionCallStatement as IFunctionCall, functionCallStatement.definingScope(), program)
if (error!=null)
throw CompilerException(error)
}
private fun checkTypes(call: IFunctionCall, scope: INameScope) { companion object {
val argtypes = call.args.map { it.inferType(program).typeOrElse(DataType.STRUCT) } fun checkTypes(call: IFunctionCall, scope: INameScope, program: Program): String? {
val target = call.target.targetStatement(scope) val argtypes = call.args.map { it.inferType(program).typeOrElse(DataType.STRUCT) }
when(target) { val target = call.target.targetStatement(scope)
is Subroutine -> { when (target) {
val paramtypes = target.parameters.map { it.type } is Subroutine -> {
if(argtypes!=paramtypes) val paramtypes = target.parameters.map { it.type }
throw CompilerException("parameter type mismatch $call") val mismatch = argtypes.zip(paramtypes).indexOfFirst { it.first != it.second}
} if(mismatch>=0)
is BuiltinFunctionStatementPlaceholder -> { return "argument ${mismatch+1} type mismatch"
val func = BuiltinFunctions.getValue(target.name) }
val paramtypes = func.parameters.map { it.possibleDatatypes } is BuiltinFunctionStatementPlaceholder -> {
for(x in argtypes.zip(paramtypes)) { val func = BuiltinFunctions.getValue(target.name)
if(x.first !in x.second) val paramtypes = func.parameters.map { it.possibleDatatypes }
throw CompilerException("parameter type mismatch $call") for (x in argtypes.zip(paramtypes).withIndex()) {
if (x.value.first !in x.value.second)
return "argument ${x.index+1} type mismatch"
}
}
else -> {
} }
} }
else -> {} return null
} }
} }
} }

View File

@@ -16,9 +16,7 @@ main {
} }
sub wot(uword text) { sub wot(uword text) {
;c64scr.print(text) ; TODO better type error c64scr.print(4.4, 1)
;c64.CHROUT('\n')
c64scr.print_uwhex(text, 1)
c64.CHROUT('\n') c64.CHROUT('\n')
} }
} }