Class: Moxml::XPath::Ruby::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/moxml/xpath/ruby/generator.rb

Overview

Class for converting a Ruby AST to a String.

This class takes a Node instance and converts it (and its child nodes) to a String that can be passed to ‘eval`.

Instance Method Summary collapse

Instance Method Details

#on_and(ast) ⇒ String

Processes a boolean “and” node.

Parameters:

Returns:



91
92
93
94
95
96
97
98
# File 'lib/moxml/xpath/ruby/generator.rb', line 91

def on_and(ast)
  left, right = *ast

  left_str = process(left)
  right_str = process(right)

  "#{left_str} && #{right_str}"
end

#on_array(ast) ⇒ String

Processes an array literal node.

Parameters:

Returns:



255
256
257
258
# File 'lib/moxml/xpath/ruby/generator.rb', line 255

def on_array(ast)
  elements = ast.to_a.map { |elem| process(elem) }
  "[#{elements.join(', ')}]"
end

#on_assign(ast) ⇒ String

Processes an assignment node.

Parameters:

Returns:



29
30
31
32
33
34
35
36
# File 'lib/moxml/xpath/ruby/generator.rb', line 29

def on_assign(ast)
  var, val = *ast

  var_str = process(var)
  val_str = process(val)

  "#{var_str} = #{val_str}"
end

#on_begin(ast) ⇒ String

Processes a ‘begin` node.

Parameters:

Returns:



55
56
57
58
59
60
61
62
63
# File 'lib/moxml/xpath/ruby/generator.rb', line 55

def on_begin(ast)
  body = process(ast.to_a[0])

  <<~RUBY
    begin
      #{body}
    end
  RUBY
end

#on_block(ast) ⇒ String

Processes a block node.

Parameters:

Returns:



192
193
194
195
196
197
198
199
200
201
202
203
204
# File 'lib/moxml/xpath/ruby/generator.rb', line 192

def on_block(ast)
  receiver, args, body = *ast

  receiver_str = process(receiver)
  body_str = body ? process(body) : nil
  arg_strs = args.map { |arg| process(arg) }

  <<~RUBY
    #{receiver_str} do |#{arg_strs.join(', ')}|
      #{body_str}
    end
  RUBY
end

#on_const(ast) ⇒ String

Processes a constant reference node (e.g., Moxml::Document).

Parameters:

Returns:



247
248
249
# File 'lib/moxml/xpath/ruby/generator.rb', line 247

def on_const(ast)
  ast.to_a.join("::")
end

#on_eq(ast) ⇒ String

Processes an equality node.

Parameters:

Returns:



69
70
71
72
73
74
75
76
# File 'lib/moxml/xpath/ruby/generator.rb', line 69

def on_eq(ast)
  left, right = *ast

  left_str = process(left)
  right_str = process(right)

  "#{left_str} == #{right_str}"
end

#on_followed_by(ast) ⇒ String

Parameters:

Returns:



21
22
23
# File 'lib/moxml/xpath/ruby/generator.rb', line 21

def on_followed_by(ast)
  ast.to_a.map { |child| process(child) }.join("\n\n")
end

#on_if(ast) ⇒ String

Processes an if statement node.

Parameters:

Returns:



117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'lib/moxml/xpath/ruby/generator.rb', line 117

def on_if(ast)
  cond, body, else_body = *ast

  cond_str = process(cond)
  body_str = process(body)

  if else_body
    else_str = process(else_body)

    <<~RUBY
      if #{cond_str}
        #{body_str}
      else
        #{else_str}
      end
    RUBY
  else
    <<~RUBY
      if #{cond_str}
        #{body_str}
      end
    RUBY
  end
end

#on_lit(ast) ⇒ String

Processes a literal node.

Parameters:

Returns:



239
240
241
# File 'lib/moxml/xpath/ruby/generator.rb', line 239

def on_lit(ast)
  ast.to_a[0]
end

#on_massign(ast) ⇒ String

Processes a mass assignment node.

Parameters:

Returns:



42
43
44
45
46
47
48
49
# File 'lib/moxml/xpath/ruby/generator.rb', line 42

def on_massign(ast)
  vars, val = *ast

  var_names = vars.map { |var| process(var) }
  val_str = process(val)

  "#{var_names.join(', ')} = #{val_str}"
end

#on_neq(ast) ⇒ Object



78
79
80
81
82
83
84
85
# File 'lib/moxml/xpath/ruby/generator.rb', line 78

def on_neq(ast)
  left, right = *ast

  left_str = process(left)
  right_str = process(right)

  "#{left_str} != #{right_str}"
end

#on_or(ast) ⇒ String

Processes a boolean “or” node.

Parameters:

Returns:



104
105
106
107
108
109
110
111
# File 'lib/moxml/xpath/ruby/generator.rb', line 104

def on_or(ast)
  left, right = *ast

  left_str = process(left)
  right_str = process(right)

  "(#{left_str} || #{right_str})"
end

#on_range(ast) ⇒ String

Processes a Range node.

Parameters:

Returns:



210
211
212
213
214
215
216
217
# File 'lib/moxml/xpath/ruby/generator.rb', line 210

def on_range(ast)
  start, stop = *ast

  start_str = process(start)
  stop_str = process(stop)

  "(#{start_str}..#{stop_str})"
end

#on_send(ast) ⇒ String

Processes a method call node.

Parameters:

Returns:



163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
# File 'lib/moxml/xpath/ruby/generator.rb', line 163

def on_send(ast)
  children = ast.to_a
  receiver = children[0]
  name = children[1]
  args = children[2..] || []

  call = name
  brackets = name == "[]"

  unless args.empty?
    arg_strs = args.map do |arg|
      process(arg)
    end
    arg_str = arg_strs.join(", ")
    call = brackets ? "[#{arg_str}]" : "#{call}(#{arg_str})"
  end

  if receiver
    rec_str = process(receiver)
    call = brackets ? "#{rec_str}#{call}" : "#{rec_str}.#{call}"
  end

  call
end

#on_string(ast) ⇒ String

Processes a string node.

Parameters:

Returns:



223
224
225
# File 'lib/moxml/xpath/ruby/generator.rb', line 223

def on_string(ast)
  ast.to_a[0].inspect
end

#on_symbol(ast) ⇒ String

Processes a Symbol node.

Parameters:

Returns:



231
232
233
# File 'lib/moxml/xpath/ruby/generator.rb', line 231

def on_symbol(ast)
  ast.to_a[0].to_sym.inspect
end

#on_while(ast) ⇒ String

Processes a while statement node.

Parameters:

Returns:



146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/moxml/xpath/ruby/generator.rb', line 146

def on_while(ast)
  cond, body = *ast

  cond_str = process(cond)
  body_str = process(body)

  <<~RUBY
    while #{cond_str}
      #{body_str}
    end
  RUBY
end

#process(ast) ⇒ String

Parameters:

Returns:



15
16
17
# File 'lib/moxml/xpath/ruby/generator.rb', line 15

def process(ast)
  send(:"on_#{ast.type}", ast)
end