2024-09-08 16:03:57 +02:00
|
|
|
package prog8tests.compiler
|
2021-06-28 13:46:05 +02:00
|
|
|
|
2021-11-08 15:50:29 +01:00
|
|
|
import io.kotest.assertions.fail
|
2021-11-08 00:16:58 +01:00
|
|
|
import io.kotest.assertions.withClue
|
|
|
|
import io.kotest.core.spec.style.FunSpec
|
|
|
|
import io.kotest.matchers.shouldBe
|
|
|
|
import io.kotest.matchers.types.instanceOf
|
2021-06-28 13:46:05 +02:00
|
|
|
import prog8.ast.IFunctionCall
|
|
|
|
import prog8.ast.expressions.IdentifierReference
|
2022-02-11 00:21:40 +01:00
|
|
|
import prog8.ast.expressions.NumericLiteral
|
2022-03-10 22:38:16 +01:00
|
|
|
import prog8.ast.statements.VarDeclType
|
|
|
|
import prog8.code.core.DataType
|
|
|
|
import prog8.code.core.Encoding
|
2022-03-11 20:35:25 +01:00
|
|
|
import prog8.code.target.Cx16Target
|
2021-10-11 00:22:04 +02:00
|
|
|
import prog8tests.helpers.compileText
|
2021-06-28 13:46:05 +02:00
|
|
|
|
|
|
|
|
2021-06-28 18:49:01 +02:00
|
|
|
/**
|
|
|
|
* ATTENTION: this is just kludge!
|
|
|
|
* They are not really unit tests, but rather tests of the whole process,
|
|
|
|
* from source file loading all the way through to running 64tass.
|
|
|
|
*/
|
2021-11-08 00:16:58 +01:00
|
|
|
class TestCompilerOnCharLit: FunSpec({
|
2021-06-28 13:46:05 +02:00
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
test("testCharLitAsRomsubArg") {
|
2022-02-06 21:29:06 +01:00
|
|
|
val platform = Cx16Target()
|
2021-07-13 09:47:31 +02:00
|
|
|
val result = compileText(platform, false, """
|
|
|
|
main {
|
|
|
|
romsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
|
|
|
sub start() {
|
|
|
|
chrout('\n')
|
|
|
|
}
|
|
|
|
}
|
2022-03-07 21:41:12 +01:00
|
|
|
""")!!
|
2021-06-28 13:46:05 +02:00
|
|
|
|
2023-02-09 01:46:23 +01:00
|
|
|
val program = result.compilerAst
|
2021-10-11 00:01:26 +02:00
|
|
|
val startSub = program.entrypoint
|
2021-06-28 13:46:05 +02:00
|
|
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
withClue("char literal should have been replaced by ubyte literal") {
|
2022-02-11 00:21:40 +01:00
|
|
|
funCall.args[0] shouldBe instanceOf<NumericLiteral>()
|
2021-11-08 00:16:58 +01:00
|
|
|
}
|
2022-02-11 00:21:40 +01:00
|
|
|
val arg = funCall.args[0] as NumericLiteral
|
2021-11-08 00:16:58 +01:00
|
|
|
arg.type shouldBe DataType.UBYTE
|
2022-01-18 21:21:49 +01:00
|
|
|
arg.number shouldBe platform.encodeString("\n", Encoding.PETSCII)[0].toDouble()
|
2021-06-28 13:46:05 +02:00
|
|
|
}
|
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
test("testCharVarAsRomsubArg") {
|
2022-02-06 21:29:06 +01:00
|
|
|
val platform = Cx16Target()
|
2021-07-13 09:47:31 +02:00
|
|
|
val result = compileText(platform, false, """
|
|
|
|
main {
|
|
|
|
romsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
|
|
|
sub start() {
|
|
|
|
ubyte ch = '\n'
|
|
|
|
chrout(ch)
|
|
|
|
}
|
|
|
|
}
|
2022-03-07 21:41:12 +01:00
|
|
|
""")!!
|
2021-07-11 18:18:27 +02:00
|
|
|
|
2023-02-09 01:46:23 +01:00
|
|
|
val program = result.compilerAst
|
2021-10-11 00:01:26 +02:00
|
|
|
val startSub = program.entrypoint
|
2021-06-28 13:46:05 +02:00
|
|
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
funCall.args[0] shouldBe instanceOf<IdentifierReference>()
|
2021-06-28 13:46:05 +02:00
|
|
|
val arg = funCall.args[0] as IdentifierReference
|
|
|
|
val decl = arg.targetVarDecl(program)!!
|
2021-11-08 00:16:58 +01:00
|
|
|
decl.type shouldBe VarDeclType.VAR
|
|
|
|
decl.datatype shouldBe DataType.UBYTE
|
2021-06-28 13:46:05 +02:00
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
withClue("initializer value should have been moved to separate assignment"){
|
|
|
|
decl.value shouldBe null
|
|
|
|
}
|
2022-01-11 00:34:44 +01:00
|
|
|
val assignInitialValue = decl.findInitializer(program)!!
|
2021-11-08 00:16:58 +01:00
|
|
|
assignInitialValue.target.identifier!!.nameInSource shouldBe listOf("ch")
|
|
|
|
withClue("char literal should have been replaced by ubyte literal") {
|
2022-02-11 00:21:40 +01:00
|
|
|
assignInitialValue.value shouldBe instanceOf<NumericLiteral>()
|
2021-11-08 00:16:58 +01:00
|
|
|
}
|
2022-02-11 00:21:40 +01:00
|
|
|
val initializerValue = assignInitialValue.value as NumericLiteral
|
2021-11-08 00:16:58 +01:00
|
|
|
initializerValue.type shouldBe DataType.UBYTE
|
2022-01-18 21:21:49 +01:00
|
|
|
initializerValue.number shouldBe platform.encodeString("\n", Encoding.PETSCII)[0].toDouble()
|
2021-06-28 13:46:05 +02:00
|
|
|
}
|
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
test("testCharConstAsRomsubArg") {
|
2022-02-06 21:29:06 +01:00
|
|
|
val platform = Cx16Target()
|
2021-07-13 09:47:31 +02:00
|
|
|
val result = compileText(platform, false, """
|
|
|
|
main {
|
|
|
|
romsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
|
|
|
sub start() {
|
|
|
|
const ubyte ch = '\n'
|
|
|
|
chrout(ch)
|
|
|
|
}
|
|
|
|
}
|
2022-03-07 21:41:12 +01:00
|
|
|
""")!!
|
2021-07-11 18:18:27 +02:00
|
|
|
|
2023-02-09 01:46:23 +01:00
|
|
|
val program = result.compilerAst
|
2021-10-11 00:01:26 +02:00
|
|
|
val startSub = program.entrypoint
|
2021-06-28 13:46:05 +02:00
|
|
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
|
|
|
|
|
|
|
// Now, both is ok for the arg: a) still the IdRef or b) replaced by numeric literal
|
|
|
|
when (val arg = funCall.args[0]) {
|
|
|
|
is IdentifierReference -> {
|
|
|
|
val decl = arg.targetVarDecl(program)!!
|
2021-11-08 00:16:58 +01:00
|
|
|
decl.type shouldBe VarDeclType.CONST
|
|
|
|
decl.datatype shouldBe DataType.UBYTE
|
2022-02-11 00:21:40 +01:00
|
|
|
(decl.value as NumericLiteral).number shouldBe platform.encodeString("\n", Encoding.PETSCII)[0]
|
2021-06-28 13:46:05 +02:00
|
|
|
}
|
2022-02-11 00:21:40 +01:00
|
|
|
is NumericLiteral -> {
|
2022-01-18 21:21:49 +01:00
|
|
|
arg.number shouldBe platform.encodeString("\n", Encoding.PETSCII)[0].toDouble()
|
2021-06-28 13:46:05 +02:00
|
|
|
}
|
2021-11-08 00:16:58 +01:00
|
|
|
else -> fail("invalid arg type") // funCall.args[0] shouldBe instanceOf<IdentifierReference>() // make test fail
|
2021-06-28 13:46:05 +02:00
|
|
|
}
|
|
|
|
}
|
2021-07-13 09:47:31 +02:00
|
|
|
|
2021-11-08 00:16:58 +01:00
|
|
|
})
|