2021-06-28 11:46:05 +00:00
|
|
|
package prog8tests
|
|
|
|
|
2021-07-11 17:04:53 +00:00
|
|
|
import org.junit.jupiter.api.Test
|
2021-10-10 22:22:04 +00:00
|
|
|
import org.junit.jupiter.api.TestInstance
|
2021-06-28 11:46:05 +00:00
|
|
|
import prog8.ast.IFunctionCall
|
|
|
|
import prog8.ast.base.DataType
|
|
|
|
import prog8.ast.base.VarDeclType
|
|
|
|
import prog8.ast.expressions.IdentifierReference
|
|
|
|
import prog8.ast.expressions.NumericLiteralValue
|
2021-07-01 22:11:21 +00:00
|
|
|
import prog8.compiler.target.Cx16Target
|
2021-10-10 22:22:04 +00:00
|
|
|
import prog8tests.helpers.assertSuccess
|
|
|
|
import prog8tests.helpers.compileText
|
|
|
|
import kotlin.test.assertEquals
|
|
|
|
import kotlin.test.assertIs
|
2021-06-28 11:46:05 +00:00
|
|
|
|
|
|
|
|
2021-06-28 16:49:01 +00: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-06-28 11:46:05 +00:00
|
|
|
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
|
|
|
|
class TestCompilerOnCharLit {
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testCharLitAsRomsubArg() {
|
2021-07-11 16:18:27 +00:00
|
|
|
val platform = Cx16Target
|
2021-07-13 07:47:31 +00:00
|
|
|
val result = compileText(platform, false, """
|
|
|
|
main {
|
|
|
|
romsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
|
|
|
sub start() {
|
|
|
|
chrout('\n')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
""").assertSuccess()
|
2021-06-28 11:46:05 +00:00
|
|
|
|
|
|
|
val program = result.programAst
|
2021-10-10 22:01:26 +00:00
|
|
|
val startSub = program.entrypoint
|
2021-06-28 11:46:05 +00:00
|
|
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
|
|
|
|
|
|
|
assertIs<NumericLiteralValue>(funCall.args[0],
|
|
|
|
"char literal should have been replaced by ubyte literal")
|
|
|
|
val arg = funCall.args[0] as NumericLiteralValue
|
|
|
|
assertEquals(DataType.UBYTE, arg.type)
|
2021-06-28 10:04:34 +00:00
|
|
|
assertEquals(platform.encodeString("\n", false)[0], arg.number.toShort()) // TODO: short/int/UBYTE - which should it be?
|
2021-06-28 11:46:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testCharVarAsRomsubArg() {
|
2021-07-11 16:18:27 +00:00
|
|
|
val platform = Cx16Target
|
2021-07-13 07:47:31 +00:00
|
|
|
val result = compileText(platform, false, """
|
|
|
|
main {
|
|
|
|
romsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
|
|
|
sub start() {
|
|
|
|
ubyte ch = '\n'
|
|
|
|
chrout(ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
""").assertSuccess()
|
2021-07-11 16:18:27 +00:00
|
|
|
|
2021-06-28 11:46:05 +00:00
|
|
|
val program = result.programAst
|
2021-10-10 22:01:26 +00:00
|
|
|
val startSub = program.entrypoint
|
2021-06-28 11:46:05 +00:00
|
|
|
val funCall = startSub.statements.filterIsInstance<IFunctionCall>()[0]
|
|
|
|
|
|
|
|
assertIs<IdentifierReference>(funCall.args[0])
|
|
|
|
val arg = funCall.args[0] as IdentifierReference
|
|
|
|
val decl = arg.targetVarDecl(program)!!
|
|
|
|
assertEquals(VarDeclType.VAR, decl.type)
|
|
|
|
assertEquals(DataType.UBYTE, decl.datatype)
|
|
|
|
|
|
|
|
// TODO: assertIs<CharLiteral>(decl.value,
|
|
|
|
// "char literals should be kept until code gen")
|
|
|
|
// val initializerValue = decl.value as CharLiteral
|
|
|
|
// assertEquals('\n', (initializerValue as CharLiteral).value)
|
|
|
|
|
|
|
|
assertIs<NumericLiteralValue>(decl.value,
|
|
|
|
"char literal should have been replaced by ubyte literal")
|
|
|
|
val initializerValue = decl.value as NumericLiteralValue
|
|
|
|
assertEquals(DataType.UBYTE, initializerValue.type)
|
2021-06-28 10:04:34 +00:00
|
|
|
assertEquals(platform.encodeString("\n", false)[0], initializerValue.number.toShort()) // TODO: short/int/UBYTE - which should it be?
|
2021-06-28 11:46:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Test
|
|
|
|
fun testCharConstAsRomsubArg() {
|
2021-07-11 16:18:27 +00:00
|
|
|
val platform = Cx16Target
|
2021-07-13 07:47:31 +00:00
|
|
|
val result = compileText(platform, false, """
|
|
|
|
main {
|
|
|
|
romsub ${"$"}FFD2 = chrout(ubyte ch @ A)
|
|
|
|
sub start() {
|
|
|
|
const ubyte ch = '\n'
|
|
|
|
chrout(ch)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
""").assertSuccess()
|
2021-07-11 16:18:27 +00:00
|
|
|
|
2021-06-28 11:46:05 +00:00
|
|
|
val program = result.programAst
|
2021-10-10 22:01:26 +00:00
|
|
|
val startSub = program.entrypoint
|
2021-06-28 11:46:05 +00: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)!!
|
|
|
|
assertEquals(VarDeclType.CONST, decl.type)
|
|
|
|
assertEquals(DataType.UBYTE, decl.datatype)
|
|
|
|
assertEquals(
|
2021-07-11 16:18:27 +00:00
|
|
|
platform.encodeString("\n", false)[0],
|
2021-06-28 10:04:34 +00:00
|
|
|
(decl.value as NumericLiteralValue).number.toShort()) // TODO: short/int/UBYTE - which should it be?
|
2021-06-28 11:46:05 +00:00
|
|
|
}
|
|
|
|
is NumericLiteralValue -> {
|
|
|
|
assertEquals(
|
2021-07-11 16:18:27 +00:00
|
|
|
platform.encodeString("\n", false)[0],
|
2021-06-28 10:04:34 +00:00
|
|
|
arg.number.toShort()) // TODO: short/int/UBYTE - which should it be?
|
2021-06-28 11:46:05 +00:00
|
|
|
}
|
|
|
|
else -> assertIs<IdentifierReference>(funCall.args[0]) // make test fail
|
|
|
|
}
|
|
|
|
}
|
2021-07-13 07:47:31 +00:00
|
|
|
|
2021-07-01 22:11:21 +00:00
|
|
|
}
|
2021-07-13 07:47:31 +00:00
|
|
|
|