konpeito 0.1.0

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.
Files changed (180) hide show
  1. checksums.yaml +7 -0
  2. data/.ruby-version +1 -0
  3. data/CHANGELOG.md +75 -0
  4. data/CONTRIBUTING.md +123 -0
  5. data/LICENSE +21 -0
  6. data/README.md +257 -0
  7. data/Rakefile +11 -0
  8. data/bin/konpeito +6 -0
  9. data/konpeito.gemspec +43 -0
  10. data/lib/konpeito/ast/typed_ast.rb +620 -0
  11. data/lib/konpeito/ast/visitor.rb +78 -0
  12. data/lib/konpeito/cache/cache_manager.rb +230 -0
  13. data/lib/konpeito/cache/dependency_graph.rb +192 -0
  14. data/lib/konpeito/cache.rb +8 -0
  15. data/lib/konpeito/cli/base_command.rb +187 -0
  16. data/lib/konpeito/cli/build_command.rb +220 -0
  17. data/lib/konpeito/cli/check_command.rb +104 -0
  18. data/lib/konpeito/cli/config.rb +231 -0
  19. data/lib/konpeito/cli/deps_command.rb +128 -0
  20. data/lib/konpeito/cli/doctor_command.rb +340 -0
  21. data/lib/konpeito/cli/fmt_command.rb +199 -0
  22. data/lib/konpeito/cli/init_command.rb +312 -0
  23. data/lib/konpeito/cli/lsp_command.rb +40 -0
  24. data/lib/konpeito/cli/run_command.rb +150 -0
  25. data/lib/konpeito/cli/test_command.rb +248 -0
  26. data/lib/konpeito/cli/watch_command.rb +212 -0
  27. data/lib/konpeito/cli.rb +301 -0
  28. data/lib/konpeito/codegen/builtin_methods.rb +229 -0
  29. data/lib/konpeito/codegen/cruby_backend.rb +1090 -0
  30. data/lib/konpeito/codegen/debug_info.rb +352 -0
  31. data/lib/konpeito/codegen/inliner.rb +486 -0
  32. data/lib/konpeito/codegen/jvm_backend.rb +197 -0
  33. data/lib/konpeito/codegen/jvm_generator.rb +13412 -0
  34. data/lib/konpeito/codegen/llvm_generator.rb +13191 -0
  35. data/lib/konpeito/codegen/loop_optimizer.rb +363 -0
  36. data/lib/konpeito/codegen/monomorphizer.rb +359 -0
  37. data/lib/konpeito/codegen/profile_runtime.c +341 -0
  38. data/lib/konpeito/codegen/profiler.rb +99 -0
  39. data/lib/konpeito/compiler.rb +592 -0
  40. data/lib/konpeito/dependency_resolver.rb +296 -0
  41. data/lib/konpeito/diagnostics/collector.rb +127 -0
  42. data/lib/konpeito/diagnostics/diagnostic.rb +237 -0
  43. data/lib/konpeito/diagnostics/renderer.rb +144 -0
  44. data/lib/konpeito/formatter/formatter.rb +1214 -0
  45. data/lib/konpeito/hir/builder.rb +7167 -0
  46. data/lib/konpeito/hir/nodes.rb +2465 -0
  47. data/lib/konpeito/lsp/document_manager.rb +820 -0
  48. data/lib/konpeito/lsp/server.rb +183 -0
  49. data/lib/konpeito/lsp/transport.rb +38 -0
  50. data/lib/konpeito/parser/prism_adapter.rb +65 -0
  51. data/lib/konpeito/platform.rb +103 -0
  52. data/lib/konpeito/profile/report.rb +136 -0
  53. data/lib/konpeito/rbs_inline/preprocessor.rb +199 -0
  54. data/lib/konpeito/stdlib/compression/compression.rb +72 -0
  55. data/lib/konpeito/stdlib/compression/compression.rbs +60 -0
  56. data/lib/konpeito/stdlib/compression/compression_native.c +415 -0
  57. data/lib/konpeito/stdlib/compression/extconf.rb +19 -0
  58. data/lib/konpeito/stdlib/crypto/crypto.rb +85 -0
  59. data/lib/konpeito/stdlib/crypto/crypto.rbs +74 -0
  60. data/lib/konpeito/stdlib/crypto/crypto_native.c +312 -0
  61. data/lib/konpeito/stdlib/crypto/extconf.rb +40 -0
  62. data/lib/konpeito/stdlib/http/extconf.rb +19 -0
  63. data/lib/konpeito/stdlib/http/http.rb +125 -0
  64. data/lib/konpeito/stdlib/http/http.rbs +57 -0
  65. data/lib/konpeito/stdlib/http/http_native.c +440 -0
  66. data/lib/konpeito/stdlib/json/extconf.rb +17 -0
  67. data/lib/konpeito/stdlib/json/json.rb +44 -0
  68. data/lib/konpeito/stdlib/json/json.rbs +33 -0
  69. data/lib/konpeito/stdlib/json/json_native.c +286 -0
  70. data/lib/konpeito/stdlib/ui/extconf.rb +216 -0
  71. data/lib/konpeito/stdlib/ui/konpeito_ui_native.cpp +1625 -0
  72. data/lib/konpeito/stdlib/ui/konpeito_ui_native.h +162 -0
  73. data/lib/konpeito/stdlib/ui/ui.rb +318 -0
  74. data/lib/konpeito/stdlib/ui/ui.rbs +247 -0
  75. data/lib/konpeito/type_checker/annotation_parser.rb +67 -0
  76. data/lib/konpeito/type_checker/hm_inferrer.rb +2565 -0
  77. data/lib/konpeito/type_checker/inferrer.rb +565 -0
  78. data/lib/konpeito/type_checker/rbs_loader.rb +1621 -0
  79. data/lib/konpeito/type_checker/type_resolver.rb +276 -0
  80. data/lib/konpeito/type_checker/types.rb +1434 -0
  81. data/lib/konpeito/type_checker/unification.rb +323 -0
  82. data/lib/konpeito/ui/animation/animated_state.rb +80 -0
  83. data/lib/konpeito/ui/animation/easing.rb +59 -0
  84. data/lib/konpeito/ui/animation/value_tween.rb +66 -0
  85. data/lib/konpeito/ui/app.rb +379 -0
  86. data/lib/konpeito/ui/box.rb +38 -0
  87. data/lib/konpeito/ui/castella.rb +70 -0
  88. data/lib/konpeito/ui/castella_native.rb +76 -0
  89. data/lib/konpeito/ui/chart/area_chart.rb +305 -0
  90. data/lib/konpeito/ui/chart/bar_chart.rb +288 -0
  91. data/lib/konpeito/ui/chart/base_chart.rb +210 -0
  92. data/lib/konpeito/ui/chart/chart_helpers.rb +79 -0
  93. data/lib/konpeito/ui/chart/gauge_chart.rb +171 -0
  94. data/lib/konpeito/ui/chart/heatmap_chart.rb +222 -0
  95. data/lib/konpeito/ui/chart/line_chart.rb +289 -0
  96. data/lib/konpeito/ui/chart/pie_chart.rb +219 -0
  97. data/lib/konpeito/ui/chart/scales.rb +77 -0
  98. data/lib/konpeito/ui/chart/scatter_chart.rb +303 -0
  99. data/lib/konpeito/ui/chart/stacked_bar_chart.rb +276 -0
  100. data/lib/konpeito/ui/column.rb +271 -0
  101. data/lib/konpeito/ui/core.rb +2199 -0
  102. data/lib/konpeito/ui/dsl.rb +443 -0
  103. data/lib/konpeito/ui/frame.rb +171 -0
  104. data/lib/konpeito/ui/frame_native.rb +494 -0
  105. data/lib/konpeito/ui/markdown/ast.rb +124 -0
  106. data/lib/konpeito/ui/markdown/mermaid/layout.rb +387 -0
  107. data/lib/konpeito/ui/markdown/mermaid/models.rb +232 -0
  108. data/lib/konpeito/ui/markdown/mermaid/parser.rb +519 -0
  109. data/lib/konpeito/ui/markdown/mermaid/renderer.rb +336 -0
  110. data/lib/konpeito/ui/markdown/parser.rb +805 -0
  111. data/lib/konpeito/ui/markdown/renderer.rb +639 -0
  112. data/lib/konpeito/ui/markdown/theme.rb +165 -0
  113. data/lib/konpeito/ui/render_node.rb +260 -0
  114. data/lib/konpeito/ui/row.rb +207 -0
  115. data/lib/konpeito/ui/spacer.rb +18 -0
  116. data/lib/konpeito/ui/style.rb +799 -0
  117. data/lib/konpeito/ui/theme.rb +563 -0
  118. data/lib/konpeito/ui/themes/material.rb +35 -0
  119. data/lib/konpeito/ui/themes/tokyo_night.rb +6 -0
  120. data/lib/konpeito/ui/widgets/button.rb +103 -0
  121. data/lib/konpeito/ui/widgets/calendar.rb +1034 -0
  122. data/lib/konpeito/ui/widgets/checkbox.rb +119 -0
  123. data/lib/konpeito/ui/widgets/container.rb +91 -0
  124. data/lib/konpeito/ui/widgets/data_table.rb +667 -0
  125. data/lib/konpeito/ui/widgets/divider.rb +29 -0
  126. data/lib/konpeito/ui/widgets/image.rb +105 -0
  127. data/lib/konpeito/ui/widgets/input.rb +485 -0
  128. data/lib/konpeito/ui/widgets/markdown.rb +57 -0
  129. data/lib/konpeito/ui/widgets/modal.rb +163 -0
  130. data/lib/konpeito/ui/widgets/multiline_input.rb +968 -0
  131. data/lib/konpeito/ui/widgets/multiline_text.rb +180 -0
  132. data/lib/konpeito/ui/widgets/net_image.rb +100 -0
  133. data/lib/konpeito/ui/widgets/progress_bar.rb +70 -0
  134. data/lib/konpeito/ui/widgets/radio_buttons.rb +93 -0
  135. data/lib/konpeito/ui/widgets/slider.rb +133 -0
  136. data/lib/konpeito/ui/widgets/switch.rb +84 -0
  137. data/lib/konpeito/ui/widgets/tabs.rb +157 -0
  138. data/lib/konpeito/ui/widgets/text.rb +110 -0
  139. data/lib/konpeito/ui/widgets/tree.rb +426 -0
  140. data/lib/konpeito/version.rb +5 -0
  141. data/lib/konpeito.rb +109 -0
  142. data/test_native_array.rb +172 -0
  143. data/test_native_array_class.rb +197 -0
  144. data/test_native_class.rb +151 -0
  145. data/tools/konpeito-asm/build.sh +65 -0
  146. data/tools/konpeito-asm/lib/asm-9.7.1.jar +0 -0
  147. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KArray.class +0 -0
  148. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCompression.class +0 -0
  149. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KConditionVariable.class +0 -0
  150. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCrypto.class +0 -0
  151. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KFile.class +0 -0
  152. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHTTP.class +0 -0
  153. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHash.class +0 -0
  154. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON$Parser.class +0 -0
  155. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON.class +0 -0
  156. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KMath.class +0 -0
  157. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactor.class +0 -0
  158. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactorPort.class +0 -0
  159. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KSizedQueue.class +0 -0
  160. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KThread.class +0 -0
  161. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KTime.class +0 -0
  162. data/tools/konpeito-asm/runtime-classes/konpeito/runtime/RubyDispatch.class +0 -0
  163. data/tools/konpeito-asm/src/ClassIntrospector.java +312 -0
  164. data/tools/konpeito-asm/src/KonpeitoAssembler.java +659 -0
  165. data/tools/konpeito-asm/src/konpeito/runtime/KArray.java +390 -0
  166. data/tools/konpeito-asm/src/konpeito/runtime/KCompression.java +168 -0
  167. data/tools/konpeito-asm/src/konpeito/runtime/KConditionVariable.java +48 -0
  168. data/tools/konpeito-asm/src/konpeito/runtime/KCrypto.java +151 -0
  169. data/tools/konpeito-asm/src/konpeito/runtime/KFile.java +100 -0
  170. data/tools/konpeito-asm/src/konpeito/runtime/KHTTP.java +113 -0
  171. data/tools/konpeito-asm/src/konpeito/runtime/KHash.java +228 -0
  172. data/tools/konpeito-asm/src/konpeito/runtime/KJSON.java +405 -0
  173. data/tools/konpeito-asm/src/konpeito/runtime/KMath.java +54 -0
  174. data/tools/konpeito-asm/src/konpeito/runtime/KRactor.java +244 -0
  175. data/tools/konpeito-asm/src/konpeito/runtime/KRactorPort.java +53 -0
  176. data/tools/konpeito-asm/src/konpeito/runtime/KSizedQueue.java +49 -0
  177. data/tools/konpeito-asm/src/konpeito/runtime/KThread.java +49 -0
  178. data/tools/konpeito-asm/src/konpeito/runtime/KTime.java +53 -0
  179. data/tools/konpeito-asm/src/konpeito/runtime/RubyDispatch.java +416 -0
  180. metadata +267 -0
