fst - FSM State

Module Description

The fst module implements a state in a Finite State Machine. See [fsm] for more info about using this module.

Module Words

State structure

fst% ( -- n )
Get the required space for a state variable

State creation, initialisation and destruction

fst-init ( x xt1 xt2 c-addr u n fst -- )
Initialise the state with id n and label c-addr u, entry action xt1, exit action xt2 and data x

fst-(free) ( fst -- )
Free the internal, private variables from the heap

fst-new ( x xt1 xt2 c-addr u n -- fst )
Create a new state on the heap with id n, label c-addr u, entry action xt1, exit action xt2 and data x

fst-free ( fst -- )
Free the state from the heap

Member words

fst-id@ ( fst -- n )
Get the id of the state

fst-label@ ( fst -- c-addr u )
Get the label of the state

fst-label? ( c-addr u fst -- c-addr u false | fst true )
Compare the label

fst-data@ ( fst -- x )
Get the data of the state

fst-data! ( x fst -- )
Set the data for the state

fst-entry@ ( fst -- xt )
Get the entry action of the state

fst-exit@ ( fst -- xt )
Get the exit action of the state

fst-attributes! ( c-addr u fst -- )
Set the extra graphviz attributes for the state

fst-attributes@ ( fst -- c-addr u )
Get the extra graphviz attributes of the state

Transition words

fst-new-transition ( x xt c-addr u fst1 n fst -- ftr )
Add a new transition to state fst1 with label c-addr u, number events n, action xt and data x

fst-any-transition ( x xt c-addr u fst1 fst -- ftr )
Set the any transition to state fst1 with label c-addr u, action xt and data x

fst-find-transition ( c-addr u fst -- ftr | nil )
Find the transition with label c-addr u, else return nil

Event words

fst-feed ( n fst -- fst | nil )
Feed the event to this state, return the next state or nil if the event did not match any condition

fst-try ( n fst -- fst | nil )
Try the event for this state, return the result

Inspection

fst-dump ( fst - )
Dump the state

Examples

include ffl/fsm.fs
include ffl/enm.fs


\ Example: vending machine


\ Enumerate the events

begin-enumeration
enum: voilence
enum: coin
enum: choice
enum: refuse
enum: #events
end-enumeration


\ Create the finite state machine on the heap with #events events

#events fsm-new value machine


\ Create the entry and exit action words

: say-thank-you  ( fst -- = Say 'thank you' after a coin or choice )
  drop
  ." Thank you" cr
;

: say-choice?    ( fst -- = Ask for choice after the coin )
  drop
  ." Please make your choice" cr
;

: say-coin?      ( fst -- = Ask for coin after the choice )
  drop
  ." Please enter your coin" cr
;

: call-support   ( fst -- = Call support after voilence, states data contains the phone number )
  ." Voilence against the machine, calling: " fst-data@ . cr
;


\ Create the states in the state machine

0     nil            ' say-thank-you s" start"    machine fsm-new-state value start
0   ' say-choice?    ' say-thank-you s" choice?"  machine fsm-new-state value choice?
0   ' say-coin?      ' say-thank-you s" coin?"    machine fsm-new-state value coin?
112 ' call-support     nil           s" support"  machine fsm-new-state value support


\ Set extra dot attributes for the support state

s" color=red" support fst-attributes!


\ Create the transitions for state start, use the bit array to set the condition

0     nil             s" coin"      start choice? machine fsm-new-transition ftr-condition@ coin     swap bar-set-bit
0     nil             s" choice"    start coin?   machine fsm-new-transition ftr-condition@ choice   swap bar-set-bit
0     nil             s" voilence"  start support machine fsm-new-transition ftr-condition@ voilence swap bar-set-bit

s" voilence" start fst-find-transition s" color=yellow" rot ftr-attributes!


\ Create the transition actions for choice? and coin? states

: deliver-choice   ( n ftr -- = Deliver the choosen product )
  2drop
  ." Deliver choice" cr
;

: do-refund        ( n ftr -- = Refused the product, refund the coin )
  2drop
  ." Refund coin" cr
;


\ Create the transitions for state choice?

0   ' deliver-choice  s" choice"    choice? start   machine fsm-new-transition ftr-condition@ choice   swap bar-set-bit
0   ' do-refund       s" refuse"    choice? start   machine fsm-new-transition ftr-condition@ refuse   swap bar-set-bit
0     nil             s" voilence"  choice? support machine fsm-new-transition ftr-condition@ voilence swap bar-set-bit


\ Set extra dot attributes for the voilence transition

s" voilence" choice? fst-find-transition s" color=yellow" rot ftr-attributes!


\ Create the transitions for state coin?

0   ' deliver-choice  s" coin"      coin? start   machine fsm-new-transition ftr-condition@ coin     swap bar-set-bit
0     nil             s" refuse"    coin? start   machine fsm-new-transition ftr-condition@ refuse   swap bar-set-bit
0     nil             s" voilence"  coin? support machine fsm-new-transition ftr-condition@ voilence swap bar-set-bit

s" voilence" coin? fst-find-transition s" color=yellow" rot ftr-attributes!


\ Start the state machine and feed it events 

machine fsm-start

coin     machine fsm-feed drop
choice   machine fsm-feed drop
coin     machine fsm-feed drop
refuse   machine fsm-feed drop
choice   machine fsm-feed drop
coin     machine fsm-feed drop
voilence machine fsm-feed drop


\ Create a text output stream for writing the state machine to dot

tos-new value dot-tos


\ Create the writer word

: write-dot    ( c-addr u file-id -- flag = Write the string )
  write-line 
  0=
;


\ Create the output file

s" out.dot" w/o create-file throw value dot-file


\ Set the writer word and the file in the stream

dot-file  ' write-dot  dot-tos  tos-set-writer


\ Write the state machine to the dot-file with graph name "Machine"

s" Machine" dot-tos machine fsm-to-dot


\ Free the dot stream

dot-tos tos-free


\ Close the dot file

dot-file close-file throw


\ To generate an image, use for example: dot -Tpng -o fsm.png out.dot

\ ==============================================================================

generated 10-Apr-2008 by ofcfrth-0.5.0