cannonbol 1.3.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -30,9 +30,9 @@ Simple syntax looks great alongside ruby!
30
30
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
31
  spec.require_paths = ["lib"]
32
32
 
33
- spec.add_development_dependency "bundler", "~> 1.8"
34
- spec.add_development_dependency "rake", "~> 10.0"
33
+ spec.add_development_dependency "bundler", ">= 1.8"
34
+ # spec.add_development_dependency "rake", "~> 10.0"
35
35
  spec.add_development_dependency "rspec"
36
- spec.add_development_dependency "opal-rspec"
37
- spec.add_development_dependency "opal"
36
+ # spec.add_development_dependency "opal-rspec"
37
+ # spec.add_development_dependency "opal"
38
38
  end
@@ -1,48 +1,48 @@
1
1
  module Cannonbol
2
-
2
+
3
3
  class MatchFailed < Exception; end
4
-
4
+
5
5
  class MatchString < String
6
-
6
+
7
7
  attr_reader :captured
8
8
  attr_reader :match_start
9
9
  attr_reader :match_end
10
-
10
+
11
11
  def initialize(string, match_start, match_end, captured)
12
12
  @cannonbol_string = string
13
13
  @match_start = match_start
14
14
  @match_end = match_end
15
15
  @captured = captured.dup
16
16
  super(@match_end < 0 ? "" : string[@match_start..@match_end])
17
- end
18
-
17
+ end
18
+
19
19
  def replace_match_with(s)
20
20
  before_match = ""
21
21
  before_match = @cannonbol_string[0..@match_start-1] if @match_start > 0
22
22
  after_match = @cannonbol_string[@match_end+1..-1] || ""
23
23
  before_match + s + after_match
24
24
  end
25
-
25
+
26
26
  end
27
-
27
+
28
28
  class Needle
29
-
29
+
30
30
  attr_reader :cursor
31
31
  attr_reader :string
32
32
  attr_accessor :captures
33
33
  attr_accessor :match_failed
34
34
  attr_accessor :ignore_case
35
-
35
+
36
36
  def initialize(string)
37
37
  @string = string
38
38
  end
39
-
39
+
40
40
  def thread(pattern, opts = {}, &match_block)
41
41
  @captures = {}
42
42
  anchor = opts[:anchor]
43
43
  raise_error = opts[:raise_error]
44
44
  replace_with = opts[:replace_match_with]
45
- ignore_case = opts[:ignore_case]
45
+ ignore_case = opts[:ignore_case] | opts[:insensitive]
46
46
  @cursor = -1
47
47
  match = nil
48
48
  begin
@@ -52,7 +52,7 @@ module Cannonbol
52
52
  @success_blocks = []
53
53
  @ignore_case = ignore_case
54
54
  match = pattern._match?(self)
55
- break if !match and anchor
55
+ break if !match and anchor
56
56
  end
57
57
  rescue MatchFailed
58
58
  end
@@ -69,17 +69,17 @@ module Cannonbol
69
69
  end
70
70
  match
71
71
  end
72
-
72
+
73
73
  def capture(name, value)
74
74
  @captures[name.to_sym] = value if name
75
75
  value
76
76
  end
77
-
78
-
77
+
78
+
79
79
  def remaining_string
80
80
  @string[@cursor..-1]
81
81
  end
82
-
82
+
83
83
  def push(length, &success_block)
84
84
  thread_state = [@starting_character, @cursor, @success_blocks.dup, @ignore_case]
85
85
  @starting_character ||= @cursor
@@ -87,59 +87,71 @@ module Cannonbol
87
87
  @success_blocks << success_block if success_block
88
88
  thread_state
89
89
  end
90
-
90
+
91
91
  def pull(thread_state)
92
92
  @starting_character, @cursor, @success_blocks, @ignore_case = thread_state if thread_state
93
93
  nil
94
94
  end
95
-
95
+
96
96
  end
97
-
97
+
98
98
  module Operators
99
-
99
+
100
100
  def _match?(needle, *args, &block)
101
101
  return if needle.match_failed
102
102
  __match?(needle, *args, &block)
103
103
  end
