origen_testers 0.5.7 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/config/shared_commands.rb +6 -0
  3. data/config/version.rb +2 -2
  4. data/lib/commands/run.rb +44 -0
  5. data/lib/origen_testers.rb +19 -1
  6. data/lib/origen_testers/flow.rb +382 -0
  7. data/lib/origen_testers/generator.rb +32 -29
  8. data/lib/origen_testers/igxl_based_tester/base/ac_specsets.rb +79 -0
  9. data/lib/origen_testers/igxl_based_tester/base/dc_specsets.rb +98 -0
  10. data/lib/origen_testers/igxl_based_tester/base/edge.rb +60 -0
  11. data/lib/origen_testers/igxl_based_tester/base/edges.rb +24 -0
  12. data/lib/origen_testers/igxl_based_tester/base/edgeset.rb +39 -0
  13. data/lib/origen_testers/igxl_based_tester/base/edgesets.rb +97 -0
  14. data/lib/origen_testers/igxl_based_tester/base/flow.rb +390 -115
  15. data/lib/origen_testers/igxl_based_tester/base/flow_line.rb +4 -54
  16. data/lib/origen_testers/igxl_based_tester/base/generator.rb +257 -11
  17. data/lib/origen_testers/igxl_based_tester/base/level_io_se.rb +59 -0
  18. data/lib/origen_testers/igxl_based_tester/base/level_supply.rb +39 -0
  19. data/lib/origen_testers/igxl_based_tester/base/levels.rb +31 -0
  20. data/lib/origen_testers/igxl_based_tester/base/levelset.rb +109 -0
  21. data/lib/origen_testers/igxl_based_tester/base/pinmap.rb +93 -0
  22. data/lib/origen_testers/igxl_based_tester/base/test_instance.rb +33 -1
  23. data/lib/origen_testers/igxl_based_tester/base/timeset.rb +37 -0
  24. data/lib/origen_testers/igxl_based_tester/base/timesets.rb +47 -0
  25. data/lib/origen_testers/igxl_based_tester/j750/templates/flow.txt.erb +2 -2
  26. data/lib/origen_testers/igxl_based_tester/ultraflex/ac_specsets.rb +10 -0
  27. data/lib/origen_testers/igxl_based_tester/ultraflex/custom_test_instance.rb +4 -0
  28. data/lib/origen_testers/igxl_based_tester/ultraflex/dc_specsets.rb +10 -0
  29. data/lib/origen_testers/igxl_based_tester/ultraflex/edge.rb +9 -0
  30. data/lib/origen_testers/igxl_based_tester/ultraflex/edges.rb +9 -0
  31. data/lib/origen_testers/igxl_based_tester/ultraflex/edgeset.rb +9 -0
  32. data/lib/origen_testers/igxl_based_tester/ultraflex/edgesets.rb +10 -0
  33. data/lib/origen_testers/igxl_based_tester/ultraflex/flow.rb +137 -0
  34. data/lib/origen_testers/igxl_based_tester/ultraflex/level_io_se.rb +9 -0
  35. data/lib/origen_testers/igxl_based_tester/ultraflex/level_supply.rb +9 -0
  36. data/lib/origen_testers/igxl_based_tester/ultraflex/levels.rb +9 -0
  37. data/lib/origen_testers/igxl_based_tester/ultraflex/levelset.rb +10 -0
  38. data/lib/origen_testers/igxl_based_tester/ultraflex/pinmap.rb +10 -0
  39. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/ac_specsets.txt.erb +58 -0
  40. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/dc_specsets.txt.erb +58 -0
  41. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/edgesets.txt.erb +95 -0
  42. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/flow.txt.erb +2 -2
  43. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/levelset.txt.erb +121 -0
  44. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/pinmap.txt.erb +24 -0
  45. data/lib/origen_testers/igxl_based_tester/ultraflex/templates/timesets.txt.erb +137 -0
  46. data/lib/origen_testers/igxl_based_tester/ultraflex/test_instance.rb +4 -0
  47. data/lib/origen_testers/igxl_based_tester/ultraflex/timeset.rb +9 -0
  48. data/lib/origen_testers/igxl_based_tester/ultraflex/timesets.rb +10 -0
  49. data/lib/origen_testers/interface.rb +41 -6
  50. data/lib/origen_testers/no_interface.rb +7 -0
  51. data/lib/origen_testers/origen_ext/application/runner.rb +25 -0
  52. data/lib/origen_testers/origen_ext/generator.rb +37 -0
  53. data/lib/origen_testers/origen_ext/generator/flow.rb +70 -0
  54. data/lib/origen_testers/origen_ext/generator/resources.rb +21 -0
  55. data/lib/origen_testers/program_generators.rb +0 -1
  56. data/lib/origen_testers/smartest_based_tester/base/flow.rb +158 -134
  57. data/lib/origen_testers/smartest_based_tester/base/generator.rb +2 -3
  58. data/lib/origen_testers/smartest_based_tester/base/test_suite.rb +4 -0
  59. data/lib/origen_testers/smartest_based_tester/v93k/templates/template.flow.erb +5 -6
  60. data/lib/origen_testers/test/dut.rb +5 -0
  61. data/lib/origen_testers/test/j750_base_interface.rb +0 -3
  62. data/lib/origen_testers/test/ultraflex_interface.rb +230 -4
  63. data/lib/origen_testers/test/v93k_interface.rb +5 -23
  64. data/program/components/_temp.rb +6 -0
  65. data/program/flow_control.rb +190 -62
  66. data/program/prb1.rb +13 -50
  67. data/program/prb2.rb +0 -16
  68. data/program/test.rb +12 -3
  69. data/program/uflex_resources.rb +159 -0
  70. metadata +66 -16
  71. data/lib/origen_testers/doc.rb +0 -224
  72. data/lib/origen_testers/doc/generator.rb +0 -124
  73. data/lib/origen_testers/doc/generator/flow.rb +0 -69
  74. data/lib/origen_testers/doc/generator/flow_line.rb +0 -201
  75. data/lib/origen_testers/doc/generator/test.rb +0 -66
  76. data/lib/origen_testers/doc/generator/test_group.rb +0 -64
  77. data/lib/origen_testers/doc/generator/tests.rb +0 -45
  78. data/lib/origen_testers/doc/model.rb +0 -160
  79. data/lib/origen_testers/generator/flow_control_api.rb +0 -611
  80. data/lib/origen_testers/smartest_based_tester/base/flow_node.rb +0 -476
  81. data/lib/origen_testers/smartest_based_tester/v93k/flow_node.rb +0 -9
