Finite state machine: Difference between revisions
Content added Content deleted
m (→{{header|Kotlin}}: added zkl header) |
(→{{header|zkl}}: added code) |
||
Line 472: | Line 472: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
A lame FSM, we just convert text to a [hopefully valid] zkl program, compile and run it. |
|||
⚫ | |||
⚫ | |||
If we need true state to state hops, we could use tail recursion (another name for goto). |
|||
⚫ | |||
<lang zkl>class FSM{ // our Finite State Machine |
|||
var bank=0, item=Void; |
|||
fcn deposit(coin){ bank=coin } |
|||
fcn select(item){ |
|||
if(bank){ bank=0; self.item=item; } |
|||
else print("Depost coin, then select ") |
|||
} |
|||
fcn take { if(item) item=Void; else print("Select first "); } |
|||
fcn refund { coin:=bank; bank=0; return(coin) } |
|||
// couple of wrappers to state changes |
|||
fcn state{ println("Bank(%4d), Item(%s)".fmt(bank,item)) } |
|||
fcn act(f){ print("%-10s-->".fmt(f.name)); f(); state(); } |
|||
} |
|||
Vault.add(FSM); // put class FSM where I can find it</lang> |
|||
<lang zkl>fcn run(program){ // convert text to FSM instructions and run them |
|||
program=program.replace("(",".fp("); // deposit(10)-->deposit.fp(10) |
|||
a,b,p := 0,0,Sink("class P(FSM){ state(); "); |
|||
while(Void!=(b=program.find(";",a))) |
|||
{ p.write("act(",program[a,b-a],");"); a=b + 1; } |
|||
program=p.write(program[a,*],"}").close(); |
|||
// println(program); // WTH did I just do? |
|||
Compiler.Compiler.compileText(program)(); // compile and run our little FSM |
|||
⚫ | |||
<lang zkl>run("select(); take(); deposit(10); select(\"snickers\"); take();");</lang> |
|||
The above is converted to: |
|||
⚫ | |||
state(); |
|||
act(select.fp()); |
|||
act( take.fp()); |
|||
act( deposit.fp(10)); |
|||
act( select.fp("snickers")); |
|||
act( take.fp()); |
|||
⚫ | |||
The .fp() is function application (ie deferred execution) so I can extract the |
|||
function name and print it. |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Bank( 0), Item(Void) |
|||
select -->Depost coin, then select Bank( 0), Item(Void) |
|||
take -->Select first Bank( 0), Item(Void) |
|||
deposit -->Bank( 10), Item(Void) |
|||
select -->Bank( 0), Item(snickers) |
|||
take -->Bank( 0), Item(Void) |
|||
</pre> |
</pre> |