@@ -0,0 +1,390 @@
1
+ package konpeito.runtime;
2
+
3
+ import java.util.*;
4
+
5
+ /**
6
+ * KArray - Ruby Array implementation for JVM backend.
7
+ *
8
+ * Implements java.util.List<T> via composition (wrapping ArrayList<T>),
9
+ * providing both Java collection interop and Ruby-specific methods.
10
+ *
11
+ * @param <T> Element type
12
+ */
13
+ public class KArray<T> implements List<T> {
14
+ private final ArrayList<T> data;
15
+
16
+ // ========================================================================
17
+ // Constructors
18
+ // ========================================================================
19
+
20
+ public KArray() {
21
+ this.data = new ArrayList<>();
22
+ }
23
+
24
+ public KArray(int capacity) {
25
+ this.data = new ArrayList<>(capacity);
26
+ }
27
+
28
+ public KArray(Collection<? extends T> c) {
29
+ this.data = new ArrayList<>(c);
30
+ }
31
+
32
+ // ========================================================================
33
+ // Ruby-specific methods
34
+ // ========================================================================
35
+
36
+ /** Ruby: arr.first */
37
+ public T first() {
38
+ return data.isEmpty() ? null : data.get(0);
39
+ }
40
+
41
+ /** Ruby: arr.last */
42
+ public T last() {
43
+ return data.isEmpty() ? null : data.get(data.size() - 1);
44
+ }
45
+
46
+ /** Ruby: arr.push(elem) / arr << elem — returns self for chaining */
47
+ public KArray<T> push(T elem) {
48
+ data.add(elem);
49
+ return this;
50
+ }
51
+
52
+ /** Ruby: arr.pop */
53
+ public T pop() {
54
+ return data.isEmpty() ? null : data.remove(data.size() - 1);
55
+ }
56
+
57
+ /** Ruby: arr.length / arr.size — returns long (Ruby Integer) */
58
+ public long length() {
59
+ return data.size();
60
+ }
61
+
62
+ /** Ruby: arr.empty? */
63
+ public boolean isEmpty_() {
64
+ return data.isEmpty();
65
+ }
66
+
67
+ /** Ruby: arr.include?(elem) */
68
+ public boolean includes(T elem) {
69
+ return data.contains(elem);
70
+ }
71
+
72
+ /** Ruby: arr.flatten (single-level) */
73
+ @SuppressWarnings("unchecked")
74
+ public KArray<Object> flatten() {
75
+ KArray<Object> result = new KArray<>();
76
+ for (T elem : data) {
77
+ if (elem instanceof KArray) {
78
+ result.data.addAll(((KArray<Object>) elem).flatten().data);
79
+ } else {
80
+ result.data.add(elem);
81
+ }
82
+ }
83
+ return result;
84
+ }
85
+
86
+ /** Ruby: arr.deconstruct — returns self (for pattern matching) */
87
+ public KArray<T> deconstruct() {
88
+ return this;
89
+ }
90
+
91
+ /** Ruby: arr.compact — removes nil (null) elements */
92
+ public KArray<T> compact() {
93
+ KArray<T> result = new KArray<>();
94
+ for (T elem : data) {
95
+ if (elem != null) {
96
+ result.data.add(elem);
97
+ }
98
+ }
99
+ return result;
100
+ }
101
+
102
+ /** Ruby: arr.uniq */
103
+ public KArray<T> uniq() {
104
+ KArray<T> result = new KArray<>();
105
+ Set<T> seen = new LinkedHashSet<>();
106
+ for (T elem : data) {
107
+ if (seen.add(elem)) {
108
+ result.data.add(elem);
109
+ }
110
+ }
111
+ return result;
112
+ }
113
+
114
+ /** Ruby: arr.reverse */
115
+ public KArray<T> reverse() {
116
+ KArray<T> result = new KArray<>(data);
117
+ Collections.reverse(result.data);
118
+ return result;
119
+ }
120
+
121
+ /** Ruby: arr.sort (natural ordering) */
122
+ @SuppressWarnings("unchecked")
123
+ public KArray<T> sort() {
124
+ KArray<T> result = new KArray<>(data);
125
+ result.data.sort((a, b) -> ((Comparable<T>) a).compareTo(b));
126
+ return result;
127
+ }
128
+
129
+ /** Ruby: arr.min */
130
+ @SuppressWarnings("unchecked")
131
+ public T min() {
132
+ if (data.isEmpty()) return null;
133
+ T result = data.get(0);
134
+ for (int i = 1; i < data.size(); i++) {
135
+ if (((Comparable<T>) data.get(i)).compareTo(result) < 0) {
136
+ result = data.get(i);
137
+ }
138
+ }
139
+ return result;
140
+ }
141
+
142
+ /** Ruby: arr.max */
143
+ @SuppressWarnings("unchecked")
144
+ public T max() {
145
+ if (data.isEmpty()) return null;
146
+ T result = data.get(0);
147
+ for (int i = 1; i < data.size(); i++) {
148
+ if (((Comparable<T>) data.get(i)).compareTo(result) > 0) {
149
+ result = data.get(i);
150
+ }
151
+ }
152
+ return result;
153
+ }
154
+
155
+ /** Ruby: arr.count (without block, same as length) */
156
+ public long count() {
157
+ return data.size();
158
+ }
159
+
160
+ /** Ruby: arr.shift — remove and return first element */
161
+ public T shift() {
162
+ return data.isEmpty() ? null : data.remove(0);
163
+ }
164
+
165
+ /** Ruby: arr.unshift(elem) / arr.prepend(elem) — add to front, return self */
166
+ public KArray<T> unshift(T elem) {
167
+ data.add(0, elem);
168
+ return this;
169
+ }
170
+
171
+ /** Ruby: arr.delete_at(index) — remove and return element at index */
172
+ public T deleteAt(int index) {
173
+ int idx = index < 0 ? data.size() + index : index;
174
+ if (idx < 0 || idx >= data.size()) return null;
175
+ return data.remove(idx);
176
+ }
177
+
178
+ /** Ruby: arr.delete(value) — remove all occurrences, return last removed or nil */
179
+ public T deleteValue(T value) {
180
+ boolean found = data.remove(value);
181
+ return found ? value : null;
182
+ }
183
+
184
+ /** Ruby: arr.sum — sum all elements (for numeric arrays) */
185
+ @SuppressWarnings("unchecked")
186
+ public long sumLong() {
187
+ long total = 0;
188
+ for (T elem : data) {
189
+ if (elem instanceof Long) total += (Long) elem;
190
+ else if (elem instanceof Integer) total += (Integer) elem;
191
+ }
192
+ return total;
193
+ }
194
+
195
+ /** Ruby: arr.sum for double arrays */
196
+ public double sumDouble() {
197
+ double total = 0.0;
198
+ for (T elem : data) {
199
+ if (elem instanceof Double) total += (Double) elem;
200
+ else if (elem instanceof Float) total += (Float) elem;
201
+ else if (elem instanceof Long) total += (Long) elem;
202
+ }
203
+ return total;
204
+ }
205
+
206
+ /** Ruby: arr.find_index(value) — returns index or -1 */
207
+ public long findIndex(T value) {
208
+ int idx = data.indexOf(value);
209
+ return idx;
210
+ }
211
+
212
+ /** Ruby: arr.join(sep) */
213
+ public String join(String separator) {
214
+ StringBuilder sb = new StringBuilder();
215
+ for (int i = 0; i < data.size(); i++) {
216
+ if (i > 0) sb.append(separator);
217
+ sb.append(data.get(i));
218
+ }
219
+ return sb.toString();
220
+ }
221
+
222
+ /** Ruby: arr.join (no separator) */
223
+ public String join() {
224
+ return join("");
225
+ }
226
+
227
+ // ========================================================================
228
+ // Negative index support (Ruby semantics)
229
+ // ========================================================================
230
+
231
+ private int adjustIndex(int index) {
232
+ return index < 0 ? data.size() + index : index;
233
+ }
234
+
235
+ // ========================================================================
236
+ // List<T> interface delegation with negative index support
237
+ // ========================================================================
238
+
239
+ @Override
240
+ public int size() {
241
+ return data.size();
242
+ }
243
+
244
+ @Override
245
+ public boolean isEmpty() {
246
+ return data.isEmpty();
247
+ }
248
+
249
+ @Override
250
+ public boolean contains(Object o) {
251
+ return data.contains(o);
252
+ }
253
+
254
+ @Override
255
+ public Iterator<T> iterator() {
256
+ return data.iterator();
257
+ }
258
+
259
+ @Override
260
+ public Object[] toArray() {
261
+ return data.toArray();
262
+ }
263
+
264
+ @Override
265
+ public <U> U[] toArray(U[] a) {
266
+ return data.toArray(a);
267
+ }
268
+
269
+ @Override
270
+ public boolean add(T t) {
271
+ return data.add(t);
272
+ }
273
+
274
+ @Override
275
+ public boolean remove(Object o) {
276
+ return data.remove(o);
277
+ }
278
+
279
+ @Override
280
+ public boolean containsAll(Collection<?> c) {
281
+ return data.containsAll(c);
282
+ }
283
+
284
+ @Override
285
+ public boolean addAll(Collection<? extends T> c) {
286
+ return data.addAll(c);
287
+ }
288
+
289
+ @Override
290
+ public boolean addAll(int index, Collection<? extends T> c) {
291
+ return data.addAll(adjustIndex(index), c);
292
+ }
293
+
294
+ @Override
295
+ public boolean removeAll(Collection<?> c) {
296
+ return data.removeAll(c);
297
+ }
298
+
299
+ @Override
300
+ public boolean retainAll(Collection<?> c) {
301
+ return data.retainAll(c);
302
+ }
303
+
304
+ @Override
305
+ public void clear() {
306
+ data.clear();
307
+ }
308
+
309
+ @Override
310
+ public T get(int index) {
311
+ return data.get(adjustIndex(index));
312
+ }
313
+
314
+ @Override
315
+ public T set(int index, T element) {
316
+ return data.set(adjustIndex(index), element);
317
+ }
318
+
319
+ @Override
320
+ public void add(int index, T element) {
321
+ data.add(adjustIndex(index), element);
322
+ }
323
+
324
+ @Override
325
+ public T remove(int index) {
326
+ return data.remove(adjustIndex(index));
327
+ }
328
+
329
+ @Override
330
+ public int indexOf(Object o) {
331
+ return data.indexOf(o);
332
+ }
333
+
334
+ @Override
335
+ public int lastIndexOf(Object o) {
336
+ return data.lastIndexOf(o);
337
+ }
338
+
339
+ @Override
340
+ public ListIterator<T> listIterator() {
341
+ return data.listIterator();
342
+ }
343
+
344
+ @Override
345
+ public ListIterator<T> listIterator(int index) {
346
+ return data.listIterator(adjustIndex(index));
347
+ }
348
+
349
+ @Override
350
+ public List<T> subList(int fromIndex, int toIndex) {
351
+ return data.subList(adjustIndex(fromIndex), adjustIndex(toIndex));
352
+ }
353
+
354
+ // ========================================================================
355
+ // Ruby-compatible toString: [1, 2, 3]
356
+ // ========================================================================
357
+
358
+ @Override
359
+ public String toString() {
360
+ StringBuilder sb = new StringBuilder("[");
361
+ for (int i = 0; i < data.size(); i++) {
362
+ if (i > 0) sb.append(", ");
363
+ T elem = data.get(i);
364
+ if (elem instanceof String) {
365
+ sb.append("\"").append(elem).append("\"");
366
+ } else {
367
+ sb.append(elem);
368
+ }
369
+ }
370
+ sb.append("]");
371
+ return sb.toString();
372
+ }
373
+
374
+ @Override
375
+ public boolean equals(Object o) {
376
+ if (this == o) return true;
377
+ if (o instanceof KArray) {
378
+ return data.equals(((KArray<?>) o).data);
379
+ }
380
+ if (o instanceof List) {
381
+ return data.equals(o);
382
+ }
383
+ return false;
384
+ }
385
+
386
+ @Override
387
+ public int hashCode() {
388
+ return data.hashCode();
389
+ }
390
+ }
@@ -0,0 +1,168 @@
1
+ package konpeito.runtime;
2
+
3
+ import java.io.ByteArrayInputStream;
4
+ import java.io.ByteArrayOutputStream;
5
+ import java.nio.charset.StandardCharsets;
6
+ import java.util.zip.Deflater;
7
+ import java.util.zip.GZIPInputStream;
8
+ import java.util.zip.GZIPOutputStream;
9
+ import java.util.zip.Inflater;
10
+
11
+ /**
12
+ * KCompression - Data compression for Konpeito JVM backend.
13
+ * Maps to KonpeitoCompression Ruby module.
14
+ * Uses java.util.zip.* (no external dependencies).
15
+ *
16
+ * Binary data is encoded as ISO-8859-1 strings for lossless round-tripping.
17
+ */
18
+ public class KCompression {
19
+
20
+ public static final long BEST_SPEED = 1;
21
+ public static final long BEST_COMPRESSION = 9;
22
+ public static final long DEFAULT_COMPRESSION = -1;
23
+
24
+ // ========================================================================
25
+ // Gzip (RFC 1952)
26
+ // ========================================================================
27
+
28
+ /** KonpeitoCompression.gzip(data) -> String (binary) */
29
+ public static String gzip(String data) {
30
+ try {
31
+ byte[] input = data.getBytes(StandardCharsets.UTF_8);
32
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
33
+ try (GZIPOutputStream gzos = new GZIPOutputStream(baos)) {
34
+ gzos.write(input);
35
+ }
36
+ return new String(baos.toByteArray(), StandardCharsets.ISO_8859_1);
37
+ } catch (Exception e) {
38
+ throw new RuntimeException("gzip failed: " + e.getMessage(), e);
39
+ }
40
+ }
41
+
42
+ /** KonpeitoCompression.gunzip(data) -> String */
43
+ public static String gunzip(String data) {
44
+ try {
45
+ byte[] input = data.getBytes(StandardCharsets.ISO_8859_1);
46
+ ByteArrayInputStream bais = new ByteArrayInputStream(input);
47
+ try (GZIPInputStream gzis = new GZIPInputStream(bais)) {
48
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
49
+ byte[] buffer = new byte[4096];
50
+ int n;
51
+ while ((n = gzis.read(buffer)) != -1) {
52
+ baos.write(buffer, 0, n);
53
+ }
54
+ return baos.toString(StandardCharsets.UTF_8);
55
+ }
56
+ } catch (Exception e) {
57
+ throw new RuntimeException("gunzip failed: " + e.getMessage(), e);
58
+ }
59
+ }
60
+
61
+ // ========================================================================
62
+ // Raw Deflate (RFC 1951)
63
+ // ========================================================================
64
+
65
+ /** KonpeitoCompression.deflate(data, level) -> String (binary) */
66
+ public static String deflate(String data, Object level) {
67
+ try {
68
+ int compressionLevel = Deflater.DEFAULT_COMPRESSION;
69
+ if (level instanceof Long) {
70
+ compressionLevel = ((Long) level).intValue();
71
+ } else if (level instanceof Integer) {
72
+ compressionLevel = (Integer) level;
73
+ }
74
+ byte[] input = data.getBytes(StandardCharsets.UTF_8);
75
+ Deflater deflater = new Deflater(compressionLevel, true); // true = raw deflate (no zlib header)
76
+ deflater.setInput(input);
77
+ deflater.finish();
78
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
79
+ byte[] buffer = new byte[4096];
80
+ while (!deflater.finished()) {
81
+ int count = deflater.deflate(buffer);
82
+ baos.write(buffer, 0, count);
83
+ }
84
+ deflater.end();
85
+ return new String(baos.toByteArray(), StandardCharsets.ISO_8859_1);
86
+ } catch (Exception e) {
87
+ throw new RuntimeException("deflate failed: " + e.getMessage(), e);
88
+ }
89
+ }
90
+
91
+ /** KonpeitoCompression.inflate(data) -> String */
92
+ public static String inflate(String data) {
93
+ try {
94
+ byte[] input = data.getBytes(StandardCharsets.ISO_8859_1);
95
+ Inflater inflater = new Inflater(true); // true = raw inflate (no zlib header)
96
+ inflater.setInput(input);
97
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
98
+ byte[] buffer = new byte[4096];
99
+ while (!inflater.finished()) {
100
+ int count = inflater.inflate(buffer);
101
+ if (count == 0 && inflater.needsInput()) break;
102
+ baos.write(buffer, 0, count);
103
+ }
104
+ inflater.end();
105
+ return baos.toString(StandardCharsets.UTF_8);
106
+ } catch (Exception e) {
107
+ throw new RuntimeException("inflate failed: " + e.getMessage(), e);
108
+ }
109
+ }
110
+
111
+ // ========================================================================
112
+ // Zlib (RFC 1950) - with zlib header
113
+ // ========================================================================
114
+
115
+ /** KonpeitoCompression.zlib_compress(data) -> String (binary) */
116
+ public static String zlibCompress(String data) {
117
+ try {
118
+ byte[] input = data.getBytes(StandardCharsets.UTF_8);
119
+ Deflater deflater = new Deflater(); // default: zlib format (with header)
120
+ deflater.setInput(input);
121
+ deflater.finish();
122
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
123
+ byte[] buffer = new byte[4096];
124
+ while (!deflater.finished()) {
125
+ int count = deflater.deflate(buffer);
126
+ baos.write(buffer, 0, count);
127
+ }
128
+ deflater.end();
129
+ return new String(baos.toByteArray(), StandardCharsets.ISO_8859_1);
130
+ } catch (Exception e) {
131
+ throw new RuntimeException("zlib_compress failed: " + e.getMessage(), e);
132
+ }
133
+ }
134
+
135
+ /** KonpeitoCompression.zlib_decompress(data, maxSize) -> String */
136
+ public static String zlibDecompress(String data, Object maxSize) {
137
+ try {
138
+ long maxBytes = 100 * 1024 * 1024; // 100MB default
139
+ if (maxSize instanceof Long) {
140
+ maxBytes = (Long) maxSize;
141
+ } else if (maxSize instanceof Integer) {
142
+ maxBytes = (Integer) maxSize;
143
+ }
144
+ byte[] input = data.getBytes(StandardCharsets.ISO_8859_1);
145
+ Inflater inflater = new Inflater(); // default: zlib format (with header)
146
+ inflater.setInput(input);
147
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
148
+ byte[] buffer = new byte[4096];
149
+ long totalBytes = 0;
150
+ while (!inflater.finished()) {
151
+ int count = inflater.inflate(buffer);
152
+ if (count == 0 && inflater.needsInput()) break;
153
+ totalBytes += count;
154
+ if (totalBytes > maxBytes) {
155
+ inflater.end();
156
+ throw new RuntimeException("Decompressed data exceeds max size: " + maxBytes);
157
+ }
158
+ baos.write(buffer, 0, count);
159
+ }
160
+ inflater.end();
161
+ return baos.toString(StandardCharsets.UTF_8);
162
+ } catch (RuntimeException e) {
163
+ throw e;
164
+ } catch (Exception e) {
165
+ throw new RuntimeException("zlib_decompress failed: " + e.getMessage(), e);
166
+ }
167
+ }
168
+ }
@@ -0,0 +1,48 @@
1
+ package konpeito.runtime;
2
+
3
+ import java.util.concurrent.locks.Condition;
4
+ import java.util.concurrent.locks.ReentrantLock;
5
+
6
+ /**
7
+ * KConditionVariable - Ruby ConditionVariable implementation for JVM backend.
8
+ *
9
+ * Uses an internal ReentrantLock + Condition pair.
10
+ * Note: In Ruby, ConditionVariable can be used with any Mutex.
11
+ * This simplified implementation uses its own internal lock.
12
+ */
13
+ public class KConditionVariable {
14
+ private final ReentrantLock lock = new ReentrantLock();
15
+ private final Condition condition = lock.newCondition();
16
+
17
+ /** Ruby: cv.wait(mutex) — waits for signal */
18
+ public void await() {
19
+ lock.lock();
20
+ try {
21
+ condition.await();
22
+ } catch (InterruptedException e) {
23
+ Thread.currentThread().interrupt();
24
+ } finally {
25
+ lock.unlock();
26
+ }
27
+ }
28
+
29
+ /** Ruby: cv.signal — wakes one waiting thread */
30
+ public void signal() {
31
+ lock.lock();
32
+ try {
33
+ condition.signal();
34
+ } finally {
35
+ lock.unlock();
36
+ }
37
+ }
38
+
39
+ /** Ruby: cv.broadcast — wakes all waiting threads */
40
+ public void broadcast() {
41
+ lock.lock();
42
+ try {
43
+ condition.signalAll();
44
+ } finally {
45
+ lock.unlock();
46
+ }
47
+ }
48
+ }