Version 9 of A tiny state machine

Updated 2006-08-26 21:23:45 by suchenwi

Richard Suchenwirth 2003-02-12 - The following little state machine was created, with help from dkf, in the Tcl chatroom, instigated by the quote (Alan Cox?): "A computer is a state machine. Threads are for people who can't program state machines."

So here is one, starting with the necessary state transition command - goto in Tcl. Note some unusal points: the proc changes a variable (next) in its caller, and lets that continue, so it can only be called in a loop. }

 proc goto label {
    upvar 1 next next
    set next $label
    return -code continue
 }

if 0 {The "machine" itself takes a paired list of alternating labels and state code (which could be implemented as dict, once that is available - 8.5?); if a state code does not end in a goto or break, the same state will be repeated as long as not left, with goto or break (implicit endless loop). Execution starts at the first of the states. }

 proc statemachine states {
    array set state $states
    set next [lindex $states 0]
    while 1 {eval $state($next)}
 }

RS 2006-08-26: Three years later, I like this version better, which keeps the goto command locally - it is not for general consumption after all, and hence disappears when the state machine returns:

 proc statemachine states {
    array set S $states
    proc goto label {
        uplevel 1 set this $label
        return -code continue
    }
    set this [lindex $states 0]
    while 1 {eval $S($this)}
    rename goto {}
 }

# Testing: a tiny state machine that greets you as often as you wish, and ends if you only hit <Return> on the "how often?" question:

 statemachine {
    1 {
        puts "hello - how often?"
        gets stdin n
        if {$n eq ""} {goto 3}
        goto 2
    } 2 {
        if {$n==0} {goto 1}
        puts Howdy!
        incr n -1
    } 3 {puts "Thank you!"; break}
 }

A more elaborate page: Finite state machines


Category Concept | Arts and crafts of Tcl-Tk programming