lib/furnace/ast/node.rb in furnace-0.0.1 vs lib/furnace/ast/node.rb in furnace-0.0.2
- old
+ new
@@ -1,70 +1,96 @@
-module Furnace
- module AST
- class Node
- attr_accessor :type, :parent, :children, :metadata
+module Furnace::AST
+ class Node
+ attr_accessor :type, :parent, :children, :metadata
- def initialize(type, children=[], metadata={})
- @type, @children, @metadata = type.to_sym, children, metadata
- end
+ def initialize(type, children=[], metadata={})
+ @type, @children, @metadata = type.to_sym, children, metadata
+ end
- def update(type, children=nil, metadata={})
- @type = type
- @children = children || @children
-
- # If something non-nil is passed, including default value, then merge.
- # Else, clear metadata store.
- if metadata
- @metadata.merge!(metadata)
- else
- @metadata = {}
+ def normalize_hierarchy!
+ @children.each do |child|
+ if child.respond_to? :parent=
+ child.parent = self
end
- self
+ if child.respond_to? :normalize_hierarchy!
+ child.normalize_hierarchy!
+ end
end
- def index
- parent.children.find_index(self)
- end
+ self
+ end
- def next
- parent.children[index + 1]
- end
+ def update(type, children=nil, metadata={})
+ @type = type
+ @children = children || @children
- def prev
- parent.children[index - 1]
+ # If something non-nil is passed, including default value, then merge.
+ # Else, clear metadata store.
+ if metadata
+ @metadata.merge!(metadata)
+ else
+ @metadata = {}
end
- def to_s
- "(#{fancy_type} ...)"
- end
+ self
+ end
- def to_sexp(indent=0)
- str = "#{" " * indent}(#{fancy_type}"
+ def dup
+ node = super
+ node.children = @children.dup
+ node.metadata = @metadata.dup
+ node
+ end
- children.each do |child|
- if child.is_a? Node
- str << "\n#{child.to_sexp(indent + 1)}"
- else
- str << " #{child.inspect}"
- end
- end
+ def index
+ parent.children.find_index(self)
+ end
- str << ")"
+ def next
+ parent.children[index + 1]
+ end
- str
- end
- alias :inspect :to_sexp
+ def prev
+ parent.children[index - 1]
+ end
- protected
+ def to_s
+ "(#{fancy_type} ...)"
+ end
- def fancy_type
- dasherized = @type.to_s.gsub('_', '-')
- if @metadata[:label]
- "#{@metadata[:label]}:#{dasherized}"
+ def to_sexp(indent=0)
+ str = "#{" " * indent}(#{fancy_type}"
+
+ children.each do |child|
+ if (!children[0].is_a?(Node) && child.is_a?(Node)) ||
+ (children[0].is_a?(Node) && child.is_a?(Node) &&
+ child.children.any? { |c| c.is_a?(Node) || c.is_a?(Array) }) ||
+ (child.is_a?(Node) && child.metadata[:label])
+ str << "\n#{child.to_sexp(indent + 1)}"
else
- dasherized
+ str << " #{child.inspect}"
end
+ end
+
+ str << ")"
+
+ str
+ end
+ alias :inspect :to_sexp
+
+ def to_astlet
+ self
+ end
+
+ protected
+
+ def fancy_type
+ dasherized = @type.to_s.gsub('_', '-')
+ if @metadata[:label]
+ "#{@metadata[:label]}:#{dasherized}"
+ else
+ dasherized
end
end
end
end
\ No newline at end of file