[= AutoGen5 Template  -*- Mode: text -*-

fsm=%s-att.fsm

=]
[=#

FSM-PURPOSE:
   This template will produce an FSM description suitable for use with
   the AT&T Research FSM tools.  One of those programs will produce a
   PostScript drawing and ps2pdf can be used to produce PDF output.
   Use this something like as follows:

      autogen -L ~/ag/autofsm -Tatt-fsm example.def
      arcopt='-i example-att.arc -o example-att.arc'
      fsmcompile ${arcopt} -S example-att.ste example-att.fsm | \
        fsmdraw ${arcopt} -s example-att.ste > example.dot
      dot -Tps example.dot > example.ps
      ps2pdf example.ps example.pdf

   The "/1" appearing in the output are default transition costs.
   You can get different costs by specifying a cost attribute for
   each transition. For example:

      cost = 0.123;

   This template is not part of the AutoGen distribution.
   It is available within the separately downloadable package: AutoFSM.

YOU SUPPLY:
   One additional attribute with the "transition" values:  "cost".
   Otherwise, all costs will default to "1".
\=]
[= (out-push-new (string-append (base-name) "-att.ste")) \=]
INIT            0
[=

FOR state

  =][=
  (sprintf "%-14s  %d\n" (string-upcase! (get "state")) (+ 1 (for-index)))
  =][=

ENDFOR state

\=]
DONE            [= (+ 1 (count "state")) =]
[=

(out-pop) (out-push-new (string-append (base-name) "-att.arc"))

=][=

FOR event

  =][=
  (sprintf "%-14s  %d\n" (string-upcase! (get "event")) (for-index))
  =][=

ENDFOR

=][=

(out-pop)

;;; Initialize every possible transition as invalid
;;;
(define tr_name "")

(define pfx     (string->c-name! (string-downcase!
                (if (exist? "prefix") (get "prefix") (base-name))  )))
(define PFX     (string-upcase pfx))
(define Pfx     (string-capitalize pfx))

(shellf
  "ev_list='%s' ; st_list='INIT %s'
   for f in $ev_list ; do for g in $st_list
   do  eval FSM_TRANS_${g}_to_${f}='%s_ST_INVALID'
       export FSM_TRANS_${g}_to_${f}
   done ; done"

   (string-upcase! (join " " (stack "event")))
   (string-upcase! (join " " (stack "state")))
   PFX )

(define tev  "")
(define tst   "")
(define ttype "")
(define next  "")

=][=#
;;; Now replace the initial values with proper ones gotten from
;;; the trasition definitions.
;;;
;;; It is actually possible to have multiple specifications for a
;;; single state/event pair, however the last state/event assignment
;;; will supply the value for the transition table.  Different
;;; transitions may also specify the same transition method.  For
;;; that, we unique sort the list and eliminate dups that way.  The
;;; unique-ified list is used to produce the callout table.
;;;
=][=

FOR   transition              =][=

   IF (== (get "tst") "*")    =][=

     ;;  This transition applies for all states
     ;;
     (set! tev (string-upcase! (get "tev")))
     (set! ttype (if (exist? "ttype") (get "ttype")
                     (string-append "${f}_" tev)  ))

     (set! next (if (exist? "next") (string-upcase! (get "next")) "${f}"))

     (shellf
       "for f in ${st_list} ; do
       eval FSM_TRANS_${f}_to_%s=\\'%s_ST_%s %s\\'
       done"
       tev PFX next (if (exist? "cost") (get "cost") "1.0")) =][=

   ELIF (== (get "tev") "*")  =][=

     ;;  This transition applies for all transitions in a certain state
     ;;
     (set! tst  (string-upcase! (get "tst")))
     (set! ttype (if (exist? "ttype")
           (string-upcase! (get "ttype")) (string-append tst "_${f}")  ))

     (set! next (if (exist? "next") (string-upcase! (get "next")) tst))

     (shellf
       "for f in ${ev_list} ; do
       eval FSM_TRANS_%s_to_${f}=\\'%s_ST_%s %s\\'
       done"
       tst PFX next (if (exist? "cost") (get "cost") "1.0"))  =][=

   ELSE                       =][=

     FOR tst                  =][=

       (set! tst  (string-upcase! (get "tst")))
       (set! next (if (exist? "next") (string-upcase! (get "next")) tst))

                              =][=
       FOR tev                =][=

         (set! tev   (string-upcase! (get "tev")))

         (shellf "FSM_TRANS_%s_to_%s='%s_ST_%s %s'"
          tst tev PFX next (if (exist? "cost") (get "cost") "1.0")) =][=

       ENDFOR  tev            =][=
     ENDFOR    tst            =][=
   ENDIF tst or ttkn as '*'   =][=
ENDFOR   transition           =][=

(define trans-ct
  (shellf
    "env | egrep '^FSM_TRANS_' | \
    sed '/=.*%s_ST_INVALID/d;' | \
    sort -u > .fsm.xlist
    echo `wc -l < .fsm.xlist` "
    PFX
) )

(shellf "

eval `sed 's/  */=/' %s-att.ste`
while read line
do
  v=`echo $line|sed 's/_to_.*//;s/^FSM_TRANS_//'`
  eval v=\\${$v}
  echo ${v} `echo $line | sed 's/^FSM_TRANS_//;s/_to_/ /;s/=.[A-Z]*_ST_/ /'`
done < .fsm.xlist | sort -n > .fsm.list
" (base-name))

(shell "

while read _ initial token result cost _
do  printf '%-14s  %-14s  %-14s %s\n' ${initial} ${result} ${token} ${cost}
done < .fsm.list
rm -f .fsm.*list

")
=]
DONE