@@ -1,168 +1,443 @@
1
1
  module OrigenTesters
2
2
  module IGXLBasedTester
3
3
  class Base
4
- class Flow
5
- include OrigenTesters::Generator
6
- include OrigenTesters::Generator::FlowControlAPI
4
+ class Flow < ATP::Formatter
5
+ include OrigenTesters::Flow
7
6
 
8
7
  OUTPUT_POSTFIX = 'flow'
9
8
 
10
- def add(type, options = {})
11
- ins = false
12
- options = save_context(options) if [:test, :cz].include?(type)
13
- branch_unless_enabled(options) do |options|
14
- ins = track_relationships(options) do |options|
15
- platform::FlowLine.new(type, options)
16
- end
17
- collection << ins unless Origen.interface.resources_mode?
18
- if ins.test?
19
- c = Origen.interface.consume_comments
20
- unless Origen.interface.resources_mode?
21
- Origen.interface.descriptions.add_for_test_usage(ins.parameter, Origen.interface.top_level_flow, c)
22
- end
9
+ attr_reader :branch
10
+ attr_reader :stack
11
+ attr_reader :current_group
12
+ attr_reader :context
13
+ attr_reader :set_run_flags
14
+ attr_accessor :run_flag
15
+ attr_accessor :flow_flag
16
+
17
+ class FlowLineAPI
18
+ def initialize(flow)
19
+ @flow = flow
20
+ end
21
+
22
+ def method_missing(method, *args, &block)
23
+ if Base::FlowLine::DEFAULTS.key?(method.to_sym)
24
+ line = @flow.platform::FlowLine.new(method, *args)
25
+ @flow.render(line)
26
+ line
23
27
  else
