Skip to content

Commit b7fffbb

Browse files
committed
release 7.4.1 - oops, funcion call arg count validation was broken
1 parent 1f34623 commit b7fffbb

File tree

8 files changed

+109
-10
lines changed

8 files changed

+109
-10
lines changed

compiler/res/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
7.4
1+
7.4.1

compiler/src/prog8/compiler/Compiler.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions
257257
// perform initial syntax checks and processings
258258
println("Processing for target ${compilerOptions.compTarget.name}...")
259259
program.preprocessAst(program)
260-
program.checkIdentifiers(errors, compilerOptions)
260+
program.checkIdentifiers(errors, program, compilerOptions)
261261
errors.report()
262262
// TODO: turning char literals into UBYTEs via an encoding should really happen in code gen - but for that we'd need DataType.CHAR
263263
// ...but what do we gain from this? We can leave it as it is now: where a char literal is no more than syntactic sugar for an UBYTE value.
@@ -274,7 +274,7 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions
274274
errors.report()
275275
program.checkValid(errors, compilerOptions)
276276
errors.report()
277-
program.checkIdentifiers(errors, compilerOptions)
277+
program.checkIdentifiers(errors, program, compilerOptions)
278278
errors.report()
279279
}
280280

compiler/src/prog8/compiler/astprocessing/AstChecker.kt

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,8 +1015,7 @@ internal class AstChecker(private val program: Program,
10151015

10161016
}
10171017

1018-
val error =
1019-
VerifyFunctionArgTypes.checkTypes(functionCallStatement, program)
1018+
val error = VerifyFunctionArgTypes.checkTypes(functionCallStatement, program)
10201019
if(error!=null) {
10211020
errors.err(error, functionCallStatement.args.firstOrNull()?.position ?: functionCallStatement.position)
10221021
}

compiler/src/prog8/compiler/astprocessing/AstExtensions.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,9 +73,9 @@ internal fun Program.preprocessAst(program: Program) {
7373
mods = transforms.applyModifications()
7474
}
7575

