class Bpl::AST::Node

Constants

REFERENCES

Attributes

parent[R]
token[R]

Public Class Methods

children(*args) click to toggle source
# File lib/bpl/ast/node.rb, line 14
def children(*args)
  @children ||= []
  @children += args
  args.each do |arg|
    define_method(arg) do
      x = instance_variable_get("@#{arg}")
      case x when Array then x.dup.freeze else x end
    end
  end
  @children
end
inherited(subclass) click to toggle source
# File lib/bpl/ast/node.rb, line 25
def inherited(subclass)
  subclass.instance_variable_set("@children",@children)
end
new(opts = {}) click to toggle source
# File lib/bpl/ast/node.rb, line 34
def initialize(opts = {})
  @attributes = []
  @parent = nil
  @token = nil
  opts.each do |k,v|
    instance_variable_set("@#{k}",v) if respond_to?(k)
    next unless self.class.children.include?(k)
    case v
    when Node then v.link(self)
    when Array then v.each {|x| x.link(self) if x.is_a?(Node)}
    end
  end
end
observers() click to toggle source
# File lib/bpl/ast/node.rb, line 9
def self.observers
  @@observers ||= []
end

Public Instance Methods

abstract() click to toggle source
# File lib/bpl/passes/transformation/abstraction.rb, line 4
def abstract
end
abstractions() click to toggle source
# File lib/bpl/passes/transformation/abstraction.rb, line 7
def abstractions
  Enumerator.new do |y|
    abstract{|abs| y.yield abs}
  end
end
add_attribute(key, *values) click to toggle source
# File lib/bpl/ast/node.rb, line 71
def add_attribute(key, *values)
  append_children(:attributes, Attribute.new(key: key, values: values))
