tp_plus 0.0.87 → 0.0.88

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +87 -87
  3. data/Rakefile +35 -35
  4. data/bin/tpp +92 -92
  5. data/lib/tp_plus/interpreter.rb +153 -152
  6. data/lib/tp_plus/namespace.rb +66 -66
  7. data/lib/tp_plus/nodes/abort_node.rb +9 -9
  8. data/lib/tp_plus/nodes/acc_node.rb +24 -19
  9. data/lib/tp_plus/nodes/address_node.rb +22 -22
  10. data/lib/tp_plus/nodes/argument_node.rb +20 -20
  11. data/lib/tp_plus/nodes/assignment_node.rb +52 -52
  12. data/lib/tp_plus/nodes/base_node.rb +9 -9
  13. data/lib/tp_plus/nodes/call_node.rb +34 -34
  14. data/lib/tp_plus/nodes/case_condition_node.rb +26 -26
  15. data/lib/tp_plus/nodes/case_node.rb +33 -33
  16. data/lib/tp_plus/nodes/comment_node.rb +18 -18
  17. data/lib/tp_plus/nodes/conditional_node.rb +60 -60
  18. data/lib/tp_plus/nodes/definition_node.rb +22 -22
  19. data/lib/tp_plus/nodes/digit_node.rb +22 -22
  20. data/lib/tp_plus/nodes/empty_stmt_node.rb +9 -9
  21. data/lib/tp_plus/nodes/eval_node.rb +13 -13
  22. data/lib/tp_plus/nodes/expression_node.rb +71 -68
  23. data/lib/tp_plus/nodes/for_node.rb +20 -20
  24. data/lib/tp_plus/nodes/header_node.rb +27 -27
  25. data/lib/tp_plus/nodes/indirect_node.rb +27 -27
  26. data/lib/tp_plus/nodes/inline_conditional_node.rb +36 -36
  27. data/lib/tp_plus/nodes/io_method_node.rb +55 -55
  28. data/lib/tp_plus/nodes/io_node.rb +31 -31
  29. data/lib/tp_plus/nodes/jpos_node.rb +13 -13
  30. data/lib/tp_plus/nodes/jump_node.rb +23 -23
  31. data/lib/tp_plus/nodes/label_definition_node.rb +21 -21
  32. data/lib/tp_plus/nodes/lpos_node.rb +13 -13
  33. data/lib/tp_plus/nodes/motion_node.rb +62 -62
  34. data/lib/tp_plus/nodes/namespace_node.rb +16 -16
  35. data/lib/tp_plus/nodes/namespaced_var_node.rb +38 -38
  36. data/lib/tp_plus/nodes/numreg_node.rb +26 -26
  37. data/lib/tp_plus/nodes/offset_node.rb +27 -27
  38. data/lib/tp_plus/nodes/operator_node.rb +78 -80
  39. data/lib/tp_plus/nodes/paren_expression_node.rb +17 -17
  40. data/lib/tp_plus/nodes/pause_node.rb +9 -9
  41. data/lib/tp_plus/nodes/position_data_node.rb +66 -66
  42. data/lib/tp_plus/nodes/position_node.rb +26 -26
  43. data/lib/tp_plus/nodes/posreg_node.rb +64 -64
  44. data/lib/tp_plus/nodes/raise_node.rb +13 -13
  45. data/lib/tp_plus/nodes/real_node.rb +27 -27
  46. data/lib/tp_plus/nodes/return_node.rb +9 -9
  47. data/lib/tp_plus/nodes/set_skip_node.rb +14 -14
  48. data/lib/tp_plus/nodes/skip_node.rb +22 -22
  49. data/lib/tp_plus/nodes/speed_node.rb +29 -29
  50. data/lib/tp_plus/nodes/string_node.rb +13 -13
  51. data/lib/tp_plus/nodes/string_register_node.rb +26 -26
  52. data/lib/tp_plus/nodes/termination_node.rb +29 -23
  53. data/lib/tp_plus/nodes/terminator_node.rb +16 -16
  54. data/lib/tp_plus/nodes/time_node.rb +24 -24
  55. data/lib/tp_plus/nodes/timer_method_node.rb +33 -33
  56. data/lib/tp_plus/nodes/timer_node.rb +16 -16
  57. data/lib/tp_plus/nodes/unary_expression_node.rb +40 -39
  58. data/lib/tp_plus/nodes/units_node.rb +20 -20
  59. data/lib/tp_plus/nodes/use_node.rb +21 -21
  60. data/lib/tp_plus/nodes/user_alarm_node.rb +16 -16
  61. data/lib/tp_plus/nodes/var_method_node.rb +23 -23
  62. data/lib/tp_plus/nodes/var_node.rb +39 -39
  63. data/lib/tp_plus/nodes/vision_register_node.rb +22 -22
  64. data/lib/tp_plus/nodes/wait_for_node.rb +57 -50
  65. data/lib/tp_plus/nodes/wait_until_node.rb +61 -61
  66. data/lib/tp_plus/nodes/while_node.rb +40 -40
  67. data/lib/tp_plus/parser.rb +1749 -1749
  68. data/lib/tp_plus/scanner.rb +295 -295
  69. data/lib/tp_plus/token.rb +101 -101
  70. data/lib/tp_plus/version.rb +3 -3
  71. data/lib/tp_plus.rb +72 -72
  72. data/test/test_helper.rb +5 -5
  73. data/test/tp_plus/test_interpreter.rb +1378 -1372
  74. data/test/tp_plus/test_parser.rb +502 -502
  75. data/test/tp_plus/test_scanner.rb +591 -591
  76. data/tp_plus.gemspec +31 -31
  77. metadata +4 -3
