mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
push,pushw,pop and popw are no longer built-in functions but regular routines in sys
This commit is contained in:
parent
38a22fbc99
commit
0d44492086
@ -125,10 +125,6 @@ val BuiltinFunctions: Map<String, FSignature> = mapOf(
|
||||
"pokew" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD)), FParam("value", arrayOf(DataType.UWORD))), null),
|
||||
"pokef" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD)), FParam("value", arrayOf(DataType.FLOAT))), null),
|
||||
"pokemon" to FSignature(false, listOf(FParam("address", arrayOf(DataType.UWORD)), FParam("value", arrayOf(DataType.UBYTE))), DataType.UBYTE),
|
||||
"pop" to FSignature(false, listOf(FParam("target", ByteDatatypes)), null),
|
||||
"popw" to FSignature(false, listOf(FParam("target", WordDatatypes)), null),
|
||||
"push" to FSignature(false, listOf(FParam("value", ByteDatatypes)), null),
|
||||
"pushw" to FSignature(false, listOf(FParam("value", WordDatatypes)), null),
|
||||
"rsave" to FSignature(false, emptyList(), null),
|
||||
"rrestore" to FSignature(false, emptyList(), null),
|
||||
"memory" to FSignature(true, listOf(FParam("name", arrayOf(DataType.STR)), FParam("size", arrayOf(DataType.UWORD)), FParam("alignment", arrayOf(DataType.UWORD))), DataType.UWORD),
|
||||
|
@ -3059,30 +3059,16 @@ $repeatLabel""")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun popCpuStack(dt: DataType, target: IPtVariable, scope: IPtSubroutine?) {
|
||||
// note: because A is pushed first so popped last, saving A is often not required here.
|
||||
val targetAsmSub = (target as PtNode).definingAsmSub()
|
||||
if(targetAsmSub != null) {
|
||||
val parameter = targetAsmSub.parameters.first { it.second.name==target.name }
|
||||
popCpuStack(targetAsmSub, parameter.second, parameter.first)
|
||||
return
|
||||
}
|
||||
val scopedName = when(target) {
|
||||
is PtConstant -> target.scopedName
|
||||
is PtMemMapped -> target.scopedName
|
||||
is PtVariable -> target.scopedName
|
||||
else -> throw AssemblyError("weird target var")
|
||||
}
|
||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, this, target.type, scope, target.position, variableAsmName = asmVariableName(scopedName))
|
||||
internal fun popCpuStack(dt: DataType) {
|
||||
if (dt in ByteDatatypes) {
|
||||
out(" pla")
|
||||
assignRegister(RegisterOrPair.A, tgt)
|
||||
} else {
|
||||
} else if (dt in WordDatatypes) {
|
||||
if (isTargetCpu(CpuType.CPU65c02))
|
||||
out(" ply | pla")
|
||||
else
|
||||
out(" pla | tay | pla")
|
||||
assignRegister(RegisterOrPair.AY, tgt)
|
||||
} else {
|
||||
throw AssemblyError("can't pop type $dt")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,24 +63,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
asmgen.out(" pla")
|
||||
}
|
||||
"poke" -> throw AssemblyError("poke() should have been replaced by @()")
|
||||
"push" -> asmgen.pushCpuStack(DataType.UBYTE, fcall.args[0])
|
||||
"pushw" -> asmgen.pushCpuStack(DataType.UWORD, fcall.args[0])
|
||||
"pop" -> {
|
||||
require(fcall.args[0] is PtIdentifier) {
|
||||
"attempt to pop a value into a differently typed variable, or in something else that isn't supported ${fcall.position}"
|
||||
}
|
||||
val symbol = asmgen.symbolTable.lookup((fcall.args[0] as PtIdentifier).name)
|
||||
val target = symbol!!.astNode as IPtVariable
|
||||
asmgen.popCpuStack(DataType.UBYTE, target, fcall.definingISub())
|
||||
}
|
||||
"popw" -> {
|
||||
require(fcall.args[0] is PtIdentifier) {
|
||||
"attempt to pop a value into a differently typed variable, or in something else that isn't supported ${fcall.position}"
|
||||
}
|
||||
val symbol = asmgen.symbolTable.lookup((fcall.args[0] as PtIdentifier).name)
|
||||
val target = symbol!!.astNode as IPtVariable
|
||||
asmgen.popCpuStack(DataType.UWORD, target, fcall.definingISub())
|
||||
}
|
||||
"rsave" -> funcRsave()
|
||||
"rrestore" -> funcRrestore()
|
||||
"cmp" -> funcCmp(fcall)
|
||||
|
@ -20,10 +20,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
"sqrt__ubyte", "sqrt__uword", "sqrt__float" -> funcSqrt(call)
|
||||
"divmod__ubyte" -> funcDivmod(call, IRDataType.BYTE)
|
||||
"divmod__uword" -> funcDivmod(call, IRDataType.WORD)
|
||||
"pop" -> funcPop(call)
|
||||
"popw" -> funcPopw(call)
|
||||
"push" -> funcPush(call)
|
||||
"pushw" -> funcPushw(call)
|
||||
"rsave", "rrestore" -> ExpressionCodeResult.EMPTY // vm doesn't have registers to save/restore
|
||||
"callfar" -> funcCallfar(call)
|
||||
"call" -> funcCall(call)
|
||||
@ -278,44 +274,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcPop(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val code = IRCodeChunk(null, null)
|
||||
val reg = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.POP, IRDataType.BYTE, reg1=reg)
|
||||
val result = mutableListOf<IRCodeChunkBase>(code)
|
||||
result += assignRegisterTo(call.args.single(), reg)
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, reg, -1)
|
||||
}
|
||||
|
||||
private fun funcPopw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val code = IRCodeChunk(null, null)
|
||||
val reg = codeGen.registers.nextFree()
|
||||
code += IRInstruction(Opcode.POP, IRDataType.WORD, reg1=reg)
|
||||
val result = mutableListOf<IRCodeChunkBase>(code)
|
||||
result += assignRegisterTo(call.args.single(), reg)
|
||||
return ExpressionCodeResult(result, IRDataType.WORD, reg, -1)
|
||||
}
|
||||
|
||||
private fun funcPush(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.BYTE, reg1=tr.resultReg)
|
||||
}
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcPushw(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val result = mutableListOf<IRCodeChunkBase>()
|
||||
val tr = exprGen.translateExpression(call.args.single())
|
||||
addToResult(result, tr, tr.resultReg, -1)
|
||||
result += IRCodeChunk(null, null).also {
|
||||
it += IRInstruction(Opcode.PUSH, IRDataType.WORD, reg1 = tr.resultReg)
|
||||
}
|
||||
return ExpressionCodeResult(result, IRDataType.BYTE, -1, -1)
|
||||
}
|
||||
|
||||
private fun funcReverse(call: PtBuiltinFunctionCall): ExpressionCodeResult {
|
||||
val arrayName = call.args[0] as PtIdentifier
|
||||
val arrayLength = codeGen.symbolTable.getLength(arrayName.name)
|
||||
|
@ -269,6 +269,34 @@ save_SCRATCH_ZPWORD2 .word 0
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cx16 {
|
||||
|
@ -774,6 +774,34 @@ _longcopy
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cx16 {
|
||||
|
@ -772,6 +772,33 @@ _longcopy
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
cx16 {
|
||||
|
@ -114,10 +114,10 @@ psg {
|
||||
; cx16.r0 = the volume word (volume scaled by 256)
|
||||
; cx16.r1L = the voice number
|
||||
; cx16.r2L = attack value
|
||||
pushw(cx16.r0)
|
||||
push(cx16.r1L)
|
||||
push(cx16.r2L)
|
||||
pushw(cx16.r9)
|
||||
sys.pushw(cx16.r0)
|
||||
sys.push(cx16.r1L)
|
||||
sys.push(cx16.r2L)
|
||||
sys.pushw(cx16.r9)
|
||||
; calculate new volumes
|
||||
for cx16.r1L in 0 to 15 {
|
||||
when envelope_states[cx16.r1L] {
|
||||
@ -166,10 +166,10 @@ psg {
|
||||
cx16.VERA_DATA0 = cx16.VERA_DATA1 & %11000000 | msb(envelope_volumes[cx16.r1L])
|
||||
}
|
||||
cx16.restore_vera_context()
|
||||
popw(cx16.r9)
|
||||
pop(cx16.r2L)
|
||||
pop(cx16.r1L)
|
||||
popw(cx16.r0)
|
||||
cx16.r9 = sys.popw()
|
||||
cx16.r2L = sys.pop()
|
||||
cx16.r1L = sys.pop()
|
||||
cx16.r0 = sys.popw()
|
||||
return true ; run the system IRQ handler afterwards
|
||||
}
|
||||
|
||||
|
@ -1615,4 +1615,31 @@ save_SCRATCH_ZPWORD2 .word 0
|
||||
ldy #>prog8_program_end
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
phy
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
ply
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -361,6 +361,34 @@ save_SCRATCH_ZPWORD2 .word 0
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub push(ubyte value @A) {
|
||||
%asm {{
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pushw(uword value @AY) {
|
||||
%asm {{
|
||||
pha
|
||||
tya
|
||||
pha
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub pop() -> ubyte @A {
|
||||
%asm {{
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
inline asmsub popw() -> uword @AY {
|
||||
%asm {{
|
||||
pla
|
||||
tay
|
||||
pla
|
||||
}}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
cx16 {
|
||||
|
@ -126,6 +126,38 @@ sys {
|
||||
returnr.b r0
|
||||
}}
|
||||
}
|
||||
|
||||
sub push(ubyte b) {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
loadm.b r65535,sys.push.b
|
||||
push.b r65535
|
||||
}}
|
||||
}
|
||||
|
||||
sub pushw(uword w) {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
loadm.w r65535,sys.pushw.w
|
||||
push.w r65535
|
||||
}}
|
||||
}
|
||||
|
||||
sub pop() -> ubyte {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
pop.b r65535
|
||||
returnr.b r65535
|
||||
}}
|
||||
}
|
||||
|
||||
sub popw() -> uword {
|
||||
; note: this *should* be inlined, however since the VM has separate program counter and value stacks, this also works
|
||||
%ir {{
|
||||
pop.w r65535
|
||||
returnr.w r65535
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
||||
cx16 {
|
||||
|
@ -1216,19 +1216,6 @@ internal class AstChecker(private val program: Program,
|
||||
errors.err("sorting a floating point array is not supported", functionCallStatement.args.first().position)
|
||||
}
|
||||
}
|
||||
else if(funcName[0] in arrayOf("pop", "popw")) {
|
||||
// can only pop into a variable, that has to have the correct type
|
||||
val idref = functionCallStatement.args[0]
|
||||
if(idref !is IdentifierReference) {
|
||||
if(idref is TypecastExpression) {
|
||||
val passByRef = idref.expression.inferType(program).isPassByReference
|
||||
if(idref.type!=DataType.UWORD || !passByRef)
|
||||
errors.err("invalid argument to pop, must be a variable with the correct type: ${functionCallStatement.args.first()}", functionCallStatement.args.first().position)
|
||||
} else {
|
||||
errors.err("invalid argument to pop, must be a variable with the correct type: ${functionCallStatement.args.first()}", functionCallStatement.args.first().position)
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(funcName[0].startsWith("divmod")) {
|
||||
if(functionCallStatement.args[2] is TypecastExpression || functionCallStatement.args[3] is TypecastExpression) {
|
||||
errors.err("arguments must be all ubyte or all uword", functionCallStatement.position)
|
||||
|
@ -2,7 +2,6 @@ package prog8tests
|
||||
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.shouldNotBe
|
||||
import prog8.ast.expressions.NumericLiteral
|
||||
import prog8.ast.statements.Assignment
|
||||
import prog8.ast.statements.FunctionCallStatement
|
||||
@ -69,19 +68,6 @@ class TestBuiltinFunctions: FunSpec({
|
||||
conv.returns.reg shouldBe null
|
||||
}
|
||||
|
||||
test("push pop") {
|
||||
val src="""
|
||||
main {
|
||||
sub start () {
|
||||
pushw(cx16.r0)
|
||||
push(cx16.r1L)
|
||||
pop(cx16.r1L)
|
||||
popw(cx16.r0)
|
||||
}
|
||||
}"""
|
||||
compileText(Cx16Target(), false, src, writeAssembly = true) shouldNotBe null
|
||||
}
|
||||
|
||||
test("certain builtin functions should be compile time evaluated") {
|
||||
val src="""
|
||||
main {
|
||||
|
@ -693,9 +693,9 @@ main {
|
||||
sub start() {
|
||||
uword variable
|
||||
|
||||
pushw(variable)
|
||||
pushw(handler)
|
||||
pushw(&handler)
|
||||
sys.pushw(variable)
|
||||
sys.pushw(handler)
|
||||
sys.pushw(&handler)
|
||||
handler(variable)
|
||||
handler(handler)
|
||||
handler(&handler)
|
||||
|
@ -16,6 +16,7 @@ import prog8.code.target.Cx16Target
|
||||
import prog8.code.target.VMTarget
|
||||
import prog8tests.helpers.ErrorReporterForTests
|
||||
import prog8tests.helpers.compileText
|
||||
import kotlin.io.path.readText
|
||||
|
||||
class TestVariousCodeGen: FunSpec({
|
||||
test("bool to byte cast in expression is correct") {
|
||||
@ -358,4 +359,24 @@ main {
|
||||
compileText(VMTarget(), true, src, writeAssembly = false) shouldNotBe null
|
||||
compileText(Cx16Target(), true, src, writeAssembly = false) shouldNotBe null
|
||||
}
|
||||
|
||||
test("push pop are inlined also with noopt") {
|
||||
val text = """
|
||||
main {
|
||||
sub start() {
|
||||
sys.push(11)
|
||||
sys.pushw(2222)
|
||||
cx16.r2++
|
||||
cx16.r1 = sys.popw()
|
||||
cx16.r0L = sys.pop()
|
||||
}
|
||||
}"""
|
||||
val result = compileText(C64Target(), false, text, writeAssembly = true)!!
|
||||
val assemblyFile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".asm")
|
||||
val assembly = assemblyFile.readText()
|
||||
assembly shouldContain "inlined routine follows: push"
|
||||
assembly shouldContain "inlined routine follows: pushw"
|
||||
assembly shouldContain "inlined routine follows: pop"
|
||||
assembly shouldContain "inlined routine follows: popw"
|
||||
}
|
||||
})
|
@ -140,6 +140,20 @@ sys (part of syslib)
|
||||
It stores and restores the values of the internal prog8 variables.
|
||||
This allows other code to run that might clobber these values temporarily.
|
||||
|
||||
``push (value)``
|
||||
pushes a byte value on the CPU hardware stack. Low-level function that should normally not be used.
|
||||
|
||||
``pushw (value)``
|
||||
pushes a 16-bit word value on the CPU hardware stack. Low-level function that should normally not be used.
|
||||
|
||||
``pop ()``
|
||||
pops a byte value off the CPU hardware stack and returns it.
|
||||
Low-level function that should normally not be used.
|
||||
|
||||
``popw ()``
|
||||
pops a 16-bit word value off the CPU hardware stack and returns it.
|
||||
Low-level function that should normally not be used.
|
||||
|
||||
|
||||
conv
|
||||
----
|
||||
|
@ -898,20 +898,6 @@ pokemon (address, value)
|
||||
Like poke(), but also returns the previous value in the given address.
|
||||
Also doesn't have anything to do with a certain video game.
|
||||
|
||||
push (value)
|
||||
pushes a byte value on the CPU hardware stack. Low-level function that should normally not be used.
|
||||
|
||||
pushw (value)
|
||||
pushes a 16-bit word value on the CPU hardware stack. Low-level function that should normally not be used.
|
||||
|
||||
pop (variable)
|
||||
pops a byte value off the CPU hardware stack into the given variable. Only variables can be used.
|
||||
Low-level function that should normally not be used.
|
||||
|
||||
popw (value)
|
||||
pops a 16-bit word value off the CPU hardware stack into the given variable. Only variables can be used.
|
||||
Low-level function that should normally not be used.
|
||||
|
||||
rol (x)
|
||||
Rotate the bits in x (byte or word) one position to the left.
|
||||
This uses the CPU's rotate semantics: bit 0 will be set to the current value of the Carry flag,
|
||||
|
@ -1,14 +1,25 @@
|
||||
%import textio
|
||||
%zeropage dontuse
|
||||
;;%import floats
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
sub start() {
|
||||
uword empty
|
||||
uword block = memory("block", 500, 0)
|
||||
sys.push(11)
|
||||
sys.pushw(2222)
|
||||
;;floats.pushf(floats.π)
|
||||
cx16.r2++
|
||||
|
||||
txt.print_uwhex(&empty, true)
|
||||
;;float pi = floats.popf()
|
||||
;;floats.print_f(pi)
|
||||
;;txt.nl()
|
||||
|
||||
cx16.r1 = sys.popw()
|
||||
cx16.r0L = sys.pop()
|
||||
|
||||
txt.print_ub(cx16.r0L)
|
||||
txt.nl()
|
||||
txt.print_uwhex(block, true)
|
||||
txt.print_uw(cx16.r1)
|
||||
txt.nl()
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
<filetype binary="false" default_extension="prog8" description="Prog8 source file" name="Prog8">
|
||||
<filetype binary="false" default_extension="p8" description="Prog8 source file" name="Prog8">
|
||||
<highlighting>
|
||||
<options>
|
||||
<option name="LINE_COMMENT" value=";" />
|
||||
@ -14,10 +14,10 @@
|
||||
<keywords keywords="&;->;@;and;as;asmsub;break;clobbers;continue;do;downto;else;false;for;goto;if;if_cc;if_cs;if_eq;if_mi;if_ne;if_neg;if_nz;if_pl;if_pos;if_vc;if_vs;if_z;in;inline;not;or;repeat;return;romsub;step;sub;to;true;unroll;until;when;while;xor;~" ignore_case="false" />
|
||||
<keywords2 keywords="%address;%asm;%asmbinary;%asminclude;%breakpoint;%encoding;%import;%ir;%launcher;%option;%output;%zeropage;%zpallowed;%zpreserved;atascii:;default:;iso:;petscii:;sc:" />
|
||||
<keywords3 keywords="@requirezp;@shared;@split;@zp;bool;byte;const;float;str;ubyte;uword;void;word" />
|
||||
<keywords4 keywords="abs;all;any;call;callfar;clamp;cmp;divmod;len;lsb;max;memory;min;mkword;msb;peek;peekf;peekw;poke;pokef;pokew;pop;popw;push;pushw;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sort;sqrt;swap;|>" />
|
||||
<keywords4 keywords="abs;all;any;call;callfar;clamp;cmp;divmod;len;lsb;max;memory;min;mkword;msb;peek;peekf;peekw;poke;pokef;pokew;reverse;rol;rol2;ror;ror2;rrestore;rrestorex;rsave;rsavex;setlsb;setmsb;sgn;sizeof;sort;sqrt;swap;|>" />
|
||||
</highlighting>
|
||||
<extensionMap>
|
||||
<mapping ext="prog8" />
|
||||
<mapping ext="p8" />
|
||||
<mapping ext="prog8" />
|
||||
</extensionMap>
|
||||
</filetype>
|
@ -27,7 +27,7 @@
|
||||
<Keywords name="Keywords1">void const
str
byte ubyte bool
word uword
float
zp shared split requirezp</Keywords>
|
||||
<Keywords name="Keywords2">%address
%asm
%ir
%asmbinary
%asminclude
%breakpoint
%encoding
%import
%launcher
%option
%output
%zeropage
%zpreserved
%zpallowed</Keywords>
|
||||
<Keywords name="Keywords3">inline sub asmsub romsub
clobbers
asm
if
when else
if_cc if_cs if_eq if_mi if_neg if_nz if_pl if_pos if_vc if_vs if_z
for in step do while repeat unroll
break continue return goto</Keywords>
|
||||
<Keywords name="Keywords4">abs all any call callfar clamp cmp divmod len lsb lsl lsr memory mkword min max msb peek peekw peekf poke pokew pokef push pushw pop popw rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sort sqrtw swap</Keywords>
|
||||
<Keywords name="Keywords4">abs all any call callfar clamp cmp divmod len lsb lsl lsr memory mkword min max msb peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex reverse rnd rndw rol rol2 ror ror2 setlsb setmsb sgn sizeof sort sqrtw swap</Keywords>
|
||||
<Keywords name="Keywords5">true false
not and or xor
as to downto |></Keywords>
|
||||
<Keywords name="Keywords6"></Keywords>
|
||||
<Keywords name="Keywords7"></Keywords>
|
||||
|
@ -13,7 +13,7 @@ syn keyword prog8BuiltInFunc sgn sqrtw
|
||||
syn keyword prog8BuiltInFunc any all len reverse sort
|
||||
|
||||
" Miscellaneous functions
|
||||
syn keyword prog8BuiltInFunc cmp divmod lsb msb mkword min max peek peekw peekf poke pokew pokef push pushw pop popw rsave rsavex rrestore rrestorex
|
||||
syn keyword prog8BuiltInFunc cmp divmod lsb msb mkword min max peek peekw peekf poke pokew pokef rsave rsavex rrestore rrestorex
|
||||
syn keyword prog8BuiltInFunc rol rol2 ror ror2 sizeof setlsb setmsb
|
||||
syn keyword prog8BuiltInFunc swap memory call callfar clamp
|
||||
|
||||
|
@ -43,7 +43,7 @@ class VmProgramLoader {
|
||||
|
||||
block.children.forEach { child ->
|
||||
when(child) {
|
||||
is IRAsmSubroutine -> throw IRParseException("vm does not support asmsubs (use normal sub): ${child.label}")
|
||||
is IRAsmSubroutine -> throw IRParseException("vm does not support non-inlined asmsubs (use normal sub): ${child.label}")
|
||||
is IRCodeChunk -> programChunks += child
|
||||
is IRInlineAsmChunk -> throw IRParseException("encountered unconverted inline assembly chunk")
|
||||
is IRInlineBinaryChunk -> throw IRParseException("inline binary data not yet supported in the VM")
|
||||
|
@ -85,7 +85,7 @@ class TestVm: FunSpec( {
|
||||
)
|
||||
block += startSub
|
||||
program.addBlock(block)
|
||||
shouldThrowWithMessage<IRParseException>("vm does not support asmsubs (use normal sub): main.asmstart") {
|
||||
shouldThrowWithMessage<IRParseException>("vm does not support non-inlined asmsubs (use normal sub): main.asmstart") {
|
||||
VirtualMachine(program)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user