mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
(7.2) correctly parse datatype of array parameters
This commit is contained in:
parent
4d5094a517
commit
35e88dd529
@ -290,7 +290,7 @@ internal class AstChecker(private val program: Program,
|
||||
else if(param.second.registerOrPair in arrayOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
|
||||
if (param.first.type != DataType.UWORD && param.first.type != DataType.WORD
|
||||
&& param.first.type != DataType.STR && param.first.type !in ArrayDatatypes && param.first.type != DataType.FLOAT)
|
||||
err("parameter '${param.first.name}' should be (u)word/address")
|
||||
err("parameter '${param.first.name}' should be (u)word (an address) or str")
|
||||
}
|
||||
else if(param.second.statusflag!=null) {
|
||||
if (param.first.type != DataType.UBYTE)
|
||||
@ -626,7 +626,6 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
// string assignment is not supported in a vard
|
||||
if(decl.datatype==DataType.STR) {
|
||||
if(decl.value==null)
|
||||
err("string var must be initialized with a string literal")
|
||||
|
@ -252,7 +252,9 @@ private fun Prog8ANTLRParser.Asmsub_returnsContext.toAst(): List<AsmSubroutineRe
|
||||
private fun Prog8ANTLRParser.Asmsub_paramsContext.toAst(): List<AsmSubroutineParameter>
|
||||
= asmsub_param().map {
|
||||
val vardecl = it.vardecl()
|
||||
val datatype = vardecl.datatype()?.toAst() ?: DataType.UNDEFINED
|
||||
var datatype = vardecl.datatype()?.toAst() ?: DataType.UNDEFINED
|
||||
if(vardecl.ARRAYSIG()!=null || vardecl.arrayindex()!=null)
|
||||
datatype = ElementToArrayTypes.getValue(datatype)
|
||||
val register = it.register().text
|
||||
var registerorpair: RegisterOrPair? = null
|
||||
var statusregister: Statusflag? = null
|
||||
@ -318,7 +320,9 @@ private fun Prog8ANTLRParser.Sub_return_partContext.toAst(): List<DataType> {
|
||||
|
||||
private fun Prog8ANTLRParser.Sub_paramsContext.toAst(): List<SubroutineParameter> =
|
||||
vardecl().map {
|
||||
val datatype = it.datatype()?.toAst() ?: DataType.UNDEFINED
|
||||
var datatype = it.datatype()?.toAst() ?: DataType.UNDEFINED
|
||||
if(it.ARRAYSIG()!=null || it.arrayindex()!=null)
|
||||
datatype = ElementToArrayTypes.getValue(datatype)
|
||||
SubroutineParameter(it.varname.text, datatype, it.toPosition())
|
||||
}
|
||||
|
||||
|
67
compilerAst/test/TestSubroutines.kt
Normal file
67
compilerAst/test/TestSubroutines.kt
Normal file
@ -0,0 +1,67 @@
|
||||
package prog8tests
|
||||
|
||||
import org.junit.jupiter.api.Test
|
||||
import org.junit.jupiter.api.TestInstance
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.statements.Block
|
||||
import prog8.ast.statements.Subroutine
|
||||
import prog8.parser.Prog8Parser.parseModule
|
||||
import prog8.parser.SourceCode
|
||||
import kotlin.test.*
|
||||
|
||||
|
||||
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
||||
class TestSubroutines {
|
||||
|
||||
@Test
|
||||
fun stringParameterAcceptedInParser() {
|
||||
// note: the *parser* should accept this as it is valid *syntax*,
|
||||
// however, the compiler itself may or may not complain about it later.
|
||||
val text = """
|
||||
main {
|
||||
asmsub asmfunc(str thing @AY) {
|
||||
}
|
||||
|
||||
sub func(str thing) {
|
||||
}
|
||||
}
|
||||
"""
|
||||
val src = SourceCode.Text(text)
|
||||
val module = parseModule(src)
|
||||
val mainBlock = module.statements.single() as Block
|
||||
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
|
||||
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
|
||||
assertTrue(asmfunc.isAsmSubroutine)
|
||||
assertEquals(DataType.STR, asmfunc.parameters.single().type)
|
||||
assertTrue(asmfunc.statements.isEmpty())
|
||||
assertFalse(func.isAsmSubroutine)
|
||||
assertEquals(DataType.STR, func.parameters.single().type)
|
||||
assertTrue(func.statements.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun arrayParameterAcceptedInParser() {
|
||||
// note: the *parser* should accept this as it is valid *syntax*,
|
||||
// however, the compiler itself may or may not complain about it later.
|
||||
val text = """
|
||||
main {
|
||||
asmsub asmfunc(ubyte[] thing @AY) {
|
||||
}
|
||||
|
||||
sub func(ubyte[22] thing) {
|
||||
}
|
||||
}
|
||||
"""
|
||||
val src = SourceCode.Text(text)
|
||||
val module = parseModule(src)
|
||||
val mainBlock = module.statements.single() as Block
|
||||
val asmfunc = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="asmfunc"}
|
||||
val func = mainBlock.statements.filterIsInstance<Subroutine>().single { it.name=="func"}
|
||||
assertTrue(asmfunc.isAsmSubroutine)
|
||||
assertEquals(DataType.ARRAY_UB, asmfunc.parameters.single().type)
|
||||
assertTrue(asmfunc.statements.isEmpty())
|
||||
assertFalse(func.isAsmSubroutine)
|
||||
assertEquals(DataType.ARRAY_UB, func.parameters.single().type)
|
||||
assertTrue(func.statements.isEmpty())
|
||||
}
|
||||
}
|
@ -1,10 +1,16 @@
|
||||
main {
|
||||
sub start() {
|
||||
uword address = &irq
|
||||
; cx16.set_irq(&irq, false)
|
||||
address++
|
||||
asmfunc("text")
|
||||
func("text")
|
||||
}
|
||||
|
||||
sub irq() {
|
||||
asmsub asmfunc(str thing @AY) {
|
||||
%asm {{
|
||||
rts
|
||||
}}
|
||||
}
|
||||
|
||||
|
||||
sub func(str thing) {
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user