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.
Files changed (67) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +65 -0
  3. data/Rakefile +21 -0
  4. data/bin/tpp +73 -0
  5. data/lib/tp_plus/interpreter.rb +129 -0
  6. data/lib/tp_plus/namespace.rb +66 -0
  7. data/lib/tp_plus/nodes/abort_node.rb +9 -0
  8. data/lib/tp_plus/nodes/argument_node.rb +19 -0
  9. data/lib/tp_plus/nodes/assignment_node.rb +45 -0
  10. data/lib/tp_plus/nodes/call_node.rb +34 -0
  11. data/lib/tp_plus/nodes/case_condition_node.rb +26 -0
  12. data/lib/tp_plus/nodes/case_node.rb +33 -0
  13. data/lib/tp_plus/nodes/comment_node.rb +22 -0
  14. data/lib/tp_plus/nodes/conditional_node.rb +54 -0
  15. data/lib/tp_plus/nodes/definition_node.rb +22 -0
  16. data/lib/tp_plus/nodes/digit_node.rb +21 -0
  17. data/lib/tp_plus/nodes/eval_node.rb +13 -0
  18. data/lib/tp_plus/nodes/expression_node.rb +65 -0
  19. data/lib/tp_plus/nodes/for_node.rb +20 -0
  20. data/lib/tp_plus/nodes/header_node.rb +27 -0
  21. data/lib/tp_plus/nodes/indirect_node.rb +49 -0
  22. data/lib/tp_plus/nodes/inline_conditional_node.rb +40 -0
  23. data/lib/tp_plus/nodes/io_method_node.rb +55 -0
  24. data/lib/tp_plus/nodes/io_node.rb +30 -0
  25. data/lib/tp_plus/nodes/jump_node.rb +23 -0
  26. data/lib/tp_plus/nodes/label_definition_node.rb +21 -0
  27. data/lib/tp_plus/nodes/motion_node.rb +62 -0
  28. data/lib/tp_plus/nodes/namespace_node.rb +16 -0
  29. data/lib/tp_plus/nodes/namespaced_var_node.rb +38 -0
  30. data/lib/tp_plus/nodes/numreg_node.rb +25 -0
  31. data/lib/tp_plus/nodes/offset_node.rb +27 -0
  32. data/lib/tp_plus/nodes/operator_node.rb +72 -0
  33. data/lib/tp_plus/nodes/pause_node.rb +9 -0
  34. data/lib/tp_plus/nodes/position_data_node.rb +50 -0
  35. data/lib/tp_plus/nodes/position_node.rb +25 -0
  36. data/lib/tp_plus/nodes/posreg_node.rb +48 -0
  37. data/lib/tp_plus/nodes/raise_node.rb +13 -0
  38. data/lib/tp_plus/nodes/real_node.rb +27 -0
  39. data/lib/tp_plus/nodes/set_node.rb +22 -0
  40. data/lib/tp_plus/nodes/skip_node.rb +22 -0
  41. data/lib/tp_plus/nodes/speed_node.rb +29 -0
  42. data/lib/tp_plus/nodes/string_node.rb +13 -0
  43. data/lib/tp_plus/nodes/string_register_node.rb +25 -0
  44. data/lib/tp_plus/nodes/termination_node.rb +18 -0
  45. data/lib/tp_plus/nodes/terminator_node.rb +16 -0
  46. data/lib/tp_plus/nodes/time_node.rb +24 -0
  47. data/lib/tp_plus/nodes/timer_method_node.rb +37 -0
  48. data/lib/tp_plus/nodes/timer_node.rb +21 -0
  49. data/lib/tp_plus/nodes/units_node.rb +20 -0
  50. data/lib/tp_plus/nodes/use_node.rb +21 -0
  51. data/lib/tp_plus/nodes/user_alarm_node.rb +15 -0
  52. data/lib/tp_plus/nodes/var_method_node.rb +23 -0
  53. data/lib/tp_plus/nodes/var_node.rb +39 -0
  54. data/lib/tp_plus/nodes/vision_register_node.rb +21 -0
  55. data/lib/tp_plus/nodes/wait_for_node.rb +54 -0
  56. data/lib/tp_plus/nodes/wait_until_node.rb +65 -0
  57. data/lib/tp_plus/nodes/while_node.rb +36 -0
  58. data/lib/tp_plus/parser.rb +1592 -0
  59. data/lib/tp_plus/scanner.rb +383 -0
  60. data/lib/tp_plus/version.rb +3 -0
  61. data/lib/tp_plus.rb +62 -0
  62. data/test/test_helper.rb +5 -0
  63. data/test/tp_plus/test_interpreter.rb +1168 -0
  64. data/test/tp_plus/test_parser.rb +489 -0
  65. data/test/tp_plus/test_scanner.rb +522 -0
  66. data/tp_plus.gemspec +28 -0
  67. metadata +156 -0
