package prog8tests.ast import io.kotest.core.spec.style.FunSpec import io.kotest.matchers.shouldBe import io.kotest.matchers.shouldNotBe import io.kotest.matchers.types.instanceOf import prog8.ast.IFunctionCall import prog8.ast.expressions.* import prog8.ast.statements.Assignment import prog8.ast.statements.InlineAssembly import prog8.ast.statements.VarDecl import prog8.code.core.DataType import prog8.code.core.Position import prog8.code.target.C64Target import prog8tests.helpers.compileText class TestVariousCompilerAst: FunSpec({ test("symbol names in inline assembly blocks") { val names1 = InlineAssembly(""" """, false, Position.DUMMY).names names1 shouldBe emptySet() val names2 = InlineAssembly(""" label: lda #255") { val src=""" main { sub start() { uword pointer = ${'$'}2000 @(pointer+${'$'}1000) = 123 ubyte @shared ub = @(pointer+${'$'}1000) pointer[${'$'}1000] = 99 ub = pointer[${'$'}1000] uword index = ${'$'}1000 pointer[index] = 55 ub = pointer[index] } }""" compileText(C64Target(), optimize=false, src, writeAssembly=false) shouldNotBe null } test("bitshift left of const byte converted to word") { val src=""" main { sub start() { ubyte shift = 10 uword value = 1< ubyte { return lsb(x+y) } sub start() { uword[128] YY ubyte[] ARRAY = [1, 5, 2] repeat { ubyte pixel_side1 = pget(2, YY[2]+1) in ARRAY ubyte pixel_side2 = pget(2, 2) in ARRAY ubyte[] array2 = [1,2,3] } } }""" val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!! val stmts = result.compilerAst.entrypoint.statements stmts.size shouldBe 9 } test("alternative notation for negative containment check") { val src=""" main { sub start() { ubyte[] array=[1,2,3] cx16.r0L = not (3 in array) cx16.r1L = 3 not in array } } """ val result = compileText(C64Target(), optimize=false, src, writeAssembly=false)!! val stmts = result.compilerAst.entrypoint.statements stmts.size shouldBe 3 val value1 = (stmts[1] as Assignment).value as BinaryExpression val value2 = (stmts[2] as Assignment).value as BinaryExpression value1.operator shouldBe "==" value1.left shouldBe instanceOf() (value1.right as NumericLiteral).number shouldBe 0.0 value2.operator shouldBe "==" value2.left shouldBe instanceOf() (value2.right as NumericLiteral).number shouldBe 0.0 } })