24
- Origen.interface.discard_comments
28
+ super
25
29
  end
26
30
  end
27
- ins
31
+
32
+ def respond_to?(method)
33
+ !!Base::FlowLine::DEFAULTS.key?(method.to_sym)
34
+ end
28
35
  end
29
36
 
30
- def logprint(message, options = {})
31
- message.gsub!(/\s/, '_')
32
- add(:logprint, options.merge(parameter: message))
37
+ class TestCounter < ATP::Processor
38
+ def run(node)
39
+ @tests = 0
40
+ process(node)
41
+ @tests
42
+ end
43
+
44
+ def on_test(node)
45
+ @tests += 1
46
+ end
33
47
  end
34
48
 
35
- def test(instance, options = {})
36
- add(:test, options.merge(parameter: instance))
49
+ # Returns the API to manually generate an IG-XL flow line
50
+ def ultraflex
51
+ @flow_line_api ||= FlowLineAPI.new(self)
37
52
  end
53
+ alias_method :uflex, :ultraflex
54
+ alias_method :j750, :ultraflex
38
55
 
39
- def cz(instance, cz_setup, options = {})
40
- add(:cz, options.merge(parameter: instance, cz_setup: cz_setup))
56
+ def number_of_tests_in(node)
57
+ @test_counter ||= TestCounter.new
58
+ @test_counter.run(node)
41
59
  end
42
60
 
43
- def use_limit(name, options = {})
44
- add(:use_limit, options)
61
+ # Will be called at the end to transform the final flow model into an array
62
+ # of lines to be rendered to the IG-XL flow sheet
63
+ def format
64
+ @lines = []
65
+ @stack = { jobs: [], groups: [] }
66
+ @set_run_flags = {}
67
+ @context = []
68
+ process(model.ast)
69
+ lines
45
70
  end
46
71
 
47
- def goto(label, options = {})
48
- add(:goto, options.merge(parameter: label))
72
+ def on_flow(node)
73
+ name, *nodes = *node
74
+ process_all(nodes)
49
75
  end
50
76
 
51
- def nop(options = {})
52
- add(:nop, options.merge(parameter: nil))
77
+ def on_test(node)
78
+ line = new_line(:test) { |l| process_all(node) }
79
+
80
+ # In IG-XL you can't set the same flag in case of pass or fail, if that situation has
81
+ # occurred then rectify it now
82
+ if line.flag_fail && line.flag_fail == line.flag_pass
83
+ # If the test will bin, don't need to resolve the situation, the flag only matters
84
+ # in the pass case
85
+ if line.result = 'Fail'
86
+ line.flag_fail = nil
87
+ completed_lines << line
88
+ else
89
+ flag = line.flag_fail
90
+ line.flag_fail = "#{flag}_FAILED"
91
+ line.flag_pass = "#{flag}_PASSED"
92
+ completed_lines << line
93
+ existing_flag = run_flag
94
+ self.run_flag = [line.flag_fail, true]
95
+ completed_lines << new_line(:flag_true, parameter: flag)
96
+ self.run_flag = [line.flag_pass, true]
97
+ completed_lines << new_line(:flag_true, parameter: flag)
98
+ self.run_flag = existing_flag
99
+ end
100
+ else
101
+ completed_lines << line
102
+ end
53
103
  end
54
104
 
55
- def set_device(options = {})
56
- add(:set_device, options)
105
+ def on_cz(node)
106
+ setup, test = *node
107
+ completed_lines << new_line(:cz, cz_setup: setup) do |line|
108
+ process_all(test)
109
+ end
57
110
  end
