sexp_processor 4.14.0 → 4.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/History.rdoc +46 -0
- data/Rakefile +2 -0
- data/lib/pt_testcase.rb +9 -4
- data/lib/sexp.rb +19 -9
- data/lib/sexp_matcher.rb +7 -9
- data/lib/sexp_processor.rb +1 -1
- data/lib/strict_sexp.rb +25 -3
- data/test/test_sexp.rb +23 -1
- data.tar.gz.sig +0 -0
- metadata +20 -17
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07ef3f53aa7901804e1d92cba1d04eb0ad8631c26a021653e4855b15da3566fc
|
4
|
+
data.tar.gz: e35d6224928d2f29504fa1734dcb62c6f5c984511dffac7a0538c5b163b7f6a5
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 876af156dcbe63d56c35796dc12ae32a2447640f1fc45b47286b6197dafb733512913028c127d45517fd6e0915d7182c767ed162823406ced6402336f852280b
|
7
|
+
data.tar.gz: a22bec5d094bfbd59ef3b92cb2091d0279be18a2302bb88bade6c8c382d40071b404c897b137cbf7b592222b7f75407058e08282e423ce60bbcfa834e1ef58fc
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,49 @@
|
|
1
|
+
=== 4.16.0 / 2021-10-27
|
2
|
+
|
3
|
+
* 4 minor enhancements:
|
4
|
+
|
5
|
+
* Added Sexp#value (pushed up from ruby_parser).
|
6
|
+
* Aliased Sexp#concat to #_concat and use that so it can be overridden.
|
7
|
+
* Cache the #hash result.
|
8
|
+
* StrictSexp mode (4) now covers concat.
|
9
|
+
|
10
|
+
* 3 bug fixes:
|
11
|
+
|
12
|
+
* Fix some doco on each_sexp to clarify that it is not recursive.
|
13
|
+
* Fixed a bug calling enum_for when using each_of_type w/ no block.
|
14
|
+
* Minor fixes to pt_testcase.rb for custom timeouts and better error handling.
|
15
|
+
|
16
|
+
=== 4.15.3 / 2021-05-15
|
17
|
+
|
18
|
+
* 1 minor enhancement:
|
19
|
+
|
20
|
+
* Added 3.0 to pt_testcase.rb
|
21
|
+
|
22
|
+
=== 4.15.2 / 2021-01-10
|
23
|
+
|
24
|
+
* 1 bug fix:
|
25
|
+
|
26
|
+
* Bumped ruby version to include < 4 (trunk).
|
27
|
+
|
28
|
+
=== 4.15.1 / 2020-08-31
|
29
|
+
|
30
|
+
* 1 bug fix:
|
31
|
+
|
32
|
+
* Bumped ruby version to include 3.0 (trunk).
|
33
|
+
|
34
|
+
=== 4.15.0 / 2020-06-09
|
35
|
+
|
36
|
+
* 1 minor enhancement:
|
37
|
+
|
38
|
+
* Added `child` and `include` to Sexp::Matcher.parse language.
|
39
|
+
|
40
|
+
=== 4.14.1 / 2020-02-09
|
41
|
+
|
42
|
+
* 2 bug fixes:
|
43
|
+
|
44
|
+
* Declared support for ruby 2.2+ to gemspec.
|
45
|
+
* Fixed alias for `not?` to `-` for ruby <= 2.4. (nard-tech).
|
46
|
+
|
1
47
|
=== 4.14.0 / 2020-02-06
|
2
48
|
|
3
49
|
* 4 minor enhancements:
|
data/Rakefile
CHANGED
data/lib/pt_testcase.rb
CHANGED
@@ -77,7 +77,7 @@ class ParseTreeTestCase < Minitest::Test
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def self.add_19tests name, hash
|
80
|
-
add_tests "#{name}
|
80
|
+
add_tests "#{name}__19_20_21_22_23_24_25_26_27_30", hash # HACK?
|
81
81
|
end
|
82
82
|
|
83
83
|
def self.add_19edgecases ruby, sexp, cases
|
@@ -102,7 +102,7 @@ class ParseTreeTestCase < Minitest::Test
|
|
102
102
|
testcases[verbose][klass] = testcases[nonverbose][klass]
|
103
103
|
end
|
104
104
|
|
105
|
-
VER_RE = "(1[89]|2[
|
105
|
+
VER_RE = "(1[89]|2[01234567]|3[0])"
|
106
106
|
|
107
107
|
def self.generate_test klass, node, data, input_name, output_name
|
108
108
|
klass.send :define_method, "test_#{node}" do
|
@@ -150,7 +150,8 @@ class ParseTreeTestCase < Minitest::Test
|
|
150
150
|
|
151
151
|
before_process_hook klass, node, data, input_name, output_name
|
152
152
|
refute_nil data[input_name], "testcase does not exist?"
|
153
|
-
|
153
|
+
timeout = (ENV["RP_TIMEOUT"] || 10).to_i
|
154
|
+
@result = processor.process input, "(string)", timeout
|
154
155
|
assert_equal(expected, @result,
|
155
156
|
"failed on input: #{data[input_name].inspect}")
|
156
157
|
after_process_hook klass, node, data, input_name, output_name
|
@@ -158,7 +159,11 @@ class ParseTreeTestCase < Minitest::Test
|
|
158
159
|
extra_input.each do |extra|
|
159
160
|
processor.process(extra)
|
160
161
|
end
|
161
|
-
extra = processor.extra_methods
|
162
|
+
extra = if processor.respond_to?(:extra_methods) then
|
163
|
+
processor.extra_methods
|
164
|
+
else
|
165
|
+
[]
|
166
|
+
end
|
162
167
|
assert_equal extra_expected, extra
|
163
168
|
end
|
164
169
|
end
|
data/lib/sexp.rb
CHANGED
@@ -31,13 +31,15 @@ class Sexp < Array # ZenTest FULL
|
|
31
31
|
super(args)
|
32
32
|
end
|
33
33
|
|
34
|
+
alias _concat concat
|
35
|
+
|
34
36
|
##
|
35
37
|
# Creates a new Sexp from Array +a+.
|
36
38
|
|
37
39
|
def self.from_array a
|
38
40
|
ary = Array === a ? a : [a]
|
39
41
|
|
40
|
-
self.new.
|
42
|
+
self.new._concat(ary.map { |x|
|
41
43
|
case x
|
42
44
|
when Sexp
|
43
45
|
x
|
@@ -54,7 +56,7 @@ class Sexp < Array # ZenTest FULL
|
|
54
56
|
# same +file+, +line+, and +comment+ as self.
|
55
57
|
|
56
58
|
def new(*body)
|
57
|
-
r = self.class.new.
|
59
|
+
r = self.class.new._concat(body) # ensures a sexp from map
|
58
60
|
r.file = self.file if self.file
|
59
61
|
r.line = self.line if self.line
|
60
62
|
r.comments = self.comments if self.comments
|
@@ -62,7 +64,7 @@ class Sexp < Array # ZenTest FULL
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def map &blk # :nodoc:
|
65
|
-
self.new.
|
67
|
+
self.new._concat(super(&blk)) # ensures a sexp from map
|
66
68
|
end
|
67
69
|
|
68
70
|
def == obj # :nodoc:
|
@@ -74,7 +76,7 @@ class Sexp < Array # ZenTest FULL
|
|
74
76
|
end
|
75
77
|
|
76
78
|
def hash
|
77
|
-
[self.class, *self].hash
|
79
|
+
@hash ||= [self.class, *self].hash
|
78
80
|
end
|
79
81
|
|
80
82
|
##
|
@@ -93,7 +95,7 @@ class Sexp < Array # ZenTest FULL
|
|
93
95
|
end
|
94
96
|
|
95
97
|
##
|
96
|
-
# Recursively enumerates the sexp yielding to +block+ for every
|
98
|
+
# Recursively enumerates the sexp yielding to +block+ for every sub-Sexp.
|
97
99
|
#
|
98
100
|
# Returning :skip will stop traversing that subtree:
|
99
101
|
#
|
@@ -122,7 +124,7 @@ class Sexp < Array # ZenTest FULL
|
|
122
124
|
# Enumeratates the sexp yielding to +b+ when the node_type == +t+.
|
123
125
|
|
124
126
|
def each_of_type t, &b
|
125
|
-
return enum_for(:each_of_type) unless block_given?
|
127
|
+
return enum_for(:each_of_type, t) unless block_given?
|
126
128
|
|
127
129
|
each_sexp do | sexp |
|
128
130
|
sexp.each_of_type(t, &b)
|
@@ -131,7 +133,7 @@ class Sexp < Array # ZenTest FULL
|
|
131
133
|
end
|
132
134
|
|
133
135
|
##
|
134
|
-
#
|
136
|
+
# Enumerates all sub-sexps skipping non-Sexp elements.
|
135
137
|
|
136
138
|
def each_sexp
|
137
139
|
return enum_for(:each_sexp) unless block_given?
|
@@ -289,11 +291,11 @@ class Sexp < Array # ZenTest FULL
|
|
289
291
|
# the values without the node type.
|
290
292
|
|
291
293
|
def sexp_body from = 1
|
292
|
-
self.new.
|
294
|
+
self.new._concat(self[from..-1] || [])
|
293
295
|
end
|
294
296
|
|
295
297
|
##
|
296
|
-
#
|
298
|
+
# Sets the Sexp body to new content.
|
297
299
|
|
298
300
|
def sexp_body= v
|
299
301
|
self[1..-1] = v
|
@@ -362,6 +364,14 @@ class Sexp < Array # ZenTest FULL
|
|
362
364
|
end
|
363
365
|
|
364
366
|
alias to_s inspect # :nodoc:
|
367
|
+
|
368
|
+
##
|
369
|
+
# Return the value (last item) of a single element sexp (eg `s(:lit, 42)`).
|
370
|
+
|
371
|
+
def value
|
372
|
+
raise "multi item sexp" if size > 2
|
373
|
+
last
|
374
|
+
end
|
365
375
|
end
|
366
376
|
|
367
377
|
##
|
data/lib/sexp_matcher.rb
CHANGED
@@ -156,8 +156,9 @@ class Sexp #:nodoc:
|
|
156
156
|
Not.new arg
|
157
157
|
end
|
158
158
|
|
159
|
-
|
160
|
-
|
159
|
+
class << self
|
160
|
+
alias - not?
|
161
|
+
end
|
161
162
|
|
162
163
|
# TODO: add Sibling factory method?
|
163
164
|
|
@@ -454,7 +455,7 @@ class Sexp #:nodoc:
|
|
454
455
|
# | NAME:name => name.to_sym
|
455
456
|
# UP_NAME: /[A-Z]\w*/
|
456
457
|
# NAME : /:?[\w?!=~-]+/
|
457
|
-
# CMD :
|
458
|
+
# CMD : t | k | m | atom | not? | - | any | child | include
|
458
459
|
|
459
460
|
def parse_sexp
|
460
461
|
token = next_token
|
@@ -504,7 +505,7 @@ class Sexp #:nodoc:
|
|
504
505
|
##
|
505
506
|
# A collection of allowed commands to convert into matchers.
|
506
507
|
|
507
|
-
ALLOWED = [:t, :m, :k, :atom, :not?, :-, :any].freeze
|
508
|
+
ALLOWED = [:t, :m, :k, :atom, :not?, :-, :any, :child, :include].freeze
|
508
509
|
|
509
510
|
##
|
510
511
|
# Parses a balanced command. A command is denoted by square
|
@@ -759,11 +760,8 @@ class Sexp #:nodoc:
|
|
759
760
|
# +child+.
|
760
761
|
|
761
762
|
def satisfy? o
|
762
|
-
|
763
|
-
|
764
|
-
elsif o.kind_of? Sexp
|
765
|
-
o.search_each(child).any?
|
766
|
-
end
|
763
|
+
child.satisfy?(o) ||
|
764
|
+
(o.kind_of?(Sexp) && o.search_each(child).any?)
|
767
765
|
end
|
768
766
|
|
769
767
|
def == o # :nodoc:
|
data/lib/sexp_processor.rb
CHANGED
data/lib/strict_sexp.rb
CHANGED
@@ -36,6 +36,7 @@
|
|
36
36
|
# 4 = sexp << => no
|
37
37
|
|
38
38
|
class Sexp
|
39
|
+
# alias :_concat :concat in sexp.rb so we have access to the original
|
39
40
|
alias :safe_idx :[]
|
40
41
|
alias :safe_asgn :[]=
|
41
42
|
alias :sexp_type= :sexp_type=
|
@@ -43,9 +44,10 @@ class Sexp
|
|
43
44
|
alias :shift :shift
|
44
45
|
|
45
46
|
def self.nuke_method name, level
|
47
|
+
return unless __strict >= level
|
46
48
|
define_method name do |*args|
|
47
49
|
raise "no mutation allowed on sexps: %s.%s %s" % [self, name, args]
|
48
|
-
end
|
50
|
+
end
|
49
51
|
end
|
50
52
|
|
51
53
|
def self.__strict
|
@@ -87,7 +89,7 @@ class Sexp
|
|
87
89
|
|
88
90
|
nuke_method :collect!, 4
|
89
91
|
nuke_method :compact!, 4
|
90
|
-
|
92
|
+
nuke_method :concat, 4 # HACK: using self.class.new.concat(...) for speed
|
91
93
|
nuke_method :flatten!, 4
|
92
94
|
nuke_method :map!, 4
|
93
95
|
nuke_method :pop, 4
|
@@ -111,7 +113,7 @@ class Sexp
|
|
111
113
|
end
|
112
114
|
|
113
115
|
def sexp_body from = 1
|
114
|
-
self.new.
|
116
|
+
self.new._concat(safe_idx(from..-1) || [])
|
115
117
|
end
|
116
118
|
|
117
119
|
def sexp_type= v
|
@@ -123,4 +125,24 @@ class Sexp
|
|
123
125
|
end
|
124
126
|
end unless Sexp.new.respond_to? :safe_asgn if ENV["STRICT_SEXP"]
|
125
127
|
|
128
|
+
if ENV["SP_DEBUG"] && !ENV["STRICT_SEXP"] then
|
129
|
+
class Sexp
|
130
|
+
mutators = %i[
|
131
|
+
[]= clear collect! compact! concat delete delete_at
|
132
|
+
delete_if drop drop_while fill flatten! replace insert
|
133
|
+
keep_if map! pop push reject! reverse! rotate! select!
|
134
|
+
shift shuffle! slice! sort! sort_by! transpose uniq!
|
135
|
+
unshift
|
136
|
+
]
|
137
|
+
|
138
|
+
mutators.each do |method|
|
139
|
+
define_method method do |*|
|
140
|
+
warn "Sexp modified by %p at %s" % [__method__, caller.first] if
|
141
|
+
$VERBOSE or (defined?(@hash) and @hash)
|
142
|
+
super
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
126
148
|
# :startdoc:
|
data/test/test_sexp.rb
CHANGED
@@ -193,6 +193,12 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
193
193
|
assert_equal(3, count, "must find 3 a's in #{@sexp.inspect}")
|
194
194
|
end
|
195
195
|
|
196
|
+
def test_each_of_type_no_block
|
197
|
+
@sexp = s(:a, s(:b), s(:c), :d)
|
198
|
+
|
199
|
+
assert_equal [s(:b)], @sexp.each_of_type(:b).to_a
|
200
|
+
end
|
201
|
+
|
196
202
|
def test_equals2_array
|
197
203
|
refute_equal @sexp, [1, 2, 3] # Sexp == Array
|
198
204
|
assert_raises Minitest::Assertion do # Array == Sexp.
|
@@ -654,6 +660,18 @@ class TestSexp < SexpTestCase # ZenTest FULL
|
|
654
660
|
assert_equal DEEP_EXP, act.map { |k, _| k }
|
655
661
|
end
|
656
662
|
|
663
|
+
def test_deep_each_sexp_recursive
|
664
|
+
sexp = s(:array, s(:lit, 1), nil, 42, s(:array, s(:lit, 2)))
|
665
|
+
|
666
|
+
result = []
|
667
|
+
sexp.deep_each { |x| result << x.last if x.sexp_type == :lit }
|
668
|
+
assert_equal [1, 2], result
|
669
|
+
|
670
|
+
result = []
|
671
|
+
sexp.each_of_type(:lit) { |x| result << x.last }
|
672
|
+
assert_equal [1, 2], result
|
673
|
+
end
|
674
|
+
|
657
675
|
def test_deep_each_skip
|
658
676
|
exp = DEEP_EXP.first(3) + DEEP_EXP.last(4)
|
659
677
|
act = []
|
@@ -906,7 +924,7 @@ class TestChild < MatcherTestCase
|
|
906
924
|
end
|
907
925
|
|
908
926
|
def sexp
|
909
|
-
s(:x, s(:a))
|
927
|
+
s(:x, s(:b), s(:a))
|
910
928
|
end
|
911
929
|
|
912
930
|
def bad_sexp
|
@@ -926,6 +944,8 @@ class TestChild < MatcherTestCase
|
|
926
944
|
|
927
945
|
def test_satisfy_eh_by_child
|
928
946
|
assert_satisfy matcher, s(:a)
|
947
|
+
assert_satisfy matcher, sexp
|
948
|
+
refute_satisfy matcher, bad_sexp
|
929
949
|
end
|
930
950
|
end
|
931
951
|
|
@@ -1602,8 +1622,10 @@ class TestSexpMatcherParser < Minitest::Test
|
|
1602
1622
|
test_parse "not?", delay{ not?(m(/^_$/)) }, "[not? [m /^_$/]]"
|
1603
1623
|
test_parse "not2", delay{ -_ }, "[- _]"
|
1604
1624
|
test_parse "any", delay{ q(:a) | q(:b) }, "[any (a) (b)]"
|
1625
|
+
test_parse "child", delay{ child(q(:str, m(/woot/))) }, "[child (str [m /woot/])]"
|
1605
1626
|
|
1606
1627
|
test_parse "klass", delay{ q(:lit, k(Float)) }, "(lit [k Float])"
|
1628
|
+
test_parse "const", delay{ q(:const, :Float) }, "(const :Float)"
|
1607
1629
|
|
1608
1630
|
test_bad_parse "open_sexp", "(a"
|
1609
1631
|
test_bad_parse "closed_sexp", "a)"
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,18 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sexp_processor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.16.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Davis
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain:
|
11
11
|
- |
|
12
12
|
-----BEGIN CERTIFICATE-----
|
13
|
-
|
13
|
+
MIIDPjCCAiagAwIBAgIBBTANBgkqhkiG9w0BAQsFADBFMRMwEQYDVQQDDApyeWFu
|
14
14
|
ZC1ydWJ5MRkwFwYKCZImiZPyLGQBGRYJemVuc3BpZGVyMRMwEQYKCZImiZPyLGQB
|
15
|
-
|
15
|
+
GRYDY29tMB4XDTIwMTIyMjIwMzgzMFoXDTIxMTIyMjIwMzgzMFowRTETMBEGA1UE
|
16
16
|
AwwKcnlhbmQtcnVieTEZMBcGCgmSJomT8ixkARkWCXplbnNwaWRlcjETMBEGCgmS
|
17
17
|
JomT8ixkARkWA2NvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALda
|
18
18
|
b9DCgK+627gPJkB6XfjZ1itoOQvpqH1EXScSaba9/S2VF22VYQbXU1xQXL/WzCkx
|
@@ -22,14 +22,14 @@ cert_chain:
|
|
22
22
|
qhtV7HJxNKuPj/JFH0D2cswvzznE/a5FOYO68g+YCuFi5L8wZuuM8zzdwjrWHqSV
|
23
23
|
gBEfoTEGr7Zii72cx+sCAwEAAaM5MDcwCQYDVR0TBAIwADALBgNVHQ8EBAMCBLAw
|
24
24
|
HQYDVR0OBBYEFEfFe9md/r/tj/Wmwpy+MI8d9k/hMA0GCSqGSIb3DQEBCwUAA4IB
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
25
|
+
AQAE3XRm1YZcCVjAJy5yMZvTOFrS7B2SYErc+0QwmKYbHztTTDY2m5Bii+jhpuxh
|
26
|
+
H+ETcU1z8TUKLpsBUP4kUpIRowkVN1p/jKapV8T3Rbwq+VuYFe+GMKsf8wGZSecG
|
27
|
+
oMQ8DzzauZfbvhe2kDg7G9BBPU0wLQlY25rDcCy9bLnD7R0UK3ONqpwvsI5I7x5X
|
28
|
+
ZIMXR0a9/DG+55mawwdGzCQobDKiSNLK89KK7OcNTALKU0DfgdTkktdgKchzKHqZ
|
29
|
+
d/AHw/kcnU6iuMUoJEcGiJd4gVCTn1l3cDcIvxakGslCA88Jubw0Sqatan0TnC9g
|
30
|
+
KToW560QIey7SPfHWduzFJnV
|
31
31
|
-----END CERTIFICATE-----
|
32
|
-
date:
|
32
|
+
date: 2021-10-27 00:00:00.000000000 Z
|
33
33
|
dependencies:
|
34
34
|
- !ruby/object:Gem::Dependency
|
35
35
|
name: rdoc
|
@@ -57,14 +57,14 @@ dependencies:
|
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '3.
|
60
|
+
version: '3.22'
|
61
61
|
type: :development
|
62
62
|
prerelease: false
|
63
63
|
version_requirements: !ruby/object:Gem::Requirement
|
64
64
|
requirements:
|
65
65
|
- - "~>"
|
66
66
|
- !ruby/object:Gem::Version
|
67
|
-
version: '3.
|
67
|
+
version: '3.22'
|
68
68
|
description: |-
|
69
69
|
sexp_processor branches from ParseTree bringing all the generic sexp
|
70
70
|
processing tools with it. Sexp, SexpProcessor, Environment, etc... all
|
@@ -98,7 +98,7 @@ licenses:
|
|
98
98
|
- MIT
|
99
99
|
metadata:
|
100
100
|
homepage_uri: https://github.com/seattlerb/sexp_processor
|
101
|
-
post_install_message:
|
101
|
+
post_install_message:
|
102
102
|
rdoc_options:
|
103
103
|
- "--main"
|
104
104
|
- README.rdoc
|
@@ -108,15 +108,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
108
108
|
requirements:
|
109
109
|
- - ">="
|
110
110
|
- !ruby/object:Gem::Version
|
111
|
-
version: '
|
111
|
+
version: '2.1'
|
112
|
+
- - "<"
|
113
|
+
- !ruby/object:Gem::Version
|
114
|
+
version: '4'
|
112
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
116
|
requirements:
|
114
117
|
- - ">="
|
115
118
|
- !ruby/object:Gem::Version
|
116
119
|
version: '0'
|
117
120
|
requirements: []
|
118
|
-
rubygems_version: 3.
|
119
|
-
signing_key:
|
121
|
+
rubygems_version: 3.2.16
|
122
|
+
signing_key:
|
120
123
|
specification_version: 4
|
121
124
|
summary: sexp_processor branches from ParseTree bringing all the generic sexp processing
|
122
125
|
tools with it
|
metadata.gz.sig
CHANGED
Binary file
|