104
-
105
- def match?(s, opts = {}, &match_block)
104
+
105
+ def matches?(s, opts = {}, &match_block)
106
106
  Needle.new(s).thread(self, opts, &match_block)
107
107
  end
108
-
108
+
109
109
  def |(pattern)
110
110
  Choose.new(self, pattern)
111
111
  end
112
-
112
+
113
113
  def &(pattern)
114
114
  Concat.new(self, pattern)
115
115
  end
116
-
117
- def -@
116
+
117
+ def insensitive
118
118
  CaseSensitiveOff.new(self)
119
- end
119
+ end
120
120
 
121
121
  def capture?(opts = {}, &block)
122
122
  OnSuccess.new(self, opts, &block)
123
123
  end
124
-
124
+
125
125
  def capture!(opts = {}, &block)
126
126
  OnMatch.new(self, opts, &block)
127
127
  end
128
-
128
+
129
+ def self.included(base)
130
+ base.alias_method :match?, :matches? unless base.method_defined? :match?
131
+ base.alias_method :-@, :insensitive unless base.method_defined? :-@
132
+ end
133
+ end
134
+
135
+ module CompatibilityAdapter
136
+ def self.included(base)
137
+ base.alias_method :match?, :matches?
138
+ base.alias_method :-@, :insensitive
139
+ end
129
140
  end
130
-
131
- class Pattern
132
-
141
+
142
+ class Pattern
143
+
133
144
  include Operators
134
-
145
+
146
+
135
147
  def __match?(needle)
136
148
  []
137
149
  end
138
-
150
+
139
151
  end
140
-
152
+
141
153
  class Choose < Pattern
142
-
154
+
143
155
  def __match?(needle, i = 0, s = [])
144
156
  while i < @params.length
145
157
  s = @params[i]._match?(needle, *s)
@@ -149,15 +161,15 @@ module Cannonbol
149
161
  end
150
162
  nil
151
163
  end
152
-
164
+
153
165
  def initialize(p1, p2)
154
166
  @params = [p1, p2]
155
167
  end
156
-
168
+
157
169
  end
158
-
170
+
159
171
  class Concat < Pattern
160
-
172
+
161
173
  def __match?(needle, i = 0, s = [])
162
174
  while i < @params.length and i >= 0
163
175
  s[i] = @params[i]._match?(needle, *(s[i] || []))
@@ -165,19 +177,19 @@ module Cannonbol
165
177
  end
166
178
  [i-1, s] if i == @params.length
167
179
  end
168
-
180
+
169
181
  def initialize(p1, p2)
170
182
  @params = [p1, p2]
171
183
  end
172
-
184
+
173
185
  end
174
-
186
+
175
187
  class CaseSensitiveOff < Pattern
176
-
188
+
177
189
  def initialize(pattern)
178
190
  @pattern = pattern
179
- end
180
-
191
+ end
192
+
181
193
  def __match?(needle, s=[])
182
194
  ignore_case = needle.ignore_case
183
195
  needle.ignore_case = true
@@ -185,24 +197,24 @@ module Cannonbol
185
197
  needle.ignore_case = ignore_case
186
198
  return [s] if s
187
199
  end
188
-
200
+
189
201
  end
190
-
202
+
191
203
  class OnSuccess < Pattern
192
-
204
+
193
205
  def initialize(pattern, opts, &block)
194
206
  if opts.class == Hash
195
207
  if opts.first
196
208
  @capture_name = opts.first.first
197
209
  @initial_capture_value = opts.first.last
198
- end
210
+ end
199
211
  else
200
212
  @capture_name = opts
201
213
  end
202
214
  @pattern = pattern
203
215
  @block = block
204
216
  end
205
-
217
+
206
218
  def __match?(needle, thread_state = nil, starting_cursor = nil, s=[])
207
219
  needle.pull(thread_state)
208
220
  starting_cursor ||= needle.cursor
@@ -210,9 +222,9 @@ module Cannonbol
210
222
  ending_cursor = needle.cursor-1
211
223
  push = needle.push(0) do
212
224
  match_string = MatchString.new(needle.string, starting_cursor, ending_cursor, needle.captures)
