mirror of
https://github.com/irmen/prog8.git
synced 2025-08-14 22:27:48 +00:00
improved call arguments type check
This commit is contained in:
@@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -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')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user