Skip to content

Commit f4fec62

Browse files
committed
works as crystal shard
1 parent f4e593f commit f4fec62

File tree

4 files changed

+294
-278
lines changed

4 files changed

+294
-278
lines changed

ext/shard.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
name: activesupport-inflector
1+
name: fast_inflector
22
version: 0.1.0
33

44
authors:

ext/src/lib_ruby/lib_ruby.cr

Lines changed: 1 addition & 277 deletions
Original file line numberDiff line numberDiff line change
@@ -1,277 +1 @@
1-
lib LibRuby
2-
type VALUE = Void*
3-
type METHOD_FUNC = VALUE -> VALUE
4-
type ID = Void*
5-
6-
$rb_cObject : VALUE
7-
$rb_cNumeric : VALUE
8-
$rb_cBasicObject : VALUE
9-
10-
# generic
11-
fun rb_type(value : VALUE) : Int32 # can't get this working :/
12-
fun rb_any_to_s(value : VALUE) : UInt8*
13-
fun rb_class2name(value : VALUE) : UInt8*
14-
# fun rb_type(value : VALUE) : UInt8*
15-
fun rb_funcall(value : VALUE, method : ID, argc : Int32) : VALUE
16-
# fun rb_nil_p(value : VALUE) : Boolean # not sure how to handle this
17-
fun rb_obj_dup(value : VALUE) : VALUE
18-
19-
# integers
20-
fun rb_num2int(value : VALUE) : Int32
21-
fun rb_num2dbl(value : VALUE) : Float32
22-
fun rb_int2inum(value : Int32) : VALUE
23-
24-
# strings
25-
fun rb_str_to_str(value : VALUE) : VALUE
26-
fun rb_string_value_cstr(value_ptr : VALUE*) : UInt8*
27-
fun rb_str_new_cstr(str : UInt8*) : VALUE
28-
29-
fun rb_id2sym(value : ID) : VALUE
30-
fun rb_intern(name : UInt8*) : ID
31-
32-
# regexp
33-
fun rb_reg_new_str(str : VALUE, options : Int32) : VALUE # re.c:2792
34-
35-
# arrays
36-
fun rb_ary_new() : VALUE
37-
fun rb_ary_push(array : VALUE, value : VALUE)
38-
fun rb_ary_length(array : VALUE) : Int32
39-
fun rb_ary_shift(array : VALUE) : VALUE
40-
41-
# hashes
42-
fun rb_hash_new() : VALUE
43-
fun rb_hash_aset(hash : VALUE, key : VALUE, value : VALUE)
44-
fun rb_hash_foreach(hash : VALUE, callback : (Int32, Void* ->), data : Void*)
45-
fun rb_hash_keys(hash : VALUE)
46-
47-
# classes & modules
48-
fun rb_define_class(name : UInt8*, super : VALUE) : VALUE
49-
fun rb_define_class_under(parent : VALUE, name : UInt8*, super : VALUE) : VALUE
50-
fun rb_define_module(name : UInt8*, super : VALUE) : VALUE
51-
fun rb_define_module_under(parent : VALUE, name : UInt8*, super : VALUE) : VALUE
52-
fun rb_define_method(klass : VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
53-
fun rb_define_singleton_method(klass : VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
54-
fun rb_define_module_function(module : VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
55-
end
56-
57-
lib LibRuby1
58-
type METHOD_FUNC = LibRuby::VALUE, LibRuby::VALUE -> LibRuby::VALUE # STUB
59-
fun rb_define_method(klass : LibRuby::VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
60-
fun rb_define_singleton_method(klass : LibRuby::VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
61-
end
62-
63-
lib LibRuby2
64-
type METHOD_FUNC = LibRuby::VALUE, LibRuby::VALUE, LibRuby::VALUE -> LibRuby::VALUE
65-
fun rb_define_method(klass : LibRuby::VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
66-
fun rb_define_singleton_method(klass : LibRuby::VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
67-
end
68-
69-
lib LibRuby3
70-
type METHOD_FUNC = LibRuby::VALUE, LibRuby::VALUE, LibRuby::VALUE, LibRuby::VALUE -> LibRuby::VALUE
71-
fun rb_define_method(klass : LibRuby::VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
72-
fun rb_define_singleton_method(klass : LibRuby::VALUE, name : UInt8*, func : METHOD_FUNC, argc : Int32)
73-
end
74-
75-
module RubyImporter
76-
def self.import_hash_key(&callback : Int32 ->) #(key: VALUE, val : VALUE, data : Void*)
77-
@@callback = callback
78-
boxed_data = Box.box(callback)
79-
80-
# LibRuby.rb_hash_foreach(->(key, tick, data) {
81-
# # Now we turn data back into the Proc, using Box.unbox
82-
# data_as_callback = Box(typeof(callback)).unbox(data)
83-
# # And finally invoke the user's callback
84-
# data_as_callback.call(tick)
85-
# }, boxed_data)
86-
# String.from_ruby(key)
87-
"hi".to_ruby
88-
end
89-
# end
90-
91-
# class Object
92-
def self.scalar_from_ruby(obj : LibRuby::VALUE, klass_name : String = "")
93-
klass_name = rb_class(obj) if klass_name == ""
94-
case klass_name
95-
when "NilClass"
96-
nil
97-
when "TrueClass"
98-
true
99-
when "FalseClass"
100-
false
101-
when "String"
102-
String.from_ruby(obj)
103-
when "Symbol"
104-
RubySymbol.from_ruby(obj)
105-
when "Fixnum"
106-
Int32.from_ruby(obj)
107-
when "Bignum", "Integer"
108-
# puts Int.from_ruby(obj).inspect
109-
Int.from_ruby(obj)
110-
when "Regexp"
111-
Regex.from_ruby(obj)
112-
when "Float"
113-
Float.from_ruby(obj)
114-
else
115-
"sorry :/"
116-
end
117-
end
118-
def self.from_ruby(obj : LibRuby::VALUE)
119-
case (klass_name = rb_class(obj))
120-
when "Array"
121-
Array.from_ruby(obj)
122-
else
123-
scalar_from_ruby(obj, klass_name)
124-
end
125-
end
126-
RB_method_class = LibRuby.rb_intern("class")
127-
def self.rb_class(obj : LibRuby::VALUE)
128-
rb_klass = LibRuby.rb_funcall(obj, RB_method_class, 0)
129-
ptr = LibRuby.rb_class2name(rb_klass)
130-
cr_str = String.new(ptr)
131-
end
132-
RB_method_to_s = LibRuby.rb_intern("to_s")
133-
def self.rb_any_to_str(obj)
134-
str = LibRuby.rb_funcall(obj, RB_method_to_s, 0)
135-
c_str = LibRuby.rb_string_value_cstr(pointerof(str))
136-
cr_str = String.new(c_str)
137-
end
138-
end
139-
140-
struct Symbol
141-
def to_ruby
142-
LibRuby.rb_id2sym(LibRuby.rb_intern(self.to_s))
143-
end
144-
end
145-
146-
class Regex
147-
RB_REGEX_INT = {
148-
Regex::Options::IGNORE_CASE => 1,
149-
Regex::Options::MULTILINE => 2,
150-
Regex::Options::EXTENDED => 4,
151-
}
152-
def to_ruby
153-
code = RB_REGEX_INT.reduce(0){ |code, ( k, i )| self.options.includes?(k) ? code + i : code }
154-
LibRuby.rb_reg_new_str(self.source.to_ruby, code)
155-
end
156-
RB_REGEX_OPTIONS = {
157-
'i' => Regex::Options::IGNORE_CASE,
158-
'm' => Regex::Options::MULTILINE,
159-
'x' => Regex::Options::EXTENDED,
160-
}
161-
def self.from_ruby(val : LibRuby::VALUE) # needs improvement
162-
str = RubyImporter.rb_any_to_str(val)
163-
self.from_ruby(str)
164-
end
165-
def self.from_ruby(str : String)
166-
options = str[2..5].split('-').first
167-
exp = str[7..-2]
168-
options_enum = options.chars.reduce(Regex::Options::None) { |enum_obj, char| enum_obj | RB_REGEX_OPTIONS[char] }
169-
new(exp, options_enum)
170-
end
171-
end
172-
173-
class Array
174-
def to_ruby
175-
LibRuby.rb_ary_new().tap do |rb_array|
176-
self.each do |val|
177-
val.inspect # stops working without this. no idea why. seriously, comment this line and it fails (at least when spitting out an array that came from ruby)
178-
LibRuby.rb_ary_push(rb_array, val.to_ruby)
179-
end
180-
end
181-
end
182-
def self.from_ruby(ary) # this is awful
183-
rb_ary = LibRuby.rb_obj_dup(ary)
184-
element = LibRuby.rb_ary_shift(rb_ary)
185-
element = RubyImporter.scalar_from_ruby(element)
186-
arr = [element]
187-
until element.is_a?(Nil)
188-
element = LibRuby.rb_ary_shift(rb_ary)
189-
element = RubyImporter.scalar_from_ruby(element)
190-
arr << element
191-
end
192-
arr.pop
193-
arr
194-
end
195-
end
196-
197-
class Hash
198-
def to_ruby
199-
LibRuby.rb_hash_new().tap do |rb_hash|
200-
self.each do |k, v|
201-
LibRuby.rb_hash_aset(rb_hash, k.to_ruby, v.to_ruby)
202-
end
203-
end
204-
end
205-
def self.from_ruby
206-
# RubyImporter.import_hash_key do |tick|
207-
# puts tick
208-
# end
209-
{cant: "import ruby hashes"}
210-
end
211-
end
212-
213-
struct Nil
214-
def to_ruby
215-
Pointer(Void).new(8_u64).as(LibRuby::VALUE)
216-
end
217-
end
218-
219-
struct Bool
220-
def to_ruby
221-
Pointer(Void).new(self ? 20_u64 : 0_u64).as(LibRuby::VALUE)
222-
end
223-
def self.from_ruby
224-
#
225-
end
226-
end
227-
228-
class String
229-
def to_ruby
230-
LibRuby.rb_str_new_cstr(self)
231-
end
232-
233-
def self.from_ruby(str : LibRuby::VALUE)
234-
rb_str = LibRuby.rb_str_to_str(str)
235-
c_str = LibRuby.rb_string_value_cstr(pointerof(rb_str))
236-
cr_str = new(c_str)
237-
end
238-
end
239-
240-
# not working as intended
241-
class RubySymbol < String
242-
def to_ruby
243-
LibRuby.rb_id2sym(LibRuby.rb_intern(self))
244-
end
245-
def self.from_ruby(sym : LibRuby::VALUE)
246-
str = LibRuby.rb_funcall(sym, RubyImporter::RB_method_to_s, 0)
247-
rb_str = LibRuby.rb_str_to_str(str)
248-
c_str = LibRuby.rb_string_value_cstr(pointerof(rb_str))
249-
cr_str = new(c_str)
250-
end
251-
end
252-
struct Int
253-
def to_ruby
254-
LibRuby.rb_int2inum(self)
255-
end
256-
257-
def self.from_ruby(int)
258-
LibRuby.rb_num2int(int)
259-
end
260-
end
261-
struct Int32
262-
def to_ruby
263-
LibRuby.rb_int2inum(self)
264-
end
265-
266-
def self.from_ruby(int)
267-
LibRuby.rb_num2int(int)
268-
end
269-
end
270-
struct Float
271-
def self.from_ruby(float)
272-
LibRuby.rb_num2dbl(float)
273-
end
274-
def to_ruby
275-
to_i.to_ruby
276-
end
277-
end
1+
require "../../../src/lib_ruby.cr"

shard.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
name: crystalized_ruby
2+
version: 0.1.0
3+
4+
authors:
5+
- Paul Hoffer <paulrhoffer@gmail.com>
6+
7+
description: |
8+
Write native Ruby extensions in Crystal. Do not use this in a Crystal project.
9+
10+
# license: MIT

0 commit comments

Comments
 (0)