tp_plus 0.0.73
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.
- checksums.yaml +7 -0
- data/README.md +65 -0
- data/Rakefile +21 -0
- data/bin/tpp +73 -0
- data/lib/tp_plus/interpreter.rb +129 -0
- data/lib/tp_plus/namespace.rb +66 -0
- data/lib/tp_plus/nodes/abort_node.rb +9 -0
- data/lib/tp_plus/nodes/argument_node.rb +19 -0
- data/lib/tp_plus/nodes/assignment_node.rb +45 -0
- data/lib/tp_plus/nodes/call_node.rb +34 -0
- data/lib/tp_plus/nodes/case_condition_node.rb +26 -0
- data/lib/tp_plus/nodes/case_node.rb +33 -0
- data/lib/tp_plus/nodes/comment_node.rb +22 -0
- data/lib/tp_plus/nodes/conditional_node.rb +54 -0
- data/lib/tp_plus/nodes/definition_node.rb +22 -0
- data/lib/tp_plus/nodes/digit_node.rb +21 -0
- data/lib/tp_plus/nodes/eval_node.rb +13 -0
- data/lib/tp_plus/nodes/expression_node.rb +65 -0
- data/lib/tp_plus/nodes/for_node.rb +20 -0
- data/lib/tp_plus/nodes/header_node.rb +27 -0
- data/lib/tp_plus/nodes/indirect_node.rb +49 -0
- data/lib/tp_plus/nodes/inline_conditional_node.rb +40 -0
- data/lib/tp_plus/nodes/io_method_node.rb +55 -0
- data/lib/tp_plus/nodes/io_node.rb +30 -0
- data/lib/tp_plus/nodes/jump_node.rb +23 -0
- data/lib/tp_plus/nodes/label_definition_node.rb +21 -0
- data/lib/tp_plus/nodes/motion_node.rb +62 -0
- data/lib/tp_plus/nodes/namespace_node.rb +16 -0
- data/lib/tp_plus/nodes/namespaced_var_node.rb +38 -0
- data/lib/tp_plus/nodes/numreg_node.rb +25 -0
- data/lib/tp_plus/nodes/offset_node.rb +27 -0
- data/lib/tp_plus/nodes/operator_node.rb +72 -0
- data/lib/tp_plus/nodes/pause_node.rb +9 -0
- data/lib/tp_plus/nodes/position_data_node.rb +50 -0
- data/lib/tp_plus/nodes/position_node.rb +25 -0
- data/lib/tp_plus/nodes/posreg_node.rb +48 -0
- data/lib/tp_plus/nodes/raise_node.rb +13 -0
- data/lib/tp_plus/nodes/real_node.rb +27 -0
- data/lib/tp_plus/nodes/set_node.rb +22 -0
- data/lib/tp_plus/nodes/skip_node.rb +22 -0
- data/lib/tp_plus/nodes/speed_node.rb +29 -0
- data/lib/tp_plus/nodes/string_node.rb +13 -0
- data/lib/tp_plus/nodes/string_register_node.rb +25 -0
- data/lib/tp_plus/nodes/termination_node.rb +18 -0
- data/lib/tp_plus/nodes/terminator_node.rb +16 -0
- data/lib/tp_plus/nodes/time_node.rb +24 -0
- data/lib/tp_plus/nodes/timer_method_node.rb +37 -0
- data/lib/tp_plus/nodes/timer_node.rb +21 -0
- data/lib/tp_plus/nodes/units_node.rb +20 -0
- data/lib/tp_plus/nodes/use_node.rb +21 -0
- data/lib/tp_plus/nodes/user_alarm_node.rb +15 -0
- data/lib/tp_plus/nodes/var_method_node.rb +23 -0
- data/lib/tp_plus/nodes/var_node.rb +39 -0
- data/lib/tp_plus/nodes/vision_register_node.rb +21 -0
- data/lib/tp_plus/nodes/wait_for_node.rb +54 -0
- data/lib/tp_plus/nodes/wait_until_node.rb +65 -0
- data/lib/tp_plus/nodes/while_node.rb +36 -0
- data/lib/tp_plus/parser.rb +1592 -0
- data/lib/tp_plus/scanner.rb +383 -0
- data/lib/tp_plus/version.rb +3 -0
- data/lib/tp_plus.rb +62 -0
- data/test/test_helper.rb +5 -0
- data/test/tp_plus/test_interpreter.rb +1168 -0
- data/test/tp_plus/test_parser.rb +489 -0
- data/test/tp_plus/test_scanner.rb +522 -0
- data/tp_plus.gemspec +28 -0
- metadata +156 -0
@@ -0,0 +1,1168 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestInterpreter < Test::Unit::TestCase
|
4
|
+
include TPPlus::Nodes
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@scanner = TPPlus::Scanner.new
|
8
|
+
@parser = TPPlus::Parser.new @scanner
|
9
|
+
@interpreter = @parser.interpreter
|
10
|
+
end
|
11
|
+
|
12
|
+
def parse(s)
|
13
|
+
@scanner.scan_setup(s)
|
14
|
+
@parser.parse
|
15
|
+
end
|
16
|
+
|
17
|
+
def last_node
|
18
|
+
@last_node ||= @interpreter.nodes.last
|
19
|
+
end
|
20
|
+
|
21
|
+
def assert_node_type(t, n)
|
22
|
+
assert_equal t, n.class
|
23
|
+
end
|
24
|
+
|
25
|
+
def assert_prog(s)
|
26
|
+
assert_equal s, @interpreter.eval
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_blank_prog
|
30
|
+
parse("")
|
31
|
+
assert_prog ""
|
32
|
+
end
|
33
|
+
|
34
|
+
def test_definition
|
35
|
+
parse("foo := R[1]")
|
36
|
+
assert_prog ""
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_multi_define_fails
|
40
|
+
parse("foo := R[1]\nfoo := R[2]")
|
41
|
+
assert_raise(RuntimeError) do
|
42
|
+
assert_prog ""
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_var_usage
|
47
|
+
parse("foo := R[1]\nfoo = 1")
|
48
|
+
assert_prog "R[1:foo]=1 ;\n"
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_basic_addition
|
52
|
+
parse("foo := R[1]\nfoo = 1 + 1")
|
53
|
+
assert_prog "R[1:foo]=1+1 ;\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_basic_addition_with_var
|
57
|
+
parse("foo := R[1]\n foo = foo + 1")
|
58
|
+
assert_prog "R[1:foo]=R[1:foo]+1 ;\n"
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_label_definition
|
62
|
+
parse("@foo")
|
63
|
+
assert_prog "LBL[100:foo] ;\n"
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_duplicate_label_definition
|
67
|
+
parse("@foo\n@foo")
|
68
|
+
assert_raise RuntimeError do
|
69
|
+
assert_prog ""
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_jump_to_label
|
74
|
+
parse("@foo\njump_to @foo")
|
75
|
+
assert_prog "LBL[100:foo] ;\nJMP LBL[100] ;\n"
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_nonexistent_label_error
|
79
|
+
parse("jump_to @foo")
|
80
|
+
assert_raise RuntimeError do
|
81
|
+
assert_prog ""
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_turn_on
|
86
|
+
parse("foo := DO[1]\nturn_on foo")
|
87
|
+
assert_prog "DO[1:foo]=ON ;\n"
|
88
|
+
end
|
89
|
+
|
90
|
+
def test_turn_off
|
91
|
+
parse("foo := DO[1]\nturn_off foo")
|
92
|
+
assert_prog "DO[1:foo]=OFF ;\n"
|
93
|
+
end
|
94
|
+
|
95
|
+
def test_toggle
|
96
|
+
parse("foo := DO[1]\ntoggle foo")
|
97
|
+
assert_prog "DO[1:foo]=(!DO[1:foo]) ;\n"
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_simple_linear_motion
|
101
|
+
parse("foo := PR[1]\nlinear_move.to(foo).at(2000, 'mm/s').term(0)")
|
102
|
+
assert_prog "L PR[1:foo] 2000mm/sec CNT0 ;\n"
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_simple_if
|
106
|
+
parse("foo := R[1]\nif foo==1\nfoo=2\nend")
|
107
|
+
assert_prog "IF (R[1:foo]=1),R[1:foo]=(2) ;\n"
|
108
|
+
end
|
109
|
+
|
110
|
+
def test_simple_if_else
|
111
|
+
parse("foo := R[1]\nif foo==1\nfoo=2\nelse\nfoo=1\nend")
|
112
|
+
assert_prog "IF R[1:foo]<>1,JMP LBL[100] ;\nR[1:foo]=2 ;\nJMP LBL[101] ;\nLBL[100] ;\nR[1:foo]=1 ;\nLBL[101] ;\n"
|
113
|
+
end
|
114
|
+
|
115
|
+
def test_simple_unless
|
116
|
+
parse("foo := R[1]\nunless foo==1\nfoo=2\nend")
|
117
|
+
assert_prog "IF (R[1:foo]<>1),R[1:foo]=(2) ;\n"
|
118
|
+
end
|
119
|
+
|
120
|
+
def test_simple_unless_else
|
121
|
+
parse("foo := R[1]\nunless foo==1\nfoo=2\nelse\nfoo=1\nend")
|
122
|
+
assert_prog "IF R[1:foo]=1,JMP LBL[100] ;\nR[1:foo]=2 ;\nJMP LBL[101] ;\nLBL[100] ;\nR[1:foo]=1 ;\nLBL[101] ;\n"
|
123
|
+
end
|
124
|
+
|
125
|
+
def test_comment
|
126
|
+
parse("# this is a comment")
|
127
|
+
assert_prog "! this is a comment ;\n"
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_two_comments
|
131
|
+
parse("# comment one\n# comment two")
|
132
|
+
assert_prog "! comment one ;\n! comment two ;\n"
|
133
|
+
end
|
134
|
+
|
135
|
+
def test_inline_comment
|
136
|
+
parse("foo := R[1] # comment\nfoo = 1 # another comment")
|
137
|
+
assert_prog "! comment ;\nR[1:foo]=1 ;\n! another comment ;\n"
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_inline_conditional_if_on_jump
|
141
|
+
parse("foo := R[1]\n@bar\njump_to @bar if foo==1\n")
|
142
|
+
assert_prog "LBL[100:bar] ;\nIF R[1:foo]=1,JMP LBL[100] ;\n"
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_inline_conditional_unless_on_jump
|
146
|
+
parse("foo := R[1]\n@bar\njump_to @bar unless foo==1\n")
|
147
|
+
assert_prog "LBL[100:bar] ;\nIF R[1:foo]<>1,JMP LBL[100] ;\n"
|
148
|
+
end
|
149
|
+
|
150
|
+
def test_inline_assignment
|
151
|
+
parse("foo := R[1]\nfoo=2 if foo==1\n")
|
152
|
+
assert_prog "IF (R[1:foo]=1),R[1:foo]=(2) ;\n"
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_inline_io_method
|
156
|
+
parse("foo := DO[1]\nbar := R[1]\nturn_on foo if bar < 10\n")
|
157
|
+
assert_prog "IF (R[1:bar]<10),DO[1:foo]=(ON) ;\n"
|
158
|
+
end
|
159
|
+
|
160
|
+
def test_program_call
|
161
|
+
parse("foo()")
|
162
|
+
assert_prog "CALL FOO ;\n"
|
163
|
+
end
|
164
|
+
|
165
|
+
def test_program_call_with_simple_arg
|
166
|
+
parse("foo(1)")
|
167
|
+
assert_prog "CALL FOO(1) ;\n"
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_program_call_with_multiple_simple_args
|
171
|
+
parse("foo(1,2,3)")
|
172
|
+
assert_prog "CALL FOO(1,2,3) ;\n"
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_program_call_with_variable_argument
|
176
|
+
parse("foo := R[1]\nbar(foo)")
|
177
|
+
assert_prog "CALL BAR(R[1:foo]) ;\n"
|
178
|
+
end
|
179
|
+
|
180
|
+
def test_preserve_whitespace
|
181
|
+
parse("\n\n")
|
182
|
+
assert_prog " ;\n"
|
183
|
+
end
|
184
|
+
|
185
|
+
def test_plus_equals
|
186
|
+
parse("foo := R[1]\nfoo += 1\n")
|
187
|
+
assert_prog "R[1:foo]=R[1:foo]+1 ;\n"
|
188
|
+
end
|
189
|
+
|
190
|
+
def test_minus_equals
|
191
|
+
parse("foo := R[1]\nfoo -= 1\n")
|
192
|
+
assert_prog "R[1:foo]=R[1:foo]-1 ;\n"
|
193
|
+
end
|
194
|
+
|
195
|
+
def test_motion_to_a_position
|
196
|
+
parse("foo := P[1]\nlinear_move.to(foo).at(2000, 'mm/s').term(0)")
|
197
|
+
assert_prog "L P[1:foo] 2000mm/sec CNT0 ;\n"
|
198
|
+
end
|
199
|
+
|
200
|
+
def test_joint_move
|
201
|
+
parse("foo := P[1]\njoint_move.to(foo).at(100, '%').term(0)")
|
202
|
+
assert_prog "J P[1:foo] 100% CNT0 ;\n"
|
203
|
+
end
|
204
|
+
|
205
|
+
def test_joint_move_throws_error_with_bad_units
|
206
|
+
parse("foo := P[1]\njoint_move.to(foo).at(2000, 'mm/s').term(0)")
|
207
|
+
assert_raise(RuntimeError) do
|
208
|
+
assert_prog "J P[1:foo] 100% CNT0 ;\n"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
def test_linear_move_throws_error_with_bad_units
|
213
|
+
parse("foo := P[1]\nlinear_move.to(foo).at(100, '%').term(0)")
|
214
|
+
assert_raise(RuntimeError) do
|
215
|
+
assert_prog "L P[1:foo] 100% CNT0 ;\n"
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
|
220
|
+
def test_pr_offset
|
221
|
+
parse("home := P[1]\nmy_offset := PR[1]\nlinear_move.to(home).at(2000, 'mm/s').term(0).offset(my_offset)")
|
222
|
+
assert_prog "L P[1:home] 2000mm/sec CNT0 Offset,PR[1:my_offset] ;\n"
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_vr_offset
|
226
|
+
parse("home := P[1]\nvoff := VR[1]\nlinear_move.to(home).at(2000, 'mm/s').term(0).vision_offset(voff)")
|
227
|
+
assert_prog "L P[1:home] 2000mm/sec CNT0 VOFFSET,VR[1:voff] ;\n"
|
228
|
+
end
|
229
|
+
|
230
|
+
def test_time_before
|
231
|
+
parse("p := P[1]\nlinear_move.to(p).at(2000, 'mm/s').term(0).time_before(0.5, foo())")
|
232
|
+
assert_prog "L P[1:p] 2000mm/sec CNT0 TB .50sec,CALL FOO ;\n"
|
233
|
+
end
|
234
|
+
|
235
|
+
def test_time_after
|
236
|
+
parse("p := P[1]\nlinear_move.to(p).at(2000, 'mm/s').term(0).time_after(0.5, foo())")
|
237
|
+
assert_prog "L P[1:p] 2000mm/sec CNT0 TA .50sec,CALL FOO ;\n"
|
238
|
+
end
|
239
|
+
|
240
|
+
def test_time_before_with_register_time
|
241
|
+
parse("p := P[1]\nt := R[1]\nlinear_move.to(p).at(2000, 'mm/s').term(0).time_before(t, foo())")
|
242
|
+
assert_prog "L P[1:p] 2000mm/sec CNT0 TB R[1:t]sec,CALL FOO ;\n"
|
243
|
+
end
|
244
|
+
|
245
|
+
def test_time_before_with_io_method
|
246
|
+
parse("p := P[1]\nbar := DO[1]\nlinear_move.to(p).at(2000, 'mm/s').term(0).time_before(0.5, turn_on bar)")
|
247
|
+
assert_prog "L P[1:p] 2000mm/sec CNT0 TB .50sec,DO[1:bar]=ON ;\n"
|
248
|
+
end
|
249
|
+
|
250
|
+
def test_motion_with_indirect_termination
|
251
|
+
parse("p := P[1]\ncnt := R[1]\nlinear_move.to(p).at(2000, 'mm/s').term(cnt)")
|
252
|
+
assert_prog "L P[1:p] 2000mm/sec CNT R[1:cnt] ;\n"
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_motion_with_indirect_speed
|
256
|
+
parse("p := P[1]\nspeed := R[1]\nlinear_move.to(p).at(speed, 'mm/s').term(0)")
|
257
|
+
assert_prog "L P[1:p] R[1:speed]mm/sec CNT0 ;\n"
|
258
|
+
end
|
259
|
+
|
260
|
+
def test_motion_with_max_speed
|
261
|
+
parse("p := P[1]\nlinear_move.to(p).at('max_speed').term(0)")
|
262
|
+
assert_prog "L P[1:p] max_speed CNT0 ;\n"
|
263
|
+
end
|
264
|
+
|
265
|
+
def test_use_uframe
|
266
|
+
parse("use_uframe 5")
|
267
|
+
assert_prog "UFRAME_NUM=5 ;\n"
|
268
|
+
end
|
269
|
+
|
270
|
+
def test_indirect_uframe
|
271
|
+
parse("foo := R[1]\nuse_uframe foo")
|
272
|
+
assert_prog "UFRAME_NUM=R[1:foo] ;\n"
|
273
|
+
end
|
274
|
+
|
275
|
+
def test_use_utool
|
276
|
+
parse("use_utool 5")
|
277
|
+
assert_prog "UTOOL_NUM=5 ;\n"
|
278
|
+
end
|
279
|
+
|
280
|
+
def test_indirect_utool
|
281
|
+
parse("foo := R[1]\nuse_utool foo")
|
282
|
+
assert_prog "UTOOL_NUM=R[1:foo] ;\n"
|
283
|
+
end
|
284
|
+
|
285
|
+
def test_payload
|
286
|
+
parse("use_payload 1")
|
287
|
+
assert_prog "PAYLOAD[1] ;\n"
|
288
|
+
end
|
289
|
+
|
290
|
+
def test_indirect_payload
|
291
|
+
parse("foo := R[1]\nuse_payload foo")
|
292
|
+
assert_prog "PAYLOAD[R[1:foo]] ;\n"
|
293
|
+
end
|
294
|
+
|
295
|
+
def test_nested_conditionals
|
296
|
+
parse("foo := R[1]\nif foo==1\nif foo==2\nfoo=3\nelse\nfoo=4\nend\nend")
|
297
|
+
assert_prog "IF R[1:foo]<>1,JMP LBL[100] ;\nIF R[1:foo]<>2,JMP LBL[101] ;\nR[1:foo]=3 ;\nJMP LBL[102] ;\nLBL[101] ;\nR[1:foo]=4 ;\nLBL[102] ;\nLBL[100] ;\n"
|
298
|
+
end
|
299
|
+
|
300
|
+
def test_inline_unless
|
301
|
+
parse("foo := R[1]\n@bar\njump_to @bar unless foo > 1")
|
302
|
+
assert_prog "LBL[100:bar] ;\nIF R[1:foo]<=1,JMP LBL[100] ;\n"
|
303
|
+
end
|
304
|
+
|
305
|
+
def test_inline_unless_with_two_vars
|
306
|
+
parse("foo := R[1]\nbar := R[2]\n@baz\njump_to @baz unless foo > bar")
|
307
|
+
assert_prog "LBL[100:baz] ;\nIF R[1:foo]<=R[2:bar],JMP LBL[100] ;\n"
|
308
|
+
end
|
309
|
+
|
310
|
+
def test_labels_can_be_defined_after_jumps_to_them
|
311
|
+
parse("jump_to @foo\n@foo")
|
312
|
+
assert_prog "JMP LBL[100] ;\nLBL[100:foo] ;\n"
|
313
|
+
end
|
314
|
+
|
315
|
+
def test_multiple_motion_modifiers
|
316
|
+
parse("p := P[1]\no := PR[1]\nlinear_move.to(p).at('max_speed').term(0).offset(o).time_before(0.5,foo())")
|
317
|
+
assert_prog "L P[1:p] max_speed CNT0 Offset,PR[1:o] TB .50sec,CALL FOO ;\n"
|
318
|
+
end
|
319
|
+
|
320
|
+
def test_motion_modifiers_swallow_terminators_after_dots
|
321
|
+
parse("p := P[1]\no := PR[1]\nlinear_move.\nto(p).\nat('max_speed').\nterm(0).\noffset(o).\ntime_before(0.5,foo())")
|
322
|
+
assert_prog "L P[1:p] max_speed CNT0 Offset,PR[1:o] TB .50sec,CALL FOO ;\n"
|
323
|
+
end
|
324
|
+
|
325
|
+
def test_wait_for_with_seconds
|
326
|
+
parse("wait_for(5,'s')")
|
327
|
+
assert_prog "WAIT 5.00(sec) ;\n"
|
328
|
+
end
|
329
|
+
|
330
|
+
def test_wait_for_with_invalid_units_throws_error
|
331
|
+
parse("wait_for(5,'ns')")
|
332
|
+
assert_raise(RuntimeError) do
|
333
|
+
assert_prog ""
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
def test_wait_for_with_milliseconds
|
338
|
+
parse("wait_for(100,'ms')")
|
339
|
+
assert_prog "WAIT .10(sec) ;\n"
|
340
|
+
end
|
341
|
+
|
342
|
+
def test_wait_for_with_indirect_seconds
|
343
|
+
parse "foo := R[1]\nwait_for(foo, 's')"
|
344
|
+
assert_prog "WAIT R[1:foo] ;\n"
|
345
|
+
end
|
346
|
+
|
347
|
+
def test_wait_for_with_indirect_ms
|
348
|
+
parse "foo := R[1]\nwait_for(foo, 'ms')"
|
349
|
+
assert_raise(RuntimeError) do
|
350
|
+
assert_prog ""
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
def test_wait_until_with_exp
|
355
|
+
parse("wait_until(1==0)")
|
356
|
+
assert_prog "WAIT (1=0) ;\n"
|
357
|
+
end
|
358
|
+
|
359
|
+
def test_wait_until_with_flag
|
360
|
+
parse("foo := F[1]\nwait_until(foo)")
|
361
|
+
assert_prog "WAIT (F[1:foo]) ;\n"
|
362
|
+
end
|
363
|
+
|
364
|
+
def test_wait_until_with_di
|
365
|
+
parse("foo := DI[1]\nwait_until(foo)")
|
366
|
+
assert_prog "WAIT (DI[1:foo]) ;\n"
|
367
|
+
end
|
368
|
+
|
369
|
+
def test_wait_until_with_boolean
|
370
|
+
parse("foo := DI[1]\nbar := DI[2]\nwait_until(foo && bar)")
|
371
|
+
assert_prog "WAIT (DI[1:foo] AND DI[2:bar]) ;\n"
|
372
|
+
end
|
373
|
+
|
374
|
+
def test_wait_until_with_timeout_to
|
375
|
+
parse("wait_until(1==0).timeout_to(@end)\n@end")
|
376
|
+
assert_prog "WAIT (1=0) TIMEOUT,LBL[100] ;\nLBL[100:end] ;\n"
|
377
|
+
end
|
378
|
+
|
379
|
+
def test_wait_until_with_timeout_to_and_after
|
380
|
+
parse("wait_until(1==0).timeout_to(@end).after(1, 's')\n@end")
|
381
|
+
assert_prog "$WAITTMOUT=(100) ;\nWAIT (1=0) TIMEOUT,LBL[100] ;\nLBL[100:end] ;\n"
|
382
|
+
end
|
383
|
+
|
384
|
+
def test_wait_until_after_ms
|
385
|
+
parse("wait_until(1==0).timeout_to(@end).after(1000, 'ms')\n@end")
|
386
|
+
assert_prog "$WAITTMOUT=(100) ;\nWAIT (1=0) TIMEOUT,LBL[100] ;\nLBL[100:end] ;\n"
|
387
|
+
end
|
388
|
+
|
389
|
+
def test_wait_until_after_indirect
|
390
|
+
parse("foo := R[1]\nwait_until(1==0).timeout_to(@end).after(foo, 's')\n@end")
|
391
|
+
assert_prog "$WAITTMOUT=(R[1:foo]*100) ;\nWAIT (1=0) TIMEOUT,LBL[100] ;\nLBL[100:end] ;\n"
|
392
|
+
end
|
393
|
+
|
394
|
+
def test_wait_until_with_constant
|
395
|
+
parse("WAIT := 5\nwait_until(1==0).timeout_to(@end).after(WAIT, 's')\n@end")
|
396
|
+
assert_prog "$WAITTMOUT=(5*100) ;\nWAIT (1=0) TIMEOUT,LBL[100] ;\nLBL[100:end] ;\n"
|
397
|
+
end
|
398
|
+
|
399
|
+
def test_pr_components
|
400
|
+
parse("foo := PR[1]\nfoo.x=5\nfoo.y=6\nfoo.z=7\nfoo.w=8\nfoo.p=9\nfoo.r=10\n")
|
401
|
+
assert_prog "PR[1,1:foo]=5 ;\nPR[1,2:foo]=6 ;\nPR[1,3:foo]=7 ;\nPR[1,4:foo]=8 ;\nPR[1,5:foo]=9 ;\nPR[1,6:foo]=10 ;\n"
|
402
|
+
end
|
403
|
+
|
404
|
+
def test_pr_with_invalid_component_raises_error
|
405
|
+
parse("foo := PR[1]\nfoo.bar=5\n")
|
406
|
+
assert_raise(RuntimeError) do
|
407
|
+
assert_prog ""
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
def test_simple_case_statement
|
412
|
+
parse("foo := R[1]\ncase foo\nwhen 1\njump_to @asdf\nend\n@asdf")
|
413
|
+
assert_prog %(SELECT R[1:foo]=1,JMP LBL[100] ;\nLBL[100:asdf] ;\n)
|
414
|
+
end
|
415
|
+
|
416
|
+
def test_simple_case_with_else_statement
|
417
|
+
parse("foo := R[1]\ncase foo\nwhen 1\njump_to @asdf\nelse\njump_to @ghjk\nend\n@asdf\n@ghjk")
|
418
|
+
assert_prog %(SELECT R[1:foo]=1,JMP LBL[100] ;
|
419
|
+
ELSE,JMP LBL[101] ;
|
420
|
+
LBL[100:asdf] ;
|
421
|
+
LBL[101:ghjk] ;\n)
|
422
|
+
end
|
423
|
+
|
424
|
+
def test_case_statement_with_two_whens
|
425
|
+
parse("foo := R[1]\ncase foo\nwhen 1\njump_to @asdf\nwhen 2\njump_to @ghjk\nend\n@asdf\n@ghjk")
|
426
|
+
assert_prog %(SELECT R[1:foo]=1,JMP LBL[100] ;
|
427
|
+
=2,JMP LBL[101] ;
|
428
|
+
LBL[100:asdf] ;
|
429
|
+
LBL[101:ghjk] ;\n)
|
430
|
+
end
|
431
|
+
|
432
|
+
def test_case_statement_with_three_whens
|
433
|
+
parse("foo := R[1]\ncase foo\nwhen 1\nbar()\nwhen 2\nbar()\nwhen 3\nbar()\nend")
|
434
|
+
assert_prog %(SELECT R[1:foo]=1,CALL BAR ;
|
435
|
+
=2,CALL BAR ;
|
436
|
+
=3,CALL BAR ;\n)
|
437
|
+
end
|
438
|
+
|
439
|
+
def test_case_statement_with_three_whens_and_else
|
440
|
+
parse("foo := R[1]\ncase foo\nwhen 1\nbar()\nwhen 2\nbar()\nwhen 3\nbar()\nelse\nbar()\nend")
|
441
|
+
assert_prog %(SELECT R[1:foo]=1,CALL BAR ;
|
442
|
+
=2,CALL BAR ;
|
443
|
+
=3,CALL BAR ;
|
444
|
+
ELSE,CALL BAR ;\n)
|
445
|
+
end
|
446
|
+
|
447
|
+
def test_can_use_simple_io_value_as_condition
|
448
|
+
parse("foo := UI[5]\n@top\njump_to @top if foo")
|
449
|
+
assert_prog "LBL[100:top] ;\nIF (UI[5:foo]),JMP LBL[100] ;\n"
|
450
|
+
end
|
451
|
+
|
452
|
+
def test_can_use_simple_io_value_as_condition_with_unless
|
453
|
+
parse("foo := UI[5]\n@top\njump_to @top unless foo")
|
454
|
+
assert_prog "LBL[100:top] ;\nIF (!UI[5:foo]),JMP LBL[100] ;\n"
|
455
|
+
end
|
456
|
+
|
457
|
+
def test_inline_program_call
|
458
|
+
parse("foo := UI[5]\nbar() unless foo")
|
459
|
+
assert_prog "IF (!UI[5:foo]),CALL BAR ;\n"
|
460
|
+
end
|
461
|
+
|
462
|
+
def test_constant_definition
|
463
|
+
parse("FOO := 5\nfoo := R[1]\nfoo = FOO")
|
464
|
+
assert_prog "R[1:foo]=5 ;\n"
|
465
|
+
end
|
466
|
+
|
467
|
+
def test_constant_definition_real
|
468
|
+
parse("PI := 3.14159\nfoo:= R[1]\nfoo = PI")
|
469
|
+
assert_prog "R[1:foo]=3.14159 ;\n"
|
470
|
+
end
|
471
|
+
|
472
|
+
def test_redefining_const_throws_error
|
473
|
+
assert_raise(RuntimeError) do
|
474
|
+
parse("PI := 3.14\nPI := 5")
|
475
|
+
assert_prog ""
|
476
|
+
end
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_defining_const_without_caps_raises_error
|
480
|
+
parse("pi := 3.14")
|
481
|
+
assert_raise(RuntimeError) do
|
482
|
+
assert_prog ""
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
def test_using_argument_var
|
487
|
+
parse("foo := AR[1]\n@top\njump_to @top if foo==1")
|
488
|
+
assert_prog "LBL[100:top] ;\nIF (AR[1]=1),JMP LBL[100] ;\n"
|
489
|
+
end
|
490
|
+
|
491
|
+
def test_use_uframe_with_constant
|
492
|
+
parse("FOO := 1\nuse_uframe FOO")
|
493
|
+
assert_prog "UFRAME_NUM=1 ;\n"
|
494
|
+
end
|
495
|
+
|
496
|
+
def test_fanuc_set_uframe_with_pr
|
497
|
+
parse("foo := PR[1]\nset_uframe 5, foo")
|
498
|
+
assert_prog "UFRAME[5]=PR[1:foo] ;\n"
|
499
|
+
end
|
500
|
+
|
501
|
+
def test_fanuc_set_uframe_with_constant
|
502
|
+
parse("foo := PR[1]\nBAR := 5\nset_uframe BAR, foo")
|
503
|
+
assert_prog "UFRAME[5]=PR[1:foo] ;\n"
|
504
|
+
end
|
505
|
+
|
506
|
+
def test_fanuc_set_uframe_with_reg
|
507
|
+
parse("foo := PR[1]\nbar := R[1]\nset_uframe bar, foo")
|
508
|
+
assert_prog "UFRAME[R[1:bar]]=PR[1:foo] ;\n"
|
509
|
+
end
|
510
|
+
|
511
|
+
def test_set_skip_condition
|
512
|
+
parse("foo := RI[1]\nset_skip_condition foo")
|
513
|
+
assert_prog "SKIP CONDITION RI[1:foo]=ON ;\n"
|
514
|
+
end
|
515
|
+
|
516
|
+
def test_set_skip_condition_with_bang
|
517
|
+
parse("foo := RI[1]\nset_skip_condition !foo")
|
518
|
+
assert_prog "SKIP CONDITION RI[1:foo]=OFF ;\n"
|
519
|
+
end
|
520
|
+
|
521
|
+
def test_skip_to
|
522
|
+
parse("p := P[1]\n@somewhere\nlinear_move.to(p).at(2000,'mm/s').term(0).skip_to(@somewhere)")
|
523
|
+
assert_prog "LBL[100:somewhere] ;\nL P[1:p] 2000mm/sec CNT0 Skip,LBL[100] ;\n"
|
524
|
+
end
|
525
|
+
|
526
|
+
def test_skip_to_with_pr
|
527
|
+
parse("p := P[1]\nlpos := PR[1]\n@somewhere\nlinear_move.to(p).at(2000,'mm/s').term(0).skip_to(@somewhere, lpos)")
|
528
|
+
assert_prog "LBL[100:somewhere] ;\nL P[1:p] 2000mm/sec CNT0 Skip,LBL[100],PR[1:lpos]=LPOS ;\n"
|
529
|
+
end
|
530
|
+
|
531
|
+
def test_label_comment_automatically_adds_a_comment_if_over_16_chars
|
532
|
+
parse("@foo_bar_foo_bar_foo")
|
533
|
+
assert_prog "LBL[100:foo_bar_foo_bar_] ;\n! foo_bar_foo_bar_foo ;\n"
|
534
|
+
end
|
535
|
+
|
536
|
+
def test_automatic_long_comment_wrapping
|
537
|
+
parse("# this is a really long comment so it should wrap")
|
538
|
+
assert_prog "! this is a really long comment ;\n! so it should wrap ;\n"
|
539
|
+
end
|
540
|
+
|
541
|
+
def test_turning_on_a_flag_requires_mixed_logic
|
542
|
+
parse("foo := F[1]\nturn_on foo")
|
543
|
+
assert_prog "F[1:foo]=(ON) ;\n"
|
544
|
+
end
|
545
|
+
|
546
|
+
def test_boolean_assignment
|
547
|
+
parse("foo := F[1]\nfoo = 1 && 1")
|
548
|
+
assert_prog "F[1:foo]=(1 AND 1) ;\n"
|
549
|
+
end
|
550
|
+
|
551
|
+
def test_simple_math
|
552
|
+
parse("foo := R[1]\nfoo=1+1")
|
553
|
+
assert_prog "R[1:foo]=1+1 ;\n"
|
554
|
+
end
|
555
|
+
|
556
|
+
def test_more_complicated_math
|
557
|
+
parse("foo := R[1]\nfoo=1+2+3")
|
558
|
+
assert_prog "R[1:foo]=(1+2+3) ;\n"
|
559
|
+
end
|
560
|
+
|
561
|
+
def test_operator_precedence
|
562
|
+
parse "foo := R[1]\nfoo=1+2*3"
|
563
|
+
assert_prog "R[1:foo]=(1+2*3) ;\n"
|
564
|
+
end
|
565
|
+
|
566
|
+
def test_expression_grouping
|
567
|
+
parse "foo := R[1]\nfoo=(1+2)*3"
|
568
|
+
assert_prog "R[1:foo]=((1+2)*3) ;\n"
|
569
|
+
end
|
570
|
+
|
571
|
+
def test_boolean_expression
|
572
|
+
parse "foo := F[1]\nfoo = 1 || 1 && 0"
|
573
|
+
assert_prog "F[1:foo]=(1 OR 1 AND 0) ;\n"
|
574
|
+
end
|
575
|
+
|
576
|
+
def test_bang
|
577
|
+
parse "foo := F[1]\nbar := F[2]\nfoo = !bar"
|
578
|
+
assert_prog "F[1:foo]=(!F[2:bar]) ;\n"
|
579
|
+
end
|
580
|
+
|
581
|
+
def test_bang_with_grouping
|
582
|
+
parse "foo := F[1]\nbar := F[2]\nbaz := F[3]\nfoo = foo || !(bar || baz)"
|
583
|
+
assert_prog "F[1:foo]=(F[1:foo] OR !(F[2:bar] OR F[3:baz])) ;\n"
|
584
|
+
end
|
585
|
+
|
586
|
+
def test_opposite_flag_in_simple_if
|
587
|
+
parse "foo := F[1]\nif foo\n# foo is true\nend"
|
588
|
+
assert_prog "IF (!F[1:foo]),JMP LBL[100] ;\n! foo is true ;\nLBL[100] ;\n"
|
589
|
+
end
|
590
|
+
|
591
|
+
def test_opposite_flag_in_simple_unless
|
592
|
+
parse "foo := F[1]\nunless foo\n# foo is false\nend"
|
593
|
+
assert_prog "IF (F[1:foo]),JMP LBL[100] ;\n! foo is false ;\nLBL[100] ;\n"
|
594
|
+
end
|
595
|
+
|
596
|
+
def test_inline_if_with_flag
|
597
|
+
parse "foo := F[1]\njump_to @end if foo\n@end"
|
598
|
+
assert_prog "IF (F[1:foo]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
599
|
+
end
|
600
|
+
|
601
|
+
def test_inline_unless_with_flag
|
602
|
+
parse "foo := F[1]\njump_to @end unless foo\n@end"
|
603
|
+
assert_prog "IF (!F[1:foo]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
604
|
+
end
|
605
|
+
|
606
|
+
def test_automatic_parens_on_boolean
|
607
|
+
parse "foo := F[1]\njump_to @end if foo || foo\n@end"
|
608
|
+
assert_prog "IF (F[1:foo] OR F[1:foo]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
609
|
+
end
|
610
|
+
|
611
|
+
def test_no_extra_parens_with_booleans
|
612
|
+
parse "foo := F[1]\njump_to @end if foo || foo || foo\n@end"
|
613
|
+
assert_prog "IF (F[1:foo] OR F[1:foo] OR F[1:foo]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
614
|
+
end
|
615
|
+
|
616
|
+
def test_assignment_as_bool_result
|
617
|
+
parse "foo := F[1]\nbar := R[1]\nfoo = bar == 1"
|
618
|
+
assert_prog "F[1:foo]=(R[1:bar]=1) ;\n"
|
619
|
+
end
|
620
|
+
|
621
|
+
def test_args_dont_get_comments
|
622
|
+
parse "foo := AR[1]\njump_to @end if foo == 1\n@end"
|
623
|
+
assert_prog "IF (AR[1]=1),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
624
|
+
end
|
625
|
+
|
626
|
+
def test_indirect_position_assignment
|
627
|
+
parse "foo := PR[1]\nfoo = indirect('position',5)"
|
628
|
+
assert_prog "PR[1:foo]=P[5] ;\n"
|
629
|
+
end
|
630
|
+
|
631
|
+
def test_indirect_indirect_position_assignment
|
632
|
+
parse "foo := PR[1]\nbar := R[1]\nfoo = indirect('position',bar)"
|
633
|
+
assert_prog "PR[1:foo]=P[R[1:bar]] ;\n"
|
634
|
+
end
|
635
|
+
|
636
|
+
def test_indirect_posreg_assignment
|
637
|
+
parse "foo := PR[1]\nfoo = indirect('position_register',5)"
|
638
|
+
assert_prog "PR[1:foo]=PR[5] ;\n"
|
639
|
+
end
|
640
|
+
|
641
|
+
def test_namespace
|
642
|
+
parse "namespace Foo\nbar := R[1]\nend\nFoo::bar = 5"
|
643
|
+
assert_prog "R[1:Foo bar]=5 ;\n"
|
644
|
+
end
|
645
|
+
|
646
|
+
def test_no_namespace_collision
|
647
|
+
parse "namespace Foo\nbar := R[1]\nend\nbar := R[2]\nbar = 2\nFoo::bar = 1"
|
648
|
+
assert_prog "R[2:bar]=2 ;\nR[1:Foo bar]=1 ;\n"
|
649
|
+
end
|
650
|
+
|
651
|
+
def test_namespace_constant_definition
|
652
|
+
parse "namespace Math\nPI := 3.14\nend\nfoo := R[1]\nfoo = Math::PI"
|
653
|
+
assert_prog "R[1:foo]=3.14 ;\n"
|
654
|
+
end
|
655
|
+
|
656
|
+
def test_namespace_swallows_everything
|
657
|
+
parse "namespace Foo\n# this is a comment\n#this is another comment\nend"
|
658
|
+
assert_prog ""
|
659
|
+
end
|
660
|
+
|
661
|
+
def test_nested_namespace
|
662
|
+
parse %(namespace Foo
|
663
|
+
bar := R[1]
|
664
|
+
namespace Bar
|
665
|
+
baz := R[2]
|
666
|
+
end
|
667
|
+
end
|
668
|
+
Foo::bar = 1
|
669
|
+
Foo::Bar::baz = 2)
|
670
|
+
assert_prog "R[1:Foo bar]=1 ;\nR[2:Foo Bar baz]=2 ;\n"
|
671
|
+
end
|
672
|
+
|
673
|
+
def test_load_environment
|
674
|
+
environment = "foo := R[1]\nbar := R[2]\n#asdf\n#asdf"
|
675
|
+
@interpreter.load_environment(environment)
|
676
|
+
parse "foo = 5"
|
677
|
+
assert_prog "R[1:foo]=5 ;\n"
|
678
|
+
assert_equal 1, @interpreter.source_line_count
|
679
|
+
end
|
680
|
+
|
681
|
+
def test_load_environment_only_saves_definitions_etc
|
682
|
+
environment = "foo := R[1]\nbar := R[2]\n#asdf\n#asdf\nfoo=3"
|
683
|
+
@interpreter.load_environment(environment)
|
684
|
+
parse "foo = 5"
|
685
|
+
assert_prog "R[1:foo]=5 ;\n"
|
686
|
+
assert_equal 1, @interpreter.source_line_count
|
687
|
+
end
|
688
|
+
|
689
|
+
|
690
|
+
def test_bad_environment
|
691
|
+
assert_raise(RuntimeError) do
|
692
|
+
@interpreter.load_environment("asdf")
|
693
|
+
end
|
694
|
+
end
|
695
|
+
|
696
|
+
def test_inline_conditional_with_namespaced_var
|
697
|
+
parse "namespace Foo\nbar := DI[1]\nend\njump_to @end unless Foo::bar\n@end"
|
698
|
+
assert_prog "IF (!DI[1:Foo bar]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
699
|
+
end
|
700
|
+
|
701
|
+
def test_namespaced_var_as_condition
|
702
|
+
parse "namespace Foo\nbar := DI[1]\nend\nif Foo::bar\n# bar is on\nend"
|
703
|
+
assert_prog "IF (!DI[1:Foo bar]),JMP LBL[100] ;\n! bar is on ;\nLBL[100] ;\n"
|
704
|
+
end
|
705
|
+
|
706
|
+
def test_reopen_namespace
|
707
|
+
parse "namespace Foo\nbar := R[1]\nend\nnamespace Foo\nbaz := R[2]\nend\nFoo::bar = 1\nFoo::baz = 2"
|
708
|
+
assert_prog "R[1:Foo bar]=1 ;\nR[2:Foo baz]=2 ;\n"
|
709
|
+
end
|
710
|
+
|
711
|
+
def test_eval
|
712
|
+
parse %(eval "R[1]=5")
|
713
|
+
assert_prog "R[1]=5 ;\n"
|
714
|
+
end
|
715
|
+
|
716
|
+
def test_multiline_eval
|
717
|
+
parse %(eval "R[1]=5 ;\nR[2]=3")
|
718
|
+
assert_prog "R[1]=5 ;\nR[2]=3 ;\n"
|
719
|
+
end
|
720
|
+
|
721
|
+
def test_namespaced_position_reg_component
|
722
|
+
parse "namespace Fixture\npick_offset := PR[1]\nend\nFixture::pick_offset.x = 10"
|
723
|
+
assert_prog "PR[1,1:Fixture pick_offset]=10 ;\n"
|
724
|
+
end
|
725
|
+
|
726
|
+
def test_inline_program_call_two
|
727
|
+
parse "foo := R[1]\nbar() if foo >= 5"
|
728
|
+
assert_prog "IF R[1:foo]>=5,CALL BAR ;\n"
|
729
|
+
end
|
730
|
+
|
731
|
+
def test_forlooop
|
732
|
+
parse "foo := R[1]\nfor foo in (1 TO 10)\n# bar\nend"
|
733
|
+
assert_prog "FOR R[1:foo]=1 TO 10 ;\n! bar ;\nENDFOR ;\n"
|
734
|
+
end
|
735
|
+
|
736
|
+
def test_forloop_with_vars
|
737
|
+
parse "foo := R[1]\nmin := R[2]\nmax := R[3]\nfor foo in (min to max)\n#bar\nend"
|
738
|
+
assert_prog "FOR R[1:foo]=R[2:min] TO R[3:max] ;\n! bar ;\nENDFOR ;\n"
|
739
|
+
end
|
740
|
+
|
741
|
+
def test_indirect_flag
|
742
|
+
parse "foo := R[1]\nturn_on indirect('flag',foo)"
|
743
|
+
assert_prog "F[R[1:foo]]=(ON) ;\n"
|
744
|
+
end
|
745
|
+
|
746
|
+
def test_indirect_flag_condition
|
747
|
+
parse "foo := R[1]\njump_to @end if indirect('flag',foo)\n@end"
|
748
|
+
assert_prog "IF (F[R[1:foo]]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
749
|
+
end
|
750
|
+
|
751
|
+
def test_indirect_flag_condition_not_inline
|
752
|
+
parse "foo := R[1]\nif indirect('flag',foo)\n# bar\nend"
|
753
|
+
assert_prog "IF (!F[R[1:foo]]),JMP LBL[100] ;\n! bar ;\nLBL[100] ;\n"
|
754
|
+
end
|
755
|
+
|
756
|
+
def test_indirect_unless_flag_condition
|
757
|
+
parse "foo := R[1]\njump_to @end unless indirect('flag',foo)\n@end"
|
758
|
+
assert_prog "IF (!F[R[1:foo]]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
759
|
+
end
|
760
|
+
|
761
|
+
def test_indirect_flag_with_if_bang
|
762
|
+
parse "foo := R[1]\njump_to @end if !indirect('flag',foo)\n@end"
|
763
|
+
assert_prog "IF (!F[R[1:foo]]),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
764
|
+
end
|
765
|
+
|
766
|
+
def test_while_loop
|
767
|
+
parse "foo := R[1]\nwhile foo < 10\n# bar\nend"
|
768
|
+
assert_prog "LBL[100] ;\nIF R[1:foo]>=10,JMP LBL[101] ;\n! bar ;\nJMP LBL[100] ;\nLBL[101] ;\n"
|
769
|
+
end
|
770
|
+
|
771
|
+
def test_while_with_not_flag
|
772
|
+
parse "foo := F[1]\nwhile !foo\n#bar\nend"
|
773
|
+
assert_prog "LBL[100] ;\nIF (F[1:foo]),JMP LBL[101] ;\n! bar ;\nJMP LBL[100] ;\nLBL[101] ;\n"
|
774
|
+
end
|
775
|
+
|
776
|
+
def test_while_with_flag
|
777
|
+
parse "foo := F[1]\nwhile foo\n#bar\nend"
|
778
|
+
assert_prog "LBL[100] ;\nIF (!F[1:foo]),JMP LBL[101] ;\n! bar ;\nJMP LBL[100] ;\nLBL[101] ;\n"
|
779
|
+
end
|
780
|
+
|
781
|
+
def test_timer_start
|
782
|
+
parse "foo := TIMER[1]\nstart foo"
|
783
|
+
assert_prog "TIMER[1:foo]=START ;\n"
|
784
|
+
end
|
785
|
+
|
786
|
+
def test_timer_reset
|
787
|
+
parse "foo := TIMER[1]\nreset foo"
|
788
|
+
assert_prog "TIMER[1:foo]=RESET ;\n"
|
789
|
+
end
|
790
|
+
|
791
|
+
def test_timer_stop
|
792
|
+
parse "foo := TIMER[1]\nstop foo"
|
793
|
+
assert_prog "TIMER[1:foo]=STOP ;\n"
|
794
|
+
end
|
795
|
+
|
796
|
+
def test_timer_restart
|
797
|
+
parse "foo := TIMER[1]\nrestart foo"
|
798
|
+
assert_prog "TIMER[1:foo]=STOP ;\nTIMER[1:foo]=RESET ;\nTIMER[1:foo]=START ;\n"
|
799
|
+
end
|
800
|
+
|
801
|
+
def test_indirect_timer
|
802
|
+
parse "foo := R[1]\nfoo = indirect('timer', 3)"
|
803
|
+
assert_prog "R[1:foo]=TIMER[3] ;\n"
|
804
|
+
end
|
805
|
+
|
806
|
+
def test_indirect_indirect_timer
|
807
|
+
parse "foo := R[1]\nfoo = indirect('timer', foo)"
|
808
|
+
assert_prog "R[1:foo]=TIMER[R[1:foo]] ;\n"
|
809
|
+
end
|
810
|
+
|
811
|
+
def test_start_indirect_timer
|
812
|
+
parse "start indirect('timer', 3)"
|
813
|
+
assert_prog "TIMER[3]=START ;\n"
|
814
|
+
end
|
815
|
+
|
816
|
+
def test_start_indirect_indirect_timer
|
817
|
+
parse "foo := R[1]\nstart indirect('timer', foo)"
|
818
|
+
assert_prog "TIMER[R[1:foo]]=START ;\n"
|
819
|
+
end
|
820
|
+
|
821
|
+
def test_position_data_does_not_output_with_eval
|
822
|
+
parse %(position_data
|
823
|
+
{
|
824
|
+
'positions': [
|
825
|
+
{
|
826
|
+
'id': 1,
|
827
|
+
'comment': "test",
|
828
|
+
'group': 1,
|
829
|
+
'uframe': 1,
|
830
|
+
'utool': 1,
|
831
|
+
'config': {
|
832
|
+
'flip': true,
|
833
|
+
'up': true,
|
834
|
+
'top': false,
|
835
|
+
'turn_counts': [-1,0,1]
|
836
|
+
},
|
837
|
+
'components': {
|
838
|
+
'x': -50.0,
|
839
|
+
'y': 0.0,
|
840
|
+
'z': 0.0,
|
841
|
+
'w': 0.0,
|
842
|
+
'p': 0.0,
|
843
|
+
'r': 0.0
|
844
|
+
}
|
845
|
+
}
|
846
|
+
]
|
847
|
+
}
|
848
|
+
end)
|
849
|
+
|
850
|
+
assert_prog ""
|
851
|
+
end
|
852
|
+
|
853
|
+
def test_position_data_populates_interpreter_position_data
|
854
|
+
parse %(position_data
|
855
|
+
{
|
856
|
+
'positions': [
|
857
|
+
{
|
858
|
+
'id': 1,
|
859
|
+
'comment': "test",
|
860
|
+
'group': 1,
|
861
|
+
'uframe': 1,
|
862
|
+
'utool': 1,
|
863
|
+
'config': {
|
864
|
+
'flip': true,
|
865
|
+
'up': true,
|
866
|
+
'top': false,
|
867
|
+
'turn_counts': [0,0,0]
|
868
|
+
},
|
869
|
+
'components': {
|
870
|
+
'x': 0.0,
|
871
|
+
'y': 0.0,
|
872
|
+
'z': 0.0,
|
873
|
+
'w': 0.0,
|
874
|
+
'p': 0.0,
|
875
|
+
'r': 0.0
|
876
|
+
}
|
877
|
+
}
|
878
|
+
]
|
879
|
+
}
|
880
|
+
end)
|
881
|
+
|
882
|
+
assert_prog ""
|
883
|
+
assert_equal 1, @interpreter.position_data[:positions].length
|
884
|
+
end
|
885
|
+
|
886
|
+
def test_throws_a_fault_if_position_data_invalid
|
887
|
+
parse %(position_data
|
888
|
+
{
|
889
|
+
'positions' : "asdf"
|
890
|
+
}
|
891
|
+
end)
|
892
|
+
assert_raise(RuntimeError) do
|
893
|
+
@interpreter.eval
|
894
|
+
end
|
895
|
+
end
|
896
|
+
|
897
|
+
def test_outputs_position_data_correctly
|
898
|
+
parse %(position_data
|
899
|
+
{
|
900
|
+
'positions': [
|
901
|
+
{
|
902
|
+
'id': 1,
|
903
|
+
'comment': "test",
|
904
|
+
'group': 1,
|
905
|
+
'uframe': 1,
|
906
|
+
'utool': 1,
|
907
|
+
'config': {
|
908
|
+
'flip': true,
|
909
|
+
'up': true,
|
910
|
+
'top': true,
|
911
|
+
'turn_counts': [0,0,0]
|
912
|
+
},
|
913
|
+
'components': {
|
914
|
+
'x': 0.0,
|
915
|
+
'y': 0.0,
|
916
|
+
'z': 0.0,
|
917
|
+
'w': 0.0,
|
918
|
+
'p': 0.0,
|
919
|
+
'r': 0.0
|
920
|
+
}
|
921
|
+
}
|
922
|
+
]
|
923
|
+
}
|
924
|
+
end)
|
925
|
+
|
926
|
+
assert_prog ""
|
927
|
+
assert_equal %(P[1:"test"]{
|
928
|
+
GP1:
|
929
|
+
UF : 1, UT : 1, CONFIG : 'F U T, 0, 0, 0',
|
930
|
+
X = 0.0 mm, Y = 0.0 mm, Z = 0.0 mm,
|
931
|
+
W = 0.0 deg, P = 0.0 deg, R = 0.0 deg
|
932
|
+
};\n), @interpreter.pos_section
|
933
|
+
end
|
934
|
+
|
935
|
+
def test_outputs_position_data_correctly_with_two_positions
|
936
|
+
parse %(position_data
|
937
|
+
{
|
938
|
+
'positions': [
|
939
|
+
{
|
940
|
+
'id': 1,
|
941
|
+
'comment': "test",
|
942
|
+
'group': 1,
|
943
|
+
'uframe': 1,
|
944
|
+
'utool': 1,
|
945
|
+
'config': {
|
946
|
+
'flip': true,
|
947
|
+
'up': true,
|
948
|
+
'top': true,
|
949
|
+
'turn_counts': [0,0,0]
|
950
|
+
},
|
951
|
+
'components': {
|
952
|
+
'x': 0.0,
|
953
|
+
'y': 0.0,
|
954
|
+
'z': 0.0,
|
955
|
+
'w': 0.0,
|
956
|
+
'p': 0.0,
|
957
|
+
'r': 0.0
|
958
|
+
}
|
959
|
+
},
|
960
|
+
{
|
961
|
+
'id': 2,
|
962
|
+
'comment': "test2",
|
963
|
+
'group': 1,
|
964
|
+
'uframe': 1,
|
965
|
+
'utool': 1,
|
966
|
+
'config': {
|
967
|
+
'flip': true,
|
968
|
+
'up': true,
|
969
|
+
'top': true,
|
970
|
+
'turn_counts': [0,0,0]
|
971
|
+
},
|
972
|
+
'components': {
|
973
|
+
'x': 0.0,
|
974
|
+
'y': 0.0,
|
975
|
+
'z': 0.0,
|
976
|
+
'w': 0.0,
|
977
|
+
'p': 0.0,
|
978
|
+
'r': 0.0
|
979
|
+
}
|
980
|
+
}
|
981
|
+
]
|
982
|
+
}
|
983
|
+
end)
|
984
|
+
|
985
|
+
assert_prog ""
|
986
|
+
assert_equal %(P[1:"test"]{
|
987
|
+
GP1:
|
988
|
+
UF : 1, UT : 1, CONFIG : 'F U T, 0, 0, 0',
|
989
|
+
X = 0.0 mm, Y = 0.0 mm, Z = 0.0 mm,
|
990
|
+
W = 0.0 deg, P = 0.0 deg, R = 0.0 deg
|
991
|
+
};
|
992
|
+
P[2:"test2"]{
|
993
|
+
GP1:
|
994
|
+
UF : 1, UT : 1, CONFIG : 'F U T, 0, 0, 0',
|
995
|
+
X = 0.0 mm, Y = 0.0 mm, Z = 0.0 mm,
|
996
|
+
W = 0.0 deg, P = 0.0 deg, R = 0.0 deg
|
997
|
+
};\n), @interpreter.pos_section
|
998
|
+
end
|
999
|
+
|
1000
|
+
def test_simple_pulse
|
1001
|
+
parse "foo := DO[1]\npulse foo"
|
1002
|
+
assert_prog "DO[1:foo]=PULSE ;\n"
|
1003
|
+
end
|
1004
|
+
|
1005
|
+
def test_pulse_for_seconds
|
1006
|
+
parse "foo := DO[1]\npulse(foo,5,'s')"
|
1007
|
+
assert_prog "DO[1:foo]=PULSE,5.0sec ;\n"
|
1008
|
+
end
|
1009
|
+
|
1010
|
+
def test_pulse_for_ms
|
1011
|
+
parse "foo := DO[1]\npulse(foo,500,'ms')"
|
1012
|
+
assert_prog "DO[1:foo]=PULSE,0.5sec ;\n"
|
1013
|
+
end
|
1014
|
+
|
1015
|
+
def test_indirect_numreg
|
1016
|
+
parse "foo := R[1]\nindirect('register',foo) = 5"
|
1017
|
+
assert_prog "R[R[1:foo]]=5 ;\n"
|
1018
|
+
end
|
1019
|
+
|
1020
|
+
def test_raise
|
1021
|
+
parse "my_alarm := UALM[1]\nraise my_alarm"
|
1022
|
+
assert_prog "UALM[1] ;\n"
|
1023
|
+
end
|
1024
|
+
|
1025
|
+
def test_indirect_raise
|
1026
|
+
parse "raise indirect('user_alarm',1)"
|
1027
|
+
assert_prog "UALM[1] ;\n"
|
1028
|
+
end
|
1029
|
+
|
1030
|
+
def test_indirect_indirect_raise
|
1031
|
+
parse "foo := R[1]\nraise indirect('user_alarm',foo)"
|
1032
|
+
assert_prog "UALM[R[1:foo]] ;\n"
|
1033
|
+
end
|
1034
|
+
|
1035
|
+
def test_namespaced_pr_component_assignment
|
1036
|
+
parse "namespace Foo\nbar := PR[1]\nend\nFoo::bar.x = 10"
|
1037
|
+
assert_prog "PR[1,1:Foo bar]=10 ;\n"
|
1038
|
+
end
|
1039
|
+
|
1040
|
+
def test_namespaced_pr_component_plus_equals
|
1041
|
+
parse "namespace Foo\nbar := PR[1]\nend\nFoo::bar.x += 10"
|
1042
|
+
assert_prog "PR[1,1:Foo bar]=PR[1,1:Foo bar]+10 ;\n"
|
1043
|
+
end
|
1044
|
+
|
1045
|
+
def test_namespaced_pr_component_in_expression
|
1046
|
+
parse "namespace Foo\nbar := PR[1]\nend\nFoo::bar.x += Foo::bar.x * 10 \n"
|
1047
|
+
assert_prog "PR[1,1:Foo bar]=(PR[1,1:Foo bar]+PR[1,1:Foo bar]*10) ;\n"
|
1048
|
+
end
|
1049
|
+
|
1050
|
+
def test_namespaced_pr_assignment_then_expression
|
1051
|
+
parse "namespace Foo\nbar := PR[1]\nend\nbaz := P[1]\nFoo::bar = baz\nFoo::bar.x += 5"
|
1052
|
+
assert_prog "PR[1:Foo bar]=P[1:baz] ;\nPR[1,1:Foo bar]=PR[1,1:Foo bar]+5 ;\n"
|
1053
|
+
end
|
1054
|
+
|
1055
|
+
def test_wait_until_does_not_get_inlined
|
1056
|
+
parse "foo := DO[1]\nunless foo\nwait_until(foo)\nend"
|
1057
|
+
assert_prog "IF (DO[1:foo]),JMP LBL[100] ;\nWAIT (DO[1:foo]) ;\nLBL[100] ;\n"
|
1058
|
+
end
|
1059
|
+
|
1060
|
+
def test_wait_for_does_not_get_inlined
|
1061
|
+
parse "foo := DO[1]\nunless foo\nwait_for(1,'s')\nend"
|
1062
|
+
assert_prog "IF (DO[1:foo]),JMP LBL[100] ;\nWAIT 1.00(sec) ;\nLBL[100] ;\n"
|
1063
|
+
end
|
1064
|
+
|
1065
|
+
def test_inline_conditional_does_not_get_inlined
|
1066
|
+
parse "foo := DO[1]\nif foo\nturn_off foo if foo\nend"
|
1067
|
+
assert_prog "IF (!DO[1:foo]),JMP LBL[100] ;\nIF (DO[1:foo]),DO[1:foo]=(OFF) ;\nLBL[100] ;\n"
|
1068
|
+
end
|
1069
|
+
|
1070
|
+
def test_run
|
1071
|
+
parse "run foo()"
|
1072
|
+
assert_prog "RUN FOO ;\n"
|
1073
|
+
end
|
1074
|
+
|
1075
|
+
def test_tp_ignore_pause
|
1076
|
+
parse "TP_IGNORE_PAUSE = true"
|
1077
|
+
assert_prog ""
|
1078
|
+
assert @interpreter.header_data[:ignore_pause]
|
1079
|
+
end
|
1080
|
+
|
1081
|
+
def test_tp_subtype
|
1082
|
+
parse "TP_SUBTYPE = 'macro'"
|
1083
|
+
assert_prog ""
|
1084
|
+
assert_equal :macro, @interpreter.header_data[:subtype]
|
1085
|
+
end
|
1086
|
+
|
1087
|
+
def test_tp_comment
|
1088
|
+
parse %(TP_COMMENT = "foo")
|
1089
|
+
assert_prog ""
|
1090
|
+
assert_equal "foo", @interpreter.header_data[:comment]
|
1091
|
+
end
|
1092
|
+
|
1093
|
+
def test_tp_groupmask
|
1094
|
+
parse %(TP_GROUPMASK = "*,*,*,*,*")
|
1095
|
+
assert_prog ""
|
1096
|
+
assert_equal "*,*,*,*,*", @interpreter.header_data[:group_mask]
|
1097
|
+
end
|
1098
|
+
|
1099
|
+
def test_mixed_logic_or
|
1100
|
+
parse %(foo := DI[1]\nbar := DI[2]\nif foo || bar\n# do something\nend)
|
1101
|
+
assert_prog "IF (!DI[1:foo] AND !DI[2:bar]),JMP LBL[100] ;\n! do something ;\nLBL[100] ;\n"
|
1102
|
+
end
|
1103
|
+
|
1104
|
+
def test_flag_assignment_always_gets_parens
|
1105
|
+
parse %(foo := F[1]\nbar := DI[2]\nfoo = bar)
|
1106
|
+
assert_prog "F[1:foo]=(DI[2:bar]) ;\n"
|
1107
|
+
end
|
1108
|
+
|
1109
|
+
def test_tool_offset
|
1110
|
+
parse %(p := P[1]\ntoff := PR[1]\nlinear_move.to(p).at(2000,'mm/s').term(0).tool_offset(toff))
|
1111
|
+
assert_prog "L P[1:p] 2000mm/sec CNT0 Tool_Offset,PR[1:toff] ;\n"
|
1112
|
+
end
|
1113
|
+
|
1114
|
+
def test_wait_for_digit
|
1115
|
+
parse %(wait_for(1,'s'))
|
1116
|
+
assert_prog "WAIT 1.00(sec) ;\n"
|
1117
|
+
end
|
1118
|
+
|
1119
|
+
def test_wait_for_real
|
1120
|
+
parse %(wait_for(0.5,'s'))
|
1121
|
+
assert_prog "WAIT .50(sec) ;\n"
|
1122
|
+
end
|
1123
|
+
|
1124
|
+
def test_wait_for_real_const
|
1125
|
+
parse %(FOO := 0.5\nwait_for(FOO,'s'))
|
1126
|
+
assert_prog "WAIT .50(sec) ;\n"
|
1127
|
+
end
|
1128
|
+
|
1129
|
+
def test_negative_numbers_have_parens
|
1130
|
+
parse %(foo := R[1]\njump_to @end if foo > -1\njump_to @end if foo > -5.3\n@end)
|
1131
|
+
assert_prog "IF R[1:foo]>(-1),JMP LBL[100] ;\nIF R[1:foo]>(-5.3),JMP LBL[100] ;\nLBL[100:end] ;\n"
|
1132
|
+
end
|
1133
|
+
|
1134
|
+
def test_modulus
|
1135
|
+
parse %(foo := R[1]\nfoo = 5 % 2)
|
1136
|
+
assert_prog "R[1:foo]=5 MOD 2 ;\n"
|
1137
|
+
end
|
1138
|
+
|
1139
|
+
def test_assignment_to_sop
|
1140
|
+
parse %(foo := DO[1]\nbar := SO[1]\nfoo = bar)
|
1141
|
+
assert_prog "DO[1:foo]=(SO[1:bar]) ;\n"
|
1142
|
+
end
|
1143
|
+
|
1144
|
+
def test_assignment_to_di
|
1145
|
+
parse %(foo := DO[1]\nbar := DI[1]\nfoo = bar)
|
1146
|
+
assert_prog "DO[1:foo]=(DI[1:bar]) ;\n"
|
1147
|
+
end
|
1148
|
+
|
1149
|
+
def test_string_register_definition
|
1150
|
+
parse %(foo := SR[1]\nbar := SR[2]\nfoo = bar)
|
1151
|
+
assert_prog "SR[1:foo]=SR[2:bar] ;\n"
|
1152
|
+
end
|
1153
|
+
|
1154
|
+
def test_string_argument
|
1155
|
+
parse %(foo('bar'))
|
1156
|
+
assert_prog "CALL FOO('bar') ;\n"
|
1157
|
+
end
|
1158
|
+
|
1159
|
+
def test_pause
|
1160
|
+
parse %(pause)
|
1161
|
+
assert_prog "PAUSE ;\n"
|
1162
|
+
end
|
1163
|
+
|
1164
|
+
def test_abort
|
1165
|
+
parse %(abort)
|
1166
|
+
assert_prog "ABORT ;\n"
|
1167
|
+
end
|
1168
|
+
end
|