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,301 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "optparse"
4
+ require_relative "cli/config"
5
+ require_relative "cli/base_command"
6
+ require_relative "cli/build_command"
7
+ require_relative "cli/check_command"
8
+ require_relative "cli/lsp_command"
9
+ require_relative "cli/init_command"
10
+ require_relative "cli/fmt_command"
11
+ require_relative "cli/test_command"
12
+ require_relative "cli/watch_command"
13
+ require_relative "cli/run_command"
14
+ require_relative "cli/deps_command"
15
+ require_relative "cli/doctor_command"
16
+
17
+ module Konpeito
18
+ # Main CLI router - dispatches to subcommands
19
+ class CLI
20
+ COMMANDS = {
21
+ "build" => Commands::BuildCommand,
22
+ "run" => Commands::RunCommand,
23
+ "check" => Commands::CheckCommand,
24
+ "lsp" => Commands::LspCommand,
25
+ "init" => Commands::InitCommand,
26
+ "fmt" => Commands::FmtCommand,
27
+ "test" => Commands::TestCommand,
28
+ "watch" => Commands::WatchCommand,
29
+ "deps" => Commands::DepsCommand,
30
+ "doctor" => Commands::DoctorCommand
31
+ }.freeze
32
+
33
+ attr_reader :args
34
+
35
+ def initialize(args)
36
+ @args = args.dup
37
+ end
38
+
39
+ def run
40
+ # Handle global options first
41
+ if args.empty? || args.first == "-h" || args.first == "--help"
42
+ show_help
43
+ exit(args.empty? ? 1 : 0)
44
+ end
45
+
46
+ if args.first == "--version" || args.first == "-V"
47
+ show_version
48
+ exit 0
49
+ end
50
+
51
+ # Determine command
52
+ command_name = args.first
53
+
54
+ if COMMANDS.key?(command_name)
55
+ # Explicit subcommand
56
+ args.shift
57
+ run_command(command_name, args)
58
+ elsif command_name.start_with?("-") || File.exist?(command_name)
59
+ # Legacy mode: implicit build command for backwards compatibility
60
+ # Either starts with option flag or is an existing file
61
+ run_legacy_mode
62
+ else
63
+ # Unknown command
64
+ $stderr.puts "Unknown command: #{command_name}"
65
+ $stderr.puts "Run 'konpeito --help' for usage information."
66
+ exit 1
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def run_command(command_name, command_args)
73
+ command_class = COMMANDS[command_name]
74
+ config = Commands::Config.new
75
+ command = command_class.new(command_args, config: config)
76
+ command.run
77
+ end
78
+
79
+ def run_legacy_mode
80
+ # Parse legacy options and delegate to appropriate command
81
+ legacy = LegacyCLI.new(args)
82
+ legacy.run
83
+ end
84
+
85
+ def show_help
86
+ puts "Konpeito - Ruby AOT Native Compiler"
87
+ puts ""
88
+ puts "Usage: konpeito <command> [options] [args]"
89
+ puts " konpeito [options] <source.rb> (legacy build mode)"
90
+ puts ""
91
+ puts "Commands:"
92
+ COMMANDS.each do |name, klass|
93
+ puts " %-10s %s" % [name, klass.description]
94
+ end
95
+ puts ""
96
+ puts "Global Options:"
97
+ puts " -h, --help Show this help"
98
+ puts " -V, --version Show version and environment info"
99
+ puts ""
100
+ puts "Examples:"
101
+ puts " konpeito build src/main.rb Compile to CRuby extension"
102
+ puts " konpeito build --target jvm src/app.rb Compile to JAR"
103
+ puts " konpeito run src/main.rb Build and run"
104
+ puts " konpeito check src/main.rb Type check only"
105
+ puts " konpeito test Run tests"
106
+ puts " konpeito fmt Format source files"
107
+ puts " konpeito doctor Check environment"
108
+ puts ""
109
+ puts "Legacy mode (backwards compatible):"
110
+ puts " konpeito source.rb Same as: konpeito build source.rb"
111
+ puts " konpeito -c source.rb Same as: konpeito check source.rb"
112
+ puts ""
113
+ puts "For help on a specific command, run: konpeito <command> --help"
114
+ end
115
+
116
+ def show_version
117
+ puts "konpeito #{Konpeito::VERSION}"
118
+ puts "ruby #{RUBY_VERSION} [#{RUBY_PLATFORM}]"
119
+
120
+ # LLVM
121
+ clang = Platform.find_llvm_tool("clang")
122
+ if clang
123
+ llvm_version = clang[/llvm[@-]?(\d+)/, 1]
124
+ unless llvm_version
125
+ # Try clang --version
126
+ begin
127
+ output = `"#{clang}" --version 2>&1`
128
+ llvm_version = output[/(?:clang|LLVM)\s+version\s+(\d+)/, 1]
129
+ rescue
130
+ end
131
+ end
132
+ llvm_version ||= "?"
133
+ llvm_dir = File.dirname(File.dirname(clang))
134
+ puts "llvm #{llvm_version} (#{llvm_dir})"
135
+ else
136
+ puts "llvm not found"
137
+ end
138
+
139
+ # Java
140
+ java_home = ENV["JAVA_HOME"] || Platform.default_java_home
141
+ java_path = File.join(java_home, "bin", "java")
142
+ java_path = Platform.find_executable("java") unless File.exist?(java_path)
143
+ if java_path
144
+ version = begin
145
+ output = `"#{java_path}" -version 2>&1`
146
+ output[/version "(\d+)/, 1] || "?"
147
+ rescue
148
+ "?"
149
+ end
150
+ java_dir = File.dirname(File.dirname(java_path))
151
+ puts "java #{version} (#{java_dir})"
152
+ else
153
+ puts "java not found"
154
+ end
155
+ end
156
+ end
157
+
158
+ # Legacy CLI class for backwards compatibility
159
+ # Supports old-style options like -c, -o, --lsp, etc.
160
+ class LegacyCLI
161
+ attr_reader :args, :options
162
+
163
+ def initialize(args)
164
+ @args = args.dup
165
+ @options = {
166
+ output: nil,
167
+ format: :cruby_ext,
168
+ verbose: false,
169
+ type_check_only: false,
170
+ rbs_paths: [],
171
+ require_paths: [],
172
+ color: $stderr.tty?,
173
+ debug: false,
174
+ lsp: false,
175
+ profile: false,
176
+ incremental: false,
177
+ clean_cache: false
178
+ }
179
+ end
180
+
181
+ def run
182
+ parse_options!
183
+
184
+ # Start LSP server if requested
185
+ if options[:lsp]
186
+ Commands::LspCommand.new([], config: Commands::Config.new).run
187
+ return
188
+ end
189
+
190
+ if args.empty?
191
+ puts "Usage: konpeito [options] <source.rb>"
192
+ puts "Run 'konpeito --help' for more information."
193
+ exit 1
194
+ end
195
+
196
+ source_file = args.first
197
+
198
+ unless File.exist?(source_file)
199
+ $stderr.puts "Error: File not found: #{source_file}"
200
+ exit 1
201
+ end
202
+
203
+ if options[:type_check_only]
204
+ # Delegate to check command
205
+ check_args = []
206
+ check_args << "-v" if options[:verbose]
207
+ check_args << "--no-color" unless options[:color]
208
+ options[:rbs_paths].each { |p| check_args << "--rbs" << p }
209
+ options[:require_paths].each { |p| check_args << "-I" << p }
210
+ check_args << source_file
211
+ Commands::CheckCommand.new(check_args, config: Commands::Config.new).run
212
+ else
213
+ # Delegate to build command
214
+ build_args = []
215
+ build_args << "-o" << options[:output] if options[:output]
216
+ build_args << "-f" << options[:format].to_s if options[:format] != :cruby_ext
217
+ build_args << "-v" if options[:verbose]
218
+ build_args << "-g" if options[:debug]
219
+ build_args << "-p" if options[:profile]
220
+ build_args << "--no-color" unless options[:color]
221
+ build_args << "--incremental" if options[:incremental]
222
+ build_args << "--clean-cache" if options[:clean_cache]
223
+ options[:rbs_paths].each { |p| build_args << "--rbs" << p }
224
+ options[:require_paths].each { |p| build_args << "-I" << p }
225
+ build_args << source_file
226
+ Commands::BuildCommand.new(build_args, config: Commands::Config.new).run
227
+ end
228
+ end
229
+
230
+ private
231
+
232
+ def parse_options!
233
+ parser = OptionParser.new do |opts|
234
+ opts.banner = "Usage: konpeito [options] <source.rb>"
235
+ opts.separator ""
236
+ opts.separator "Options:"
237
+
238
+ opts.on("-o", "--output FILE", "Output file name") do |file|
239
+ options[:output] = file
240
+ end
241
+
242
+ opts.on("-f", "--format FORMAT", %i[cruby_ext standalone],
243
+ "Output format (cruby_ext, standalone)") do |format|
244
+ options[:format] = format
245
+ end
246
+
247
+ opts.on("-c", "--check", "Type check only (no code generation)") do
248
+ options[:type_check_only] = true
249
+ end
250
+
251
+ opts.on("-g", "--debug", "Generate debug info (DWARF) for lldb/gdb") do
252
+ options[:debug] = true
253
+ end
254
+
255
+ opts.on("-p", "--profile", "Enable profiling (function call counts and timing)") do
256
+ options[:profile] = true
257
+ end
258
+
259
+ opts.on("-v", "--verbose", "Verbose output") do
260
+ options[:verbose] = true
261
+ end
262
+
263
+ opts.on("-I", "--require-path PATH", "Add require search path (can be used multiple times)") do |path|
264
+ options[:require_paths] << path
265
+ end
266
+
267
+ opts.on("--rbs FILE", "RBS type definition file (can be used multiple times)") do |file|
268
+ options[:rbs_paths] << file
269
+ end
270
+
271
+ opts.on("--no-color", "Disable colored output") do
272
+ options[:color] = false
273
+ end
274
+
275
+ opts.on("--lsp", "Start Language Server Protocol server") do
276
+ options[:lsp] = true
277
+ end
278
+
279
+ opts.on("--incremental", "Enable incremental compilation (cache unchanged files)") do
280
+ options[:incremental] = true
281
+ end
282
+
283
+ opts.on("--clean-cache", "Clear compilation cache before building") do
284
+ options[:clean_cache] = true
285
+ end
286
+
287
+ opts.on("--version", "Show version") do
288
+ puts "konpeito #{Konpeito::VERSION}"
289
+ exit
290
+ end
291
+
292
+ opts.on("-h", "--help", "Show this help") do
293
+ puts opts
294
+ exit
295
+ end
296
+ end
297
+
298
+ parser.parse!(args)
299
+ end
300
+ end
301
+ end
@@ -0,0 +1,229 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Konpeito
4
+ module Codegen
5
+ # Mapping of Ruby built-in methods to their CRuby C API functions
6
+ # This enables direct C function calls instead of rb_funcallv dispatch
7
+ #
8
+ # IMPORTANT: Only include functions that are actually EXPORTED from libruby.
9
+ # Many internal Ruby methods (like rb_str_upcase) are static and not callable.
10
+ # Check with: nm -gU $(ruby -e 'puts RbConfig::CONFIG["libdir"]')/libruby.*.dylib | grep rb_str
11
+ #
12
+ # Calling conventions:
13
+ # - :simple - VALUE func(VALUE recv) or VALUE func(VALUE recv, VALUE arg1, ...)
14
+ # - :block_iterator - uses rb_block_call with block callback
15
+ #
16
+ BUILTIN_METHODS = {
17
+ Integer: {
18
+ # Block iterators - use rb_block_call
19
+ times: { arity: 0, return_type: :Integer, conv: :block_iterator },
20
+ upto: { arity: 1, return_type: :Integer, conv: :block_iterator },
21
+ downto: { arity: 1, return_type: :Integer, conv: :block_iterator },
22
+ },
23
+
24
+ String: {
25
+ # String query methods
26
+ length: { c_func: "rb_str_length", arity: 0, return_type: :Integer, conv: :simple },
27
+ size: { c_func: "rb_str_length", arity: 0, return_type: :Integer, conv: :simple },
28
+
29
+ # String operations - these are EXPORTED
30
+ :+ => { c_func: "rb_str_plus", arity: 1, return_type: :String, conv: :simple },
31
+ :<< => { c_func: "rb_str_concat", arity: 1, return_type: :String, conv: :simple },
32
+ concat: { c_func: "rb_str_concat", arity: 1, return_type: :String, conv: :simple },
33
+
34
+ # String comparison - exported
35
+ :<=> => { c_func: "rb_str_cmp", arity: 1, return_type: :Integer, conv: :simple },
36
+ :== => { c_func: "rb_str_equal", arity: 1, return_type: :Bool, conv: :simple },
37
+
38
+ # String conversion - exported
39
+ to_sym: { c_func: "rb_str_intern", arity: 0, return_type: :Symbol, conv: :simple },
40
+ intern: { c_func: "rb_str_intern", arity: 0, return_type: :Symbol, conv: :simple },
41
+
42
+ # String duplication - exported
43
+ dup: { c_func: "rb_str_dup", arity: 0, return_type: :String, conv: :simple },
44
+
45
+ # String hash - exported (useful for Hash key optimization)
46
+ hash: { c_func: "rb_str_hash", arity: 0, return_type: :Integer, conv: :simple },
47
+ },
48
+
49
+ Array: {
50
+ # Array query methods - rb_ary_length not directly exported, use RARRAY_LEN macro
51
+ # length: { c_func: "rb_ary_length", arity: 0, return_type: :Integer, conv: :simple },
52
+
53
+ # Array access - exported
54
+ :[] => { c_func: "rb_ary_entry", arity: 1, return_type: :Any, conv: :ary_entry },
55
+ # Array#[]= uses rb_ary_store (special handling in llvm_generator)
56
+ :[]= => { c_func: "rb_ary_store", arity: 2, return_type: :Any, conv: :ary_store },
57
+
58
+ # Array modification - exported with simple signatures
59
+ push: { c_func: "rb_ary_push", arity: 1, return_type: :Array, conv: :simple },
60
+ :<< => { c_func: "rb_ary_push", arity: 1, return_type: :Array, conv: :simple },
61
+ pop: { c_func: "rb_ary_pop", arity: 0, return_type: :Any, conv: :simple },
62
+ shift: { c_func: "rb_ary_shift", arity: 0, return_type: :Any, conv: :simple },
63
+ clear: { c_func: "rb_ary_clear", arity: 0, return_type: :Array, conv: :simple },
64
+ # Array#delete_at uses long index (special handling in llvm_generator)
65
+ delete_at: { c_func: "rb_ary_delete_at", arity: 1, return_type: :Any, conv: :ary_delete_at },
66
+ # Note: unshift/prepend/delete use rb_funcallv fallback (args need VALUE boxing)
67
+
68
+ # Array operations - exported
69
+ :+ => { c_func: "rb_ary_plus", arity: 1, return_type: :Array, conv: :simple },
70
+ concat: { c_func: "rb_ary_concat", arity: 1, return_type: :Array, conv: :simple },
71
+
72
+ # Array transformation - exported
73
+ reverse: { c_func: "rb_ary_reverse", arity: 0, return_type: :Array, conv: :simple },
74
+ sort: { c_func: "rb_ary_sort", arity: 0, return_type: :Array, conv: :simple },
75
+
76
+ # Array query with args - exported
77
+ include?: { c_func: "rb_ary_includes", arity: 1, return_type: :Bool, conv: :simple },
78
+
79
+ # Block iterators - use rb_block_call
80
+ each: { arity: 0, return_type: :Array, conv: :block_iterator },
81
+ map: { arity: 0, return_type: :Array, conv: :block_iterator },
82
+ collect: { arity: 0, return_type: :Array, conv: :block_iterator },
83
+ select: { arity: 0, return_type: :Array, conv: :block_iterator },
84
+ filter: { arity: 0, return_type: :Array, conv: :block_iterator }, # alias for select
85
+ reject: { arity: 0, return_type: :Array, conv: :block_iterator },
86
+ each_with_index: { arity: 0, return_type: :Array, conv: :block_iterator },
87
+
88
+ # Enumerable methods
89
+ reduce: { arity: -1, return_type: :Any, conv: :block_iterator }, # arity -1 = optional args
90
+ inject: { arity: -1, return_type: :Any, conv: :block_iterator }, # alias for reduce
91
+ find: { arity: 0, return_type: :Any, conv: :block_iterator },
92
+ detect: { arity: 0, return_type: :Any, conv: :block_iterator }, # alias for find
93
+ find_all: { arity: 0, return_type: :Array, conv: :block_iterator }, # alias for select
94
+ any?: { arity: 0, return_type: :Bool, conv: :block_iterator },
95
+ all?: { arity: 0, return_type: :Bool, conv: :block_iterator },
96
+ none?: { arity: 0, return_type: :Bool, conv: :block_iterator },
97
+ one?: { arity: 0, return_type: :Bool, conv: :block_iterator },
98
+ count: { arity: -1, return_type: :Integer, conv: :block_iterator }, # optional block
99
+ min_by: { arity: 0, return_type: :Any, conv: :block_iterator },
100
+ max_by: { arity: 0, return_type: :Any, conv: :block_iterator },
101
+ sort_by: { arity: 0, return_type: :Array, conv: :block_iterator },
102
+ find_index: { arity: -1, return_type: :Any, conv: :block_iterator },
103
+ first: { arity: -1, return_type: :Any, conv: :block_iterator },
104
+ take_while: { arity: 0, return_type: :Array, conv: :block_iterator },
105
+ drop_while: { arity: 0, return_type: :Array, conv: :block_iterator },
106
+ partition: { arity: 0, return_type: :Array, conv: :block_iterator },
107
+ group_by: { arity: 0, return_type: :Hash, conv: :block_iterator },
108
+ flat_map: { arity: 0, return_type: :Array, conv: :block_iterator },
109
+ collect_concat: { arity: 0, return_type: :Array, conv: :block_iterator }, # alias for flat_map
110
+ },
111
+
112
+ Hash: {
113
+ # Hash access - rb_hash_aref is exported
114
+ :[] => { c_func: "rb_hash_aref", arity: 1, return_type: :Any, conv: :simple },
115
+ :[]= => { c_func: "rb_hash_aset", arity: 2, return_type: :Any, conv: :simple },
116
+
117
+ # Hash modification - exported
118
+ clear: { c_func: "rb_hash_clear", arity: 0, return_type: :Hash, conv: :simple },
119
+ delete: { c_func: "rb_hash_delete", arity: 1, return_type: :Any, conv: :simple },
120
+
121
+ # Hash block iterators with 2-argument blocks (|k, v|)
122
+ # Uses rb_block_call - CRuby passes key/value through argv for Hash#each
123
+ each: { arity: 0, return_type: :Hash, conv: :block_iterator },
124
+ each_pair: { arity: 0, return_type: :Hash, conv: :block_iterator },
125
+ map: { arity: 0, return_type: :Array, conv: :block_iterator },
126
+ collect: { arity: 0, return_type: :Array, conv: :block_iterator },
127
+ select: { arity: 0, return_type: :Hash, conv: :block_iterator },
128
+ filter: { arity: 0, return_type: :Hash, conv: :block_iterator },
129
+ reject: { arity: 0, return_type: :Hash, conv: :block_iterator },
130
+ any?: { arity: 0, return_type: :Bool, conv: :block_iterator },
131
+ all?: { arity: 0, return_type: :Bool, conv: :block_iterator },
132
+ none?: { arity: 0, return_type: :Bool, conv: :block_iterator },
133
+ each_with_object: { arity: 1, return_type: :Any, conv: :block_iterator },
134
+ },
135
+
136
+ Symbol: {
137
+ # Symbol methods
138
+ to_s: { c_func: "rb_sym2str", arity: 0, return_type: :String, conv: :simple },
139
+ id2name: { c_func: "rb_sym2str", arity: 0, return_type: :String, conv: :simple },
140
+ name: { c_func: "rb_sym2str", arity: 0, return_type: :String, conv: :simple },
141
+ },
142
+
143
+ Object: {
144
+ # Object identity and comparison
145
+ :== => { c_func: "rb_obj_equal", arity: 1, return_type: :Bool, conv: :simple },
146
+ :=== => { c_func: "rb_equal", arity: 1, return_type: :Bool, conv: :simple },
147
+
148
+ # Object type checking
149
+ is_a?: { c_func: "rb_obj_is_kind_of", arity: 1, return_type: :Bool, conv: :simple },
150
+ kind_of?: { c_func: "rb_obj_is_kind_of", arity: 1, return_type: :Bool, conv: :simple },
151
+ instance_of?: { c_func: "rb_obj_is_instance_of", arity: 1, return_type: :Bool, conv: :simple },
152
+
153
+ # Object info - exported
154
+ class: { c_func: "rb_obj_class", arity: 0, return_type: :Class, conv: :simple },
155
+ object_id: { c_func: "rb_obj_id", arity: 0, return_type: :Integer, conv: :simple },
156
+
157
+ # Object duplication - exported
158
+ dup: { c_func: "rb_obj_dup", arity: 0, return_type: :Any, conv: :simple },
159
+ freeze: { c_func: "rb_obj_freeze", arity: 0, return_type: :Any, conv: :simple },
160
+ },
161
+
162
+ Range: {
163
+ # Block iterators
164
+ each: { arity: 0, return_type: :Range, conv: :block_iterator },
165
+ # Range enumerable methods
166
+ map: { arity: 0, return_type: :Array, conv: :block_iterator },
167
+ collect: { arity: 0, return_type: :Array, conv: :block_iterator },
168
+ select: { arity: 0, return_type: :Array, conv: :block_iterator },
169
+ filter: { arity: 0, return_type: :Array, conv: :block_iterator },
170
+ reject: { arity: 0, return_type: :Array, conv: :block_iterator },
171
+ reduce: { arity: -1, return_type: :Any, conv: :block_iterator },
172
+ inject: { arity: -1, return_type: :Any, conv: :block_iterator },
173
+ find: { arity: 0, return_type: :Any, conv: :block_iterator },
174
+ detect: { arity: 0, return_type: :Any, conv: :block_iterator },
175
+ any?: { arity: 0, return_type: :Bool, conv: :block_iterator },
176
+ all?: { arity: 0, return_type: :Bool, conv: :block_iterator },
177
+ none?: { arity: 0, return_type: :Bool, conv: :block_iterator },
178
+ },
179
+
180
+ Float: {
181
+ # Float comparison
182
+ :<=> => { c_func: "rb_float_cmp", arity: 1, return_type: :Integer, conv: :simple },
183
+
184
+ # Float conversion
185
+ to_i: { c_func: "rb_num2long", arity: 0, return_type: :Integer, conv: :simple },
186
+ to_int: { c_func: "rb_num2long", arity: 0, return_type: :Integer, conv: :simple },
187
+ floor: { c_func: "rb_float_floor", arity: 0, return_type: :Integer, conv: :simple },
188
+ ceil: { c_func: "rb_float_ceil", arity: 0, return_type: :Integer, conv: :simple },
189
+ round: { c_func: "rb_float_round", arity: 0, return_type: :Integer, conv: :simple },
190
+ truncate: { c_func: "rb_float_truncate", arity: 0, return_type: :Integer, conv: :simple },
191
+
192
+ # Float query
193
+ nan?: { c_func: "rb_float_nan_p", arity: 0, return_type: :Bool, conv: :simple },
194
+ infinite?: { c_func: "rb_float_infinite_p", arity: 0, return_type: :Any, conv: :simple },
195
+ finite?: { c_func: "rb_float_finite_p", arity: 0, return_type: :Bool, conv: :simple },
196
+ },
197
+
198
+ NilClass: {
199
+ nil?: { c_func: "rb_true", arity: 0, return_type: :Bool, conv: :simple },
200
+ to_s: { c_func: "rb_nil_to_s", arity: 0, return_type: :String, conv: :simple },
201
+ to_a: { c_func: "rb_ary_new", arity: 0, return_type: :Array, conv: :simple },
202
+ to_h: { c_func: "rb_hash_new", arity: 0, return_type: :Hash, conv: :simple },
203
+ },
204
+
205
+ TrueClass: {
206
+ to_s: { c_func: "rb_true_to_s", arity: 0, return_type: :String, conv: :simple },
207
+ },
208
+
209
+ FalseClass: {
210
+ to_s: { c_func: "rb_false_to_s", arity: 0, return_type: :String, conv: :simple },
211
+ },
212
+ }.freeze
213
+
214
+ # Helper method to look up a builtin method
215
+ def self.lookup(class_name, method_name)
216
+ BUILTIN_METHODS.dig(class_name.to_sym, method_name.to_sym)
217
+ end
218
+
219
+ # Get all classes with builtin methods
220
+ def self.builtin_classes
221
+ BUILTIN_METHODS.keys
222
+ end
223
+
224
+ # Get all methods for a class
225
+ def self.methods_for(class_name)
226
+ BUILTIN_METHODS[class_name.to_sym] || {}
227
+ end
228
+ end
229
+ end