58
111
 
59
- def set_error_bin(options = {})
60
- add(:set_error_bin, options)
112
+ def on_group(node)
113
+ stack[:groups] << []
114
+ post_group = node.children.select { |n| [:on_fail, :on_pass, :name].include?(n.try(:type)) }
115
+ process_all(node.children - post_group)
116
+ # Now process any on_fail and similar conditional logic attached to the group
117
+ @current_group = stack[:groups].last
118
+ process_all(post_group)
119
+ @current_group = nil
120
+ flags = { on_pass: [], on_fail: [] }
121
+ stack[:groups].pop.each do |test|
122
+ flags[:on_pass] << test.flag_pass
123
+ flags[:on_fail] << test.flag_fail
124
+ completed_lines << test
125
+ end
126
+ if @group_on_fail_flag
127
+ flags[:on_fail].each do |flag|
128
+ self.run_flag = [flag, true]
129
+ completed_lines << new_line(:flag_true, parameter: @group_on_fail_flag)
130
+ end
131
+ self.run_flag = nil
132
+ @group_on_fail_flag = nil
133
+ end
134
+ if @group_on_pass_flag
135
+ flags[:on_pass].each do |flag|
136
+ self.run_flag = [flag, true]
137
+ completed_lines << new_line(:flag_true, parameter: @group_on_pass_flag)
138
+ end
139
+ self.run_flag = nil
140
+ @group_on_pass_flag = nil
141
+ end
61
142
  end
62
143
 
63
- def enable_flow_word(word, options = {})
64
- add(:enable_flow_word, options.merge(parameter: word))
144
+ def on_name(node)
145
+ if current_group
146
+ # No action, groups will not actually appear in the flow sheet
147
+ else
148
+ current_line.tname = node.to_a[0]
149
+ end
65
150
  end
66
151
 
67
- def disable_flow_word(word, options = {})
68
- add(:disable_flow_word, options.merge(parameter: word))
152
+ def on_number(node)
153
+ if Origen.tester.diff_friendly_output?
154
+ current_line.tnum = 0
155
+ else
156
+ current_line.tnum = node.to_a[0]
157
+ end
69
158
  end
70
159
 
71
- def flag_false(name, options = {})
72
- add(:flag_false, options.merge(parameter: name))
160
+ def on_object(node)
161
+ instance = node.to_a[0]
162
+ if instance.is_a?(String)
163
+ current_line.instance_variable_set('@ignore_missing_instance', true)
164
+ end
165
+ current_line.parameter = instance
73
166
  end
74
167
 
75
- def flag_false_all(name, options = {})
76
- add(:flag_false_all, options.merge(parameter: name))
168
+ def on_continue(node)
169
+ if current_group
170
+ current_group.each { |line| line.result = 'None' }
171
+ else
172
+ current_line.result = 'None'
173
+ end
174
+ end
175
+
176
+ def on_set_run_flag(node)
177
+ flag = node.to_a[0]
178
+ set_run_flags[flag] = context.dup
179
+ if current_group
180
+ if branch == :on_fail
181
+ @group_on_fail_flag = flag
182
+ current_group.each_with_index do |line, i|
183
+ line.flag_fail = "#{flag}_#{i}" unless line.flag_fail
184
+ end
185
+ else
186
+ @group_on_pass_flag = flag
187
+ current_group.each_with_index do |line, i|
188
+ line.flag_pass = "#{flag}_#{i}" unless line.flag_pass
189
+ end
190
+ end
191
+ else
192
+ if branch == :on_fail
193
+ current_line.flag_fail = flag
194
+ else
195
+ current_line.flag_pass = flag
196
+ end
197
+ end
198
+ end
199
+
200
+ def on_set_result(node)
201
+ bin = node.find(:bin).try(:value)
202
+ sbin = node.find(:softbin).try(:value)
203
+ desc = node.find(:bin_description).try(:value)
204
+ if current_line
205
+ if branch == :on_fail
206
+ current_line.bin_fail = bin
207
+ current_line.sort_fail = sbin
208
+ current_line.comment = desc
209
+ current_line.result = 'Fail'
210
+ else
211
+ current_line.bin_pass = bin
212
+ current_line.sort_pass = sbin
213
+ current_line.comment = desc
214
+ current_line.result = 'Pass'
215
+ end
216
+ else
217
+ line = new_line(:set_device)
218
+ if node.to_a[0] == 'pass'
219
+ line.bin_pass = bin
220
+ line.sort_pass = sbin
221
+ line.result = 'Pass'
222
+ else
223
+ line.bin_fail = bin
224
+ line.sort_fail = sbin
225
+ line.result = 'Fail'
226
+ end
227
+ line.comment = desc
228
+ completed_lines << line
229
+ end
77
230
  end
