kapusta 0.13.0 → 0.13.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b547075d7dcb73121e61dc17577cb8262265eaffb6ee0d74b88a74ce83c8e09a
4
- data.tar.gz: 877f490eca3f0d4419e38b4619f77470aff18ddd8fede555f2963beb8db5994f
3
+ metadata.gz: 9324827934a0647689027ecf5fc6bf83708fe536cd904dc04d1f9c0594c37581
4
+ data.tar.gz: 736a8f7d8158fc4502415168f5791d7af8b98f392800255576c1d0182ef920c6
5
5
  SHA512:
6
- metadata.gz: cddc220382f4c7f59788f4624f9e86f55bc58fe2b3fa6978f4e6d8bebaa870ff73be57786ecf2db94f14d6db460b3f485b6f82195e7fd21e255c7a7612ab50c2
7
- data.tar.gz: 6c653e095b1c3d406f95e7f1659b615a2a59eaa21ef77e709cfc2dfc398d3526fb493f5054cb541acd36b203e690dbc28626e951e3e8f9d5e27366c0d5885834
6
+ metadata.gz: 62e4118362c7fbe7ae034470a01ddf37a0bb826fb142e2611d72b09ded1777e52bf2b078cf48c0283dda6f0a8c5989ec31f60d0913cf16ec3ac9ccabf2c40626
7
+ data.tar.gz: 5fbd5b3a7809eff626c43203b1c36761efac10cb5663ca345ace26fbea731da63402909be6a04f22aedaca80945e1db3456209a6ac335b8fc4a2152bcc198395
@@ -18,11 +18,11 @@ module Kapusta
18
18
  fn_env = env.child
19
19
  ruby_name = define_local(fn_env, name_sym.name)
20
20
  <<~RUBY.chomp
21
- (-> do
21
+ lambda do
22
22
  #{ruby_name} = nil
23
23
  #{ruby_name} = #{emit_lambda(pattern, body, fn_env, current_scope)}
24
24
  #{ruby_name}
25
- end).call
25
+ end.call
26
26
  RUBY
27
27
  end
28
28
  end
@@ -259,9 +259,9 @@ module Kapusta
259
259
  def emit_let(args, env, current_scope)
260
260
  binding_code, body_code = emit_let_parts(args, env, current_scope, result: true)
261
261
  [
262
- '(-> do',
262
+ 'lambda do',
263
263
  indent(join_code(binding_code, body_code)),
264
- 'end).call'
264
+ 'end.call'
265
265
  ].join("\n")
266
266
  end
267
267
 
@@ -293,7 +293,23 @@ module Kapusta
293
293
  body_code, = emit_sequence(body, child_env, current_scope,
294
294
  allow_method_definitions: false,
295
295
  result:)
296
- [binding_codes.reject(&:empty?).join("\n"), body_code]
296
+ [join_binding_codes(binding_codes), body_code]
297
+ end
298
+
299
+ def join_binding_codes(binding_codes)
300
+ codes = binding_codes.reject(&:empty?)
301
+ return '' if codes.empty?
302
+
303
+ result = codes.first.dup
304
+ codes.each_cons(2) do |prev, curr|
305
+ separator = block_binding?(prev) || block_binding?(curr) ? "\n\n" : "\n"
306
+ result << separator << curr
307
+ end
308
+ result
309
+ end
310
+
311
+ def block_binding?(code)
312
+ code.match?(/\bdo\b/) && code.match?(/\bend\b/)
297
313
  end
298
314
 
299
315
  def join_code(*chunks)
@@ -376,7 +392,7 @@ module Kapusta
376
392
 
377
393
  def emit_local_expr(args, env, current_scope)
378
394
  code, = emit_local_form(List.new([Sym.new('local'), *args]), env.child, current_scope)
379
- "(-> do\n#{indent(code)}\nend).call"
395
+ "lambda do\n#{indent(code)}\nend.call"
380
396
  end
