commit 7da534322607a4fdbc93c96c39437914f195766a
parent f35afc9f025b822eff8ab20eee67f33b53a32863
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Thu, 16 Jun 2022 20:10:53 -0400
cc: add postfix ++ and --
Diffstat:
5 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs
@@ -11,6 +11,14 @@ UOPSCNT stringlist UOPTlist "-" "~" "!" "&" "*" "++" "--"
UOPTlist sfind dup 0< if drop 0 else 1 then ;
: uoptoken ( opid -- tok ) UOPTlist slistiter ;
+\ Postfix operators
+2 const POPSCNT
+POPSCNT stringlist POPTlist "++" "--"
+
+: popid ( tok -- opid? f )
+ POPTlist sfind dup 0< if drop 0 else 1 then ;
+: poptoken ( opid -- tok ) POPTlist slistiter ;
+
\ Binary operators
13 const BOPSCNT
BOPSCNT stringlist BOPTlist
@@ -36,7 +44,7 @@ create bopsprectbl 1 c, 1 c, 0 c, 0 c, 2 c, 2 c, 2 c, 2 c,
6 const AST_ARGSPECS
7 const AST_LVALUE \ data1=varname
8 const AST_UNARYOP \ data1=uopid
-\ 9 = unused
+9 const AST_POSTFIXOP \ data1=popid
10 const AST_BINARYOP \ data1=bopid
\ 11 = unused
12 const AST_IF
@@ -45,7 +53,7 @@ create bopsprectbl 1 c, 1 c, 0 c, 0 c, 2 c, 2 c, 2 c, 2 c,
ASTIDCNT stringlist astidnames
"declare" "unit" "function" "return" "constant" "stmts" "args" "lvalue"
-"unaryop" "_" "binop" "_" "if" "_" "call"
+"unaryop" "postop" "binop" "_" "if" "_" "call"
0 value curunit \ points to current Unit, the beginning of the AST
@@ -110,10 +118,15 @@ ASTIDCNT wordtbl astdatatbl ( node -- node )
\ Parse words
+: parsePostfixOp ( tok -- node-or-0 )
+ dup popid if ( tok opid )
+ nip AST_POSTFIXOP createnode swap , ( node )
+ else to nexttputback 0 then ;
+
\ A factor can be:
\ 1. A constant
\ 2. A Lvalue
-\ 3. A unaryop containing a factor
+\ 3. A unaryop/postfixop containing a factor
\ 4. A function call
: parseFactor ( tok -- node-or-0 )
dup uopid if ( tok opid )
@@ -128,8 +141,10 @@ ASTIDCNT wordtbl astdatatbl ( node -- node )
_nextt dup S" ," s= if drop else to nexttputback then 0
else \ not an argument
')' expectChar 1 then until ( node )
- else \ lvalue
- to nexttputback AST_LVALUE createnode swap , then
+ else ( prevtok newtok ) \ lvalue
+ swap AST_LVALUE createnode swap , ( tok lvnode )
+ swap parsePostfixOp ( lvnode node-or-0 ) ?dup if ( lvnode opnode )
+ tuck addnode then ( lv-or-op-node ) then
else \ Constant
parse if AST_CONSTANT createnode swap , else 0 then
then
diff --git a/fs/cc/gen.fs b/fs/cc/gen.fs
@@ -11,6 +11,10 @@ UOPSCNT wordtbl uopgentbl ( -- )
:w ( ! ) operand?>result vmboolnot, ;
'w operand>&operand ( & )
'w operand>[operand] ( * )
+:w ( ++ ) operand?>result vminc, ;
+:w ( -- ) operand?>result vmdec, ;
+
+POPSCNT wordtbl popgentbl ( -- )
:w ( ++ ) vminc, ;
:w ( -- ) vmdec, ;
@@ -85,10 +89,11 @@ ASTIDCNT wordtbl gentbl ( node -- )
'w genchildren ( ArgSpecs )
:w ( LValue ) lvsfoff sf+>operand ;
:w ( UnaryOp )
- dup printast nl>
dup genchildren
data1 uopgentbl swap wexec ;
-'w _err ( unused )
+:w ( PostfixOp )
+ dup genchildren
+ data1 popgentbl swap wexec ;
:w ( BinaryOp ) dup data1 12 = if _assign exit then
( node ) >r
r@ childcount 2 = not if abort" binop node with more than 2 children!" then
diff --git a/fs/cc/vm.fs b/fs/cc/vm.fs
@@ -157,10 +157,14 @@ VM_NONE value operand
eax eax test,
eax 0 i32 mov,
al setz, ;
-\ inc/dec are special because they operate on the current *operand*, not the
-\ result.
-: vminc, operandAsmKeep inc, ;
-: vmdec, operandAsmKeep dec, ;
+\ inc/dec have 2 operation modes. If there's no operand, it inc/dec the result.
+\ if there's an operand, it *post* inc/dec, that is, it moves the operand to
+\ the result and then it inc/dec the operand.
+: _ ( 'w -- ) operand VM_NONE = if
+ eax execute else
+ eax operandAsmKeep result! mov, operandAsm execute then ;
+: vminc, ['] inc, _ ;
+: vmdec, ['] dec, _ ;
: vm<,
eax operandAsm cmp,
eax 0 i32 mov,
diff --git a/fs/tests/cc/cc.fs b/fs/tests/cc/cc.fs
@@ -18,4 +18,5 @@ ptrset 54 #eq
12 condif 13 #eq
42 condif 142 #eq
42 incdec 43 #eq
+54 incdecp 55 #eq
testend
diff --git a/fs/tests/cc/test.c b/fs/tests/cc/test.c
@@ -50,3 +50,8 @@ int incdec(int x) {
--x;
return ++x;
}
+int incdecp(int x) {
+ x++;
+ x--;
+ return ++x--;
+}