fb:porticula NoPaste
FSM mit State Pattern (mit Table)
Uploader: | St_W |
Datum/Zeit: | 21.03.2013 00:50:50 |
'#Define DEBUG
#Define FALSE 0
#Define TRUE (Not FALSE)
#if Not __FB_MIN_VERSION__(0, 25, 0)
#error fbc must be at least version 0.25.0 to compile this module
#EndIf
#Macro implState(statename)
Type State##statename extends StateObj
Declare Function getNav(As String) As StateObj Ptr
Declare Function getName() As String
Dim navtab(0 To 1) As StateObj Ptr
Dim title As String = "##statename##"
Declare Constructor()
End Type
Dim Shared S_##statename As State##statename
Function State##statename##.getNav(a As String) As StateObj Ptr
If (Asc(a)-Asc("a") < LBound(this.navtab)) OrElse (Asc(a)-Asc("a") > UBound(this.navtab)) Then Return @S_Empty
Return this.navtab(Asc(a)-Asc("a"))
End Function
Function State##statename##.getName() As String
Return this.title
End Function
#EndMacro
Type StateObjFW As StateObj
Type StateCtx extends Object
Private:
Dim curState As StateObjFW Ptr
Public:
Declare Constructor()
Declare Function setState(As StateCtx Ptr) As StateCtx Ptr
Declare Sub nav(As String)
Declare Function isFinal() As Integer
End Type
Type StateObj extends Object
Declare Sub nav(As StateCtx Ptr, As String)
Declare abstract Function getNav(As String) As StateObj Ptr
Declare abstract Function getName() As String
End Type
Sub StateObj.nav(ctx As StateCtx Ptr, a As String)
ctx->setState(this.getNav(a))
End Sub
implState(Empty)
implState(A1)
implState(B1)
implState(C1)
implState(C1C2)
implState(C1C3)
Constructor StateA1()
this.navtab(0) = @S_B1
this.navtab(1) = @S_Empty
End Constructor
Constructor StateB1()
this.navtab(0) = @S_Empty
this.navtab(1) = @S_C1C2
End Constructor
Constructor StateC1()
this.navtab(0) = @S_C1
this.navtab(1) = @S_C1C2
End Constructor
Constructor StateC1C2()
this.navtab(0) = @S_C1C3
this.navtab(1) = @S_C1C2
End Constructor
Constructor StateC1C3()
this.navtab(0) = @S_C1
this.navtab(1) = @S_C1C2
End Constructor
Constructor StateEmpty()
this.navtab(0) = @S_Empty
this.navtab(1) = @S_Empty
End Constructor
Constructor StateCtx ()
this.curState = @S_A1
End Constructor
Function StateCtx.setState(s As StateCtx Ptr) As StateCtx Ptr
Dim tmp As StateCtx Ptr = this.curState
this.curState = s
Return tmp
End Function
Sub StateCtx.nav(s As String)
#Ifdef DEBUG
Print " "; this.curState->getName(); " -> ";
#EndIf
this.curState->nav(@This, s)
#Ifdef DEBUG
Print this.curState->getName()
#EndIf
End Sub
Function StateCtx.isFinal() As Integer
If *this.curState Is StateC1C3 Then Return TRUE
Return FALSE
End Function
'Open "test.input" For Input As #1
Open Cons For Input As #1
Dim s As String
Do
Dim sc As StateCtx
Line Input #1, s
If Eof(1) Then Exit Do
For q As Integer = 0 To Len(s)-1
sc.nav(Chr(s[q]))
Next
Print """"; s; """ "; *IIf(sc.isFinal, @"ACCEPT", @"REJECT")
Loop