Class: Mulang::Ruby::AstProcessor

Inherits:
AST::Processor
  • Object
show all
Includes:
AST::Sexp, Sexp
Defined in:
lib/mulang/ruby/ast_processor.rb

Instance Method Summary collapse

Methods included from Sexp

#none

Instance Method Details

#_Object



44
45
46
# File 'lib/mulang/ruby/ast_processor.rb', line 44

def _
  Object.new.tap { |it| it.define_singleton_method(:==) { |_| true } }
end

#handle_send_with_args(node, extra_args = []) ⇒ Object



281
282
283
284
285
286
# File 'lib/mulang/ruby/ast_processor.rb', line 281

def handle_send_with_args(node, extra_args=[])
  receptor, message, *args = *node
  receptor ||= s(:self)

  ms :Send, process(receptor), message_reference(message), (process_all(args) + extra_args)
end

#handler_missing(*args) ⇒ Object



277
278
279
# File 'lib/mulang/ruby/ast_processor.rb', line 277

def handler_missing(*args)
  ms :Other, args.to_s, nil
end

#message_reference(message) ⇒ Object



288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
# File 'lib/mulang/ruby/ast_processor.rb', line 288

def message_reference(message)
  case message
    when :==     then primitive :Equal
    when :!=     then primitive :NotEqual
    when :!      then primitive :Negation
    when :'&&'   then primitive :And
    when :'||'   then primitive :Or
    when :hash   then primitive :Hash
    when :>=     then primitive :GreatherOrEqualThan
    when :>      then primitive :GreatherThan
    when :<=     then primitive :LessOrEqualThan
    when :<      then primitive :LessThan
    when :+      then primitive :Plus
    when :-      then primitive :Minus
    when :*      then primitive :Multiply
    when :/      then primitive :Divide
    when :length then primitive :Size
    when :size   then primitive :Size
    else ms :Reference, message
  end
end

#on_and(node) ⇒ Object



102
103
104
105
106
# File 'lib/mulang/ruby/ast_processor.rb', line 102

def on_and(node)
  value, other = *node

  simple_send process(value), '&&', [process(other)]
end

#on_and_asgn(node) ⇒ Object



251
252
253
254
# File 'lib/mulang/ruby/ast_processor.rb', line 251

def on_and_asgn(node)
  assignee, value = *node
  on_op_asgn s :op_asgn, assignee, '&&', value
end

#on_arg(node) ⇒ Object Also known as: on_restarg, on_procarg0



153
154
155
156
157
158
159
160
# File 'lib/mulang/ruby/ast_processor.rb', line 153

def on_arg(node)
  name, _ = *node
  if name.is_a? Parser::AST::Node
    process name
  else
    ms :VariablePattern, name
  end
end

#on_array(node) ⇒ Object



272
273
274
275
# File 'lib/mulang/ruby/ast_processor.rb', line 272

def on_array(node)
  elements = *node
  {tag: :MuList, contents: process_all(elements)}
end

#on_begin(node) ⇒ Object



25
26
27
28
29
30
31
# File 'lib/mulang/ruby/ast_processor.rb', line 25

def on_begin(node)
  if node.children.size == 1 && node.children[0].nil?
    none # ruby < 2.6 only
  else
    sequence(*process_all(node))
  end
end

#on_block(node) ⇒ Object



135
136
137
138
139
# File 'lib/mulang/ruby/ast_processor.rb', line 135

def on_block(node)
  send, parameters, body = *node
  lambda = ms(:Lambda, process_all(parameters), process(body) || none)
  handle_send_with_args send, [lambda]
end

#on_casgn(node) ⇒ Object



211
212
213
214
# File 'lib/mulang/ruby/ast_processor.rb', line 211

def on_casgn(node)
  _ns, id, value = *node
  ms :Assignment, id, process(value)
end

#on_class(node) ⇒ Object



6
7
8
9
10
11
12
13
14
# File 'lib/mulang/ruby/ast_processor.rb', line 6

def on_class(node)
  name, superclass, body = *node
  body ||= s(:nil)

  _, class_name = *name
  _, superclass_name = *superclass

  ms :Class, class_name, superclass_name, process(body)
end

#on_const(node) ⇒ Object



259
260
261
262
# File 'lib/mulang/ruby/ast_processor.rb', line 259

def on_const(node)
  _ns, value = *node
  ms :Reference, value
end

