PageRenderTime 21ms CodeModel.GetById 10ms app.highlight 4ms RepoModel.GetById 1ms app.codeStats 1ms

/src/lib/automaton/automaton.e

http://github.com/tybor/Liberty
Specman e | 200 lines | 149 code | 22 blank | 29 comment | 2 complexity | b4327054650380991019c6cbea4fb2e9 MD5 | raw file
  1-- This file is part of a Liberty Eiffel library.
  2-- See the full copyright at the end.
  3--
  4class AUTOMATON[E_]
  5
  6create {ANY}
  7   manifest_creation
  8
  9feature {ANY} -- Simple one-shot execution
 10   run (start_state: ABSTRACT_STRING; e: E_)
 11      require
 12         has(start_state)
 13      local
 14         context: AUTOMATON_CONTEXT[E_]
 15      do
 16         from
 17            context := start(start_state, e)
 18         until
 19            not context.is_valid
 20         loop
 21            next(context)
 22         end
 23      end
 24
 25   has (state_name: ABSTRACT_STRING): BOOLEAN
 26      require
 27         state_name /= Void
 28      do
 29         Result := states.fast_has(state_name.intern)
 30      end
 31
 32feature {ANY} -- Step-by-step execution
 33   start (start_state: ABSTRACT_STRING; e: E_): AUTOMATON_CONTEXT[E_]
 34      require
 35         has(start_state)
 36      local
 37         state: STATE[E_]
 38      do
 39         create Result.make(e)
 40         state := next_transition(Void, start_state, e)
 41         check
 42            state_exists: state /= Void
 43         end
 44         Result.set_current_state(state)
 45      ensure
 46         Result.is_valid
 47         Result.current_state /= Void
 48      end
 49
 50   next (context: AUTOMATON_CONTEXT[E_])
 51      require
 52         context.is_valid
 53      local
 54         next_state: ABSTRACT_STRING
 55         state: STATE[E_]
 56      do
 57         next_state := context.current_state.run(Current, context.data)
 58         if next_state /= Void then
 59            check has(next_state) end
 60            state := next_transition(context.current_state, next_state, context.data)
 61            check
 62               state_exists: state /= Void
 63            end
 64            context.set_current_state(state)
 65         else
 66            last_transition(context.current_state, context.data)
 67            context.invalidate
 68         end
 69      end
 70
 71feature {}
 72   next_transition (from_state: STATE[E_]; state_name: ABSTRACT_STRING; e: E_): STATE[E_]
 73      do
 74         debug ("automaton/transition")
 75            if from_state = Void then
 76               std_output.put_line("Void => " + state_name.out)
 77            else
 78               std_output.put_line(from_state.name.out + " => " + state_name.out)
 79            end
 80         end
 81         Result := states.fast_reference_at(state_name.intern)
 82         transition.call([e, from_state, Result])
 83      end
 84
 85   last_transition (from_state: STATE[E_]; e: E_)
 86      require
 87         from_state /= Void
 88      local
 89         no_state: STATE[E_]
 90      do
 91         debug ("automaton/transition")
 92            std_output.put_line(from_state.name.out + " => Void")
 93         end
 94         transition.call([e, from_state, no_state])
 95      end
 96
 97feature {STATE} --|* TODO: should be STATE[E_] (when Liberty can bootstrap)
 98   call_before_guards (e: E_; state: STATE[E_])
 99      do
100         before_guards.call([e, state])
101      end
102
103   call_after_guards (e: E_; state: STATE[E_])
104      do
105         after_guards.call([e, state])
106      end
107
108feature {ANY}
109   set_before_guards (p: like before_guards)
110      do
111         before_guards := p
112      ensure
113         before_guards = p
114      end
115
116   set_after_guards (p: like after_guards)
117      do
118         after_guards := p
119      ensure
120         after_guards = p
121      end
122
123   set_transition (p: like transition)
124      do
125         transition := p
126      ensure
127         transition = p
128      end
129
130feature {}
131   states: DICTIONARY[STATE[E_], FIXED_STRING]
132         -- A dictionary of all the states
133
134   before_guards: PROCEDURE[TUPLE[E_, STATE[E_]]]
135         -- That agent is called before checking guards. The given state is the current one.
136
137   after_guards: PROCEDURE[TUPLE[E_, STATE[E_]]]
138         -- That agent is called after checking guards, whether a guard was raised or not. The given state
139         -- the current one.
140
141   transition: PROCEDURE[TUPLE[E_, STATE[E_], STATE[E_]]]
142         -- That agent is called when the next state was found. The given states are resp. the current one
143         -- (Void if first transition) and the successor (Void is last transition).
144
145   default_before_guards, default_after_guards, default_transition
146      do
147      end
148
149feature {}
150   manifest_make (needed_capacity: INTEGER)
151      do
152         create {HASHED_DICTIONARY[STATE[E_], FIXED_STRING]} states.with_capacity(needed_capacity)
153         before_guards := agent default_before_guards
154         after_guards := agent default_after_guards
155         transition := agent default_transition
156      end
157
158   manifest_put (index: INTEGER; state_name: ABSTRACT_STRING; state: STATE[E_])
159      require
160         index >= 0
161         not states.fast_has(state_name.intern)
162      local
163         name: FIXED_STRING
164      do
165         name := state_name.intern
166         state.set_name(name)
167         states.add(state, name)
168      ensure
169         states.fast_has(state_name.intern)
170      end
171
172   manifest_semicolon_check: INTEGER 2
173
174invariant
175   states /= Void
176   before_guards /= Void
177   after_guards /= Void
178   transition /= Void
179
180end -- class AUTOMATON
181--
182-- Copyright (C) 2009-2017: by all the people cited in the AUTHORS file.
183--
184-- Permission is hereby granted, free of charge, to any person obtaining a copy
185-- of this software and associated documentation files (the "Software"), to deal
186-- in the Software without restriction, including without limitation the rights
187-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
188-- copies of the Software, and to permit persons to whom the Software is
189-- furnished to do so, subject to the following conditions:
190--
191-- The above copyright notice and this permission notice shall be included in
192-- all copies or substantial portions of the Software.
193--
194-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
195-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
196-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
197-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
198-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
199-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
200-- THE SOFTWARE.