Array
Sexps are the basic storage mechanism of SexpProcessor. Sexps have a type (to be renamed node_type) which is the first element of the Sexp. The type is used by SexpProcessor to determine whom to dispatch the Sexp to for processing.
Creates a new Sexp from Array a.
# File lib/sexp.rb, line 27
27: def self.from_array(a)
28: ary = Array === a ? a : [a]
29:
30: result = self.new
31:
32: ary.each do |x|
33: case x
34: when Sexp
35: result << x
36: when Array
37: result << self.from_array(x)
38: else
39: result << x
40: end
41: end
42:
43: result
44: end
Create a new Sexp containing args.
# File lib/sexp.rb, line 20
20: def initialize(*args)
21: super(args)
22: end
Returns true if this Sexp’s pattern matches sexp.
# File lib/sexp.rb, line 57
57: def ===(sexp)
58: return nil unless Sexp === sexp
59: pattern = self # this is just for my brain
60:
61: return true if pattern == sexp
62:
63: sexp.each do |subset|
64: return true if pattern === subset
65: end
66:
67: return nil
68: end
Returns true if this Sexp matches pattern. (Opposite of #===.)
# File lib/sexp.rb, line 73
73: def =~(pattern)
74: return pattern === self
75: end
Returns true if the node_type is array or args.
REFACTOR: to TypedSexp - we only care when we have units.
# File lib/sexp.rb, line 82
82: def array_type?
83: type = self.first
84: @@array_types.include? type
85: end
Enumeratates the sexp yielding to b when the node_type == t.
# File lib/sexp.rb, line 94
94: def each_of_type(t, &b)
95: each do | elem |
96: if Sexp === elem then
97: elem.each_of_type(t, &b)
98: b.call(elem) if elem.first == t
99: end
100: end
101: end
Replaces all elements whose node_type is from with to. Used only for the most trivial of rewrites.
# File lib/sexp.rb, line 107
107: def find_and_replace_all(from, to)
108: each_with_index do | elem, index |
109: if Sexp === elem then
110: elem.find_and_replace_all(from, to)
111: else
112: self[index] = to if elem == from
113: end
114: end
115: end
# File lib/sexp.rb, line 144
144: def find_node name, delete = false
145: matches = find_nodes name
146:
147: case matches.size
148: when 0 then
149: nil
150: when 1 then
151: match = matches.first
152: delete match if delete
153: match
154: else
155: raise NoMethodError, "multiple nodes for #{name} were found in #{inspect}"
156: end
157: end
Find every node with type name.
# File lib/sexp.rb, line 162
162: def find_nodes name
163: find_all { | sexp | Sexp === sexp and sexp.first == name }
164: end
Replaces all Sexps matching pattern with Sexp repl.
# File lib/sexp.rb, line 120
120: def gsub(pattern, repl)
121: return repl if pattern == self
122:
123: new = self.map do |subset|
124: case subset
125: when Sexp then
126: subset.gsub(pattern, repl)
127: else
128: subset
129: end
130: end
131:
132: return Sexp.from_array(new)
133: end
If passed a line number, sets the line and returns self. Otherwise returns the line number. This allows you to do message cascades and still get the sexp back.
# File lib/sexp.rb, line 171
171: def line(n=nil)
172: if n then
173: @line = n
174: self
175: else
176: @line ||= nil
177: end
178: end
Returns the size of the sexp, flattened.
# File lib/sexp.rb, line 183
183: def mass
184: @mass ||= self.structure.flatten.size
185: end
Returns the node named node, deleting it if delete is true.
# File lib/sexp.rb, line 190
190: def method_missing meth, delete = false
191: find_node meth, delete
192: end
Returns the Sexp body, ie the values without the node type.
# File lib/sexp.rb, line 213
213: def sexp_body
214: self[1..1]
215: end
Returns the node type of the Sexp.
# File lib/sexp.rb, line 206
206: def sexp_type
207: first
208: end
Returns the bare bones structure of the sexp. s(:a, :b, s(:c, :d), :e) => s(:a, s(:c))
# File lib/sexp.rb, line 230
230: def structure
231: result = self.class.new
232: if Array === self.first then
233: result = self.first.structure
234: else
235: result << self.first
236: self.grep(Array).each do |subexp|
237: result << subexp.structure
238: end
239: end
240: result
241: end
Replaces the Sexp matching pattern with repl.
# File lib/sexp.rb, line 246
246: def sub(pattern, repl)
247: return repl.dup if pattern == self
248:
249: done = false
250:
251: new = self.map do |subset|
252: if done then
253: subset
254: else
255: case subset
256: when Sexp then
257: if pattern == subset then
258: done = true
259: repl.dup
260: elsif pattern === subset then
261: done = true
262: subset.sub pattern, repl
263: else
264: subset
265: end
266: else
267: subset
268: end
269: end
270: end
271:
272: return Sexp.from_array(new)
273: end
Disabled; run with --debug to generate this.
Generated with the Darkfish Rdoc Generator 1.1.6.