381
397
 
382
398
  def emit_global_expr(args, _env, _current_scope)
@@ -89,11 +89,11 @@ module Kapusta
89
89
  emit_sequence_value_assignment(acc_var, body_code)
90
90
  end
91
91
  [
92
- '(-> do',
92
+ 'lambda do',
93
93
  indent("#{acc_var} = #{init_code}"),
94
94
  indent(iter_code),
95
95
  indent(acc_var),
96
- 'end).call'
96
+ 'end.call'
97
97
  ].join("\n")
98
98
  end
99
99
 
@@ -221,11 +221,11 @@ module Kapusta
221
221
 
222
222
  def emit_collection_result(result_var, initial_code, iter_code)
223
223
  [
224
- '(-> do',
224
+ 'lambda do',
225
225
  indent("#{result_var} = #{initial_code}"),
226
226
  indent(iter_code),
227
227
  indent(result_var),
228
- 'end).call'
228
+ 'end.call'
229
229
  ].join("\n")
230
230
  end
231
231
 
@@ -61,10 +61,10 @@ module Kapusta
61
61
  return body unless value_var
62
62
 
63
63
  [
64
- '(-> do',
64
+ 'lambda do',
65
65
  indent("#{value_var} = #{value_code}"),
66
66
  indent(body),
67
- 'end).call'
67
+ 'end.call'
68
68
  ].join("\n")
69
69
  end
70
70
 
@@ -212,30 +212,30 @@ module Kapusta
212
212
 
213
213
  def emit_while(args, env, current_scope)
214
214
  <<~RUBY.chomp
215
- (-> do
215
+ lambda do
216
216
  #{indent(emit_while_statement(args, env, current_scope))}
217
217
  nil
218
- end).call
218
+ end.call
219
219
  RUBY
220
220
  end
221
221
 
222
222
  def emit_for(args, env, current_scope)
223
223
  loop_code = emit_for_statement(args, env, current_scope)
224
224
  <<~RUBY.chomp
225
- (-> do
225
+ lambda do
226
226
  #{indent(loop_code)}
227
227
  nil
228
- end).call
228
+ end.call
229
229
  RUBY
230
230
  end
231
231
 
232
232
  def emit_each(args, env, current_scope)
233
233
  iter_code = emit_each_statement(args, env, current_scope)
234
234
  <<~RUBY.chomp
235
- (-> do
235
+ lambda do
236
236
  #{iter_code}
237
237
  nil
238
- end).call
238
+ end.call
239
239
  RUBY
240
240
  end
241
241
 
@@ -35,7 +35,7 @@ module Kapusta
35
35
  if literal_name && binary_operator_call?(literal_name.to_s, positional, kwargs, block_form)
36
36
  return emit_binary_operator_call(receiver, literal_name.to_s, positional[0])
37
37
  end
38
- if literal_name && direct_method_name?(literal_name.to_s)
38
+ if literal_name && colon_call_direct_method_name?(literal_name.to_s)
39
39
  return emit_direct_method_call(receiver, Kapusta.kebab_to_snake(literal_name.to_s),
40
40
  positional, kwargs, block_form, env, current_scope)
41
41
  end
@@ -99,7 +99,7 @@ module Kapusta
99
99
  segments = constant_segments(name_sym)
100
100
  emit_error!(:invalid_module_name, name: name_sym.name) unless segments
101
101
  inner = build_nested_module(segments, body)
102
- ['(-> do', indent(inner), indent(segments.join('::')), 'end).call'].join("\n")
102
+ ['lambda do', indent(inner), indent(segments.join('::')), 'end.call'].join("\n")
103
103
  end
104
104
 
105
105
  def emit_direct_module_header(name_sym, body)
@@ -114,7 +114,7 @@ module Kapusta
114
114
  emit_error!(:invalid_class_name, name: name_sym.name) unless segments
115
115
  super_code = class_super_code(supers, env)
