commit d6c0c5b1293e00e22eab75aa77eed90fada707be
parent a9edd876df8b5a50f4de9da63e677b4090d63908
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Mon, 5 Sep 2022 17:17:25 -0400
cc: add postop to forth vm
and add missing test covering it.
Diffstat:
2 files changed, 25 insertions(+), 2 deletions(-)
diff --git a/fs/cc/vm/forth.fs b/fs/cc/vm/forth.fs
@@ -90,10 +90,10 @@ binop vmadd, +
binop vmsub, -
binop vmmul, *
-: apply ( w a -- ) \ apply word w to 32-bit value in addr a
- tuck @ swap execute ( a n ) swap ! ;
\ Unary operations are performed on the selected op, which can be either op1 or
\ op2.
+: apply ( w a -- ) \ apply word w to 32-bit value in addr a
+ tuck @ swap execute ( a n ) swap ! ;
: unop doer ' , does> @ ( w ) litn
&op>op opCompile* opdeinit compile apply ;
@@ -106,6 +106,13 @@ unop vm--op, 1-
\ post-inc/dec op1
\ We need to copy the old value to TOS and then inc or dec the reference.
+: apply ( w a -- n ) \ Same as unop's apply, but yield old value
+ tuck @ ( a w old ) dup rot execute ( a old new ) rot ! ;
+: postop doer ' , does> @ ( w ) litn
+ &op>op opCompile* opdeinit compile apply op>TOS ;
+
+postop vmop++, 1+
+postop vmop--, 1-
\ Copy the contents of op2 in the memory address pointed out by op1 and deinit
\ op2. In other words, perform a AST_ASSIGN with the right part as op2
diff --git a/fs/tests/cc/vm.fs b/fs/tests/cc/vm.fs
@@ -134,4 +134,20 @@ code test8
selop1 0 sf+>op
vmret,
test8 43 #eq
+
+\ "post" ops (inc and dec) must operate on their target after yielding
+ops$
+code test9
+ 0 4 vmprelude,
+ \ foo = 42
+ selop2 42 const>op
+ selop1 0 sf+>op
+ vmmov,
+ ops$
+ selop1 0 sf+>op
+ vmop++, \ inc SF+0 and yield the old value to op1
+ selop2 0 sf+>op
+ vmadd,
+ vmret,
+test9 85 #eq
testend