#on_def(node) ⇒ Object



121
122
123
124
125
126
127
128
129
130
131
132
133
# File 'lib/mulang/ruby/ast_processor.rb', line 121

def on_def(node)
  id, args, body = *node
  body ||= s(:nil)

  case id
  when :equal?, :eql?, :==
    primitive_method :Equal, process_all(args), process(body)
  when :hash
    primitive_method :Hash, process_all(args), process(body)
  else
    simple_method id, process_all(args), process(body)
  end
end

#on_defs(node) ⇒ Object



114
115
116
117
118
119
# File 'lib/mulang/ruby/ast_processor.rb', line 114

def on_defs(node)
  _target, id, args, body = *node
  body ||= s(:nil)

  simple_method id, process_all(args), process(body)
end

#on_dstr(node) ⇒ Object



91
92
93
94
95
# File 'lib/mulang/ruby/ast_processor.rb', line 91

def on_dstr(node)
  parts = *node

  simple_send ms(:MuList, process_all(parts)), :join, []
end

#on_ensure(node) ⇒ Object



75
76
77
78
79
# File 'lib/mulang/ruby/ast_processor.rb', line 75

def on_ensure(node)
  catch, finally = *node
  try, catches = on_rescue(catch)[:contents]
  ms :Try, try, catches, process(finally)
end

#on_false(_) ⇒ Object



268
269
270
# File 'lib/mulang/ruby/ast_processor.rb', line 268

def on_false(_)
  ms :MuBool, false
end

#on_float(node) ⇒ Object Also known as: on_int



186
187
188
189
# File 'lib/mulang/ruby/ast_processor.rb', line 186

def on_float(node)
  value, _ = *node
  ms :MuNumber, value
end

#on_for(node) ⇒ Object



162
163
164
165
166
167
# File 'lib/mulang/ruby/ast_processor.rb', line 162

def on_for(node)
  variable, list, block = *node

  pattern = ms(:VariablePattern, variable.children.first)
  ms(:For, [ms(:Generator, pattern, process(list))], process(block) || none)
end

#on_if(node) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/mulang/ruby/ast_processor.rb', line 193

def on_if(node)
  condition, if_true, if_false = *node
  if_true  ||= s(:nil)
  if_false ||= s(:nil)

  ms :If, process(condition), process(if_true), process(if_false)
end

#on_irange(node) ⇒ Object



81
82
83
# File 'lib/mulang/ruby/ast_processor.rb', line 81

def on_irange(node)
  ms :Other, node.to_s, nil
end

#on_kwbegin(node) ⇒ Object



71
72
73
# File 'lib/mulang/ruby/ast_processor.rb', line 71

def on_kwbegin(node)
  process node.to_a.first
end

#on_lvar(node) ⇒ Object Also known as: on_ivar



201
202
203
204
# File 'lib/mulang/ruby/ast_processor.rb', line 201

def on_lvar(node)
  value = *node
  ms :Reference, value.first
end

#on_lvasgn(node) ⇒ Object Also known as: on_ivasgn



206
207
208
209
# File 'lib/mulang/ruby/ast_processor.rb', line 206

def on_lvasgn(node)
  id, value = *node
  ms :Assignment, id, process(value)
end

#on_module(node) ⇒ Object



16
17
18
19
20
21
22
23
# File 'lib/mulang/ruby/ast_processor.rb', line 16

def on_module(node)
  name, body = *node
  body ||= s(:nil)

  _, module_name = *name

  ms :Object, module_name, process(body)
end

#on_nil(_) ⇒ Object



145
146
147
# File 'lib/mulang/ruby/ast_processor.rb', line 145

def on_nil(_)
  ms :MuNil
end

#on_op_asgn(node) ⇒ Object



216
217
218
219
220
221
222
223
224
# File 'lib/mulang/ruby/ast_processor.rb', line 216

def on_op_asgn(node)
  assignee, message, value = *node

  if assignee.type == :send
    property_assignment assignee, message, value
  else
    var_assignment assignee, message, value
  end
end

#on_optarg(node) ⇒ Object



169
170
171
# File 'lib/mulang/ruby/ast_processor.rb', line 169

def on_optarg(node)
  ms :OtherPattern, node.to_s, nil
end

#on_or(node) ⇒ Object



97
98
99
100
# File 'lib/mulang/ruby/ast_processor.rb', line 97

def on_or(node)
  value, other = *node
  simple_send process(value), '||', [process(other)]
