Module: Gemologist::AST

Defined in:
lib/gemologist/ast.rb

Class Method Summary collapse

Class Method Details

.concretize(node) ⇒ Object

rubocop:disable MethodLength, CyclomaticComplexity



7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# File 'lib/gemologist/ast.rb', line 7

def concretize(node) # rubocop:disable MethodLength, CyclomaticComplexity
  return nil unless node

  case node.type
  when :true                    then true
  when :false                   then false
  when :nil                     then nil
  when :int, :float, :str, :sym then node.children.first
  when :irange, :erange         then concretize_range(node)
  when :regexp                  then concretize_regexp(node)
  when :array                   then concretize_array(node)
  when :hash                    then concretize_hash(node)
  else                               RuntimeValue.new(node)
  end
end

.concretize_array(array_node) ⇒ Object



36
37
38
# File 'lib/gemologist/ast.rb', line 36

def concretize_array(array_node)
  array_node.children.map { |child_node| concretize(child_node) }
end

.concretize_hash(hash_node) ⇒ Object



40
41
42
43
44
45
46
# File 'lib/gemologist/ast.rb', line 40

def concretize_hash(hash_node)
  hash_node.children.each_with_object({}) do |pair_node, hash|
    key_node, value_node = *pair_node
    key = concretize(key_node)
    hash[key] = concretize(value_node) if key
  end
end

.concretize_range(range_node) ⇒ Object



23
24
25
26
# File 'lib/gemologist/ast.rb', line 23

def concretize_range(range_node)
  values = range_node.children.map { |child_node| concretize(child_node) }
  Range.new(*values, range_node.type == :erange)
end

.concretize_regexp(regexp_node) ⇒ Object



28
29
30
31
32
33
34
# File 'lib/gemologist/ast.rb', line 28

def concretize_regexp(regexp_node)
  *body_nodes, regopt_node = *regexp_node
  return RuntimeValue.new(regexp_node) unless body_nodes.all?(&:str_type?)
  string = body_nodes.map { |str_node| str_node.children.first }.reduce(:+)
  options = regopt_node.children.map(&:to_s).reduce(:+)
  eval("/#{string}/#{options}") # rubocop:disable Eval
end