Class: KaiserRuby::Transformer
- Inherits:
-
Object
- Object
- KaiserRuby::Transformer
show all
- Defined in:
- lib/kaiser_ruby/transformer.rb
Instance Attribute Summary collapse
Instance Method Summary
collapse
Constructor Details
Returns a new instance of Transformer.
5
6
7
8
9
10
11
12
|
# File 'lib/kaiser_ruby/transformer.rb', line 5
def initialize(tree)
@parsed_tree = tree
@output = []
@method_names = []
@nesting = 0
@indentation = ''
@lnum = 0
end
|
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args, &block) ⇒ Object
48
49
50
|
# File 'lib/kaiser_ruby/transformer.rb', line 48
def method_missing(m, *args, &block)
raise ArgumentError, "missing Transform rule: #{m}, #{args}"
end
|
Instance Attribute Details
#output ⇒ Object
Returns the value of attribute output.
3
4
5
|
# File 'lib/kaiser_ruby/transformer.rb', line 3
def output
@output
end
|
#parsed_tree ⇒ Object
Returns the value of attribute parsed_tree.
3
4
5
|
# File 'lib/kaiser_ruby/transformer.rb', line 3
def parsed_tree
@parsed_tree
end
|
Instance Method Details
239
240
241
242
243
244
245
246
247
|
# File 'lib/kaiser_ruby/transformer.rb', line 239
def additional_argument_transformation(argument)
arg = @method_names.include?(argument) ? "defined?(#{argument})" : argument
arg = "#{arg}.to_bool" if arg !~ /==|>|>=|<|<=|!=/
return arg
end
|
#filter_string(string, rxp: /[[:alpha:]]/) ⇒ Object
354
355
356
|
# File 'lib/kaiser_ruby/transformer.rb', line 354
def filter_string(string, rxp: /[[:alpha:]]/)
string.to_s.split(/\s+/).map { |e| e.chars.select { |c| c =~ rxp }.join }.reject { |a| a.empty? }
end
|
43
44
45
46
|
# File 'lib/kaiser_ruby/transformer.rb', line 43
def select_transformer(object)
key = object.keys.first
send("transform_#{key}", object)
end
|
#str_to_num(string) ⇒ Object
350
351
352
|
# File 'lib/kaiser_ruby/transformer.rb', line 350
def str_to_num(string)
filter_string(string).map { |e| e.length % 10 }.join
end
|
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
|
# File 'lib/kaiser_ruby/transformer.rb', line 14
def transform
@last_variable = nil @else_already = nil @local_variables = []
@parsed_tree.each_with_index do |line_object, lnum|
@lnum = lnum
transformed_line = select_transformer(line_object)
if line_object[:nesting]
@nesting = line_object[:nesting]
else
@nesting = 0
end
@indentation = ' ' * @nesting
@output << @indentation + transformed_line
end
while @nesting > 0
@nesting -= 1
@indentation = ' ' * @nesting
@output << @indentation + "end"
end
@output << '' if @output.size > 1
@output.join("\n")
end
|
131
132
133
134
135
|
# File 'lib/kaiser_ruby/transformer.rb', line 131
def transform_addition(object)
left = select_transformer(object[:addition][:left])
right = select_transformer(object[:addition][:right])
"#{left} + #{right}"
end
|
322
323
324
325
326
327
|
# File 'lib/kaiser_ruby/transformer.rb', line 322
def transform_and(object)
left = select_transformer(object[:and][:left])
right = select_transformer(object[:and][:right])
"#{left} && #{right}"
end
|
122
123
124
125
126
127
128
129
|
# File 'lib/kaiser_ruby/transformer.rb', line 122
def transform_argument_list(object)
list = []
object[:argument_list].each do |arg|
list << select_transformer(arg)
end
list.join(', ')
end
|
155
156
157
158
159
|
# File 'lib/kaiser_ruby/transformer.rb', line 155
def transform_assignment(object)
left = select_transformer(object[:assignment][:left])
right = select_transformer(object[:assignment][:right])
"#{left} = #{right}"
end
|
79
80
81
82
|
# File 'lib/kaiser_ruby/transformer.rb', line 79
def transform_break(object)
raise KaiserRuby::RockstarSyntaxError, "Break used outside of a loop" if object[:nesting].to_i.zero?
"break"
end
|
74
75
76
77
|
# File 'lib/kaiser_ruby/transformer.rb', line 74
def transform_continue(object)
raise KaiserRuby::RockstarSyntaxError, "Continue used outside of a loop" if object[:nesting].to_i.zero?
"next"
end
|
161
162
163
164
165
|
# File 'lib/kaiser_ruby/transformer.rb', line 161
def transform_decrement(object)
argument = select_transformer(object[:decrement])
amount = object.dig(:decrement, :amount)
"#{argument} -= #{amount}"
end
|
149
150
151
152
153
|
# File 'lib/kaiser_ruby/transformer.rb', line 149
def transform_division(object)
left = select_transformer(object[:division][:left])
right = select_transformer(object[:division][:right])
"#{left} / #{right}"
end
|
255
256
257
258
259
260
261
|
# File 'lib/kaiser_ruby/transformer.rb', line 255
def transform_else(object)
raise KaiserRuby::RockstarSyntaxError, "Else outside an if block" if object[:nesting].to_i.zero?
raise KaiserRuby::RockstarSyntaxError, "Double else inside if block" if @else_already != nil && object[:nesting_start_line] == @else_already
@else_already = object[:nesting_start_line]
"else"
end
|
227
228
229
230
231
232
233
234
235
236
237
|
# File 'lib/kaiser_ruby/transformer.rb', line 227
def transform_empty_line(_object)
if @nesting == 0
return ""
elsif @nesting == 1
@local_variables = []
return "end\n"
else
@else_already = nil
return "end\n"
end
end
|
275
276
277
278
279
|
# File 'lib/kaiser_ruby/transformer.rb', line 275
def transform_equality(object)
left = select_transformer(object[:equality][:left])
right = select_transformer(object[:equality][:right])
"#{left} == #{right}"
end
|
311
312
313
314
315
316
317
318
319
320
|
# File 'lib/kaiser_ruby/transformer.rb', line 311
def transform_function(object)
funcname = transform_function_name(object[:function][:name])
argument = select_transformer(object[:function][:argument])
@method_names << funcname
@local_variables = argument.split(', ')
"def #{funcname}(#{argument})"
end
|
173
174
175
176
177
178
|
# File 'lib/kaiser_ruby/transformer.rb', line 173
def transform_function_call(object)
func_name = select_transformer(object[:function_call][:left])
argument = select_transformer(object[:function_call][:right])
"#{func_name}(#{argument})"
end
|
106
107
108
|
# File 'lib/kaiser_ruby/transformer.rb', line 106
def transform_function_name(object)
object[:function_name]
end
|
287
288
289
290
291
|
# File 'lib/kaiser_ruby/transformer.rb', line 287
def transform_gt(object)
left = select_transformer(object[:gt][:left])
right = select_transformer(object[:gt][:right])
"#{left} > #{right}"
end
|
293
294
295
296
297
|
# File 'lib/kaiser_ruby/transformer.rb', line 293
def transform_gte(object)
left = select_transformer(object[:gte][:left])
right = select_transformer(object[:gte][:right])
"#{left} >= #{right}"
end
|
249
250
251
252
253
|
# File 'lib/kaiser_ruby/transformer.rb', line 249
def transform_if(object)
argument = select_transformer(object[:if][:argument])
argument = additional_argument_transformation(argument)
"if #{argument}"
end
|
167
168
169
170
171
|
# File 'lib/kaiser_ruby/transformer.rb', line 167
def transform_increment(object)
argument = select_transformer(object[:increment])
amount = object.dig(:increment, :amount)
"#{argument} += #{amount}"
end
|
281
282
283
284
285
|
# File 'lib/kaiser_ruby/transformer.rb', line 281
def transform_inequality(object)
left = select_transformer(object[:inequality][:left])
right = select_transformer(object[:inequality][:right])
"#{left} != #{right}"
end
|
64
65
66
|
# File 'lib/kaiser_ruby/transformer.rb', line 64
def transform_listen(_object)
"print '> '\n$stdin.gets.chomp"
end
|
59
60
61
62
|
# File 'lib/kaiser_ruby/transformer.rb', line 59
def transform_listen_to(object)
var = select_transformer(object[:listen_to])
"print '> '\n__input = $stdin.gets.chomp\n#{var} = Float(__input) rescue __input"
end
|
102
103
104
|
# File 'lib/kaiser_ruby/transformer.rb', line 102
def transform_local_variable_name(object)
object[:local_variable_name]
end
|
299
300
301
302
303
|
# File 'lib/kaiser_ruby/transformer.rb', line 299
def transform_lt(object)
left = select_transformer(object[:lt][:left])
right = select_transformer(object[:lt][:right])
"#{left} < #{right}"
end
|
305
306
307
308
309
|
# File 'lib/kaiser_ruby/transformer.rb', line 305
def transform_lte(object)
left = select_transformer(object[:lte][:left])
right = select_transformer(object[:lte][:right])
"#{left} <= #{right}"
end
|
137
138
139
140
141
|
# File 'lib/kaiser_ruby/transformer.rb', line 137
def transform_multiplication(object)
left = select_transformer(object[:multiplication][:left])
right = select_transformer(object[:multiplication][:right])
"#{left} * #{right}"
end
|
341
342
343
344
345
346
|
# File 'lib/kaiser_ruby/transformer.rb', line 341
def transform_nor(object)
left = select_transformer(object[:nor][:left])
right = select_transformer(object[:nor][:right])
"!(#{left} || #{right})"
end
|
329
330
331
332
|
# File 'lib/kaiser_ruby/transformer.rb', line 329
def transform_not(object)
arg = select_transformer(object[:not])
"!#{arg}"
end
|
118
119
120
|
# File 'lib/kaiser_ruby/transformer.rb', line 118
def transform_number(object)
object[:number]
end
|
203
204
205
206
207
208
209
210
211
212
|
# File 'lib/kaiser_ruby/transformer.rb', line 203
def transform_number_literal(object)
string = object[:number_literal]
if string.include?('.')
string.split('.', 2).map do |sub|
str_to_num(sub.strip)
end.join('.').to_f
else
str_to_num(string).to_f
end
end
|
334
335
336
337
338
339
|
# File 'lib/kaiser_ruby/transformer.rb', line 334
def transform_or(object)
left = select_transformer(object[:or][:left])
right = select_transformer(object[:or][:right])
"#{left} || #{right}"
end
|
180
181
182
|
# File 'lib/kaiser_ruby/transformer.rb', line 180
def transform_passed_function_call(object)
return transform_function_call(object[:passed_function_call])
end
|
197
198
199
200
201
|
# File 'lib/kaiser_ruby/transformer.rb', line 197
def transform_poetic_number(object)
var = select_transformer(object[:poetic_number][:left])
value = select_transformer(object[:poetic_number][:right])
"#{var} = #{value}"
end
|
184
185
186
187
188
189
|
# File 'lib/kaiser_ruby/transformer.rb', line 184
def transform_poetic_string(object)
var = select_transformer(object[:poetic_string][:left])
value = select_transformer(object[:poetic_string][:right])
"#{var} = #{value}"
end
|
191
192
193
194
195
|
# File 'lib/kaiser_ruby/transformer.rb', line 191
def transform_poetic_type(object)
var = select_transformer(object[:poetic_type][:left])
value = select_transformer(object[:poetic_type][:right])
"#{var} = #{value}"
end
|
transform language tree into Ruby
54
55
56
57
|
# File 'lib/kaiser_ruby/transformer.rb', line 54
def transform_print(object)
var = select_transformer(object[:print])
"puts #{var}"
end
|
110
111
112
|
# File 'lib/kaiser_ruby/transformer.rb', line 110
def transform_pronoun(_object)
@last_variable
end
|
68
69
70
71
72
|
# File 'lib/kaiser_ruby/transformer.rb', line 68
def transform_return(object)
raise KaiserRuby::RockstarSyntaxError, "Return used outside of a function" if object[:nesting].to_i.zero?
var = select_transformer(object[:return])
"return #{var}"
end
|
114
115
116
|
# File 'lib/kaiser_ruby/transformer.rb', line 114
def transform_string(object)
object[:string]
end
|
143
144
145
146
147
|
# File 'lib/kaiser_ruby/transformer.rb', line 143
def transform_subtraction(object)
left = select_transformer(object[:subtraction][:left])
right = select_transformer(object[:subtraction][:right])
"#{left} - #{right}"
end
|
214
215
216
217
218
219
220
221
222
223
224
225
|
# File 'lib/kaiser_ruby/transformer.rb', line 214
def transform_type(object)
case object[:type]
when "nil"
'nil'
when "null"
'0.0'
when "true"
'true'
when "false"
'false'
end
end
|
269
270
271
272
273
|
# File 'lib/kaiser_ruby/transformer.rb', line 269
def transform_until(object)
argument = select_transformer(object[:until][:argument])
argument = additional_argument_transformation(argument)
"until #{argument}"
end
|
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# File 'lib/kaiser_ruby/transformer.rb', line 84
def transform_variable_name(object)
varname = object[:variable_name]
if object[:type] == :assignment
if @local_variables.empty?
varname = "@#{varname}"
else
@local_variables << varname
end
else
unless @local_variables.include?(varname)
varname = @method_names.include?(varname) ? varname : "@#{varname}"
end
end
@last_variable = varname
varname
end
|
263
264
265
266
267
|
# File 'lib/kaiser_ruby/transformer.rb', line 263
def transform_while(object)
argument = select_transformer(object[:while][:argument])
argument = additional_argument_transformation(argument)
"while #{argument}"
end
|