duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 7da534322607a4fdbc93c96c39437914f195766a
parent f35afc9f025b822eff8ab20eee67f33b53a32863
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Thu, 16 Jun 2022 20:10:53 -0400

cc: add postfix ++ and --

Diffstat:
Mfs/cc/ast.fs | 25++++++++++++++++++++-----
Mfs/cc/gen.fs | 9+++++++--
Mfs/cc/vm.fs | 12++++++++----
Mfs/tests/cc/cc.fs | 1+
Mfs/tests/cc/test.c | 5+++++
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--; +}