crystalruby 0.1.10 → 0.1.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Dockerfile +17 -0
- data/README.md +16 -1
- data/examples/adder/adder.rb +10 -0
- data/exe/crystalruby +8 -8
- data/lib/crystalruby/compilation.rb +75 -0
- data/lib/crystalruby/config.rb +43 -11
- data/lib/crystalruby/templates/index.cr +1 -0
- data/lib/crystalruby/version.rb +1 -1
- data/lib/crystalruby.rb +48 -60
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 41e8370627d23725b55bb1916254b88690e93b384c94692d59d73b0cf5ceda03
|
4
|
+
data.tar.gz: 7d7192ea627331a30f6cd9ff9dcc7482ed2b1e373f115cc0e3cfa19edd5db506
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56d644c482b04bb8f5b39b6626dda93079578f3f95809294a441e0fd1707aeb71eb253da7a549c351fe448750f6dd2acfdbda3782b37e5aaebb4019332c64d0c
|
7
|
+
data.tar.gz: c529c61b9564f6d23dc551209ac7ce426d56a02424a970b57825f5e993953c376fa57afb3880db0647d581391e7d88881775cd0e2284408997fbaf4e8b37a690
|
data/Dockerfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
FROM ruby:3.3
|
2
|
+
|
3
|
+
MAINTAINER Wouter Coppieters <wc@pico.net.nz>
|
4
|
+
|
5
|
+
RUN apt-get update && apt-get install -y curl gnupg2 software-properties-common lsb-release
|
6
|
+
RUN curl -fsSL https://crystal-lang.org/install.sh | bash
|
7
|
+
WORKDIR /usr/src/app
|
8
|
+
|
9
|
+
COPY Gemfile Gemfile.lock ./
|
10
|
+
COPY crystalruby.gemspec ./
|
11
|
+
COPY lib/crystalruby/version.rb ./lib/crystalruby/version.rb
|
12
|
+
|
13
|
+
RUN bundle install
|
14
|
+
COPY . .
|
15
|
+
|
16
|
+
# Define the command to run your application
|
17
|
+
CMD ["bundle", "exec", "irb"]
|
data/README.md
CHANGED
@@ -501,7 +501,7 @@ Or install it yourself as:
|
|
501
501
|
$ gem install crystalruby
|
502
502
|
```
|
503
503
|
|
504
|
-
`crystalruby`
|
504
|
+
`crystalruby` supports some basic configuration options, which can be specified inside a crystalruby.yaml file in the root of your project.
|
505
505
|
You can run `crystalruby init` to generate a configuration file with sane defaults.
|
506
506
|
|
507
507
|
```bash
|
@@ -513,6 +513,21 @@ crystal_src_dir: "./crystalruby/src"
|
|
513
513
|
crystal_lib_dir: "./crystalruby/lib"
|
514
514
|
crystal_main_file: "main.cr"
|
515
515
|
crystal_lib_name: "crlib"
|
516
|
+
crystal_codegen_dir: "generated"
|
517
|
+
debug: true
|
518
|
+
```
|
519
|
+
|
520
|
+
Alternatively, these can be set programmatically:
|
521
|
+
|
522
|
+
```ruby
|
523
|
+
CrystalRuby.configure do |config|
|
524
|
+
config.crystal_src_dir = "./crystalruby/src"
|
525
|
+
config.crystal_lib_dir = "./crystalruby/lib"
|
526
|
+
config.crystal_main_file = "main.cr"
|
527
|
+
config.crystal_lib_name = "crlib"
|
528
|
+
config.crystal_codegen_dir = "generated"
|
529
|
+
config.debug = true
|
530
|
+
end
|
516
531
|
```
|
517
532
|
|
518
533
|
## Development
|
data/exe/crystalruby
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "bundler/setup"
|
4
4
|
require "crystalruby"
|
5
|
-
require
|
5
|
+
require "fileutils"
|
6
6
|
|
7
7
|
# Define the actions for the commands
|
8
8
|
def init
|
@@ -14,20 +14,20 @@ def init
|
|
14
14
|
crystal_main_file: "main.cr"
|
15
15
|
crystal_lib_name: "crlib"
|
16
16
|
crystal_codegen_dir: "generated"
|
17
|
+
debug: true
|
17
18
|
YAML
|
18
19
|
|
19
20
|
# Create the file at the root of the current directory
|
20
|
-
File.write(
|
21
|
-
puts
|
21
|
+
File.write("crystalruby.yaml", yaml_content)
|
22
|
+
puts "Initialized crystalruby.yaml file with dummy content."
|
22
23
|
end
|
23
24
|
|
24
|
-
|
25
25
|
def install
|
26
26
|
Dir.chdir("#{CrystalRuby.config.crystal_src_dir}") do
|
27
|
-
if system(
|
28
|
-
puts
|
27
|
+
if system("shards update")
|
28
|
+
puts "Shards installed successfully."
|
29
29
|
else
|
30
|
-
puts
|
30
|
+
puts "Error installing shards."
|
31
31
|
end
|
32
32
|
end
|
33
33
|
clean
|
@@ -40,7 +40,7 @@ end
|
|
40
40
|
|
41
41
|
def build
|
42
42
|
# This is a stub for the build command
|
43
|
-
puts
|
43
|
+
puts "Build command is not implemented yet."
|
44
44
|
end
|
45
45
|
|
46
46
|
# Main program
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require "open3"
|
2
|
+
require "tmpdir"
|
3
|
+
|
4
|
+
module CrystalRuby
|
5
|
+
module Compilation
|
6
|
+
def self.compile!(
|
7
|
+
src: config.crystal_src_dir_abs / config.crystal_main_file,
|
8
|
+
lib: config.crystal_lib_dir_abs / config.crystal_lib_name,
|
9
|
+
verbose: config.verbose,
|
10
|
+
debug: config.debug
|
11
|
+
)
|
12
|
+
Dir.chdir(config.crystal_src_dir_abs) do
|
13
|
+
compile_command = compile_command!(verbose: verbose, debug: debug, lib: lib, src: src)
|
14
|
+
link_command = link_cmd!(verbose: verbose, lib: lib, src: src)
|
15
|
+
|
16
|
+
puts "[crystalruby] Compiling Crystal code: #{compile_command}" if verbose
|
17
|
+
unless system(compile_command)
|
18
|
+
puts "Failed to build Crystal object file."
|
19
|
+
return false
|
20
|
+
end
|
21
|
+
|
22
|
+
puts "[crystalruby] Linking Crystal code: #{link_command}" if verbose
|
23
|
+
unless system(link_command)
|
24
|
+
puts "Failed to link Crystal library."
|
25
|
+
return false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.compile_command!(verbose:, debug:, lib:, src:)
|
33
|
+
@compile_command ||= begin
|
34
|
+
verbose_flag = verbose ? "--verbose" : ""
|
35
|
+
debug_flag = debug ? "" : "--release --no-debug"
|
36
|
+
redirect_output = " > /dev/null " unless verbose
|
37
|
+
|
38
|
+
%(crystal build #{verbose_flag} #{debug_flag} --cross-compile -o #{lib} #{src}#{redirect_output})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# Here we misuse the crystal compiler to build a valid linking command
|
43
|
+
# with all of the platform specific flags that we need.
|
44
|
+
# We then use this command to link the object file that we compiled in the previous step.
|
45
|
+
# This is not robust and is likely to need revision in the future.
|
46
|
+
def self.link_cmd!(verbose:, lib:, src:)
|
47
|
+
@link_cmd ||= begin
|
48
|
+
result = nil
|
49
|
+
|
50
|
+
Dir.mktmpdir do |tmp|
|
51
|
+
output, status = Open3.capture2("crystal build --verbose #{src} -o #{Pathname.new(tmp) / "main"}")
|
52
|
+
unless status.success?
|
53
|
+
puts "Failed to compile the Crystal code."
|
54
|
+
exit 1
|
55
|
+
end
|
56
|
+
|
57
|
+
# Parse the output to find the last invocation of the C compiler, which is likely the linking stage
|
58
|
+
# and strip off the targets that the crystal compiler added.
|
59
|
+
link_command_suffix = output.lines.select { |line| line.strip.start_with?("cc") }.last.strip[/.*(-o.*)/, 1]
|
60
|
+
|
61
|
+
# Replace the output file with the path to the object file we compiled
|
62
|
+
link_command_suffix.gsub!(
|
63
|
+
/-o.*main/,
|
64
|
+
"-o #{lib}"
|
65
|
+
)
|
66
|
+
result = %(cc #{lib}.o -shared #{link_command_suffix})
|
67
|
+
result << " > /dev/null 2>&1" unless verbose
|
68
|
+
result
|
69
|
+
end
|
70
|
+
|
71
|
+
result
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/lib/crystalruby/config.rb
CHANGED
@@ -9,25 +9,57 @@ module CrystalRuby
|
|
9
9
|
# Define a nested Config class
|
10
10
|
class Config
|
11
11
|
include Singleton
|
12
|
-
attr_accessor :debug, :
|
12
|
+
attr_accessor :debug, :verbose
|
13
13
|
|
14
14
|
def initialize
|
15
15
|
@debug = true
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
@paths_cache = {}
|
17
|
+
config = File.exist?("crystalruby.yaml") && begin
|
18
|
+
YAML.safe_load(IO.read("crystalruby.yaml"))
|
19
|
+
rescue StandardError
|
20
|
+
nil
|
21
|
+
end || {}
|
22
|
+
@crystal_src_dir = config.fetch("crystal_src_dir", "./crystalruby/src")
|
23
|
+
@crystal_lib_dir = config.fetch("crystal_lib_dir", "./crystalruby/lib")
|
24
|
+
@crystal_main_file = config.fetch("crystal_main_file", "main.cr")
|
25
|
+
@crystal_lib_name = config.fetch("crystal_lib_name", "crlib")
|
26
|
+
@crystal_codegen_dir = config.fetch("crystal_codegen_dir", "generated")
|
27
|
+
@crystal_project_root = config.fetch("crystal_project_root", Pathname.pwd)
|
28
|
+
@debug = config.fetch("debug", true)
|
29
|
+
@verbose = config.fetch("verbose", false)
|
30
|
+
end
|
31
|
+
|
32
|
+
%w[crystal_main_file crystal_lib_name crystal_project_root].each do |method_name|
|
33
|
+
define_method(method_name) do
|
34
|
+
@paths_cache[method_name] ||= Pathname.new(instance_variable_get(:"@#{method_name}"))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
%w[crystal_codegen_dir].each do |method_name|
|
39
|
+
abs_method_name = "#{method_name}_abs"
|
40
|
+
define_method(abs_method_name) do
|
41
|
+
@paths_cache[abs_method_name] ||= crystal_src_dir_abs / instance_variable_get(:"@#{method_name}")
|
42
|
+
end
|
43
|
+
|
44
|
+
define_method(method_name) do
|
45
|
+
@paths_cache[method_name] ||= Pathname.new instance_variable_get(:"@#{method_name}")
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
%w[crystal_src_dir crystal_lib_dir].each do |method_name|
|
50
|
+
abs_method_name = "#{method_name}_abs"
|
51
|
+
define_method(abs_method_name) do
|
52
|
+
@paths_cache[abs_method_name] ||= crystal_project_root / instance_variable_get(:"@#{method_name}")
|
53
|
+
end
|
54
|
+
|
55
|
+
define_method(method_name) do
|
56
|
+
@paths_cache[method_name] ||= Pathname.new instance_variable_get(:"@#{method_name}")
|
20
57
|
end
|
21
|
-
@crystal_src_dir = config.fetch("crystal_src_dir", "./crystalruby/src")
|
22
|
-
@crystal_lib_dir = config.fetch("crystal_lib_dir", "./crystalruby/lib")
|
23
|
-
@crystal_main_file = config.fetch("crystal_main_file", "main.cr")
|
24
|
-
@crystal_lib_name = config.fetch("crystal_lib_name", "crlib")
|
25
|
-
@crystal_codegen_dir = config.fetch("crystal_codegen_dir", "generated")
|
26
58
|
end
|
27
59
|
end
|
28
60
|
|
29
61
|
def self.configure
|
30
|
-
setup
|
31
62
|
yield(config)
|
63
|
+
@paths_cache = {}
|
32
64
|
end
|
33
65
|
end
|
data/lib/crystalruby/version.rb
CHANGED
data/lib/crystalruby.rb
CHANGED
@@ -4,12 +4,15 @@ require "ffi"
|
|
4
4
|
require "digest"
|
5
5
|
require "fileutils"
|
6
6
|
require "method_source"
|
7
|
+
require "pathname"
|
8
|
+
|
7
9
|
require_relative "crystalruby/config"
|
8
10
|
require_relative "crystalruby/version"
|
9
11
|
require_relative "crystalruby/typemaps"
|
10
12
|
require_relative "crystalruby/types"
|
11
13
|
require_relative "crystalruby/typebuilder"
|
12
14
|
require_relative "crystalruby/template"
|
15
|
+
require_relative "crystalruby/compilation"
|
13
16
|
|
14
17
|
module CrystalRuby
|
15
18
|
CR_SRC_FILES_PATTERN = "./**/*.cr"
|
@@ -71,7 +74,7 @@ module CrystalRuby
|
|
71
74
|
function = build_function(self, method_name, args, returns, function_body)
|
72
75
|
CrystalRuby.write_chunk(self, name: function[:name], body: function[:body]) do
|
73
76
|
extend FFI::Library
|
74
|
-
ffi_lib
|
77
|
+
ffi_lib config.crystal_lib_dir / config.crystal_lib_name
|
75
78
|
attach_function method_name, fname, function[:ffi_types], function[:return_ffi_type]
|
76
79
|
if block
|
77
80
|
[singleton_class, self].each do |receiver|
|
@@ -85,7 +88,7 @@ module CrystalRuby
|
|
85
88
|
[singleton_class, self].each do |receiver|
|
86
89
|
receiver.prepend(Module.new do
|
87
90
|
define_method(method_name) do |*args|
|
88
|
-
CrystalRuby.
|
91
|
+
CrystalRuby.build! unless CrystalRuby.compiled?
|
89
92
|
unless CrystalRuby.attached?
|
90
93
|
CrystalRuby.attach!
|
91
94
|
return send(method_name, *args) if block
|
@@ -219,28 +222,29 @@ module CrystalRuby
|
|
219
222
|
raise "Missing config option `#{config_key}`. \nProvide this inside crystalruby.yaml (run `bundle exec crystalruby init` to generate this file with detaults)"
|
220
223
|
end
|
221
224
|
end
|
222
|
-
FileUtils.mkdir_p
|
223
|
-
FileUtils.mkdir_p
|
224
|
-
|
225
|
+
FileUtils.mkdir_p config.crystal_codegen_dir_abs
|
226
|
+
FileUtils.mkdir_p config.crystal_lib_dir_abs
|
227
|
+
FileUtils.mkdir_p config.crystal_src_dir_abs
|
228
|
+
unless File.exist?(config.crystal_src_dir_abs / config.crystal_main_file)
|
225
229
|
IO.write(
|
226
|
-
|
230
|
+
config.crystal_src_dir_abs / config.crystal_main_file,
|
227
231
|
"require \"./#{config.crystal_codegen_dir}/index\"\n"
|
228
232
|
)
|
229
233
|
end
|
230
234
|
|
231
235
|
attach_crystal_ruby_lib! if compiled?
|
232
236
|
|
233
|
-
return if File.exist?(
|
237
|
+
return if File.exist?(config.crystal_src_dir / "shard.yml")
|
234
238
|
|
235
|
-
IO.write("#{config.crystal_src_dir}/shard.yml", <<~
|
239
|
+
IO.write("#{config.crystal_src_dir}/shard.yml", <<~YAML)
|
236
240
|
name: src
|
237
241
|
version: 0.1.0
|
238
|
-
|
242
|
+
YAML
|
239
243
|
end
|
240
244
|
|
241
245
|
def attach_crystal_ruby_lib!
|
242
246
|
extend FFI::Library
|
243
|
-
ffi_lib
|
247
|
+
ffi_lib config.crystal_lib_dir / config.crystal_lib_name
|
244
248
|
attach_function "init!", :init, [:pointer], :void
|
245
249
|
send(:remove_const, :ErrorCallback) if defined?(ErrorCallback)
|
246
250
|
const_set(:ErrorCallback, FFI::Function.new(:void, %i[string string]) do |error_type, message|
|
@@ -272,24 +276,19 @@ module CrystalRuby
|
|
272
276
|
|
273
277
|
def type_modules
|
274
278
|
(@types_cache || {}).map do |type_name, expr|
|
275
|
-
typedef = ""
|
276
279
|
parts = type_name.split("::")
|
277
|
-
|
278
|
-
|
279
|
-
typedef << "#{indent} module #{part}\n"
|
280
|
-
indent += " "
|
280
|
+
typedef = parts[0...-1].each_with_index.reduce("") do |acc, (part, index)|
|
281
|
+
acc + "#{" " * index}module #{part}\n"
|
281
282
|
end
|
282
|
-
typedef
|
283
|
-
parts[0...-1].
|
284
|
-
|
285
|
-
typedef << "#{indent} end\n"
|
283
|
+
typedef += "#{" " * (parts.size - 1)}alias #{parts.last} = #{expr}\n"
|
284
|
+
typedef + parts[0...-1].reverse.each_with_index.reduce("") do |acc, (_part, index)|
|
285
|
+
acc + "#{" " * (parts.size - 2 - index)}end\n"
|
286
286
|
end
|
287
|
-
typedef
|
288
287
|
end.join("\n")
|
289
288
|
end
|
290
289
|
|
291
290
|
def self.requires
|
292
|
-
|
291
|
+
chunk_store.map do |function|
|
293
292
|
function_data = function[:body]
|
294
293
|
file_digest = Digest::MD5.hexdigest function_data
|
295
294
|
fname = function[:name]
|
@@ -297,40 +296,26 @@ module CrystalRuby
|
|
297
296
|
end.join("\n")
|
298
297
|
end
|
299
298
|
|
300
|
-
def self.
|
301
|
-
|
302
|
-
|
303
|
-
index_content = Template.render(
|
299
|
+
def self.build!
|
300
|
+
File.write config.crystal_codegen_dir_abs / "index.cr", Template.render(
|
304
301
|
Template::Index,
|
305
|
-
|
306
|
-
|
307
|
-
requires: requires
|
308
|
-
}
|
302
|
+
type_modules: type_modules,
|
303
|
+
requires: requires
|
309
304
|
)
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
end
|
320
|
-
|
321
|
-
unless result = system(cmd)
|
322
|
-
File.delete(digest_file_name) if File.exist?(digest_file_name)
|
323
|
-
raise "Error compiling crystal code"
|
324
|
-
end
|
305
|
+
if @compiled = CrystalRuby::Compilation.compile!(
|
306
|
+
verbose: config.verbose,
|
307
|
+
debug: config.debug
|
308
|
+
)
|
309
|
+
IO.write(digest_file_name, get_cr_src_files_digest)
|
310
|
+
attach_crystal_ruby_lib!
|
311
|
+
else
|
312
|
+
File.delete(digest_file_name) if File.exist?(digest_file_name)
|
313
|
+
raise "Error compiling crystal code"
|
325
314
|
end
|
326
|
-
|
327
|
-
IO.write(digest_file_name, get_cr_src_files_digest)
|
328
|
-
@compiled = true
|
329
|
-
attach_crystal_ruby_lib!
|
330
315
|
end
|
331
316
|
|
332
317
|
def self.attach!
|
333
|
-
@
|
318
|
+
@chunk_store.each do |function|
|
334
319
|
function[:compile_callback]&.call
|
335
320
|
end
|
336
321
|
@attached = true
|
@@ -345,7 +330,11 @@ module CrystalRuby
|
|
345
330
|
end
|
346
331
|
|
347
332
|
def self.digest_file_name
|
348
|
-
@digest_file_name ||= "#{config.
|
333
|
+
@digest_file_name ||= config.crystal_lib_dir_abs / "#{config.crystal_lib_name}.digest"
|
334
|
+
end
|
335
|
+
|
336
|
+
def self.chunk_store
|
337
|
+
@chunk_store ||= []
|
349
338
|
end
|
350
339
|
|
351
340
|
def self.get_current_crystal_lib_digest
|
@@ -353,26 +342,25 @@ module CrystalRuby
|
|
353
342
|
end
|
354
343
|
|
355
344
|
def self.write_chunk(owner, body:, name: Digest::MD5.hexdigest(body), &compile_callback)
|
356
|
-
|
357
|
-
|
358
|
-
|
359
|
-
|
360
|
-
@block_store.each do |function|
|
345
|
+
chunk_store << { owner: owner, name: name, body: body, compile_callback: compile_callback }
|
346
|
+
FileUtils.mkdir_p(config.crystal_codegen_dir_abs)
|
347
|
+
existing = Dir.glob("#{config.crystal_codegen_dir_abs}/**/*.cr")
|
348
|
+
chunk_store.each do |function|
|
361
349
|
owner_name = function[:owner].name
|
362
|
-
FileUtils.mkdir_p(
|
350
|
+
FileUtils.mkdir_p(config.crystal_codegen_dir_abs / owner_name)
|
363
351
|
function_data = function[:body]
|
364
352
|
fname = function[:name]
|
365
353
|
file_digest = Digest::MD5.hexdigest function_data
|
366
|
-
filename =
|
367
|
-
unless existing.delete(filename)
|
354
|
+
filename = config.crystal_codegen_dir_abs / owner_name / "#{fname}_#{file_digest}.cr"
|
355
|
+
unless existing.delete(filename.to_s)
|
368
356
|
@compiled = false
|
369
357
|
@attached = false
|
370
358
|
File.write(filename, function_data)
|
371
359
|
end
|
372
360
|
existing.select do |f|
|
373
|
-
f =~
|
361
|
+
f =~ /#{config.crystal_codegen_dir / owner_name / "#{fname}_[a-f0-9]{32}\.cr"}/
|
374
362
|
end.each do |fl|
|
375
|
-
File.delete(fl) unless fl.eql?(filename)
|
363
|
+
File.delete(fl) unless fl.eql?(filename.to_s)
|
376
364
|
end
|
377
365
|
end
|
378
366
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: crystalruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.12
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wouter Coppieters
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-04-
|
11
|
+
date: 2024-04-12 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: digest
|
@@ -77,12 +77,15 @@ files:
|
|
77
77
|
- ".rubocop.yml"
|
78
78
|
- CHANGELOG.md
|
79
79
|
- CODE_OF_CONDUCT.md
|
80
|
+
- Dockerfile
|
80
81
|
- LICENSE.txt
|
81
82
|
- README.md
|
82
83
|
- Rakefile
|
83
84
|
- crystalruby.gemspec
|
85
|
+
- examples/adder/adder.rb
|
84
86
|
- exe/crystalruby
|
85
87
|
- lib/crystalruby.rb
|
88
|
+
- lib/crystalruby/compilation.rb
|
86
89
|
- lib/crystalruby/config.rb
|
87
90
|
- lib/crystalruby/template.rb
|
88
91
|
- lib/crystalruby/templates/function.cr
|