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 +4 -4
- data/lib/kapusta/compiler/emitter/bindings.rb +22 -6
- data/lib/kapusta/compiler/emitter/collections.rb +4 -4
- data/lib/kapusta/compiler/emitter/control_flow.rb +8 -8
- data/lib/kapusta/compiler/emitter/interop.rb +8 -3
- data/lib/kapusta/compiler/emitter/support.rb +27 -0
- data/lib/kapusta/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9324827934a0647689027ecf5fc6bf83708fe536cd904dc04d1f9c0594c37581
|
|
4
|
+
data.tar.gz: 736a8f7d8158fc4502415168f5791d7af8b98f392800255576c1d0182ef920c6
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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
|
-
|
|
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
|
|
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
|
-
'
|
|
262
|
+
'lambda do',
|
|
263
263
|
indent(join_code(binding_code, body_code)),
|
|
264
|
-
'end
|
|
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
|
|
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
|
-
"
|
|
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
|
-
'
|
|
92
|
+
'lambda do',
|
|
93
93
|
indent("#{acc_var} = #{init_code}"),
|
|
94
94
|
indent(iter_code),
|
|
95
95
|
indent(acc_var),
|
|
96
|
-
'end
|
|
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
|
-
'
|
|
224
|
+
'lambda do',
|
|
225
225
|
indent("#{result_var} = #{initial_code}"),
|
|
226
226
|
indent(iter_code),
|
|
227
227
|
indent(result_var),
|
|
228
|
-
'end
|
|
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
|
-
'
|
|
64
|
+
'lambda do',
|
|
65
65
|
indent("#{value_var} = #{value_code}"),
|
|
66
66
|
indent(body),
|
|
67
|
-
'end
|
|
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
|
-
|
|
215
|
+
lambda do
|
|
216
216
|
#{indent(emit_while_statement(args, env, current_scope))}
|
|
217
217
|
nil
|
|
218
|
-
end
|
|
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
|
-
|
|
225
|
+
lambda do
|
|
226
226
|
#{indent(loop_code)}
|
|
227
227
|
nil
|
|
228
|
-
end
|
|
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
|
-
|
|
235
|
+
lambda do
|
|
236
236
|
#{iter_code}
|
|
237
237
|
nil
|
|
238
|
-
end
|
|
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 &&
|
|
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
|
-
['
|
|
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
|
-
['
|
|
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,
|
data/lib/kapusta/version.rb
CHANGED