duskos

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

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:
Mfs/cc/ast.fs | 23++++++++++++-----------
Mfs/lib/core.fs | 16++++++++++++++++
Mfs/tests/core.fs | 13+++++++++++++
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