Module: Macros::Sexp

Extended by:
Sexp
Included in:
Compiler, Expander, Loader, Sexp
Defined in:
lib/macros/sexp.rb

Instance Method Summary collapse

Instance Method Details

#node?(node) ⇒ Boolean

Returns:

  • (Boolean)


50
51
52
# File 'lib/macros/sexp.rb', line 50

def node?(node)
  node.is_a?(AST::Node)
end

#s(type, *children) ⇒ Object



6
7
8
# File 'lib/macros/sexp.rb', line 6

def s(type, *children)
  Parser::AST::Node.new(type, children)
end

#seval(ast) ⇒ Object



54
55
56
# File 'lib/macros/sexp.rb', line 54

def seval(ast)
  eval(Unparser.unparse(ast))
end

#sfind(sexp, specs) ⇒ Object

Traverse into sexp by type and child position



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/macros/sexp.rb', line 11

def sfind(sexp, specs)
  specs.inject(sexp) do |node, spec|
    return NotFound if node.nil?

    if spec.is_a?(Symbol) && node.type == spec
      node
    elsif spec.is_a?(Integer) && node.children.length > spec
      node.children[spec]
    elsif spec.is_a?(Array)
      node.children.grep(AST::Node)
        .flat_map { |child| sfind(child, spec) }
        .reject { |child| child == NotFound }
    else
      return NotFound
    end
  end
end

#smatch?(node, pattern) ⇒ Boolean

Returns:

  • (Boolean)


43
44
45
46
47
48
# File 'lib/macros/sexp.rb', line 43

def smatch?(node, pattern)
  return false unless node.type == pattern.type
  pattern.children.zip(node.children).all? do |a, b|
    a == b || node?(a) && smatch?(b, a)
  end
end

#treefilter(node, &block) ⇒ Object



36
37
38
39
40
41
# File 'lib/macros/sexp.rb', line 36

def treefilter(node, &block)
  acc = []
  acc << node if block.call(node)
  treemap(node) { |n| acc << n if block.call(n) ; n}
  acc.freeze
end

#treemap(node, &block) ⇒ Object



29
30
31
32
33
34
# File 'lib/macros/sexp.rb', line 29

def treemap(node, &block)
  block.call(s(node.type, *node.children.map do |child|
      next child unless child.is_a? AST::Node
      block.call(treemap(child, &block))
    end))
end