213
- capture_value = @capture_name && (needle.captures.has_key?(@capture_name) ? needle.captures[@capture_name] : @initial_capture_value)
225
+ capture_value = @capture_name && (needle.captures.has_key?(@capture_name) ? needle.captures[@capture_name] : @initial_capture_value)
214
226
  if @block
215
- match_string = @block.call(match_string, ending_cursor+1, capture_value)
227
+ match_string = @block.call(match_string, ending_cursor+1, capture_value)
216
228
  elsif capture_value.class == Array
217
229
  match_string = capture_value + [match_string]
218
230
  end
@@ -221,38 +233,38 @@ module Cannonbol
221
233
  [ push, starting_cursor, s ]
222
234
  end
223
235
  end
224
-
236
+
225
237
  end
226
-
238
+
227
239
  class OnMatch < OnSuccess
228
-
240
+
229
241
  def __match?(needle, starting_cursor = nil, s=[])
230
242
  starting_cursor ||= needle.cursor
231
243
  if s = @pattern._match?(needle, *s)
232
244
  match_string = MatchString.new(needle.string, starting_cursor, needle.cursor-1, needle.captures)
233
- capture_value = @capture_name && (needle.captures.has_key?(@capture_name) ? needle.captures[@capture_name] : @initial_capture_value)
245
+ capture_value = @capture_name && (needle.captures.has_key?(@capture_name) ? needle.captures[@capture_name] : @initial_capture_value)
234
246
  match_string = @block.call(match_string, needle.cursor, capture_value) if @block
235
247
  needle.capture(@capture_name, match_string)
236
248
  [starting_cursor, s]
237
249
  end
238
250
  end
239
-
251
+
240
252
  end
241
-
253
+
242
254
  class Match < Pattern
243
-
255
+
244
256
  def initialize(sub_pattern_or_name = nil, &block)
245
257
  if block
246
258
  @block = block
247
259
  elsif sub_pattern_or_name and sub_pattern_or_name.class == Symbol
248
260
  @name = sub_pattern_or_name
249
261
  elsif sub_pattern_or_name and sub_pattern_or_name.respond_to? "_match?"
250
- @pattern = sub_pattern_or_name
262
+ @pattern = sub_pattern_or_name
251
263
  elsif sub_pattern_or_name and sub_pattern_or_name.respond_to? "to_s"
252
264
  @pattern = sub_pattern_or_name.to_s
253
265
  end
254
- end
255
-
266
+ end
267
+
256
268
  def __match?(needle, pattern = nil, s = [])
257
269
  pattern ||= if @block
258
270
  @block.call
@@ -265,66 +277,66 @@ module Cannonbol
265
277
  s = pattern._match?(needle, *s)
266
278
  needle.captures = needle.captures.merge(existing_captures)
267
279
  [pattern, s] if s
268
- end
269
-
280
+ end
281
+
270
282
  end
271
-
283
+
272
284
  class Rem < Pattern
273
-
285
+
274
286
  def __match?(needle, thread_state = nil)
275
287
  if thread_state
276
288
  needle_pull(thread_state)
277
289
  else
278
290
  [needle.push(needle.string.length-needle.cursor)]
279
- end
291
+ end
280
292
  end
281
-
293
+
282
294
  end
283
-
295
+
284
296
  class Arb < Pattern
285
-
297
+
286
298
  def __match?(needle, match_length = 0, thread_state = nil)
287
299
  needle.pull(thread_state)
288
- if needle.remaining_string.length >= match_length
300
+ if needle.remaining_string.length >= match_length
289
301
  thread_state = needle.push(match_length)
290
302
  match_length += 1
291
303
  [match_length, thread_state]
292
304
  end
293
305
  end
294
-
306
+
295
307
  end
296
-
308
+
297
309
  class ParameterizedPattern < Pattern
298
-
310
+
299
311
  def initialize(opts = nil, &block)
300
312
  if opts.class == Hash
301
313
  if opts.first
302
314
  @param_name = opts.first.first
303
315
  @initial_param_value = opts.first.last
