1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-05-31 18:41:30 +00:00
millfork/src/test/scala/millfork/test/ArraySuite.scala
2019-04-30 00:41:42 +02:00

301 lines
7.4 KiB
Scala

package millfork.test
import millfork.{Cpu, CpuFamily, OptimizationPresets}
import millfork.assembly.mos.opt.{AlwaysGoodOptimizations, DangerousOptimizations}
import millfork.test.emu._
import org.scalatest.{FunSuite, Matchers}
/**
* @author Karol Stasiak
*/
class ArraySuite extends FunSuite with Matchers {
test("Array assignment") {
val src =
"""
| array output [3] @$c000
| array input = [5,6,7]
| void main () {
| copyEntry(0)
| copyEntry(1)
| copyEntry(2)
| }
| void copyEntry(byte index) {
| output[index] = input[index]
| }
""".stripMargin
val m = EmuSuperOptimizedRun(src)
m.readByte(0xc000) should equal(5)
m.readByte(0xc001) should equal(6)
m.readByte(0xc002) should equal(7)
EmuCrossPlatformBenchmarkRun(Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(src) { m =>
m.readByte(0xc000) should equal(5)
m.readByte(0xc001) should equal(6)
m.readByte(0xc002) should equal(7)
}
}
test("Array assignment with offset") {
val src =
"""
| array output [8] @$c000
| void main () {
| byte i
| i = 0
| while i != 6 {
| output[i + 2] = i + 1
| output[i] = output[i]
| i += 1
| }
| }
""".stripMargin
EmuUltraBenchmarkRun(src) { m =>
m.readByte(0xc002) should equal(1)
m.readByte(0xc007) should equal(6)
}
EmuCrossPlatformBenchmarkRun(Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(src) { m =>
m.readByte(0xc002) should equal(1)
m.readByte(0xc007) should equal(6)
}
}
test("Array assignment with offset 1") {
val m = new EmuRun(Cpu.StrictMos, Nil, DangerousOptimizations.All ++ OptimizationPresets.Good)(
"""
| array output [8] @$c000
| void main () {
| byte i
| i = 0
| while i != 6 {
| output[i + 2] = i + 1
| output[i] = output[i]
| i += 1
| }
| }
""".stripMargin)
m.readByte(0xc002) should equal(1)
m.readByte(0xc007) should equal(6)
}
test("Array assignment through a pointer") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| array output [3] @$c000
| pointer p
| void main () {
| p = output.addr
| byte i
| byte ignored
| i = 1
| word w
| w = $105
| p[i]:ignored = w
| }
""".stripMargin) { m =>
m.readByte(0xc001) should equal(1)
}
}
test("Array in place math") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| array output [4] @$c000
| void main () {
| byte i
| i = 3
| output[i] = 3
| output[i + 1 - 1] *= 4
| output[3] *= 5
| }
""".stripMargin)(_.readByte(0xc003) should equal(60))
}
test("Array simple read") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| byte output @$c000
| array a[7]
| void main () {
| byte i
| i = 6
| a[i] = 6
| output = a[i]
| }
""".stripMargin)(_.readByte(0xc000) should equal(6))
}
test("Array simple read 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| word output @$c000
| array a[7]
| void main () {
| output = 777
| byte i
| i = 6
| a[i] = 6
| output = a[i]
| }
""".stripMargin){m =>
m.readByte(0xc000) should equal(6)
m.readByte(0xc001) should equal(0)
}
}
test("Pointers") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| byte output
| pointer a
| pointer b
| pointer c
| void main () {
| setup()
| reset()
| }
| void setup() {
| a = output.addr
| b = output.addr
| c = output.addr
| }
| void reset() {
| a[0] = 0
| b[0] = 0
| c[0] = 0
| }
""".stripMargin)(_.readByte(0xc000) should equal(0))
}
test("Pointer indexing test") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| array output [4] @$c000
| pointer a
| byte i
| void main () {
| setup()
| a[i + 1] = 55
| }
| void setup() {
| a = output.addr
| i = 2
| }
""".stripMargin)(_.readByte(0xc003) should equal(55))
}
test("Syntax") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| array a = [1, 2, 3]
| array b = "text" ascii
| array c = ["text" ascii, 5]
| void main () {
| }
""".stripMargin){m => ()}
}
test("Negative subindex") {
EmuUnoptimizedCrossPlatformRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
|
| array output [$fff] @$c000
| void main () {
| byte i
| output[$100] = 55
| i = one()
| output[1 - i] = 5
| }
| noinline byte one() {return 1}
""".stripMargin) { m =>
m.dump(0xbf00, 0x200)(println(_))
m.readByte(0xc100) should equal(55)
m.readByte(0xc000) should equal(5)
}
}
test("Word subindex 1") {
EmuBenchmarkRun(
"""
|
| array output [$fff] @$c000
| void main () {
| word i
| i = big()
| output[$64] = 55
| output[i] = 6
| output[i] = 5
| }
| noinline word big() {return $564}
""".stripMargin) {m =>
m.readByte(0xc064) should equal(55)
m.readByte(0xc564) should equal(5)
}
}
test("Word subindex 2") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
|
| array output [$fff] @$c000
| void main () {
| word i
| pointer o
| o = p()
| i = big()
| o[$164] = 55
| o[i] = 5
| }
| noinline word big() {return $564}
| noinline word p() {return output.addr}
""".stripMargin) {m =>
m.readByte(0xc164) should equal(55)
m.readByte(0xc564) should equal(5)
}
}
test("Array filters") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| array x = @word [$1144]
| byte output @$c000
| void main () {
| output = x[0]
| }
""".stripMargin) { m =>
m.readByte(0xc000) should equal(0x44)
}
}
test("Const arrays") {
EmuCrossPlatformBenchmarkRun(Cpu.Mos, Cpu.Z80, Cpu.Intel8080, Cpu.Sharp)(
"""
| const array square = [0, 1, 4, 9, 16, 25, 36, 49, 64]
| byte five() = 5
| byte output0 @$c000
| byte output1 @$c001
| void main () {
| output0 = square[3]
| output1 = square[five()]
| }
""".stripMargin) { m =>
m.readByte(0xc000) should equal(9)
m.readByte(0xc001) should equal(25)
}
}
test("Writing to const arrays should not compile") {
ShouldNotCompile(
"""
| const array a = [0]
| void main () {
| a[0] = 5
| }
""".stripMargin)
}
}