end
append_children(name,*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 149
def append_children(name,*elems) insert_children(name,:after,*elems) end
copy() click to toggle source
# File lib/bpl/ast/node.rb, line 100
def copy
  other = bpl(to_s)
  each.zip(other.each).each do |mine,theirs|
    unless mine.class == theirs.class
      fail "#{mine.class} != #{theirs.class} !?!?"
    end
    if theirs.respond_to?(:bind) && mine.declaration
      theirs.bind(mine.declaration)
    end
  end
  other
end
each(preorder: true, &block) click to toggle source
# File lib/bpl/ast/node.rb, line 113
def each(preorder: true, &block)
  enumerator = Enumerator.new {|y| enumerate(y, preorder)}
  if block_given?
    enumerator.each(&block)
  else
    enumerator
  end
end
each_ancestor(&block) click to toggle source
# File lib/bpl/ast/node.rb, line 131
def each_ancestor(&block)
  enumerator = Enumerator.new {|y| enumerate_ancestors(y)}
  if block_given?
    enumerator.each(&block)
  else
    enumerator
  end
end
each_child(&block) click to toggle source
# File lib/bpl/ast/node.rb, line 122
def each_child(&block)
  enumerator = Enumerator.new {|y| enumerate_children(y)}
  if block_given?
    enumerator.each(&block)
  else
    enumerator
  end
end
enumerate(yielder, preorder) click to toggle source

the following could be private

# File lib/bpl/ast/node.rb, line 159
def enumerate(yielder, preorder)
  yielder.yield(self) if preorder
  self.class.children.each do |sym|
    case node = instance_variable_get("@#{sym}")
    when Node
      node.enumerate(yielder, preorder)
    when Array
      node.dup.each {|n| n.enumerate(yielder, preorder) if n.is_a?(Node)}
    end
  end
  yielder.yield(self) unless preorder
end
enumerate_ancestors(yielder) click to toggle source
# File lib/bpl/ast/node.rb, line 183
def enumerate_ancestors(yielder)
  yielder.yield(self)
  parent.enumerate_ancestors(yielder) if parent
end
enumerate_children(yielder) click to toggle source
# File lib/bpl/ast/node.rb, line 172
def enumerate_children(yielder)
  self.class.children.each do |sym|
    case node = instance_variable_get("@#{sym}")
    when Node
      yielder.yield(node)
    when Array
      node.dup.each {|n| yielder.yield(n) if n.is_a?(Node)}
    end
  end
end
get_attribute(key) click to toggle source
# File lib/bpl/ast/node.rb, line 66
def get_attribute(key)
  a = @attributes.find {|_a| _a.key == key}
  a.values if a
end
has_attribute?(key) click to toggle source
# File lib/bpl/ast/node.rb, line 62
def has_attribute?(key)
  @attributes.any? {|a| a.key == key}
end
hilite() click to toggle source
# File lib/bpl/ast/node.rb, line 97
def hilite; show(&:hilite) end
insert_after(*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 153
def insert_after(*elems) insert_siblings(:after,*elems) end
insert_before(*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 152
def insert_before(*elems) insert_siblings(:before,*elems) end
insert_children(name,where,*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 188
def insert_children(name,where,*elems)
  fail "invalid child #{name}" unless self.class.children.include?(name)
  elems.each {|elem| elem.remove if elem.respond_to?(:parent) && elem.parent}

  var = instance_variable_get("@#{name}")

  if var && var.is_a?(Array)
    case where
    when :before then var.unshift(*elems)
    when :after  then var.push(*elems)
    when :inplace
      var.each {|elem| elem.unlink if elem.respond_to?(:unlink)}
      var.clear
      var.push(*elems)
    end

  else
    fail "cannot insert multiple #{name} children" if elems.count > 1
    fail "child #{name} already exists" if var && where != :inplace

    instance_variable_set("@#{name}", elems.first)
  end

  elems.each {|elem| elem.link(self) if elem.respond_to?(:link)}
  self
end
insert_siblings(where,*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 239
def insert_siblings(where,*elems)
  fail "unknown parent of #{self}" unless parent
  sym, ary, idx = parent.locate_child(self)
  if idx
    case where
    when :before then ary.insert(idx,*elems)
    when :after  then ary.insert(idx+1,*elems)
    when :inplace
      ary.delete_at(idx)
      ary.insert(idx,*elems)
    end
    true
  elsif ary
    fail "cannot insert multiple #{sym} children" if elems.count > 1
    fail "child #{sym} already exists" unless where == :inplace
    parent.instance_variable_set("@#{sym}",elems.first)
    true
  else
    fail "unknown child"
  end
  elems.each {|elem| elem.link(parent)}
  self.unlink if where == :inplace
  self
end
inspect() click to toggle source
Calls superclass method
# File lib/bpl/ast/node.rb, line 84
def inspect
  if REFERENCES.any?{|v| instance_variable_get(v).is_a?(Node)}
    node = clone
    REFERENCES.each do |v|
      n = node.instance_variable_get(v)
      node.instance_variable_set(v,n.class) if n
    end
    node.inspect
  else
    return super
  end
end
locate_child(child) click to toggle source
# File lib/bpl/ast/node.rb, line 215
def locate_child(child)
  self.class.children.each do |sym|
    ary = self.instance_variable_get("@#{sym}")
    if ary.is_a?(Array) && idx = ary.index(child)
      return sym, ary, idx
    elsif ary == child
      return sym, ary
    end
  end
  return nil
end
next_sibling() click to toggle source
# File lib/bpl/ast/node.rb, line 144
def next_sibling
  parent && (_, ary, idx = parent.locate_child(self)) && idx && ary[idx+1]
end
prepend_children(name,*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 148
def prepend_children(name,*elems) insert_children(name,:before,*elems) end
previous_sibling() click to toggle source
# File lib/bpl/ast/node.rb, line 140
def previous_sibling
  parent && (_, ary, idx = parent.locate_child(self)) && idx && ary[idx-1]
end
remove() click to toggle source
# File lib/bpl/ast/node.rb, line 155
def remove; insert_siblings(:inplace) end
remove_attribute(key) click to toggle source
# File lib/bpl/ast/node.rb, line 75
def remove_attribute(key)
  @attributes.each {|a| a.remove if a.key == key}
end
replace_children(name,*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 150
def replace_children(name,*elems) insert_children(name,:inplace,*elems) end
replace_with(*elems) click to toggle source
# File lib/bpl/ast/node.rb, line 154
def replace_with(*elems) insert_siblings(:inplace,*elems) end
show_attrs() { |a| ... } click to toggle source
# File lib/bpl/ast/node.rb, line 79
def show_attrs
  @attributes.map {|a| yield a} * " "
end
siblings() click to toggle source
# File lib/bpl/ast/node.rb, line 227
def siblings
  fail "unknown parent of #{self}" unless parent
  _, ary, idx = parent.locate_child(self)
  if idx
    ary.dup.freeze
  elsif ary
    [ary]
  else
    fail "unknown child"
  end
end
to_s() click to toggle source
# File lib/bpl/ast/node.rb, line 98
def to_s; show {|a| a} end