3 attr_accessor :to_state
4 def initialize(to_state)
9 def transition_to(state)
10 StateTransition.new(state)
15 $states[:ANYWHERE] = {
16 0x18 => [:execute, transition_to(:GROUND)],
17 0x1a => [:execute, transition_to(:GROUND)],
18 0x80..0x8f => [:execute, transition_to(:GROUND)],
19 0x91..0x97 => [:execute, transition_to(:GROUND)],
20 0x99 => [:execute, transition_to(:GROUND)],
21 0x9a => [:execute, transition_to(:GROUND)],
22 0x9c => [:execute, transition_to(:GROUND)],
23 0x1b => transition_to(:ESCAPE),
24 0x98 => transition_to(:SOS_PM_APC_STRING),
25 0x9e => transition_to(:SOS_PM_APC_STRING),
26 0x9f => transition_to(:SOS_PM_APC_STRING),
27 0x90 => transition_to(:DCS_ENTRY),
28 0x9d => transition_to(:OSC_STRING),
29 0x9b => transition_to(:CSI_ENTRY),
33 0x00..0x17 => :execute,
35 0x1c..0x1f => :execute,
37 0x80..0x8f => :execute,
38 0x91..0x9a => :execute,
44 0x00..0x17 => :execute,
46 0x1c..0x1f => :execute,
48 0x20..0x2f => [:collect, transition_to(:ESCAPE_INTERMEDIATE)],
49 0x30..0x4f => [:esc_dispatch, transition_to(:GROUND)],
50 0x51..0x57 => [:esc_dispatch, transition_to(:GROUND)],
51 0x59 => [:esc_dispatch, transition_to(:GROUND)],
52 0x5a => [:esc_dispatch, transition_to(:GROUND)],
53 0x5c => [:esc_dispatch, transition_to(:GROUND)],
54 0x60..0x7e => [:esc_dispatch, transition_to(:GROUND)],
55 0x5b => transition_to(:CSI_ENTRY),
56 0x5d => transition_to(:OSC_STRING),
57 0x50 => transition_to(:DCS_ENTRY),
58 0x58 => transition_to(:SOS_PM_APC_STRING),
59 0x5e => transition_to(:SOS_PM_APC_STRING),
60 0x5f => transition_to(:SOS_PM_APC_STRING),
63 $states[:ESCAPE_INTERMEDIATE] = {
64 0x00..0x17 => :execute,
66 0x1c..0x1f => :execute,
67 0x20..0x2f => :collect,
69 0x30..0x7e => [:esc_dispatch, transition_to(:GROUND)]
72 $states[:CSI_ENTRY] = {
74 0x00..0x17 => :execute,
76 0x1c..0x1f => :execute,
78 0x20..0x2f => [:collect, transition_to(:CSI_INTERMEDIATE)],
79 0x3a => transition_to(:CSI_IGNORE),
80 0x30..0x39 => [:param, transition_to(:CSI_PARAM)],
81 0x3b => [:param, transition_to(:CSI_PARAM)],
82 0x3c..0x3f => [:collect, transition_to(:CSI_PARAM)],
83 0x40..0x7e => [:csi_dispatch, transition_to(:GROUND)]
86 $states[:CSI_IGNORE] = {
87 0x00..0x17 => :execute,
89 0x1c..0x1f => :execute,
90 0x20..0x3f => :ignore,
92 0x40..0x7e => transition_to(:GROUND),
95 $states[:CSI_PARAM] = {
96 0x00..0x17 => :execute,
98 0x1c..0x1f => :execute,
102 0x3a => transition_to(:CSI_IGNORE),
103 0x3c..0x3f => transition_to(:CSI_IGNORE),
104 0x20..0x2f => [:collect, transition_to(:CSI_INTERMEDIATE)],
105 0x40..0x7e => [:csi_dispatch, transition_to(:GROUND)]
108 $states[:CSI_INTERMEDIATE] = {
109 0x00..0x17 => :execute,
111 0x1c..0x1f => :execute,
112 0x20..0x2f => :collect,
114 0x30..0x3f => transition_to(:CSI_IGNORE),
115 0x40..0x7e => [:csi_dispatch, transition_to(:GROUND)],
118 $states[:DCS_ENTRY] = {
120 0x00..0x17 => :ignore,
122 0x1c..0x1f => :ignore,
124 0x3a => transition_to(:DCS_IGNORE),
125 0x20..0x2f => [:collect, transition_to(:DCS_INTERMEDIATE)],
126 0x30..0x39 => [:param, transition_to(:DCS_PARAM)],
127 0x3b => [:param, transition_to(:DCS_PARAM)],
128 0x3c..0x3f => [:collect, transition_to(:DCS_PARAM)],
129 0x40..0x7e => [transition_to(:DCS_PASSTHROUGH)]
132 $states[:DCS_INTERMEDIATE] = {
133 0x00..0x17 => :ignore,
135 0x1c..0x1f => :ignore,
136 0x20..0x2f => :collect,
138 0x30..0x3f => transition_to(:DCS_IGNORE),
139 0x40..0x7e => transition_to(:DCS_PASSTHROUGH)
142 $states[:DCS_IGNORE] = {
143 0x00..0x17 => :ignore,
145 0x1c..0x1f => :ignore,
146 0x20..0x7f => :ignore,
147 0x9c => transition_to(:GROUND)
150 $states[:DCS_PARAM] = {
151 0x00..0x17 => :ignore,
153 0x1c..0x1f => :ignore,
154 0x30..0x39 => :param,
157 0x3a => transition_to(:DCS_IGNORE),
158 0x3c..0x3f => transition_to(:DCS_IGNORE),
159 0x20..0x2f => [:collect, transition_to(:DCS_INTERMEDIATE)],
160 0x40..0x7e => transition_to(:DCS_PASSTHROUGH)
163 $states[:DCS_PASSTHROUGH] = {
170 0x9c => transition_to(:GROUND),
174 $states[:SOS_PM_APC_STRING] = {
175 0x00..0x17 => :ignore,
177 0x1c..0x1f => :ignore,
178 0x20..0x7f => :ignore,
179 0x9c => transition_to(:GROUND)
182 $states[:OSC_STRING] = {
183 :on_entry => :osc_start,
184 0x00..0x17 => :ignore,
186 0x1c..0x1f => :ignore,
187 0x20..0x7f => :osc_put,
188 0x9c => transition_to(:GROUND),
192 $states.each { |state, transitions|
193 transitions.each { |keys, actions|
194 if not actions.kind_of?(Array)
195 $states[state][keys] = [actions]
201 # get the list of actions implicit in the tables
204 $states.each { |state, transitions|
205 transitions.each { |keys, actions|
206 actions.each { |action|
207 if action.kind_of?(Symbol)
208 action_names[action] = 1
214 # establish an ordering to the states and actions
216 $actions_in_order = action_names.keys.sort { |a1, a2| a1.to_s <=> a2.to_s }
217 $states_in_order = $states.keys.sort { |s1, s2| s1.to_s <=> s2.to_s }
220 # Expand the above range-based data structures (which are convenient
221 # to write) into fully expanded tables (which are easier to use).
226 def expand_ranges(hash_with_ranges_as_keys)
228 hash_with_ranges_as_keys.each { |range, val|
229 if range.kind_of?(Range)
233 elsif range.kind_of?(Fixnum)
241 $states.each { |state, transitions|
242 $state_tables[state] = expand_ranges(transitions)