end

#on_or_asgn(node) ⇒ Object



246
247
248
249
# File 'lib/mulang/ruby/ast_processor.rb', line 246

def on_or_asgn(node)
  assignee, value = *node
  on_op_asgn s :op_asgn, assignee, '||', value
end

#on_regexp(node) ⇒ Object



85
86
87
88
89
# File 'lib/mulang/ruby/ast_processor.rb', line 85

def on_regexp(node)
  value, _ops = *node

  simple_send ms(:Reference, :Regexp), :new, [process(value)]
end

#on_resbody(node) ⇒ Object



38
39
40
41
42
# File 'lib/mulang/ruby/ast_processor.rb', line 38

def on_resbody(node)
  patterns, variable, block = *node

  [to_mulang_pattern(patterns, variable), process(block) || none]
end

#on_rescue(node) ⇒ Object



33
34
35
36
# File 'lib/mulang/ruby/ast_processor.rb', line 33

def on_rescue(node)
  try, *catch, _ = *node
  ms :Try, process(try), process_all(catch), none
end

#on_return(node) ⇒ Object



108
109
110
111
112
# File 'lib/mulang/ruby/ast_processor.rb', line 108

def on_return(node)
  value = *node

  ms(:Return, process(value.first))
end

#on_self(_) ⇒ Object



149
150
151
# File 'lib/mulang/ruby/ast_processor.rb', line 149

def on_self(_)
  ms :Self
end

#on_send(node) ⇒ Object



141
142
143
# File 'lib/mulang/ruby/ast_processor.rb', line 141

def on_send(node)
  handle_send_with_args(node)
end

#on_str(node) ⇒ Object



176
177
178
179
# File 'lib/mulang/ruby/ast_processor.rb', line 176

def on_str(node)
  value, _ = *node
  ms :MuString, value
end

#on_sym(node) ⇒ Object



181
182
183
184
# File 'lib/mulang/ruby/ast_processor.rb', line 181

def on_sym(node)
  value, _ = *node
  ms :MuSymbol, value.to_s
end

#on_true(_) ⇒ Object



264
265
266
# File 'lib/mulang/ruby/ast_processor.rb', line 264

def on_true(_)
  ms :MuBool, true
end

#property_assignment(assignee, message, value) ⇒ Object



231
232
233
234
235
# File 'lib/mulang/ruby/ast_processor.rb', line 231

def property_assignment(assignee, message, value)
  receiver, accessor, *accessor_args = *assignee

  reasign accessor, process_all(accessor_args), process(receiver), message, process(value)
end

#reasign(accessor, args, id, message, value) ⇒ Object



237
238
239
240
241
242
243
244
# File 'lib/mulang/ruby/ast_processor.rb', line 237

def reasign(accessor, args, id, message, value)
  simple_send id,
              "#{accessor}=".to_sym,
              args + [ms(:Send,
                        simple_send(id, accessor, args),
                        message_reference(message),
                        [value])]
end

#to_mulang_pattern(patterns, variable) ⇒ Object



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/mulang/ruby/ast_processor.rb', line 48

def to_mulang_pattern(patterns, variable)
  case [patterns, variable]
    when [nil, nil]
      ms :WildcardPattern
    when [nil, _]
      ms :VariablePattern, variable.to_a.first
    when [_, nil]
      to_single_pattern patterns
    else
      ms(:AsPattern, variable.to_a.first, to_single_pattern(patterns))
  end
end

#to_single_pattern(patterns) ⇒ Object



61
62
63
64
# File 'lib/mulang/ruby/ast_processor.rb', line 61

def to_single_pattern(patterns)
  mu_patterns = patterns.to_a.map { |it| to_type_pattern it }
  mu_patterns.size == 1 ? mu_patterns.first : ms(:UnionPattern, mu_patterns)
end

#to_type_pattern(node) ⇒ Object



66
67
68
69
# File 'lib/mulang/ruby/ast_processor.rb', line 66

def to_type_pattern(node)
  _, type = *node
  ms :TypePattern, type
end

#var_assignment(assignee, message, value) ⇒ Object



226
227
228
229
# File 'lib/mulang/ruby/ast_processor.rb', line 226

def var_assignment(assignee, message, value)
  id = assignee.to_a.first
  ms :Assignment, id, ms(:Send, ms(:Reference, id), message_reference(message), [process(value)])
end