116
116
  inner = build_nested_class(segments, super_code, body)
117
- ['(-> do', indent(inner), indent(segments.join('::')), 'end).call'].join("\n")
117
+ ['lambda do', indent(inner), indent(segments.join('::')), 'end.call'].join("\n")
118
118
  end
119
119
 
120
120
  def emit_direct_class_header(name_sym, supers, body, env)
@@ -488,6 +488,10 @@ module Kapusta
488
488
  Kapusta.kebab_to_snake(name).match?(/\A[a-z_]\w*[!?=]?\z/)
489
489
  end
490
490
 
491
+ def colon_call_direct_method_name?(name)
492
+ Kapusta.kebab_to_snake(name).match?(/\A[a-zA-Z_]\w*[!?=]?\z/)
493
+ end
494
+
491
495
  def global_name(name)
492
496
  Kapusta.kebab_to_snake(name).gsub(/[^a-zA-Z0-9_]/, '_')
493
497
  end
@@ -501,6 +505,7 @@ module Kapusta
501
505
  /\A-?\d+(?:\.\d+)?\z/, # number
502
506
  /\A[a-z_]\w*(?:\.[a-z_]\w*[!?=]?(?:\([^()\n]*\))?|\[[^\[\]]*\])+\z/, # local + .m/[k] chain
503
507
  /\A[A-Z]\w*(?:::[A-Z]\w*)*(?:\.[a-z_]\w*[!?=]?(?:\([^()\n]*\))?|\[[^\[\]]*\])+\z/, # const + chain
508
+ /\A\([^()\n]*\)(?:\.[a-zA-Z_]\w*[!?=]?(?:\([^()\n]*\))?|\[[^\[\]]*\])+\z/, # (expr).chain
504
509
  /\A:[a-zA-Z_]\w*[!?=]?\z/, # :symbol
505
510
  /\A"(?:[^"\\]|\\.)*"\z/, # "string"
506
511
  /\A'(?:[^'\\]|\\.)*'\z/, # 'string'
@@ -158,11 +158,38 @@ module Kapusta
158
158
  emit_sequence_statement_form(form, env, current_scope, result_needed:)
159
159
  elsif set_new_local_form?(form, env)
160
160
  emit_set_form(form, env, current_scope)
161
+ elsif !result_needed && class_or_module_form?(form)
162
+ [emit_class_or_module_statement(form, env), env]
161
163
  else
162
164
  [emit_expr(form, env, current_scope), env]
163
165
  end
164
166
  end
165
167
 
168
+ def class_or_module_form?(form)
169
+ form.is_a?(List) && form.head.is_a?(Sym) &&
170
+ %w[class module].include?(form.head.name)
171
+ end
172
+
173
+ def emit_class_or_module_statement(form, env)
174
+ args = form.rest
175
+ if form.head.name == 'module'
176
+ name_sym = args[0]
177
+ body = with_class_body do
178
+ emit_sequence(args[1..], env.child, :module, allow_method_definitions: true,
179
+ result: false).first
180
+ end
181
+ emit_direct_module_header(name_sym, body) || emit_module_wrapper(name_sym, body)
182
+ else
183
+ name_sym, supers, body_forms = split_class_args(args)
184
+ body = with_class_body do
185
+ emit_sequence(body_forms, env.child, :class, allow_method_definitions: true,
186
+ result: false).first
187
+ end
188
+ emit_direct_class_header(name_sym, supers, body, env) ||
189
+ emit_class_wrapper(name_sym, supers, env, body)
190
+ end
191
+ end
192
+
166
193
  def emit_do_form(forms, env, current_scope, result_needed: true)
167
194
  body, new_env = emit_sequence(forms, env, current_scope,
168
195
  allow_method_definitions: false,
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Kapusta
4
- VERSION = '0.13.0'
4
+ VERSION = '0.13.1'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: kapusta
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.13.0
4
+ version: 0.13.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Evgenii Morozov