78
231
 
79
- # def flag_true(name, options = {})
80
- def flag_true(options = {})
81
- add(:flag_true, options)
232
+ def on_on_fail(node)
233
+ @branch = :on_fail
234
+ process_all(node)
235
+ @branch = nil
82
236
  end
83
237
 
84
- def flag_true_all(name, options = {})
85
- add(:flag_true_all, options.merge(parameter: name))
238
+ def on_on_pass(node)
239
+ @branch = :on_pass
240
+ process_all(node)
241
+ @branch = nil
86
242
  end
87
243
 
88
- # Generates 2 flow lines of flag-true to help set a single flag based on OR of 2 other flags
89
- def or_flags(name1, name2, options = {})
90
- options = {
91
- condition: :fail, # condition to check for
92
- flowname: false, # if flowname provided
93
- }.merge(options)
244
+ def on_job(node)
245
+ jobs, state, *nodes = *node
246
+ jobs = clean_job(jobs)
247
+ unless state
248
+ jobs = jobs.map { |j| "!#{j}" }
249
+ end
250
+ stack[:jobs] << [stack[:jobs].last, jobs].compact.join(',')
251
+ context << stack[:jobs].last
252
+ process_all(node)
253
+ stack[:jobs].pop
254
+ context.pop
255
+ end
94
256
 
95
- case options[:condition]
96
- when :fail
97
- options[:condition] = 'FAILED'
98
- when :pass
99
- options[:condition] = 'PASSED'
257
+ def on_run_flag(node)
258
+ flag, state, *nodes = *node
259
+ orig = run_flag
260
+ if flag.is_a?(Array)
261
+ or_flag = flag.join('_OR_')
262
+ or_flag = "NOT_#{flag}" unless state
263
+ flag.each do |f|
264
+ if run_flag
265
+ fail 'Not implemented yet!'
266
+ else
267
+ self.run_flag = [f, state]
268
+ completed_lines << new_line(:flag_true, parameter: or_flag)
269
+ self.run_flag = nil
270
+ end
271
+ end
272
+ # Don't need to create an AND flag if the flag on which this test is dependent was also
273
+ # set under the same context.
274
+ if run_flag && set_run_flags[flag] && set_run_flags[flag].hash != context.hash
275
+ and_flag = flag_to_s(or_flag, state) + '_AND_' + flag_to_s(*run_flag)
276
+ # If the AND flag has already been created and set in this context (for a previous test),
277
+ # no need to re-create it
278
+ if !set_run_flags[and_flag] || (set_run_flags[and_flag].hash != context.hash)
279
+ set_run_flags[and_flag] = context
280
+ existing_flag = run_flag
281
+ self.run_flag = nil
282
+ completed_lines << new_line(:flag_true, parameter: and_flag)
283
+ self.run_flag = [existing_flag[0], !existing_flag[1]]
284
+ completed_lines << new_line(:flag_false, parameter: and_flag)
285
+ self.run_flag = [flag, !state]
286
+ completed_lines << new_line(:flag_false, parameter: and_flag)
287
+ end
288
+ self.run_flag = [and_flag, true]
100
289
  else
