Class: Sexp

### Home Classes Methods

### In Files

- lib/sexp.rb

### Parent

Array

### Methods

- ::from_array
- ::new
- #===
- #=~
- #array_type?
- #deep_each
- #each_of_type
- #each_sexp
- #find_and_replace_all
- #find_node
- #find_nodes
- #gsub
- #head
- #line
- #mass
- #method_missing
- #rest
- #sexp_body
- #sexp_type
- #shift
- #structure
- #sub

### Files

- History.txt
- Manifest.txt
- README.txt

### Class/Module Index

Quicksearch

- SexpProcessor
- SexpProcessor::Environment
- CompositeSexpProcessor
- Examples
- MethodBasedSexpProcessor
- NotEmptyError
- Object
- ParseTreeTestCase
- Sexp
- SexpAny
- SexpInterpreter
- SexpMatchSpecial
- SexpMatchSpecials
- SexpProcessorError
- SexpTypeError
- Unique
- UnknownNodeError
- UnsupportedNodeError

No matching classes.

# 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 26
    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 19
    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 52
    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 68
    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 77
    def array_type?
      type = self.first
      @@array_types.include? type
    end

deep_each(&block) click to toggle source

Recursively enumerates the sexp yielding to `block` for every element. TODO: test

    # File lib/sexp.rb, line 90
    def deep_each(&block)
      self.each_sexp do |sexp|
        block[sexp]
        sexp.deep_each(&block)
      end
    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 100
    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

each_sexp() click to toggle source

Recursively enumerates all sub-sexps skipping non-Sexp elements. TODO: test

    # File lib/sexp.rb, line 113
    def each_sexp
      self.each do |sexp|
        next unless Sexp === sexp

        yield sexp
      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 125
    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 162
    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 180
    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 138
    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

head() click to toggle source
Alias for: sexp_type
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 189
    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 201
    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 208
    def method_missing meth, delete = false
      find_node meth, delete
    end

rest() click to toggle source
Alias for: sexp_body
sexp_body() click to toggle source

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

    # File lib/sexp.rb, line 236
    def sexp_body
      self[1..-1]
    end

Also aliased as: rest
sexp_type() click to toggle source

Returns the node type of the Sexp.

    # File lib/sexp.rb, line 229
    def sexp_type
      first
    end

Also aliased as: head
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 247
    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 256
    def structure
      if Array === self.first then
        s(:bogus, *self).structure # TODO: remove >= 4.2.0
      else
        result = s(self.first)
        self.each do |subexp|
          result << subexp.structure if Sexp === subexp
        end
        result
      end
    end

sub(pattern, repl) click to toggle source

Replaces the Sexp matching `pattern` with `repl`.

    # File lib/sexp.rb, line 271
    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.