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"
0 commit comments