76-
internal fun Program.checkIdentifiers(errors: IErrorReporter, options: CompilationOptions) {
76+
internal fun Program.checkIdentifiers(errors: IErrorReporter, program: Program, options: CompilationOptions) {
7777

78-
val checker2 = AstIdentifiersChecker(errors, options.compTarget)
78+
val checker2 = AstIdentifiersChecker(errors, program, options.compTarget)
7979
checker2.visit(this)
8080

8181
if(errors.noErrors()) {

compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
11
package prog8.compiler.astprocessing
22

3+
import prog8.ast.IFunctionCall
4+
import prog8.ast.Node
5+
import prog8.ast.Program
6+
import prog8.ast.base.FatalAstException
37
import prog8.ast.base.Position
8+
import prog8.ast.expressions.FunctionCall
49
import prog8.ast.expressions.StringLiteralValue
510
import prog8.ast.statements.*
611
import prog8.ast.walk.IAstVisitor
712
import prog8.compilerinterface.BuiltinFunctions
813
import prog8.compilerinterface.ICompilationTarget
914
import prog8.compilerinterface.IErrorReporter
1015

11-
internal class AstIdentifiersChecker(private val errors: IErrorReporter, private val compTarget: ICompilationTarget) : IAstVisitor {
16+
internal class AstIdentifiersChecker(private val errors: IErrorReporter,
17+
private val program: Program,
18+
private val compTarget: ICompilationTarget) : IAstVisitor {
1219
private var blocks = mutableMapOf<String, Block>()
1320

1421
private fun nameError(name: String, position: Position, existing: Statement) {
@@ -121,4 +128,27 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter, private
121128

122129
super.visit(string)
123130
}
131+
132+
override fun visit(functionCall: FunctionCall) = visitFunctionCall(functionCall)
133+
override fun visit(functionCallStatement: FunctionCallStatement) = visitFunctionCall(functionCallStatement)
134+
135+
private fun visitFunctionCall(call: IFunctionCall) {
136+
when (val target = call.target.targetStatement(program)) {
137+
is Subroutine -> {
138+
if(call.args.size != target.parameters.size)
139+
errors.err("invalid number of arguments", call.args[0].position)
140+
}
141+
is BuiltinFunctionStatementPlaceholder -> {
142+
val func = BuiltinFunctions.getValue(target.name)
143+
if(call.args.size != func.parameters.size)
144+
errors.err("invalid number of arguments", call.args[0].position)
145+
}
146+
is Label -> {
147+
if(call.args.isNotEmpty())
148+
errors.err("cannot use arguments when calling a label", call.args[0].position)
149+
}
150+
null -> {}
151+
else -> throw FatalAstException("weird call target")
152+
}
153+
}
124154
}

compiler/src/prog8/compiler/astprocessing/VerifyFunctionArgTypes.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import prog8.ast.walk.IAstVisitor
1111
import prog8.compilerinterface.BuiltinFunctions
1212
import prog8.compilerinterface.InternalCompilerException
1313

14-
class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
14+
internal class VerifyFunctionArgTypes(val program: Program) : IAstVisitor {
1515

1616
override fun visit(functionCall: FunctionCall) {
1717
val error = checkTypes(functionCall as IFunctionCall, program)

compiler/test/TestSubroutines.kt

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import io.kotest.matchers.types.instanceOf
99
import prog8.ast.base.DataType
1010
import prog8.ast.expressions.*
1111
import prog8.ast.statements.*
12+
import prog8.compiler.printProgram
1213
import prog8.compiler.target.C64Target
1314
import prog8tests.helpers.ErrorReporterForTests
1415
import prog8tests.helpers.assertFailure
@@ -262,4 +263,66 @@ class TestSubroutines: FunSpec({
262263
addressExpr.operator shouldBe "+"
263264
(addressExpr.right as NumericLiteralValue).number.toInt() shouldBe 10
264265
}
266+
267+
test("invalid number of args check on normal subroutine") {
268+
val text="""
269+
main {
270+
sub thing(ubyte a1, ubyte a2) {
271+
}
272+
273+
sub start() {
274+
thing(1)
275+
thing(1,2)
276+
thing(1,2,3)
277+
}
278+
}
279+
"""
280+
281+
val errors = ErrorReporterForTests()
282+
compileText(C64Target, false, text, writeAssembly = false, errors=errors).assertFailure()
283+
errors.errors.size shouldBe 2
284+
errors.errors[0] shouldContain "7:24: invalid number of arguments"
285+
errors.errors[1] shouldContain "9:24: invalid number of arguments"
286+
}
287+
288+
test("invalid number of args check on asm subroutine") {
289+
val text="""
290+
main {
291+
asmsub thing(ubyte a1 @A, ubyte a2 @Y) {
292+
}
293+
294+
sub start() {
295+
thing(1)
296+
thing(1,2)
297+
thing(1,2,3)
298+
}
299+
}
300+
"""
301+
302+
val errors = ErrorReporterForTests()
303+
compileText(C64Target, false, text, writeAssembly = false, errors=errors).assertFailure()
304+
errors.errors.size shouldBe 2
305+
errors.errors[0] shouldContain "7:24: invalid number of arguments"
306+
errors.errors[1] shouldContain "9:24: invalid number of arguments"
307+
}
308+
309+
test("invalid number of args check on call to label and builtin func") {
310+
val text="""
311+
main {
312+
label:
313+
sub start() {
314+
label()
315+
label(1)
316+
void rnd()
317+
void rnd(1)
318+
}
319+
}
320+
"""
321+
322+
val errors = ErrorReporterForTests()
323+
compileText(C64Target, false, text, writeAssembly = false, errors=errors).assertFailure()
324+
errors.errors.size shouldBe 2
325+
errors.errors[0] shouldContain "cannot use arguments"
326+
errors.errors[1] shouldContain "invalid number of arguments"
327+
}
265328
})

examples/test.p8

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,14 @@ main {
1010
byte b2 = 22
1111
word b3 = 3333
1212
dummy++
13-
func(-b1,-b2,-b3)
13+
labelz()
14+
labelz(1)
15+
printz(1)
16+
printz(1,2,3,4,5,6)
17+
func(-b1,-b2,-b3 , 3, 4, 5)
18+
19+
labelz:
20+
1421
}
1522

1623
sub printz(word a1, byte a2, word a3) {

0 commit comments

Comments
 (0)