commit 8fb909c8bdd8783e55e9f37474fd8ca9bc26d677
parent 808d2da630e13ff60b4eee260d601eb50789844f
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sat, 18 Jun 2022 10:04:00 -0400
Add case..endcase
With a special twist! I'm happy about how it turns out. Will greatly help in
cc/vm code.
Diffstat:
3 files changed, 41 insertions(+), 11 deletions(-)
diff --git a/fs/cc/ast.fs b/fs/cc/ast.fs
@@ -132,14 +132,14 @@ alias noop parseExpression ( tok -- node ) \ forward declaration
\ 4. A function call
\ 5. An expression inside () parens.
: parseFactor ( tok -- node-or-0 )
- dup S" (" s= if ( tok )
- drop nextt parseExpression nextt ')' expectChar exit then
- dup uopid if ( tok opid )
- nip AST_UNARYOP createnode swap , ( opnode )
- nextt parseFactor ?dup _assert over addnode ( opnode )
- exit then ( tok )
- dup isIdent? if \ lvalue or FunCall
- nextt ( prevtok newtok ) dup S" (" s= if \ FunCall
+ case
+ S" (" of s= ( )
+ nextt parseExpression nextt ')' expectChar endof
+ of uopid ( opid )
+ AST_UNARYOP createnode swap , ( opnode )
+ nextt parseFactor ?dup _assert over addnode ( opnode ) endof
+ of isIdent? ( ) \ lvalue or FunCall
+ r@ nextt ( prevtok newtok ) dup S" (" s= if \ FunCall
drop AST_FUNCALL createnode swap , begin ( node )
nextt dup parseFactor ?dup if \ an argument
nip over addnode
@@ -150,9 +150,10 @@ alias noop parseExpression ( tok -- node ) \ forward declaration
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 ;
+ endof
+ ( case else ) \ Constant
+ r@ parse if AST_CONSTANT createnode swap , else 0 then
+ endcase ;
\ An expression can be 2 things:
\ 1. a factor
diff --git a/fs/lib/core.fs b/fs/lib/core.fs
@@ -47,6 +47,22 @@ $08 const BS $04 const EOF
: wordname[] ( w -- sa sl )
dup wordlen swap 5 - over - ( sl sa ) swap ;
+\ case..endcase
+\ The case statement is very similar to what we see in other forths, but with
+\ one major difference: the "of" word specifies the thruth word. So, the
+\ "of" we see in other forths is equivalent to "of =" in Dusk OS. The comparator
+\ has to be a single word following "of".
+\ case x of = ... endof y of < ... endof ... endcase
+\ is syntactic sugar for:
+\ >r x r@ = if ... else y r@ < if ... else ... then then r~
+\ NOTE: if you want to access your reference value in the final "else", you
+\ need to use "r@".
+: case ( -- then-stopgap ) 0 compile >r ; immediate
+: of ( -- jump-addr ) compile r@ ' call, [compile] if ; immediate
+alias else endof immediate
+: endcase ( then-stopgap jump1? jump2? ... jumpn? -- )
+ ?dup if begin [compile] then ?dup not until then compile r~ ; immediate
+
\ Number formatting
create _ ," 0123456789abcdef"
: .xh $f and _ + c@ emit ;
diff --git a/fs/tests/core.fs b/fs/tests/core.fs
@@ -16,4 +16,17 @@ foo 43 #eq
5 to+ foo
foo 48 #eq
to' foo @ 48 #eq
+
+\ case
+: foo ( n ) case
+ 1 of = 111 endof
+ 42 of > 222 endof
+ 333
+ endcase ;
+
+1 foo 111 #eq
+2 foo 222 #eq
+3 foo 222 #eq
+42 foo 333 #eq
+
testend