@@ -0,0 +1,489 @@
1
+ require 'test_helper'
2
+
3
+ class TestParser < 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 test_minimum_prog
26
+ parse("")
27
+ end
28
+
29
+ def blank_prog
30
+ parse("\n\n\n\n\n")
31
+ end
32
+
33
+ def test_comment
34
+ parse("# foo")
35
+ assert_node_type CommentNode, last_node
36
+ end
37
+
38
+ def test_numreg_definition
39
+ parse("foo := R[1]")
40
+ assert_node_type DefinitionNode, last_node
41
+ end
42
+
43
+ def test_assignment
44
+ parse("foo = 1")
45
+ assert_node_type AssignmentNode, last_node
46
+ end
47
+
48
+ def test_label_definition
49
+ parse("@foo")
50
+ assert_node_type LabelDefinitionNode, last_node
51
+ end
52
+
53
+ def test_jump_to
54
+ parse("@foo\njump_to @foo")
55
+ assert_node_type JumpNode, last_node
56
+ end
57
+
58
+ def test_plus_equal
59
+ parse("foo += 1")
60
+ l = last_node
61
+ assert_node_type AssignmentNode, l
62
+ assert_node_type VarNode, l.identifier
63
+ assert_node_type ExpressionNode, l.assignable
64
+ assert_node_type VarNode, l.assignable.left_op
65
+ end
66
+
67
+ def test_minus_equal
68
+ parse("foo -= 1")
69
+ l = last_node
70
+ assert_node_type AssignmentNode, l
71
+ assert_node_type VarNode, l.identifier
72
+ assert_node_type ExpressionNode, l.assignable
73
+ assert_node_type VarNode, l.assignable.left_op
74
+ end
75
+
76
+ def test_turn_on
77
+ parse("turn_on foo")
78
+ assert_node_type IOMethodNode, last_node
79
+ end
80
+
81
+ def test_turn_off
82
+ parse("turn_off foo")
83
+ assert_node_type IOMethodNode, last_node
84
+ end
85
+
86
+ def test_toggle
87
+ parse("toggle foo")
88
+ assert_node_type IOMethodNode, last_node
89
+ end
90
+
91
+ def test_motion
92
+ parse("linear_move.to(home).at(2000, 'mm/s').term(0)")
93
+ assert_node_type MotionNode, last_node
94
+ end
95
+
96
+ def test_simple_if
97
+ parse("if 1==1 \n\n\njump_to @foo\nend")
98
+ assert_node_type ConditionalNode, last_node
99
+ end
100
+
101
+ def test_if_with_else
102
+ parse("if 1==1 \n\n\njump_to @foo\n else \n# something\nend")
103
+ assert_node_type ConditionalNode, last_node
104
+ end
105
+
106
+ def test_simple_unless
107
+ parse("unless 1==1\njump_to @foo\nend")
108
+ assert_node_type ConditionalNode, last_node
109
+ end
110
+
111
+ def test_inline_if
112
+ parse("jump_to @foo if foo < 10")
113
+ assert_node_type InlineConditionalNode, last_node
114
+ end
115
+
116
+ def test_inline_if_assignment
117
+ parse("foo = 1 if foo < 10")
118
+ assert_node_type InlineConditionalNode, last_node
119
+ end
120
+
121
+ def test_inline_io_method
122
+ parse("turn_on foo if bar < 10")
123
+ assert_node_type InlineConditionalNode, last_node
124
+ end
125
+
126
+ def test_prog_call
127
+ parse("foo()")
128
+ assert_node_type CallNode, last_node
129
+ end
130
+
131
+ def test_prog_call_with_an_arg
132
+ parse("foo(1)")
133
+ l = last_node
134
+ assert_node_type CallNode, l
135
+ assert_equal 1, l.args.length
136
+ end
137
+
138
+ def test_prog_call_with_multiple_args
139
+ parse("foo(1,2,3)")
140
+ l = last_node
141
+ assert_equal 3, l.args.length
142
+ end
143
+
144
+ def test_prog_call_with_variable_arg
145
+ parse("foo(bar)")
146
+ assert_node_type CallNode, last_node
147
+ end
148
+
149
+ def test_position_definition
150
+ parse("foo := P[1]")
151
+ assert_node_type DefinitionNode, last_node
152
+ end
153
+
154
+ def test_uframe_assignment
155
+ parse("uframe_num = 5")
156
+ assert_node_type AssignmentNode, last_node
157
+ end
158
+
159
+ def test_utool_assignment
160
+ parse("utool_num = 5")
161
+ assert_node_type AssignmentNode, last_node
162
+ end
163
+
164
+ def test_offset
165
+ parse("foo := P[1]\nbar := PR[1]\nlinear_move.to(foo).at(2000, 'mm/s').term(0).offset(bar)")
166
+ assert_node_type MotionNode, last_node
167
+ end
168
+
169
+ def test_vr_offset
170
+ parse("foo := P[1]\nbar := VR[1]\nlinear_move.to(foo).at(2000, 'mm/s').term(0).offset(bar)")
171
+ assert_node_type MotionNode, last_node
172
+ end
173
+
174
+ def test_time_before
175
+ parse("p := P[1]\nlinear_move.to(p).at(2000, 'mm/s').term(0).time_before(0.1, foo())")
176
+ assert_node_type MotionNode, last_node
177
+ end
178
+
179
+ def test_use_uframe
180
+ parse("use_uframe 5")
181
+ assert_node_type UseNode, last_node
182
+ end
183
+
184
+ def test_indirect_uframe
185
+ parse("foo := R[1]\nuse_uframe foo")
186
+ assert_node_type UseNode, last_node
187
+ end
188
+
189
+ def test_use_utool
190
+ parse("use_utool 5")
191
+ assert_node_type UseNode, last_node
192
+ end
193
+
194
+ def test_indirect_utool
195
+ parse("foo := R[1]\nuse_utool foo")
196
+ assert_node_type UseNode, last_node
197
+ end
198
+
199
+ def test_use_payload
200
+ parse("use_payload 1")
201
+ assert_node_type UseNode, last_node
202
+ end
203
+
204
+ def test_indirect_payload
205
+ parse("foo := R[1]\nuse_payload foo")
206
+ assert_node_type UseNode, last_node
207
+ end
208
+
209
+ def test_can_name_a_label_end
210
+ parse("@end")
211
+ assert_node_type LabelDefinitionNode, last_node
212
+ end
213
+
214
+ def test_wait_for_with_units
215
+ parse("wait_for(5,'s')")
216
+ assert_node_type WaitForNode, last_node
217
+ end
218
+
219
+ def test_scan_wait_until
220
+ parse("wait_until(1==0)")
221
+ assert_node_type WaitUntilNode, last_node
222
+ end
223
+
224
+ def test_scans_assignment_with_negative_number
225
+ parse("foo := R[1]\nfoo = -1")
226
+ assert_node_type AssignmentNode, last_node
227
+ end
228
+
229
+ def test_scans_simplest_case_statement
230
+ parse("foo := R[1]\ncase foo\nwhen 1\njump_to @asdf\nend\n@asdf")
231
+ assert_node_type CaseNode, @interpreter.nodes[@interpreter.nodes.length-3]
232
+ end
233
+
234
+ def test_scans_case_with_else
235
+ parse("foo := R[1]\ncase foo\nwhen 1\njump_to @asdf\nelse\njump_to @ghjk\nend\n@asdf\n@ghjk")
236
+ assert_node_type CaseNode, @interpreter.nodes[@interpreter.nodes.length-5]
237
+ end
238
+
239
+ def test_scans_two_cases
240
+ parse("foo := R[1]\ncase foo\nwhen 1\njump_to @asdf\nwhen 2\njump_to @ghjk\nend\n@asdf\n@ghjk")
241
+ assert_node_type CaseNode, @interpreter.nodes[@interpreter.nodes.length-5]
242
+ end
243
+
244
+ def test_case_can_use_a_var_as_a_condition
245
+ parse("foo := R[1]\nbar := R[2]\ncase foo\nwhen bar\njump_to @asdf\nend\n@asdf")
246
+ assert_node_type CaseNode, @interpreter.nodes[@interpreter.nodes.length-3]
247
+ end
248
+
249
+ def test_case_can_call_a_prog_as_an_action
250
+ parse("foo := R[1]\ncase foo\nwhen 1\nmy_program()\nend\n@asdf")
251
+ assert_node_type CaseNode, @interpreter.nodes[@interpreter.nodes.length-3]
252
+ end
253
+
254
+ def test_can_define_input
255
+ parse("foo := UI[1]")
256
+ assert_node_type DefinitionNode, last_node
257
+ end
258
+
259
+ def test_can_inline_conditional_just_io_value
260
+ parse("foo := UI[5]\n@top\njump_to @top if foo")
261
+ assert_node_type InlineConditionalNode, last_node
262
+ end
263
+
264
+ def test_inline_program_call
265
+ parse("foo := UI[5]\nbar() unless foo")
266
+ assert_node_type InlineConditionalNode, last_node
267
+ end
268
+
269
+ def test_constant_definition
270
+ parse("FOO := 5\nfoo := R[1]\nfoo = FOO")
271
+ assert_node_type DefinitionNode, @interpreter.nodes.first
272
+ end
273
+
274
+ def test_defining_arg_as_var
275
+ parse("arg_1 := AR[1]")
276
+ assert_node_type DefinitionNode, last_node
277
+ end
278
+
279
+ def test_fanuc_set_uframe_with_pr
280
+ parse("foo := PR[1]\nset_uframe 5, foo")
281
+ assert_node_type SetNode, last_node
282
+ end
283
+
284
+ def test_set_skip_condition
285
+ parse("foo := RI[1]\nset_skip_condition foo.on?")
286
+ assert_node_type SetNode, last_node
287
+ end
288
+
289
+ def test_skip_to
290
+ parse("p := P[1]\n@somewhere\nlinear_move.to(p).at(2000, 'mm/s').term(0).skip_to(@somewhere)")
291
+ assert_node_type MotionNode, last_node
292
+ end
293
+
294
+ def test_skip_to_with_pr
295
+ parse("p := P[1]\nlpos := PR[1]\n@somewhere\nlinear_move.to(p).at(2000, 'mm/s').term(0).skip_to(@somewhere, lpos)")
296
+ assert_node_type MotionNode, last_node
297
+ end
298
+
299
+ def test_simple_math
300
+ parse("foo := R[1]\nfoo=1+1")
301
+ assert_node_type AssignmentNode, last_node
302
+ end
303
+
304
+ def test_more_complicated_expression
305
+ parse("foo := R[1]\nfoo=1+2+3+4+5")
306
+ assert_node_type AssignmentNode, last_node
307
+ end
308
+
309
+ def test_operator_precedence
310
+ parse("foo := R[1]\nfoo=1+2*3")
311
+ n = last_node
312
+ assert_node_type AssignmentNode, n
313
+ e = n.assignable
314
+ assert_node_type DigitNode, e.left_op
315
+ assert_node_type ExpressionNode, e.right_op
316
+ end
317
+
318
+ def test_expression_grouping
319
+ parse("foo := R[1]\nfoo=(1+2)*3")
320
+ n = last_node
321
+ assert_node_type AssignmentNode, n
322
+ e = n.assignable
323
+ assert_node_type ExpressionNode, e.left_op
324
+ assert_node_type DigitNode, e.right_op
325
+ end
326
+
327
+ def test_boolean_expressions
328
+ parse("foo := F[1]\nfoo=1 || 1 && 0")
329
+ assert_node_type AssignmentNode, last_node
330
+ end
331
+
332
+ def test_bang
333
+ parse "foo := F[1]\nbar := F[2]\nfoo = !bar"
334
+ n = last_node
335
+ assert_node_type AssignmentNode, n
336
+ assert_node_type ExpressionNode, n.assignable
337
+ end
338
+
339
+ def test_indirect_position_assignment
340
+ parse "foo := PR[1]\nfoo = indirect('position',5)"
341
+ assert_node_type AssignmentNode, last_node
342
+ end
343
+
344
+ def test_namespace_definition
345
+ parse %(namespace Foo\nbar := R[1]\nend)
346
+ assert_node_type NamespaceNode, last_node
347
+ end
348
+
349
+ def test_scans_eval_with_string
350
+ parse %(eval "R[1]=5")
351
+ assert_node_type EvalNode, last_node
352
+ end
353
+
354
+ def test_for_loop
355
+ parse %(foo := R[1]\nfor foo in (1 to 10)\n# bar\nend)
356
+ assert_node_type ForNode, last_node
357
+ end
358
+
359
+ def test_while
360
+ parse %(foo := R[1]\nwhile foo < 10\n# bar\nend)
361
+ assert_node_type WhileNode, last_node
362
+ end
363
+
364
+ def test_start_timer
365
+ parse %(t := TIMER[1]\nstart t)
366
+ assert_node_type TimerMethodNode, last_node
367
+ end
368
+
369
+ def test_position_data_block
370
+ parse "position_data\n{}\nend"
371
+ assert_node_type PositionDataNode, last_node
372
+ end
373
+
374
+ def test_position_data_block_with_a_position
375
+ parse %(position_data
376
+ {
377
+ 'positions': [
378
+ {
379
+ 'id': 1,
380
+ 'comment': "test",
381
+ 'group': 1,
382
+ 'uframe': 1,
383
+ 'utool': 1,
384
+ 'config': {
385
+ 'flip': true,
386
+ 'up': true,
387
+ 'top': false,
388
+ 'turn_counts': [0,0,0]
389
+ },
390
+ 'components': {
391
+ 'x': 0.0,
392
+ 'y': 0.0,
393
+ 'z': 0.0,
394
+ 'w': 0.0,
395
+ 'p': 0.0,
396
+ 'r': 0.0
397
+ }
398
+ }
399
+ ]
400
+ }
401
+ end)
402
+ assert_node_type PositionDataNode, last_node
403
+ end
404
+
405
+ def test_position_data_block_with_two_positions
406
+ parse %(position_data
407
+ {
408
+ 'positions': [
409
+ {
410
+ 'id': 1,
411
+ 'comment': "test",
412
+ 'group': 1,
413
+ 'uframe': 1,
414
+ 'utool': 1,
415
+ 'config': {
416
+ 'flip': true,
417
+ 'up': true,
418
+ 'top': false,
419
+ 'turn_counts': [0,0,0]
420
+ },
421
+ 'components': {
422
+ 'x': 0.0,
423
+ 'y': 0.0,
424
+ 'z': 0.0,
425
+ 'w': 0.0,
426
+ 'p': 0.0,
427
+ 'r': 0.0
428
+ }
429
+ },
430
+ {
431
+ 'id': 2,
432
+ 'comment': "test",
433
+ 'group': 1,
434
+ 'uframe': 1,
435
+ 'utool': 1,
436
+ 'config': {
437
+ 'flip': true,
438
+ 'up': true,
439
+ 'top': false,
440
+ 'turn_counts': [0,0,0]
441
+ },
442
+ 'components': {
443
+ 'x': 0.0,
444
+ 'y': 0.0,
445
+ 'z': 0.0,
446
+ 'w': 0.0,
447
+ 'p': 0.0,
448
+ 'r': 0.0
449
+ }
450
+ }
451
+ ]
452
+ }
453
+ end)
454
+ assert_node_type PositionDataNode, last_node
455
+ end
456
+
457
+ def test_simple_pulse
458
+ parse "foo := DO[1]\npulse(foo)"
459
+ assert_node_type IOMethodNode, last_node
460
+ end
461
+
462
+ def test_pulse_with_options
463
+ parse "foo := DO[1]\npulse(foo,5,'s')"
464
+ assert_node_type IOMethodNode, last_node
465
+ end
466
+
467
+ def test_ualm_definition
468
+ parse "foo := UALM[1]"
469
+ n = last_node
470
+ assert_node_type DefinitionNode, n
471
+ assert_node_type UserAlarmNode, n.assignable
472
+ end
473
+
474
+ def test_raise
475
+ parse "my_alarm := UALM[1]\nraise my_alarm"
476
+ assert_node_type RaiseNode, last_node
477
+ end
478
+
479
+ def test_run
480
+ parse "run FOO()"
481
+ assert_node_type CallNode, last_node
482
+ assert last_node.async?
483
+ end
484
+
485
+ def test_tool_offset
486
+ parse "p := P[1]\nbar := PR[1]\nlinear_move.to(p).at(1000,'mm/s').term(0).tool_offset(bar)"
487
+ assert_node_type MotionNode, last_node
488
+ end
489
+ end