@@ -1,295 +1,295 @@
1
- module TPPlus
2
- class Scanner
3
- def initialize
4
- end
5
-
6
- attr_reader :lineno, :col
7
- attr_reader :tok_line, :tok_col
8
- def scan_setup(src)
9
- @src = src
10
- @lineno = 1
11
- @ch = " "
12
- @offset = 0
13
- @col = 0
14
- @rdOffset = 0
15
- @prevDot = false # for groups
16
-
17
- @tok_line = 0
18
- @tok_col = 0
19
-
20
- self.next
21
- end
22
-
23
- def next
24
- if @rdOffset < @src.length
25
- @offset = @rdOffset
26
- @ch = @src[@rdOffset]
27
- if @ch == "\n"
28
- @lineno += 1
29
- @col = 0
30
- end
31
- @rdOffset += 1
32
- @col += 1
33
- else
34
- @offset = @src.length
35
- @ch = -1
36
- end
37
- end
38
-
39
- def isDigit?(ch)
40
- return false if ch == -1
41
-
42
- case ch
43
- when '0','1','2','3','4','5','6','7','8','9'
44
- return true
45
- else
46
- return false
47
- end
48
- end
49
-
50
- def isLetter?(ch)
51
- return false if ch == -1
52
-
53
- case ch
54
- when 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
55
- 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
56
- '_'
57
- return true
58
- else
59
- return false
60
- end
61
- end
62
-
63
- def skipWhitespace
64
- while @ch == ' ' || @ch == "\t" || @ch == "\r"
65
- self.next
66
- end
67
- end
68
-
69
- def scanIdentifier
70
- offs = @offset
71
- while isLetter?(@ch) || isDigit?(@ch)
72
- self.next
73
- end
74
-
75
- # allow one ? or ! at end
76
- if @ch == '?' || @ch == '!'
77
- self.next
78
- end
79
-
80
- return @src[offs,(@offset-offs)]
81
- end
82
-
83
- def scanReal
84
- offs = @offset-1
85
- while self.isDigit?(@ch)
86
- self.next
87
- end
88
-
89
- return [:REAL, @src[offs,(@offset-offs)].to_f]
90
- end
91
-
92
- def scanNumber
93
- offs = @offset
94
- while self.isDigit?(@ch)
95
- self.next
96
- end
97
- if @ch == '.'
98
- self.next
99
- while self.isDigit?(@ch)
100
- self.next
101
- end
102
-
103
- return [:REAL, @src[offs,(@offset-offs)].to_f]
104
- else
105
- return [:DIGIT, @src[offs,(@offset-offs)].to_i]
106
- end
107
- end
108
-
109
- def scanComment
110
- offs = @offset-1 # opening # already consumed
111
- while @ch != "\n" && @ch != -1
112
- self.next
113
- end
114
-
115
- return @src[offs,(@offset-offs)]
116
- end
117
-
118
- def scanString(type)
119
- offs = @offset
120
- while @ch != type && @ch != -1
121
- self.next
122
- end
123
-
124
- # consume close
125
- self.next
126
-
127
- return @src[offs, (@offset-offs-1)] # -1 to remove trailing " or '
128
- end
129
-
130
- def scanLabel
131
- offs = @offset
132
- while self.isLetter?(@ch)
133
- self.next
134
- end
135
-
136
- return @src[offs, (@offset-offs)]
137
- end
138
-
139
- # return token
140
- def next_token
141
- self.skipWhitespace
142
-
143
- @tok_line = @lineno
144
- @tok_col = @col
145
-
146
- tok = nil
147
- lit = ""
148
- ch = @ch
149
-
150
- if isLetter?(ch)
151
- lit = self.scanIdentifier
152
- if @ch == '['
153
- tok = TPPlus::Token.lookup_data(lit)
154
- elsif lit == "DIV"
155
- tok = :DIV
156
- else
157
- # keywords are longer than 1 char, avoid lookup otherwise
158
- if lit.length > 1
159
- if @prevDot
160
- case lit
161
- when "gp1","gp2","gp3","gp4","gp5"
162
- tok = :GROUP
163
- else
164
- tok = TPPlus::Token.lookup(lit)
165
- end
166
- else
167
- tok = TPPlus::Token.lookup(lit)
168
- end
169
- else
170
- tok = :WORD
171
- end
172
- end
173
- elsif isDigit?(ch)
174
- tok, lit = self.scanNumber
175
- else
176
- self.next # always make progress
177
- case ch
178
- when -1
179
- return nil
180
- when '='
181
- if @ch == '='
182
- tok = :EEQUAL
183
- self.next
184
- else
185
- tok = :EQUAL
186
- end
187
- when ':'
188
- if @ch == "="
189
- tok = :ASSIGN
190
- self.next
191
- else
192
- tok = :COLON
193
- end
194
- when "<"
195
- if @ch == "="
196
- tok = :LTE
197
- self.next
198
- elsif @ch == ">"
199
- tok = :NOTEQUAL
200
- self.next
201
- else
202
- tok = :LT
203
- end
204
- when ">"
205
- if @ch == "="
206
- tok = :GTE
207
- self.next
208
- else
209
- tok = :GT
210
- end
211
- when "+"
212
- tok = :PLUS
213
- when "-"
214
- tok = :MINUS
215
- when "*"
216
- tok = :STAR
217
- when "/"
218
- tok = :SLASH
219
- when "&"
220
- if @ch == "&"
221
- tok = :AND
222
- self.next
223
- elsif isLetter?(@ch)
224
- tok = :ADDRESS
225
- lit = self.scanIdentifier
226
- else
227
- tok = :ILLEGAL
228
- end
229
- when "|"
230
- if @ch == "|"
231
- tok = :OR
232
- self.next
233
- else
234
- tok = :ILLEGAL
235
- end
236
- when "%"
237
- tok = :MOD
238
- when ";"
239
- tok = :SEMICOLON
240
- when "."
241
- if self.isDigit?(@ch)
242
- tok, lit = self.scanReal
243
- else
244
- tok = :DOT
245
- end
246
- when "!"
247
- if @ch == "="
248
- tok = :NOTEQUAL
249
- self.next
250
- else
251
- tok = :BANG
252
- end
253
- when "\"", "'"
254
- tok = :STRING
255
- lit = self.scanString(ch)
256
- when "#"
257
- tok = :COMMENT
258
- lit = self.scanComment
259
- when "@"
260
- tok = :LABEL
261
- lit = self.scanLabel
262
- when '('
263
- tok = :LPAREN
264
- when ')'
265
- tok = :RPAREN
266
- when ','
267
- tok = :COMMA
268
- when '['
269
- tok = :LBRACK
270
- when ']'
271
- tok = :RBRACK
272
- when '{'
273
- tok = :LBRACE
274
- when '}'
275
- tok = :RBRACE
276
- when "\n"
277
- tok = :NEWLINE
278
- else
279
- tok = :ILLEGAL
280
- lit = ch
281
- end
282
- end
283
-
284
- if tok == :DOT
285
- @prevDot = true
286
- else
287
- @prevDot = false
288
- end
289
-
290
- return [tok, lit]
291
- end
292
- end
293
-
294
- class ScanError < StandardError ; end
295
- end
1
+ module TPPlus
2
+ class Scanner
3
+ def initialize
4
+ end
5
+
6
+ attr_reader :lineno, :col
7
+ attr_reader :tok_line, :tok_col
8
+ def scan_setup(src)
9
+ @src = src
10
+ @lineno = 1
11
+ @ch = " "
12
+ @offset = 0
13
+ @col = 0
14
+ @rdOffset = 0
15
+ @prevDot = false # for groups
16
+
17
+ @tok_line = 0
18
+ @tok_col = 0
19
+
20
+ self.next
21
+ end
22
+
23
+ def next
24
+ if @rdOffset < @src.length
25
+ @offset = @rdOffset
26
+ @ch = @src[@rdOffset]
27
+ if @ch == "\n"
28
+ @lineno += 1
29
+ @col = 0
30
+ end
31
+ @rdOffset += 1
32
+ @col += 1
33
+ else
34
+ @offset = @src.length
35
+ @ch = -1
36
+ end
37
+ end
38
+
39
+ def isDigit?(ch)
40
+ return false if ch == -1
41
+
42
+ case ch
43
+ when '0','1','2','3','4','5','6','7','8','9'
44
+ return true
45
+ else
46
+ return false
47
+ end
48
+ end
49
+
50
+ def isLetter?(ch)
51
+ return false if ch == -1
52
+
53
+ case ch
54
+ when 'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z',
55
+ 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z',
56
+ '_'
57
+ return true
58
+ else
59
+ return false
60
+ end
61
+ end
62
+
63
+ def skipWhitespace
64
+ while @ch == ' ' || @ch == "\t" || @ch == "\r"
65
+ self.next
66
+ end
67
+ end
68
+
69
+ def scanIdentifier
70
+ offs = @offset
71
+ while isLetter?(@ch) || isDigit?(@ch)
72
+ self.next
73
+ end
74
+
75
+ # allow one ? or ! at end
76
+ if @ch == '?' || @ch == '!'
77
+ self.next
78
+ end
79
+
80
+ return @src[offs,(@offset-offs)]
81
+ end
82
+
83
+ def scanReal
84
+ offs = @offset-1
85
+ while self.isDigit?(@ch)
86
+ self.next
87
+ end
88
+
89
+ return [:REAL, @src[offs,(@offset-offs)].to_f]
90
+ end
91
+
92
+ def scanNumber
93
+ offs = @offset
94
+ while self.isDigit?(@ch)
95
+ self.next
96
+ end
97
+ if @ch == '.'
98
+ self.next
99
+ while self.isDigit?(@ch)
100
+ self.next
101
+ end
102
+
103
+ return [:REAL, @src[offs,(@offset-offs)].to_f]
104
+ else
105
+ return [:DIGIT, @src[offs,(@offset-offs)].to_i]
106
+ end
107
+ end
108
+
109
+ def scanComment
110
+ offs = @offset-1 # opening # already consumed
111
+ while @ch != "\n" && @ch != -1
112
+ self.next
113
+ end
114
+
115
+ return @src[offs,(@offset-offs)]
116
+ end
117
+
118
+ def scanString(type)
119
+ offs = @offset
120
+ while @ch != type && @ch != -1
121
+ self.next
122
+ end
123
+
124
+ # consume close
125
+ self.next
126
+
127
+ return @src[offs, (@offset-offs-1)] # -1 to remove trailing " or '
128
+ end
129
+
130
+ def scanLabel
131
+ offs = @offset
132
+ while self.isLetter?(@ch)
133
+ self.next
134
+ end
135
+
136
+ return @src[offs, (@offset-offs)]
137
+ end
138
+
139
+ # return token
140
+ def next_token
141
+ self.skipWhitespace
142
+
143
+ @tok_line = @lineno
144
+ @tok_col = @col
145
+
146
+ tok = nil
147
+ lit = ""
148
+ ch = @ch
149
+
150
+ if isLetter?(ch)
151
+ lit = self.scanIdentifier
152
+ if @ch == '['
153
+ tok = TPPlus::Token.lookup_data(lit)
154
+ elsif lit == "DIV"
155
+ tok = :DIV
156
+ else
157
+ # keywords are longer than 1 char, avoid lookup otherwise
158
+ if lit.length > 1
159
+ if @prevDot
160
+ case lit
161
+ when "gp1","gp2","gp3","gp4","gp5"
162
+ tok = :GROUP
163
+ else
164
+ tok = TPPlus::Token.lookup(lit)
165
+ end
166
+ else
167
+ tok = TPPlus::Token.lookup(lit)
168
+ end
169
+ else
170
+ tok = :WORD
171
+ end
172
+ end
173
+ elsif isDigit?(ch)
174
+ tok, lit = self.scanNumber
175
+ else
176
+ self.next # always make progress
177
+ case ch
178
+ when -1
179
+ return nil
180
+ when '='
181
+ if @ch == '='
182
+ tok = :EEQUAL
183
+ self.next
184
+ else
185
+ tok = :EQUAL
186
+ end
187
+ when ':'
188
+ if @ch == "="
189
+ tok = :ASSIGN
190
+ self.next
191
+ else
192
+ tok = :COLON
193
+ end
194
+ when "<"
195
+ if @ch == "="
196
+ tok = :LTE
197
+ self.next
198
+ elsif @ch == ">"
199
+ tok = :NOTEQUAL
200
+ self.next
201
+ else
202
+ tok = :LT
203
+ end
204
+ when ">"
205
+ if @ch == "="
206
+ tok = :GTE
207
+ self.next
208
+ else
209
+ tok = :GT
210
+ end
211
+ when "+"
212
+ tok = :PLUS
213
+ when "-"
214
+ tok = :MINUS
215
+ when "*"
216
+ tok = :STAR
217
+ when "/"
218
+ tok = :SLASH
219
+ when "&"
220
+ if @ch == "&"
221
+ tok = :AND
222
+ self.next
223
+ elsif isLetter?(@ch)
224
+ tok = :ADDRESS
225
+ lit = self.scanIdentifier
226
+ else
227
+ tok = :ILLEGAL
228
+ end
229
+ when "|"
230
+ if @ch == "|"
231
+ tok = :OR
232
+ self.next
233
+ else
234
+ tok = :ILLEGAL
235
+ end
236
+ when "%"
237
+ tok = :MOD
238
+ when ";"
239
+ tok = :SEMICOLON
240
+ when "."
241
+ if self.isDigit?(@ch)
242
+ tok, lit = self.scanReal
243
+ else
244
+ tok = :DOT
245
+ end
246
+ when "!"
247
+ if @ch == "="
248
+ tok = :NOTEQUAL
249
+ self.next
250
+ else
251
+ tok = :BANG
252
+ end
253
+ when "\"", "'"
254
+ tok = :STRING
255
+ lit = self.scanString(ch)
256
+ when "#"
257
+ tok = :COMMENT
258
+ lit = self.scanComment
259
+ when "@"
260
+ tok = :LABEL
261
+ lit = self.scanLabel
262
+ when '('
263
+ tok = :LPAREN
264
+ when ')'
265
+ tok = :RPAREN
266
+ when ','
267
+ tok = :COMMA
268
+ when '['
269
+ tok = :LBRACK
270
+ when ']'
271
+ tok = :RBRACK
272
+ when '{'
273
+ tok = :LBRACE
274
+ when '}'
275
+ tok = :RBRACE
276
+ when "\n"
277
+ tok = :NEWLINE
278
+ else
279
+ tok = :ILLEGAL
280
+ lit = ch
281
+ end
282
+ end
283
+
284
+ if tok == :DOT
285
+ @prevDot = true
286
+ else
287
+ @prevDot = false
288
+ end
289
+
290
+ return [tok, lit]
291
+ end
292
+ end
293
+
294
+ class ScanError < StandardError ; end
295
+ end