mirror of
https://github.com/irmen/prog8.git
synced 2024-11-01 15:07:10 +00:00
Merge branch 'master' into codegen-on-new-ast
This commit is contained in:
commit
3f3b01b5f6
@ -306,6 +306,8 @@ internal class AstChecker(private val program: Program,
|
|||||||
err("subroutines can only be defined in the scope of a block or within another subroutine")
|
err("subroutines can only be defined in the scope of a block or within another subroutine")
|
||||||
|
|
||||||
if(subroutine.isAsmSubroutine) {
|
if(subroutine.isAsmSubroutine) {
|
||||||
|
if(compilerOptions.compTarget.name==VMTarget.NAME)
|
||||||
|
err("cannot use asmsub for vm target, use regular subs")
|
||||||
if(subroutine.asmParameterRegisters.size != subroutine.parameters.size)
|
if(subroutine.asmParameterRegisters.size != subroutine.parameters.size)
|
||||||
err("number of asm parameter registers is not the isSameAs as number of parameters")
|
err("number of asm parameter registers is not the isSameAs as number of parameters")
|
||||||
if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size)
|
if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size)
|
||||||
|
@ -14,6 +14,7 @@ import prog8.intermediate.IRFileReader
|
|||||||
import prog8.intermediate.IRSubroutine
|
import prog8.intermediate.IRSubroutine
|
||||||
import prog8.intermediate.Opcode
|
import prog8.intermediate.Opcode
|
||||||
import prog8.vm.VmRunner
|
import prog8.vm.VmRunner
|
||||||
|
import prog8tests.helpers.ErrorReporterForTests
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
import kotlin.io.path.readText
|
import kotlin.io.path.readText
|
||||||
|
|
||||||
@ -218,7 +219,7 @@ main {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("asmsub for virtual target") {
|
test("asmsub for virtual target not supported") {
|
||||||
val src = """
|
val src = """
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
@ -230,6 +231,28 @@ main {
|
|||||||
lda #99
|
lda #99
|
||||||
tay
|
tay
|
||||||
rts
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val othertarget = Cx16Target()
|
||||||
|
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
|
||||||
|
|
||||||
|
val target = VMTarget()
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
compileText(target, false, src, writeAssembly = false, errors = errors) shouldBe null
|
||||||
|
errors.errors.size shouldBe 1
|
||||||
|
errors.errors[0] shouldContain "cannot use asmsub for vm target"
|
||||||
|
}
|
||||||
|
|
||||||
|
test("asmsub for virtual target not supported even with IR") {
|
||||||
|
val src = """
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
void test(42)
|
||||||
|
}
|
||||||
|
|
||||||
|
asmsub test(ubyte xx @A) -> ubyte @Y {
|
||||||
|
%ir {{
|
||||||
return
|
return
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
@ -237,13 +260,52 @@ main {
|
|||||||
val othertarget = Cx16Target()
|
val othertarget = Cx16Target()
|
||||||
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
|
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
|
||||||
|
|
||||||
|
val target = VMTarget()
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
compileText(target, false, src, writeAssembly = false, errors = errors) shouldBe null
|
||||||
|
errors.errors.size shouldBe 1
|
||||||
|
errors.errors[0] shouldContain "cannot use asmsub for vm target"
|
||||||
|
}
|
||||||
|
|
||||||
|
test("inline asm for virtual target should be IR") {
|
||||||
|
val src = """
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
%asm {{
|
||||||
|
lda #99
|
||||||
|
tay
|
||||||
|
rts
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val othertarget = Cx16Target()
|
||||||
|
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
|
||||||
|
|
||||||
val target = VMTarget()
|
val target = VMTarget()
|
||||||
val result = compileText(target, false, src, writeAssembly = true)!!
|
val result = compileText(target, false, src, writeAssembly = true)!!
|
||||||
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||||
val exc = shouldThrow<Exception> {
|
val exc = shouldThrow<Exception> {
|
||||||
VmRunner().runProgram(virtfile.readText())
|
VmRunner().runProgram(virtfile.readText())
|
||||||
}
|
}
|
||||||
exc.message shouldContain("does not support non-IR asmsubs")
|
exc.message shouldContain("does not support real inlined assembly")
|
||||||
|
}
|
||||||
|
|
||||||
|
test("inline asm for virtual target with IR is accepted") {
|
||||||
|
val src = """
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
%ir {{
|
||||||
|
return
|
||||||
|
}}
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val othertarget = Cx16Target()
|
||||||
|
compileText(othertarget, true, src, writeAssembly = true) shouldNotBe null
|
||||||
|
|
||||||
|
val target = VMTarget()
|
||||||
|
val result = compileText(target, false, src, writeAssembly = true)!!
|
||||||
|
val virtfile = result.compilationOptions.outputDir.resolve(result.program.name + ".p8ir")
|
||||||
|
VmRunner().runProgram(virtfile.readText())
|
||||||
}
|
}
|
||||||
|
|
||||||
test("addresses from labels/subroutines not yet supported in VM") {
|
test("addresses from labels/subroutines not yet supported in VM") {
|
||||||
|
@ -38,14 +38,7 @@ class VmProgramLoader {
|
|||||||
|
|
||||||
block.children.forEach { child ->
|
block.children.forEach { child ->
|
||||||
when(child) {
|
when(child) {
|
||||||
is IRAsmSubroutine -> {
|
is IRAsmSubroutine -> throw IRParseException("vm does not support asmsubs (use normal sub): ${child.label}")
|
||||||
if(!child.asmChunk.isIR)
|
|
||||||
throw IRParseException("vm currently does not support non-IR asmsubs: ${child.label}")
|
|
||||||
else {
|
|
||||||
val replacement = addAssemblyToProgram(child.asmChunk, programChunks, variableAddresses)
|
|
||||||
chunkReplacements += replacement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is IRCodeChunk -> programChunks += child
|
is IRCodeChunk -> programChunks += child
|
||||||
is IRInlineAsmChunk -> {
|
is IRInlineAsmChunk -> {
|
||||||
val replacement = addAssemblyToProgram(child, programChunks, variableAddresses)
|
val replacement = addAssemblyToProgram(child, programChunks, variableAddresses)
|
||||||
|
@ -2,7 +2,6 @@ import io.kotest.assertions.throwables.shouldThrowWithMessage
|
|||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
import io.kotest.matchers.collections.shouldBeEmpty
|
import io.kotest.matchers.collections.shouldBeEmpty
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
|
||||||
import prog8.code.core.*
|
import prog8.code.core.*
|
||||||
import prog8.code.target.VMTarget
|
import prog8.code.target.VMTarget
|
||||||
import prog8.intermediate.*
|
import prog8.intermediate.*
|
||||||
@ -84,7 +83,7 @@ class TestVm: FunSpec( {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("non-IR asmsub not supported in vm") {
|
test("asmsub not supported in vm even with IR") {
|
||||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
||||||
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
||||||
val startSub = IRAsmSubroutine(
|
val startSub = IRAsmSubroutine(
|
||||||
@ -93,33 +92,16 @@ class TestVm: FunSpec( {
|
|||||||
emptySet(),
|
emptySet(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
emptyList(),
|
emptyList(),
|
||||||
IRInlineAsmChunk("main.asmstart", "inlined asm here", false, null),
|
IRInlineAsmChunk("main.asmstart", "return", false, null),
|
||||||
Position.DUMMY
|
Position.DUMMY
|
||||||
)
|
)
|
||||||
block += startSub
|
block += startSub
|
||||||
program.addBlock(block)
|
program.addBlock(block)
|
||||||
shouldThrowWithMessage<IRParseException>("vm currently does not support non-IR asmsubs: main.asmstart") {
|
shouldThrowWithMessage<IRParseException>("vm does not support asmsubs (use normal sub): main.asmstart") {
|
||||||
VirtualMachine(program)
|
VirtualMachine(program)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
test("IR asmsub ok in vm") {
|
|
||||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
|
||||||
val block = IRBlock("main", null, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
|
||||||
val startSub = IRAsmSubroutine(
|
|
||||||
"main.start",
|
|
||||||
0x2000u,
|
|
||||||
emptySet(),
|
|
||||||
emptyList(),
|
|
||||||
emptyList(),
|
|
||||||
IRInlineAsmChunk("main.start", "return", true, null),
|
|
||||||
Position.DUMMY
|
|
||||||
)
|
|
||||||
block += startSub
|
|
||||||
program.addBlock(block)
|
|
||||||
VirtualMachine(program).run()
|
|
||||||
}
|
|
||||||
|
|
||||||
test("vmrunner") {
|
test("vmrunner") {
|
||||||
val runner = VmRunner()
|
val runner = VmRunner()
|
||||||
val irSource="""<?xml version="1.0" encoding="utf-8"?>
|
val irSource="""<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
Loading…
Reference in New Issue
Block a user