'case': (was: Re: [PicForth] Re: Feature Requests)

David McNab david at rebirthing.co.nz
Sat Nov 20 01:58:16 CET 2004


Hi,

> David> 1) case ... of .. endof .. endcase
> David> As per standard Forth

> I've implemented it in my development version (you can get it using
> darcs as explained on http://www.rfc1149.net/devel/picforth). However,
> as with other "if" cases that cannot be cleverly optimized, the
> generated code is ugly.

I see what you mean. Each of/endof branch costs 26 machine words, which 
on a PIC is hideously expensive.

On looking at the generated code, I can see that you're fastidiously 
complying with standard forth's stack-effects. But you're disadvantaged 
by the fact there's only one FSR on PIC16F, whereas standard Forth uses 
the return stack to store the test value. Result is that you're having 
to cope with the lack of an efficient 'return stack' and r>,>r, which 
forces you to do a heap of stack-fiddling code, including 
suspend/restore interrupts, to gain compliance.

What I'd suggest is that you might like to follow your previous example 
with v-for/v-next. In this construct, you've delegate some 
responsibility to the user - you ask the user to 'pay' a small price - a 
variable - and you deliver much more compact code than if you had 
implemented a full-stack-compliant do/loop.

So there might be a way to implement something like:

v-case  ( value variable -- )

v-of    ( testval -- )

v-endof  ( -- )

v-default ( -- )

v-endcase ( -- )

With the user providing the variable address, you don't have to worry 
about molesting the runtime stack.

Also, on the compile-time stack, you could keep a list of the endof's 
needing their gotos resolved.

I'm sure nearly all PicForth users would be happy with such a compromise.

In the meantime, I'm going to try to implement a node in my PicForth 
preprocessor which translates:

   someval case
      testval1 of
         ..
      endof
      testval2 of
         ..
      endof
      ...defaultcode...
   endcase

to:
   someval
   dup testval1 = if
     drop
     ..
   else
     dup testval2 = if
       drop
       ..
     else
       drop
       ...defaultcode...
     then
   then

which weighs in at 6 words per of/endof.

--
Cheers
David


More information about the PicForth mailing list