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
data/lib/konpeito/cli.rb
ADDED
|
@@ -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
|