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.
- checksums.yaml +7 -0
- data/.ruby-version +1 -0
- data/CHANGELOG.md +75 -0
- data/CONTRIBUTING.md +123 -0
- data/LICENSE +21 -0
- data/README.md +257 -0
- data/Rakefile +11 -0
- data/bin/konpeito +6 -0
- data/konpeito.gemspec +43 -0
- data/lib/konpeito/ast/typed_ast.rb +620 -0
- data/lib/konpeito/ast/visitor.rb +78 -0
- data/lib/konpeito/cache/cache_manager.rb +230 -0
- data/lib/konpeito/cache/dependency_graph.rb +192 -0
- data/lib/konpeito/cache.rb +8 -0
- data/lib/konpeito/cli/base_command.rb +187 -0
- data/lib/konpeito/cli/build_command.rb +220 -0
- data/lib/konpeito/cli/check_command.rb +104 -0
- data/lib/konpeito/cli/config.rb +231 -0
- data/lib/konpeito/cli/deps_command.rb +128 -0
- data/lib/konpeito/cli/doctor_command.rb +340 -0
- data/lib/konpeito/cli/fmt_command.rb +199 -0
- data/lib/konpeito/cli/init_command.rb +312 -0
- data/lib/konpeito/cli/lsp_command.rb +40 -0
- data/lib/konpeito/cli/run_command.rb +150 -0
- data/lib/konpeito/cli/test_command.rb +248 -0
- data/lib/konpeito/cli/watch_command.rb +212 -0
- data/lib/konpeito/cli.rb +301 -0
- data/lib/konpeito/codegen/builtin_methods.rb +229 -0
- data/lib/konpeito/codegen/cruby_backend.rb +1090 -0
- data/lib/konpeito/codegen/debug_info.rb +352 -0
- data/lib/konpeito/codegen/inliner.rb +486 -0
- data/lib/konpeito/codegen/jvm_backend.rb +197 -0
- data/lib/konpeito/codegen/jvm_generator.rb +13412 -0
- data/lib/konpeito/codegen/llvm_generator.rb +13191 -0
- data/lib/konpeito/codegen/loop_optimizer.rb +363 -0
- data/lib/konpeito/codegen/monomorphizer.rb +359 -0
- data/lib/konpeito/codegen/profile_runtime.c +341 -0
- data/lib/konpeito/codegen/profiler.rb +99 -0
- data/lib/konpeito/compiler.rb +592 -0
- data/lib/konpeito/dependency_resolver.rb +296 -0
- data/lib/konpeito/diagnostics/collector.rb +127 -0
- data/lib/konpeito/diagnostics/diagnostic.rb +237 -0
- data/lib/konpeito/diagnostics/renderer.rb +144 -0
- data/lib/konpeito/formatter/formatter.rb +1214 -0
- data/lib/konpeito/hir/builder.rb +7167 -0
- data/lib/konpeito/hir/nodes.rb +2465 -0
- data/lib/konpeito/lsp/document_manager.rb +820 -0
- data/lib/konpeito/lsp/server.rb +183 -0
- data/lib/konpeito/lsp/transport.rb +38 -0
- data/lib/konpeito/parser/prism_adapter.rb +65 -0
- data/lib/konpeito/platform.rb +103 -0
- data/lib/konpeito/profile/report.rb +136 -0
- data/lib/konpeito/rbs_inline/preprocessor.rb +199 -0
- data/lib/konpeito/stdlib/compression/compression.rb +72 -0
- data/lib/konpeito/stdlib/compression/compression.rbs +60 -0
- data/lib/konpeito/stdlib/compression/compression_native.c +415 -0
- data/lib/konpeito/stdlib/compression/extconf.rb +19 -0
- data/lib/konpeito/stdlib/crypto/crypto.rb +85 -0
- data/lib/konpeito/stdlib/crypto/crypto.rbs +74 -0
- data/lib/konpeito/stdlib/crypto/crypto_native.c +312 -0
- data/lib/konpeito/stdlib/crypto/extconf.rb +40 -0
- data/lib/konpeito/stdlib/http/extconf.rb +19 -0
- data/lib/konpeito/stdlib/http/http.rb +125 -0
- data/lib/konpeito/stdlib/http/http.rbs +57 -0
- data/lib/konpeito/stdlib/http/http_native.c +440 -0
- data/lib/konpeito/stdlib/json/extconf.rb +17 -0
- data/lib/konpeito/stdlib/json/json.rb +44 -0
- data/lib/konpeito/stdlib/json/json.rbs +33 -0
- data/lib/konpeito/stdlib/json/json_native.c +286 -0
- data/lib/konpeito/stdlib/ui/extconf.rb +216 -0
- data/lib/konpeito/stdlib/ui/konpeito_ui_native.cpp +1625 -0
- data/lib/konpeito/stdlib/ui/konpeito_ui_native.h +162 -0
- data/lib/konpeito/stdlib/ui/ui.rb +318 -0
- data/lib/konpeito/stdlib/ui/ui.rbs +247 -0
- data/lib/konpeito/type_checker/annotation_parser.rb +67 -0
- data/lib/konpeito/type_checker/hm_inferrer.rb +2565 -0
- data/lib/konpeito/type_checker/inferrer.rb +565 -0
- data/lib/konpeito/type_checker/rbs_loader.rb +1621 -0
- data/lib/konpeito/type_checker/type_resolver.rb +276 -0
- data/lib/konpeito/type_checker/types.rb +1434 -0
- data/lib/konpeito/type_checker/unification.rb +323 -0
- data/lib/konpeito/ui/animation/animated_state.rb +80 -0
- data/lib/konpeito/ui/animation/easing.rb +59 -0
- data/lib/konpeito/ui/animation/value_tween.rb +66 -0
- data/lib/konpeito/ui/app.rb +379 -0
- data/lib/konpeito/ui/box.rb +38 -0
- data/lib/konpeito/ui/castella.rb +70 -0
- data/lib/konpeito/ui/castella_native.rb +76 -0
- data/lib/konpeito/ui/chart/area_chart.rb +305 -0
- data/lib/konpeito/ui/chart/bar_chart.rb +288 -0
- data/lib/konpeito/ui/chart/base_chart.rb +210 -0
- data/lib/konpeito/ui/chart/chart_helpers.rb +79 -0
- data/lib/konpeito/ui/chart/gauge_chart.rb +171 -0
- data/lib/konpeito/ui/chart/heatmap_chart.rb +222 -0
- data/lib/konpeito/ui/chart/line_chart.rb +289 -0
- data/lib/konpeito/ui/chart/pie_chart.rb +219 -0
- data/lib/konpeito/ui/chart/scales.rb +77 -0
- data/lib/konpeito/ui/chart/scatter_chart.rb +303 -0
- data/lib/konpeito/ui/chart/stacked_bar_chart.rb +276 -0
- data/lib/konpeito/ui/column.rb +271 -0
- data/lib/konpeito/ui/core.rb +2199 -0
- data/lib/konpeito/ui/dsl.rb +443 -0
- data/lib/konpeito/ui/frame.rb +171 -0
- data/lib/konpeito/ui/frame_native.rb +494 -0
- data/lib/konpeito/ui/markdown/ast.rb +124 -0
- data/lib/konpeito/ui/markdown/mermaid/layout.rb +387 -0
- data/lib/konpeito/ui/markdown/mermaid/models.rb +232 -0
- data/lib/konpeito/ui/markdown/mermaid/parser.rb +519 -0
- data/lib/konpeito/ui/markdown/mermaid/renderer.rb +336 -0
- data/lib/konpeito/ui/markdown/parser.rb +805 -0
- data/lib/konpeito/ui/markdown/renderer.rb +639 -0
- data/lib/konpeito/ui/markdown/theme.rb +165 -0
- data/lib/konpeito/ui/render_node.rb +260 -0
- data/lib/konpeito/ui/row.rb +207 -0
- data/lib/konpeito/ui/spacer.rb +18 -0
- data/lib/konpeito/ui/style.rb +799 -0
- data/lib/konpeito/ui/theme.rb +563 -0
- data/lib/konpeito/ui/themes/material.rb +35 -0
- data/lib/konpeito/ui/themes/tokyo_night.rb +6 -0
- data/lib/konpeito/ui/widgets/button.rb +103 -0
- data/lib/konpeito/ui/widgets/calendar.rb +1034 -0
- data/lib/konpeito/ui/widgets/checkbox.rb +119 -0
- data/lib/konpeito/ui/widgets/container.rb +91 -0
- data/lib/konpeito/ui/widgets/data_table.rb +667 -0
- data/lib/konpeito/ui/widgets/divider.rb +29 -0
- data/lib/konpeito/ui/widgets/image.rb +105 -0
- data/lib/konpeito/ui/widgets/input.rb +485 -0
- data/lib/konpeito/ui/widgets/markdown.rb +57 -0
- data/lib/konpeito/ui/widgets/modal.rb +163 -0
- data/lib/konpeito/ui/widgets/multiline_input.rb +968 -0
- data/lib/konpeito/ui/widgets/multiline_text.rb +180 -0
- data/lib/konpeito/ui/widgets/net_image.rb +100 -0
- data/lib/konpeito/ui/widgets/progress_bar.rb +70 -0
- data/lib/konpeito/ui/widgets/radio_buttons.rb +93 -0
- data/lib/konpeito/ui/widgets/slider.rb +133 -0
- data/lib/konpeito/ui/widgets/switch.rb +84 -0
- data/lib/konpeito/ui/widgets/tabs.rb +157 -0
- data/lib/konpeito/ui/widgets/text.rb +110 -0
- data/lib/konpeito/ui/widgets/tree.rb +426 -0
- data/lib/konpeito/version.rb +5 -0
- data/lib/konpeito.rb +109 -0
- data/test_native_array.rb +172 -0
- data/test_native_array_class.rb +197 -0
- data/test_native_class.rb +151 -0
- data/tools/konpeito-asm/build.sh +65 -0
- data/tools/konpeito-asm/lib/asm-9.7.1.jar +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KArray.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCompression.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KConditionVariable.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KCrypto.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KFile.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHTTP.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KHash.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON$Parser.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KJSON.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KMath.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactor.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KRactorPort.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KSizedQueue.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KThread.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/KTime.class +0 -0
- data/tools/konpeito-asm/runtime-classes/konpeito/runtime/RubyDispatch.class +0 -0
- data/tools/konpeito-asm/src/ClassIntrospector.java +312 -0
- data/tools/konpeito-asm/src/KonpeitoAssembler.java +659 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KArray.java +390 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KCompression.java +168 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KConditionVariable.java +48 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KCrypto.java +151 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KFile.java +100 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KHTTP.java +113 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KHash.java +228 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KJSON.java +405 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KMath.java +54 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KRactor.java +244 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KRactorPort.java +53 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KSizedQueue.java +49 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KThread.java +49 -0
- data/tools/konpeito-asm/src/konpeito/runtime/KTime.java +53 -0
- data/tools/konpeito-asm/src/konpeito/runtime/RubyDispatch.java +416 -0
- 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
|
+
}
|