304
- end
316
+ end
305
317
  else
306
318
  @initial_param_value = opts
307
319
  end
308
320
  @block = block
309
321
  end
310
-
322
+
311
323
  def self.parameter(name, &post_processor)
312
324
  @post_processor = post_processor
313
325
  define_method(name) do |needle|
314
326
  value = (@param_name && needle.captures.has_key?(@param_name)) ? needle.captures[@param_name] : @initial_param_value
315
327
  value = @block.call(value) if @block
316
- needle.capture(@param_name, value)
328
+ needle.capture(@param_name, value)
317
329
  value = post_processor.call(value) if @post_processor
318
330
  value
319
331
  end
320
332
  end
321
-
333
+
322
334
  end
323
-
335
+
324
336
  class Len < ParameterizedPattern
325
-
337
+
326
338
  parameter :len
327
-
339
+
328
340
  def __match?(needle, thread_state = nil)
329
341
 
330
342
  if thread_state
@@ -333,66 +345,66 @@ module Cannonbol
333
345
  len_temp = len(needle)
334
346
  [needle.push(len_temp)] if needle.remaining_string.length >= len_temp
335
347
  end
336
-
348
+
337
349
  end
338
-
350
+
339
351
  end
340
-
352
+
341
353
  class Pos < ParameterizedPattern
342
-
354
+
343
355
  parameter :pos
344
-
356
+
345
357
  def __match?(needle, matched = nil)
346
358
  return [true] if needle.cursor == pos(needle) and !matched
347
- end
348
-
349
- end
350
-
359
+ end
360
+
361
+ end
362
+
351
363
  class RPos < ParameterizedPattern
352
-
364
+
353
365
  parameter :pos
354
-
366
+
355
367
  def __match?(needle, matched = nil)
356
368
  return [true] if needle.string.length-needle.cursor == pos(needle) and !matched
357
- end
358
-
369
+ end
370
+
359
371
  end
360
-
372
+
361
373
  class Tab < ParameterizedPattern
362
-
374
+
363
375
  parameter :pos
364
-
376
+
365
377
  def __match?(needle, thread_state = nil)
366
-
378
+
367
379
  if thread_state
368
380
  needle.pull(thread_state)
369
381
  else
370
382
  len = pos(needle) - needle.cursor
371
- [needle.push(len)] if len >= 0 and needle.remaining_string.length >= len
383
+ [needle.push(len)] if len >= 0 and needle.remaining_string.length >= len
372
384
  end
373
385
  end
374
-
386
+
375
387
  end
376
-
388
+
377
389
  class RTab < ParameterizedPattern
378
-
390
+
379
391
  parameter :pos
380
-
392
+
381
393
  def __match?(needle, thread_state = nil)
382
394
  if thread_state
383
395
  needle.pull(thread_state)
384
396
  else
385
- len = (needle.remaining_string.length - pos(needle))
397
+ len = (needle.remaining_string.length - pos(needle))
386
398
  [needle.push(len)] if len >= 0 and needle.remaining_string.length >= len
387
399
  end
388
400
  end
389
-
401
+
390
402
  end
391
-
403
+
392
404
  class Any < ParameterizedPattern
393
-
405
+
394
406
  parameter :chars, &:split
395
-
407
+
396
408
  def __match?(needle, thread_state = nil)
397
409
  if thread_state
398
410
  needle.pull(thread_state)
@@ -400,13 +412,13 @@ module Cannonbol
400
412
  [needle.push(1)]
401
413
  end
402
414
  end
403
-
415
+
404
416
  end
405
-
417
+
406
418
  class NotAny < ParameterizedPattern
407
-
419
+
408
420
  parameter :chars, &:split
409
-
421
+
410
422
  def __match?(needle, thread_state = nil)
411
423
  if thread_state
412
424
  needle.pull(thread_state)
@@ -414,34 +426,34 @@ module Cannonbol
414
426
  [needle.push(1)]
415
427
  end
416
428
  end
417
-
418
- end
419
-
429
+
430
+ end
431
+
420
432
  class Span < ParameterizedPattern
421
-
433
+
422
434
  parameter :chars, &:split