101
- options[:condition] = 'RAN'
102
- end
103
- id = options.delete(:id) # get original ID
104
-
105
- # set parameter names
106
- parameter = "#{id}"
107
- parameter += "_#{options[:flowname]}" if options[:flowname]
108
- parameter += "_#{options[:condition]}"
109
-
110
- options[:id] = id
111
- add(:flag_true_all, options.merge(parameter: parameter))
112
- options.delete(:id)
113
- add(:flag_false, options.merge(parameter: parameter, if_passed: name1, result: '', flag_pass: '', flag_fail: '')) # No ID
114
- add(:flag_false, options.merge(parameter: parameter, if_passed: name2)) # No ID
115
- nop
116
- end
117
-
118
- # All tests generated will not run unless the given enable word is asserted.
119
- #
120
- # This is specially implemented for J750 since it does not have a native
121
- # support for flow word not enabled.
122
- # It will generate a goto branch around the tests contained with the block
123
- # if the given flow word is enabled.
124
- def unless_enable(word, options = {})
125
- if options[:or]
126
- yield
290
+ self.run_flag = [or_flag, true]
291
+ end
127
292
  else
128
- @unless_enable_block = word
129
- options = options.merge(unless_enable: word)
130
- branch_unless_enabled(options.merge(_force_unless_enable: true)) do
131
- yield
293
+ # Don't need to create an AND flag if the flag on which this test is dependent was also
294
+ # set under the same context.
295
+ if run_flag && set_run_flags[flag] && set_run_flags[flag].hash != context.hash
296
+ and_flag = flag_to_s(flag, state) + '_AND_' + flag_to_s(*run_flag)
297
+ # If the AND flag has already been created and set in this context (for a previous test),
298
+ # no need to re-create it
299
+ if !set_run_flags[and_flag] || (set_run_flags[and_flag].hash != context.hash)
300
+ set_run_flags[and_flag] = context
301
+ existing_flag = run_flag
302
+ self.run_flag = nil
303
+ completed_lines << new_line(:flag_true, parameter: and_flag)
304
+ self.run_flag = [existing_flag[0], !existing_flag[1]]
305
+ completed_lines << new_line(:flag_false, parameter: and_flag)
306
+ self.run_flag = [flag, !state]
307
+ completed_lines << new_line(:flag_false, parameter: and_flag)
308
+ end
309
+ self.run_flag = [and_flag, true]
310
+ else
311
+ self.run_flag = [flag, state]
132
312
  end
133
- @unless_enable_block = nil
134
313
  end
314
+ context << run_flag
315
+ process_all(node)
316
+ context.pop
317
+ self.run_flag = orig
135
318
  end
136
- alias_method :unless_enabled, :unless_enable
137
319
 
138
- def start_flow_branch(identifier, options = {})
139
- goto(identifier, options)
320
+ def on_flow_flag(node)
321
+ flag, value = *node.to_a.take(2)
322
+ orig = flow_flag
323
+ if flag.is_a?(Array)
324
+ if flag.size > 1
325
+ or_flag = flag.join('_OR_')
326
+ flag.each do |f|
327
+ completed_lines << new_line(:enable_flow_word, parameter: or_flag, enable: f)
328
+ end
329
+ flag = or_flag
330
+ else
331
+ flag = flag.first
332
+ end
333
+ end
334
+ if value
335
+ # IG-XL docs say that enable words are not optimized for test time, so branch around
336
+ # large blocks to minimize enable word evaluation
337
+ if number_of_tests_in(node) > 5
338
+ label = generate_unique_label
339
+ branch_if_enable(flag) do
340
+ completed_lines << new_line(:goto, parameter: label, enable: nil)
341
+ end
342
+ context << flag
343
+ process_all(node)
344
+ context.pop
345
+ completed_lines << new_line(:nop, label: label, enable: nil)
346
+ else
347
+ if flow_flag
348
+ and_flag = "#{flow_flag}_AND_#{flag}"
349
+ label = generate_unique_label
350
+ branch_if_enable(flow_flag) do
351
+ completed_lines << new_line(:goto, parameter: label, enable: nil)
352
+ end
353
+ completed_lines << new_line(:enable_flow_word, parameter: and_flag, enable: flag)
354
+ completed_lines << new_line(:nop, label: label, enable: nil)
355
+ self.flow_flag = and_flag
356
+ context << and_flag
357
+ process_all(node)
358
+ context.pop
359
+ self.flow_flag = orig
360
+ else
361
+ self.flow_flag = flag
362
+ context << flag
363
+ process_all(node)
364
+ context.pop
365
+ self.flow_flag = orig
366
+ end
367
+ end
368
+ else
369
+ # IG-XL does not have a !enable option, so generate a branch around the tests
370
+ # to be skipped unless the required flag is enabled
371
+ context << "!#{flag}"
372
+ branch_if_enable(flag) do
373
+ process_all(node)
374
+ end
375
+ context.pop
376
+ end
140
377
  end
