Class: Wood::Node

Inherits:
Object
  • Object
show all
Defined in:
lib/wood/node.rb

Overview

Base node class. Represents a generic AST node to be visited, processed & rewritten in the compiler pipeline.

Defined Under Namespace

Modules: ClassMethods Classes: Position

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ Node

Returns a new instance of Node.



69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/wood/node.rb', line 69

def initialize(options = {})
  @pos  = options[:pos] || Position.new
  @type = options[:type]

  self.class.__child_nodes__.each do |c|
    node = options[c]
    instance_variable_set("@#{c}", node)
    if node.respond_to? :parent_node=
      node.parent_node = self
    end
  end

  setup
end

Instance Attribute Details

#parent_nodeObject

Parent of this node within the AST.



67
68
69
# File 'lib/wood/node.rb', line 67

def parent_node
  @parent_node
end

#posObject (readonly)

Position of node in the original source code.



63
64
65
# File 'lib/wood/node.rb', line 63

def pos
  @pos
end

#typeObject

Type of node, like they’re defined in Types.



65
66
67
# File 'lib/wood/node.rb', line 65

def type
  @type
end

Class Method Details

.__child_nodes__Object



49
50
51
# File 'lib/wood/node.rb', line 49

def self.__child_nodes__
  []
end

.inherited(klass) ⇒ Object



53
54
55
56
57
58
# File 'lib/wood/node.rb', line 53

def self.inherited(klass)
  klass.extend ClassMethods
  klass.node_name_prefix = "Wood::Nodes"
  klass.__send__ :include, Wood::TreePattern::CombinatorialMatching
  klass.extend Wood::TreePattern::CombinatorialMatching
end

.with_type(type_pattern) ⇒ Object



6
7
8
# File 'lib/wood/node.rb', line 6

def self.with_type(type_pattern)
  Wood::TreePattern::TypeMatcher.new(self, type_pattern)
end

Instance Method Details

#==(other) ⇒ true, false

Compares a node to another.

Returns:

  • (true, false)

    ‘true` if nodes equal, `false` otherwise.



124
125
126
127
128
129
130
131
132
133
134
# File 'lib/wood/node.rb', line 124

def == other
  case other
  when self.class
    each_child do |child|
      return false unless self.__send__(child) == other.__send__(child)
    end
    return true
  else
    return false
  end
end

#===(other) ⇒ true, false

Matches a node with another.

Returns:

  • (true, false)

    ‘true` if nodes match, `false` otherwise.



138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/wood/node.rb', line 138

def === other
  case other
  when self.class
    each_child do |child|
      child_val = get_child(child) || Wood::TreePattern::AnyMatcher.new
      return false unless child_val === other.get_child(child)
    end
    return true
  else
    return false
  end
end

#__rewriter_class__Object

Allows per-node custom pattern matchers & rewriters.



168
169
170
171
172
173
174
# File 'lib/wood/node.rb', line 168

def __rewriter_class__
  @rewriter_class ||= Class.new do
    include Wood::TreePattern::Matcher
    include Wood::TreeRewriter
    patterns self.new
  end
end

#child_node_namesArray<Symbol>

Returns List of child node names for ‘self`.

Returns:

  • (Array<Symbol>)

    List of child node names for ‘self`.



118
119
120
# File 'lib/wood/node.rb', line 118

def child_node_names
  self.class.__child_nodes__
end

#child_nodesArray<Node>

Returns List of child nodes for ‘self`.

Returns:

  • (Array<Node>)

    List of child nodes for ‘self`.



111
112
113
114
115
# File 'lib/wood/node.rb', line 111

def child_nodes
  child_node_names.map do |c|
    get_child(c)
  end
end

#each_child(&block) ⇒ Object

Parameters:

  • block (Proc, #call)

    Block to be called with each child node.



100
101
102
# File 'lib/wood/node.rb', line 100

def each_child(&block)
  self.class.__child_nodes__.each(&block)
end

#each_child_with_name(&block) ⇒ Object



104
105
106
107
108
# File 'lib/wood/node.rb', line 104

def each_child_with_name(&block)
  self.class.__child_nodes__.each do |child_name|
    yield(get_child(child_name), child_name)
  end
end

#get_child(child_name) ⇒ Node

Returns Child node named ‘child_name`.

Parameters:

  • child_name (Symbol)

    Name of child to get node value for.

Returns:

  • (Node)

    Child node named ‘child_name`.



157
158
159
# File 'lib/wood/node.rb', line 157

def get_child(child_name)
  __send__(child_name)
end

#inspectObject



151
152
153
# File 'lib/wood/node.rb', line 151

def inspect
  sexp.inspect
end

#node_nameSymbol

Returns Node name of this node.

Returns:

  • (Symbol)

    Node name of this node.



90
91
92
# File 'lib/wood/node.rb', line 90

def node_name
  self.class.node_name
end

#pattern(&block) ⇒ Object



176
177
178
# File 'lib/wood/node.rb', line 176

def pattern(&block)
  __rewriter_class__.pattern(&block)
end

#rewrite!Object



180
181
182
# File 'lib/wood/node.rb', line 180

def rewrite!
  __rewriter_class__.new.rewrite(self)
end

#set_child(child_name, node_val) ⇒ Object

Parameters:

  • child_name (Symbol)

    Name of child node to set value for.

  • node_val (Node)

    Node value to set child node to.



163
164
165
# File 'lib/wood/node.rb', line 163

def set_child(child_name, node_val)
  __send__("#{child_name}=", node_val)
end

#setupObject

Gets called on initialization, should be overwritten by subclass if any checking needs to be done on the child node data etc.



86
87
# File 'lib/wood/node.rb', line 86

def setup
end

#sexpArray

Returns S-expression version of ‘self`.

Returns:

  • (Array)

    S-expression version of ‘self`.



95
96
97
# File 'lib/wood/node.rb', line 95

def sexp
  [self.class.node_name, *child_nodes.map(&:sexp)]
end

#with_type(type_pattern) ⇒ Object



10
11
12
# File 'lib/wood/node.rb', line 10

def with_type(type_pattern)
  Wood::TreePattern::TypeMatcher.new(self, type_pattern)
end