423
-
435
+
424
436
  def __match?(needle, match_length = nil, thread_state = nil)
425
437
  unless match_length
426
438
  the_chars, match_length = chars(needle), 0
427
439
  while needle.remaining_string.length > match_length and the_chars.include? needle.remaining_string[match_length..match_length]
428
440
  match_length += 1
429
- end
441
+ end
430
442
  end
431
443
  needle.pull(thread_state)
432
- if match_length > 0
444
+ if match_length > 0
433
445
  thread_state = needle.push(match_length)
434
446
  match_length -= 1
435
447
  [match_length, thread_state]
436
448
  end
437
449
  end
438
-
450
+
439
451
  end
440
-
452
+
441
453
  class Break < ParameterizedPattern
442
-
454
+
443
455
  parameter :chars, &:split
444
-
456
+
445
457
  def __match?(needle, thread_state = nil)
446
458
  if thread_state
447
459
  needle.pull(thread_state)
@@ -449,31 +461,31 @@ module Cannonbol
449
461
  the_chars, len = chars(needle), 0
450
462
  while needle.remaining_string.length > len and !(the_chars.include? needle.remaining_string[len..len])
451
463
  len += 1
452
- end
464
+ end
453
465
  [needle.push(len)]
454
- end
455
- end
456
-
457
- end
466
+ end
467
+ end
468
+
469
+ end
470
+
458
471
 
459
-
460
472
  class BreakX < ParameterizedPattern
461
-
473
+
462
474
  parameter :chars, &:split
463
-
475
+
464
476
  def __match?(needle, len = 0, thread_state = nil)
465
477
  needle.pull(thread_state)
466
478
  the_chars = chars(needle)
467
479
  while needle.remaining_string.length > len and !(the_chars.include? needle.remaining_string[len..len])
468
480
  len += 1
469
- end
481
+ end
470
482
  [len+1, needle.push(len)] if needle.remaining_string.length >= len
471
- end
472
-
473
- end
474
-
483
+ end
484
+
485
+ end
486
+
475
487
  class Arbno < Match
476
-
488
+
477
489
  def __match?(needle, pattern = nil, s = [[]])
478
490
  return if s.length == 0
479
491
  if pattern
@@ -491,27 +503,27 @@ module Cannonbol
491
503
  end
492
504
  end
493
505
  [pattern, s]
494
- end
495
-
506
+ end
507
+
496
508
  end
497
-
509
+
498
510
  class FailPat < Pattern
499
-
511
+
500
512
  def __match?(needle)
501
- end
502
-
513
+ end
514
+
503
515
  end
504
-
516
+
505
517
  class Abort < Pattern
506
-
518
+
507
519
  def __match?(needle)
508
520
  raise MatchFailed
509
- end
510
-
521
+ end
522
+
511
523
  end
512
-
524
+
513
525
  class Fence < Match
514
-
526
+
515
527
  def __match?(needle, on_backtrack = nil)
516
528
  if on_backtrack == :fail_match
517
529
  needle.match_failed = true
@@ -528,39 +540,39 @@ module Cannonbol
528
540
  return [:fail_match]
529
541
  end
530
542
  return [:return_nil] if pattern._match?(needle)
531
- end
532
-
533
- end
534
-
543
+ end
544
+
545
+ end
546
+
535
547
  class Succeed < Pattern
536
548
  def _match?(needle, thread_state = nil)
537
549
  needle.pull(thread_state)
538
550
  [needle.push(0)]
539
551
  end
540
552
  end
541
-
542
553
  end
543
554
 
544
555
  class String
545
-
556
+
546
557
  include Cannonbol::Operators
547
-
558
+
548
559
  def __match?(needle, thread_state = nil)
560
+
549
561
  if thread_state
550
562
  needle.pull(thread_state)
551
- elsif self.length == 0 or
552
- (!needle.ignore_case and needle.remaining_string[0..self.length-1] == self) or
563
+ elsif self.length == 0 or
564
+ (!needle.ignore_case and needle.remaining_string[0..self.length-1] == self) or
553
565
  (needle.ignore_case and needle.remaining_string[0..self.length-1].upcase == self.upcase)