141
378
 
142
- def skip(identifier = nil, options = {})
143
- identifier, options = nil, identifier if identifier.is_a?(Hash)
144
- identifier = generate_unique_label(identifier)
145
- goto(identifier, options)
379
+ def branch_if_enable(word)
380
+ label = generate_unique_label
381
+ completed_lines << new_line(:goto, parameter: label, enable: word)
146
382
  yield
147
- nop(label: identifier)
148
- end
149
-
150
- private
151
-
152
- # If the test has an unless_enable then branch around it
153
- def branch_unless_enabled(options)
154
- word = options.delete(:unless_enable) || options.delete(:unless_enabled)
155
- if word && (word != @unless_enable_block || options.delete(:_force_unless_enable))
156
- # Not sure if this is really required, but duplicating these hashes here to ensure
157
- # that all other flow context keys are preserved and applied to the branch lines
158
- orig_options = options.merge({})
159
- close_options = options.merge({})
160
- label = generate_unique_label
161
- goto(label, options.merge(if_enable: word))
162
- yield orig_options
163
- nop(close_options.merge(label: label))
383
+ completed_lines << new_line(:nop, label: label, enable: nil)
384
+ end
385
+
386
+ def on_enable_flow_flag(node)
387
+ completed_lines << new_line(:enable_flow_word, parameter: node.value)
388
+ end
389
+
390
+ def on_disable_flow_flag(node)
391
+ completed_lines << new_line(:disable_flow_word, parameter: node.value)
392
+ end
393
+
394
+ def on_log(node)
395
+ completed_lines << new_line(:logprint, parameter: node.to_a[0].gsub(' ', '_'))
396
+ end
397
+
398
+ def on_render(node)
399
+ completed_lines << node.to_a[0]
400
+ end
401
+
402
+ def new_line(type, attrs = {})
403
+ attrs = {
404
+ job: stack[:jobs].last,
405
+ enable: flow_flag
406
+ }.merge(attrs)
407
+ line = platform::FlowLine.new(type, attrs)
408
+ if run_flag
409
+ line.device_sense = 'not' unless run_flag[1]
410
+ line.device_name = run_flag[0]
411
+ line.device_condition = 'flag-true'
412
+ end
413
+ open_lines << line
414
+ yield line if block_given?
415
+ open_lines.pop
416
+ line
417
+ end
418
+
419
+ # Any completed lines should be pushed to the array that this returns
420
+ def completed_lines
421
+ stack[:groups].last || lines
422
+ end
423
+
424
+ def open_lines
425
+ @open_lines ||= []
426
+ end
427
+
428
+ def current_line
429
+ open_lines.last
430
+ end
431
+
432
+ def clean_job(job)
433
+ [job].flatten.map { |j| j.to_s.upcase }
434
+ end
435
+
436
+ def flag_to_s(flag, state)
437
+ if state
438
+ flag
164
439
  else
165
- yield options
440
+ "NOT_#{flag}"
166
441
  end
167
442
  end
168
443
  end