In Files

Parent

Sexp

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.

Attributes

comments[RW]
file[RW]
line[W]

Public Class Methods

from_array(a) click to toggle source

Creates a new Sexp from Array a.

# File lib/sexp.rb, line 27
def self.from_array(a)
  ary = Array === a ? a : [a]

  result = self.new

  ary.each do |x|
    case x
    when Sexp
      result << x
    when Array
      result << self.from_array(x)
    else
      result << x
    end
  end

  result
end
new(*args) click to toggle source

Create a new Sexp containing args.

# File lib/sexp.rb, line 20
def initialize(*args)
  super(args)
end

Public Instance Methods

===(sexp) click to toggle source

Returns true if this Sexp’s pattern matches sexp.

# File lib/sexp.rb, line 57
def ===(sexp)
  return nil unless Sexp === sexp
  pattern = self # this is just for my brain

  return true if pattern == sexp

  sexp.each do |subset|
    return true if pattern === subset
  end

  return nil
end
=~(pattern) click to toggle source

Returns true if this Sexp matches pattern. (Opposite of #===.)

# File lib/sexp.rb, line 73
def =~(pattern)
  return pattern === self
end
array_type?() click to toggle source

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
def array_type?
  type = self.first
  @@array_types.include? type
end
each_of_type(t, &b) click to toggle source

Enumeratates the sexp yielding to b when the node_type == t.

# File lib/sexp.rb, line 94
def each_of_type(t, &b)
  each do | elem |
    if Sexp === elem then
      elem.each_of_type(t, &b)
      b.call(elem) if elem.first == t
    end
  end
end
find_and_replace_all(from, to) click to toggle source

Replaces all elements whose node_type is from with to. Used only for the most trivial of rewrites.

# File lib/sexp.rb, line 107
def find_and_replace_all(from, to)
  each_with_index do | elem, index |
    if Sexp === elem then
      elem.find_and_replace_all(from, to)
    else
      self[index] = to if elem == from
    end
  end
end
find_node(name, delete = false) click to toggle source
# File lib/sexp.rb, line 144
def find_node name, delete = false
  matches = find_nodes name

  case matches.size
  when 0 then
    nil
  when 1 then
    match = matches.first
    delete match if delete
    match
  else
    raise NoMethodError, "multiple nodes for #{name} were found in #{inspect}"
  end
end
find_nodes(name) click to toggle source

Find every node with type name.

# File lib/sexp.rb, line 162
def find_nodes name
  find_all { | sexp | Sexp === sexp and sexp.first == name }
end
gsub(pattern, repl) click to toggle source

Replaces all Sexps matching pattern with Sexp repl.

# File lib/sexp.rb, line 120
def gsub(pattern, repl)
  return repl if pattern == self

  new = self.map do |subset|
    case subset
    when Sexp then
      subset.gsub(pattern, repl)
    else
      subset
    end
  end

  return Sexp.from_array(new)
end
line(n=nil) click to toggle source

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
def line(n=nil)
  if n then
    @line = n
    self
  else
    @line ||= nil
  end
end
mass() click to toggle source

Returns the size of the sexp, flattened.

# File lib/sexp.rb, line 183
def mass
  @mass ||= self.structure.flatten.size
end
method_missing(meth, delete = false) click to toggle source

Returns the node named node, deleting it if delete is true.

# File lib/sexp.rb, line 190
def method_missing meth, delete = false
  find_node meth, delete
end
sexp_body() click to toggle source

Returns the Sexp body, ie the values without the node type.

# File lib/sexp.rb, line 213
def sexp_body
  self[1..-1]
end
sexp_type() click to toggle source

Returns the node type of the Sexp.

# File lib/sexp.rb, line 206
def sexp_type
  first
end
shift() click to toggle source

If run with debug, Sexp will raise if you shift on an empty Sexp. Helps with debugging.

# File lib/sexp.rb, line 221
def shift
  raise "I'm empty" if self.empty?
  super
end
structure() click to toggle source

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
def structure
  result = self.class.new
  if Array === self.first then
    result = self.first.structure
  else
    result << self.first
    self.grep(Array).each do |subexp|
      result << subexp.structure
    end
  end
  result
end
sub(pattern, repl) click to toggle source

Replaces the Sexp matching pattern with repl.

# File lib/sexp.rb, line 246
def sub(pattern, repl)
  return repl.dup if pattern == self

  done = false

  new = self.map do |subset|
    if done then
      subset
    else
      case subset
      when Sexp then
        if pattern == subset then
          done = true
          repl.dup
        elsif pattern === subset then
          done = true
          subset.sub pattern, repl
        else
          subset
        end
      else
        subset
      end
    end
  end

  return Sexp.from_array(new)
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.