       ͻ
        Lesson 3 Part 160  F-PC 3.5 Tutorial by Jack Brown 
       ͼ

\ Here is another way to write SPEED_CHECK .  This time the messages
\ are built into the speed interval words.
\ ***** look here ***
\ Also each interval checking word has the equivalent of a double
\ EXIT.  You may recall that when we were talking about the return
\ stack we said the system kept information on the return stack.
\ This information consists of the segment and offset of the calling
\ word that is the place we are to return when we reach the semi colon
\ So...
\ R> R> pulls this segment and offset to the parameter stack.
\ 3DROP removes the segment, offset and the speed.
\ EXIT  has the effect of removing another segment and offset
\ so that if the interval tests true we skip out not to the calling
\ word but another level higher!

\ All this may seem fairly complicated, but it has the advantage that
\ that if an inteval tests true we don't come back to test the rest
\ of the cases.

\            Message                              Speed range kmph
\           -----------                          ------------------
\ " issue ticket,    impeding traffic flow."            0   -  15
\ " issue warning,   impeding traffic flow."           16   -  30
\ " no action,       safe speed."                      31   -  55
\ " issue warning,   exceeding speed limit."           56   -  65
\ " issue ticket,    exceeding speed limit."           66   -  99
\ " arrest motorist, dangerous driving."              100   -

\ Display ticket msg ifis speed is very slow  0 - 15 kmph
: VERY_SLOW? \ ( speed -- speed) or ( speed --)
        DUP 0 15 [IN]
        IF   ." Issue ticket,    impeding traffic flow."
             R> R>   \ pull segment and offset of calling word
             3DROP   \ throw away speed and seg off of calling word
             EXIT    \ Now we exit to the word that called the calling
        THEN ;       \ word!!    ie... R> R> 2DROP EXIT  == DOUBLE_EXIT

\ Display warning msg if speed is slow  16 - 30 kmph
: SLOW? \ ( speed -- speed) or ( speed --)
        DUP 16 30 [IN]
        IF   ." Issue warning,   impeding traffic flow."
             R> R> 3DROP EXIT
        THEN ;

\ Display no action msg if speed is normal  31 - 55 kmph
: NORMAL? \ ( speed -- speed ) or ( speed --)
       DUP 31 55 [IN]
       IF   ." No action,       safe speed."
            R> R> 3DROP EXIT
       THEN ;


\ Display warning msg if speed is fast    56 - 65 kmph
: FAST? \ ( speed -- speed) or ( speed -- )
       DUP 56 65 [IN]
       IF   ." Issue warning,   exceeding speed limit."
            R> R> 3DROP EXIT
       THEN ;

\ Display ticket msg if spped is very fast  66- 99 kmph
: VERY_FAST? \ ( speed -- speed) or ( speed -- )
       DUP 66 99 [IN]
       IF   ." Issue ticket,    exceeding speed limit."
            R> R> 3DROP EXIT
       THEN ;

\ Display arrest msg if speed is dangerous   100 kmph and over.
: DANGEROUS? \ ( speed -- speed) or ( speed -- )
       DUP 100 200 [IN]
       IF   ." Arrest motorist, dangerous driving."
            R> R> 3DROP EXIT
       THEN ;

\ Display broken msg if speed is invalid, negative or > 200 kmph.
: BROKEN? \ ( speed -- speed)  or ( speed -- )
       DUP DUP 0< SWAP 200 > OR
       IF  ." Super-F Radar Gun is broken"
           R> R> 3DROP  EXIT
       THEN ;

\ Check speed and print appropriate message.
\ Note that the order of the checks has been adjusted so that
\ the most likely cases are checked first.
: SPEED_CHECK ( speed -- )
    NORMAL?
    SLOW?
    FAST?
    VERY_SLOW?
    VERY_FAST?
    DANGEROUS?
    BROKEN? ;

: SPEED_TEST ( -- )
     BEGIN
        CR ." Enter speed "
        #IN  DUP 0= IF DROP EXIT THEN
        SPACE SPEED_CHECK
     AGAIN ;