554
566
  [needle.push(self.length)]
555
567
  end
556
568
  end
557
-
569
+
558
570
  end
559
571
 
560
572
  class Regexp
561
-
573
+
562
574
  include Cannonbol::Operators
563
-
575
+
564
576
  def __match?(needle, thread_state = nil)
565
577
  if RUBY_ENGINE == 'opal'
566
578
  options = ""
@@ -577,102 +589,103 @@ class Regexp
577
589
  [needle.push(m[0].length)]
578
590
  end
579
591
  end
580
-
592
+
581
593
  end
582
594
 
595
+
583
596
  if RUBY_ENGINE == 'opal'
584
-
597
+
585
598
  class Proc
586
-
599
+
587
600
  def parameters
588
601
  /.*function[^(]*\(([^)]*)\)/.match(`#{self}.toString()`)[1].split(",").collect { |param| [:req, param.strip.to_sym]}
589
602
  end
590
-
591
- end
592
-
603
+
604
+ end
605
+
593
606
  end
594
607
 
595
608
  module Enumerable
596
-
609
+
597
610
  def match_any
598
- if self.first
611
+ if self.first
599
612
  self[1..-1].inject(self.first) { |memo, item| memo | item }
600
613
  else
601
614
  FAIL
602
615
  end
603
- end
604
-
616
+ end
617
+
605
618
  def match_all
606
619
  self.inject("") { |memo, item| memo & item }
607
- end
608
-
620
+ end
621
+
609
622
  end
610
-
623
+
611
624
 
612
625
  class Object
613
-
626
+
614
627
  REM = Cannonbol::Rem.new
615
-
628
+
616
629
  ARB = Cannonbol::Arb.new
617
-
630
+
618
631
  FAIL = Cannonbol::FailPat.new
619
-
632
+
620
633
  ABORT = Cannonbol::Abort.new
621
-
634
+
622
635
  FENCE = Cannonbol::Fence.new
623
-
636
+
624
637
  SUCCEED = Cannonbol::Succeed.new
625
-
638
+
626
639
  def LEN(p={}, &block)
627
640
  Cannonbol::Len.new(p, &block)
628
641
  end
629
-
642
+
630
643
  def POS(p=nil, &block)
631
644
  Cannonbol::Pos.new(p, &block)
632
- end
633
-
645
+ end
646
+
634
647
  def RPOS(p=nil, &block)
635
648
  Cannonbol::RPos.new(p, &block)
636
- end
637
-
649
+ end
650
+
638
651
  def TAB(p=nil, &block)
639
652
  Cannonbol::Tab.new(p, &block)
640
653
  end
641
-
654
+
642
655
  def RTAB(p=nil, &block)
643
656
  Cannonbol::RTab.new(p, &block)
644
657
  end
645
-
658
+
646
659
  def ANY(p=nil, &block)
647
660
  Cannonbol::Any.new(p, &block)
648
- end
649
-
661
+ end
662
+
650
663
  def NOTANY(p=nil, &block)
651
664
  Cannonbol::NotAny.new(p, &block)
652
665
  end
653
-
666
+
654
667
  def SPAN(p=nil, &block)
655
668
  Cannonbol::Span.new(p, &block)
656
669
  end
657
-
670
+
658
671
  def BREAK(p=nil, &block)
659
672
  Cannonbol::Break.new(p, &block)
660
- end
661
-
673
+ end
674
+
662
675
  def BREAKX(p=nil, &block)
663
676
  Cannonbol::BreakX.new(p, &block)
664
- end
665
-
677
+ end
678
+
666
679
  def MATCH(p=nil, &block)
667
680
  Cannonbol::Match.new(p, &block)
668
- end
669
-
681
+ end
682
+
670
683
  def ARBNO(p=nil, &block)
671
684
  Cannonbol::Arbno.new(p, &block)
672
- end
673
-
685
+ end
686
+
674
687
  def FENCE(p=nil, &block)
675
688
  Cannonbol::Fence.new(p, &block)
676
689
  end
677
-
678
- end
690
+
691
+ end