Class: Carbon::Compiler::Node::Base

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Includes:
Enumerable
Defined in:
lib/carbon/compiler/node/base.rb

Overview

A base-level node. Contains all of the basic behaviors that a node needs.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(children, data = {}) ⇒ Base

Initialize the node with the given children and the data.

Parameters:

  • children (Array<Base>, Scanner::Token)

    The children of this node.

  • data (Hash) (defaults to: {})

    The associated data for this node.

Options Hash (data):

  • :type (Type) — default: nil

    The type of the node.

  • :attributes (Array) — default: []

    The attributes of the node.

  • :location (Location) — default: nil

    The location of the node.

  • :components (Array) — default: children

    The nodes to derive the location of the node from.



94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/carbon/compiler/node/base.rb', line 94

def initialize(children, data = {})
  @children = children.dup.freeze
  @type = data[:type]
  @attributes = data.fetch(:attributes, [])

  if data.key?(:location)
    @location = data[:location]
  else
    derive_location(data.fetch(:components, children))
  end

  freeze
end

Instance Attribute Details

#childrenArray<Node, Scanner::Token> (readonly)

The node’s children. This is most often an array of nodes, but can sometimes include Scanner tokens as well.

Returns:



50
51
52
# File 'lib/carbon/compiler/node/base.rb', line 50

def children
  @children
end

#locationLocation (readonly)

The location describing the node. This is derived solely from the children that make up the node, and so is considered auxillary.

Returns:



56
57
58
# File 'lib/carbon/compiler/node/base.rb', line 56

def location
  @location
end

Class Method Details

.mapping(data = nil) ⇒ Hash, void Also known as: attribute, attributes

Creates a “mapping.” This contructs a mapping between a child and a name. For example, a for loop has four children: ‘initial`, `condition`, `increment`, and `body`. This creates the association between the numerical index of the child and the symbolic name of the child.

Examples:

Statement::For.mapping(initial: 0, condition: 1, increment: 2,
  body: 3)
Statement::For.new(children).initial # => children[0]

Parameters:

  • data (Hash?) (defaults to: nil)

    The data for the mapping. If this is nil, the function returns the mapping instead of setting it.

Returns:

  • (Hash, void)


25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/carbon/compiler/node/base.rb', line 25

def self.mapping(data = nil)
  if data.nil?
    @mapping ||= Concurrent::Hash.new
  else
    @mapping = Concurrent::Hash.new.merge(data)

    data.each do |key, value|
      fail if key == :klass
      define_method(key) { @children[value] }
    end
  end
end

Instance Method Details

#[](index) ⇒ Node, ...

Access a specific child at the given index. If a child exists, it is returned; otherwise, ‘nil` is returned.

Returns:



70
# File 'lib/carbon/compiler/node/base.rb', line 70

def_delegator :children, :[]

#accept(visitor, *arguments) ⇒ Object

Accepts the current visitor unto itself.

Parameters:

  • visitor (#visit)

Returns:

  • (Object)


170
171
172
# File 'lib/carbon/compiler/node/base.rb', line 170

def accept(visitor, *arguments)
  visitor.visit(self, *arguments)
end

#attributes!(attributes) ⇒ Base

Sets the attributes of a copy of this node to the given attributes. It then returns the copy.

Parameters:

  • attributes (Array)

Returns:



113
114
115
# File 'lib/carbon/compiler/node/base.rb', line 113

def attributes!(attributes)
  self.class.new(children, data.merge(attributes: attributes))
end

#behavior?Boolean

Returns true if this node is a behavior definition.

Returns:

  • (Boolean)


184
185
186
# File 'lib/carbon/compiler/node/base.rb', line 184

def behavior?
  false
end

#dataObject



195
196
197
# File 'lib/carbon/compiler/node/base.rb', line 195

def data
  { location: @location, attributes: @attributes, type: @type }
end

#data?Boolean

Returns true if this node is a data definition.

Returns:

  • (Boolean)


177
178
179
# File 'lib/carbon/compiler/node/base.rb', line 177

def data?
  false
end

#each {|child| ... } ⇒ Enumerator<Node, Scanner::Token>

Yields all children one by one, if a block is given. It then returns an enumerator that enumerates over all of the children.

Yields:

  • (child)

Yield Parameters:

Returns:



80
# File 'lib/carbon/compiler/node/base.rb', line 80

def_delegator :children, :each

#identity?Boolean

Returns true if this node is an identity definition.

Returns:

  • (Boolean)


191
192
193
# File 'lib/carbon/compiler/node/base.rb', line 191

def identity?
  false
end

#map!Base

Maps the children using the given block. It then returns a copy of the node with the new children.

Parameters:

  • children (::Array)

Returns:



141
142
143
# File 'lib/carbon/compiler/node/base.rb', line 141

def map!
  update!(children.map(&Proc.new))
end

#merge!(options) ⇒ Base Also known as: merge

Using the ClassMethods#mapping, it merges the given hash into the children.

Examples:

Statement::For.mapping(initial: 0, condition: 1, increment: 2,
  body: 3)
stmt = Statement::For.new(children)
stmt.merge!(initial: initial).initial # => initial

Parameters:

  • options ({Symbol => Base})

Returns:



155
156
157
158
159
160
161
162
# File 'lib/carbon/compiler/node/base.rb', line 155

def merge!(options)
  merged = @children.dup
  options.each do |key, value|
    merged[attributes.fetch(key)] = value
  end

  update!(merged)
end

#type!(type) ⇒ Base

Sets the type of a copy of this node to the given type. It then returns the copy.

Parameters:

  • type (Type)

Returns:



122
123
124
# File 'lib/carbon/compiler/node/base.rb', line 122

def type!(type)
  self.class.new(children, data.merge(type: type))
end

#update!(children) ⇒ Base Also known as: update

Sets the children of a copy of this node to the given children. It then returns the copy.

Parameters:

  • children (Array)

Returns:



131
132
133
# File 'lib/carbon/compiler/node/base.rb', line 131

def update!(children)
  self.class.new(children, data)
end