rubex 0.0.1 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +4 -0
- data/.travis.yml +14 -0
- data/CONTRIBUTING.md +101 -0
- data/HISTORY.md +3 -0
- data/README.md +112 -297
- data/REFERENCE.md +753 -0
- data/Rakefile +4 -1
- data/TUTORIAL.md +234 -0
- data/bin/rubex +1 -1
- data/docs/_config.yml +1 -0
- data/docs/index.html +1 -0
- data/examples/c_struct_interface/c_struct_interface.rb +6 -0
- data/examples/c_struct_interface/c_struct_interface.rubex +47 -0
- data/examples/linked_list/linked_list.rubex +39 -0
- data/examples/linked_list/rb_linked_list.rb +8 -0
- data/examples/rcsv wrapper/rcsv/README.md +1 -0
- data/examples/rcsv wrapper/rcsv/Rakefile +7 -0
- data/examples/rcsv wrapper/rcsv/ext/rcsv/extconf.rb +3 -0
- data/examples/rcsv wrapper/rcsv/ext/rcsv/rcsv.c +302 -0
- data/examples/rcsv wrapper/rcsv/ext/rcsv/rcsv.rubex +124 -0
- data/examples/rcsv wrapper/rcsv/lib/rcsv.rb +8 -0
- data/examples/rcsv wrapper/rcsv/lib/rcsv.so +0 -0
- data/examples/rcsv wrapper/rcsv/lib/rcsv/version.rb +1 -0
- data/examples/rcsv wrapper/rcsv/rcsv.gemspec +27 -0
- data/examples/rcsv wrapper/rcsv/spec/rcsv.csv +5 -0
- data/examples/rcsv wrapper/rcsv/spec/rcsv_spec.rb +17 -0
- data/examples/rcsv wrapper/rcsv/spec/spec_helper.rb +6 -0
- data/{spec/fixtures/basic_ruby_method/Makefile → examples/rcsv wrapper/rcsv/tmp/x86_64-linux/rcsv/2.3.3/Makefile } +20 -20
- data/examples/rcsv wrapper/rcsv/tmp/x86_64-linux/rcsv/2.3.3/rcsv.o +0 -0
- data/examples/rcsv wrapper/rcsv/tmp/x86_64-linux/rcsv/2.3.3/rcsv.so +0 -0
- data/examples/rcsv wrapper/rcsv/tmp/x86_64-linux/stage/lib/rcsv.so +0 -0
- data/lib/rubex.rb +6 -50
- data/lib/rubex/ast.rb +1 -3
- data/lib/rubex/ast/expression.rb +1257 -8
- data/lib/rubex/ast/node.rb +226 -28
- data/lib/rubex/ast/statement.rb +1162 -35
- data/lib/rubex/ast/top_statement.rb +815 -0
- data/lib/rubex/code_writer.rb +103 -26
- data/lib/rubex/compiler.rb +72 -0
- data/lib/rubex/compiler_config.rb +19 -0
- data/lib/rubex/constants.rb +145 -8
- data/lib/rubex/data_type.rb +667 -4
- data/lib/rubex/error.rb +15 -0
- data/lib/rubex/helpers.rb +154 -0
- data/lib/rubex/lexer.rex +186 -22
- data/lib/rubex/lexer.rex.rb +261 -35
- data/lib/rubex/parser.racc +876 -28
- data/lib/rubex/parser.racc.rb +2845 -90
- data/lib/rubex/rake_task.rb +34 -0
- data/lib/rubex/symbol_table/entry.rb +17 -3
- data/lib/rubex/symbol_table/scope.rb +298 -25
- data/lib/rubex/version.rb +1 -1
- data/rubex.gemspec +11 -3
- data/spec/basic_ruby_method_spec.rb +15 -21
- data/spec/binding_ptr_args_spec.rb +33 -0
- data/spec/bitwise_operators_spec.rb +40 -0
- data/spec/blocks_spec.rb +35 -0
- data/spec/c_bindings_spec.rb +36 -0
- data/spec/c_constants_spec.rb +33 -0
- data/spec/c_function_ptrs_spec.rb +38 -0
- data/spec/c_functions_spec.rb +35 -0
- data/spec/c_struct_interface_spec.rb +38 -0
- data/spec/call_by_reference_spec.rb +33 -0
- data/spec/class_methods_spec.rb +33 -0
- data/spec/class_spec.rb +40 -0
- data/spec/comments_spec.rb +33 -0
- data/spec/default_args_spec.rb +37 -0
- data/spec/error_handling_spec.rb +42 -0
- data/spec/examples_spec.rb +52 -0
- data/spec/expressions_spec.rb +33 -0
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.rubex +2 -0
- data/spec/fixtures/binding_ptr_args/binding_ptr_args.rubex +30 -0
- data/spec/fixtures/bitwise_operators/bitwise_operators.rubex +40 -0
- data/spec/fixtures/blocks/blocks.rubex +11 -0
- data/spec/fixtures/c_bindings/c_bindings.rubex +58 -0
- data/spec/fixtures/c_constants/c_constants.rubex +7 -0
- data/spec/fixtures/c_function_ptrs/c_function_ptrs.rubex +52 -0
- data/spec/fixtures/c_functions/c_functions.rubex +25 -0
- data/spec/fixtures/c_struct_interface/c_struct_interface.rubex +34 -0
- data/spec/fixtures/call_by_reference/call_by_reference.rubex +30 -0
- data/spec/fixtures/class/class.rubex +20 -0
- data/spec/fixtures/class_methods/class_methods.rubex +12 -0
- data/spec/fixtures/comments/comments.rubex +9 -0
- data/spec/fixtures/default_args/default_args.rubex +11 -0
- data/spec/fixtures/error_handling/error_handling.rubex +54 -0
- data/spec/fixtures/examples/array_to_hash.rubex +14 -0
- data/spec/fixtures/examples/rcsv.csv +5 -0
- data/spec/fixtures/examples/rcsv.rubex +329 -0
- data/spec/fixtures/expressions/expressions.rubex +10 -0
- data/spec/fixtures/if_else/if_else.rubex +77 -0
- data/spec/fixtures/implicit_lib_include/implicit_lib_include.rubex +15 -0
- data/spec/fixtures/init_ruby_objects_with_literal_syntax/init_ruby_objects_with_literal_syntax.rubex +17 -0
- data/spec/fixtures/loops/loops.rubex +33 -0
- data/spec/fixtures/recursion/recursion.rubex +9 -0
- data/spec/fixtures/ruby_constant_method_calls/ruby_constant_method_calls.rubex +17 -0
- data/spec/fixtures/ruby_operators/ruby_operators.rubex +29 -0
- data/spec/fixtures/ruby_raise/ruby_raise.rubex +13 -0
- data/spec/fixtures/ruby_strings/ruby_strings.rubex +19 -0
- data/spec/fixtures/ruby_strings/string_blank_bm.rb +37 -0
- data/spec/fixtures/ruby_symbols/ruby_symbols.rubex +12 -0
- data/spec/fixtures/ruby_types/ruby_types.rubex +15 -0
- data/spec/fixtures/statement_expression/statement_expression.rubex +23 -0
- data/spec/fixtures/static_array/static_array.rubex +20 -0
- data/spec/fixtures/string_literals/string_literals.rubex +15 -0
- data/spec/fixtures/struct/struct.rubex +82 -0
- data/spec/fixtures/typecasting/typecasting.rubex +23 -0
- data/spec/fixtures/var_declarations/var_declarations.rubex +39 -0
- data/spec/if_else_spec.rb +39 -0
- data/spec/implicit_lib_include_spec.rb +33 -0
- data/spec/init_ruby_objects_with_literal_syntax_spec.rb +39 -0
- data/spec/loops_spec.rb +34 -0
- data/spec/recursion_spec.rb +35 -0
- data/spec/ruby_constant_method_calls_spec.rb +35 -0
- data/spec/ruby_operators_spec.rb +40 -0
- data/spec/ruby_raise_spec.rb +35 -0
- data/spec/ruby_strings_spec.rb +33 -0
- data/spec/ruby_symbols_spec.rb +37 -0
- data/spec/ruby_types_spec.rb +35 -0
- data/spec/spec_helper.rb +54 -1
- data/spec/statement_expression_spec.rb +34 -0
- data/spec/static_array_spec.rb +33 -0
- data/spec/string_literals_spec.rb +34 -0
- data/spec/struct_spec.rb +36 -0
- data/spec/typecasting_spec.rb +38 -0
- data/spec/var_declarions_spec.rb +35 -0
- metadata +255 -29
- data/lib/rubex/ast/argument_list.rb +0 -20
- data/lib/rubex/ast/c_base_type.rb +0 -11
- data/lib/rubex/ast/ruby_method_def.rb +0 -84
- data/spec/fixtures/basic_ruby_method/basic.rb +0 -3
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.c +0 -16
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.o +0 -0
- data/spec/fixtures/basic_ruby_method/basic_ruby_method.so +0 -0
- data/spec/fixtures/basic_ruby_method/extconf.rb +0 -3
data/lib/rubex/code_writer.rb
CHANGED
@@ -4,64 +4,141 @@ module Rubex
|
|
4
4
|
|
5
5
|
def initialize target_name
|
6
6
|
@code = "/* C extension for #{target_name}.\n"\
|
7
|
-
"This file in generated by Rubex. Do not change!\n"\
|
8
|
-
|
7
|
+
"This file in generated by Rubex::Compiler. Do not change!\n"\
|
8
|
+
"File generation time: #{Time.now}."\
|
9
|
+
"*/\n\n"
|
9
10
|
@indent = 0
|
10
11
|
end
|
11
12
|
|
12
|
-
|
13
|
-
|
13
|
+
# type - Return type of the method.
|
14
|
+
# c_name - C Name.
|
15
|
+
# args - Array of Arrays containing data type and variable name.
|
16
|
+
def write_func_declaration type:, c_name:, args: [], static: true
|
17
|
+
write_func_prototype type, c_name, args, static: static
|
14
18
|
@code << ";"
|
15
19
|
new_line
|
16
20
|
end
|
17
21
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
+
def colon
|
23
|
+
@code << ";"
|
24
|
+
new_line
|
25
|
+
end
|
26
|
+
|
27
|
+
def c_macro macro
|
28
|
+
@code << "#define #{macro}"
|
29
|
+
new_line
|
30
|
+
end
|
31
|
+
|
32
|
+
def write_c_method_header type: , c_name: , args: [], static: true
|
33
|
+
write_func_prototype type, c_name, args, static: static
|
34
|
+
end
|
35
|
+
|
36
|
+
def write_ruby_method_header type: , c_name:
|
37
|
+
args = [["int", "argc"], ["VALUE*", "argv"],
|
38
|
+
["VALUE", "#{Rubex::ARG_PREFIX + "self"}"]]
|
39
|
+
write_func_prototype type, c_name, args
|
40
|
+
end
|
41
|
+
|
42
|
+
def write_location location
|
43
|
+
new_line
|
44
|
+
self << "/* Rubex file location: #{location} */"
|
45
|
+
new_line
|
46
|
+
end
|
47
|
+
|
48
|
+
def declare_variable type:, c_name:
|
49
|
+
@code << " "*@indent + "#{type} #{c_name};"
|
50
|
+
new_line
|
51
|
+
end
|
52
|
+
|
53
|
+
def declare_func_ptr var:
|
54
|
+
type = var.type
|
55
|
+
func = type.base_type
|
56
|
+
@code << " "*@indent
|
57
|
+
@code << "#{func.type.to_s} (#{type.ptr_level}#{func.c_name}) "
|
58
|
+
@code << "(" + func.arg_list.map { |e| e.type.to_s }.join(',') + ")"
|
59
|
+
@code << ";"
|
60
|
+
nl
|
22
61
|
end
|
23
62
|
|
24
|
-
def
|
25
|
-
|
63
|
+
def declare_carray type:, c_name:, dimension:, value: nil
|
64
|
+
stmt = "#{type} #{c_name}[#{dimension}]"
|
65
|
+
stmt << " = {" + value.join(',') + "}" if value
|
66
|
+
stmt << ";"
|
67
|
+
self << stmt
|
68
|
+
nl
|
26
69
|
end
|
27
|
-
|
28
|
-
def
|
29
|
-
|
70
|
+
|
71
|
+
def init_variable lhs: , rhs:
|
72
|
+
stat = " "*@indent + "#{lhs} = #{rhs};"
|
73
|
+
@code << stat
|
74
|
+
new_line
|
75
|
+
end
|
76
|
+
|
77
|
+
def << str
|
78
|
+
str.each_line do |s|
|
79
|
+
@code << " "*@indent
|
80
|
+
@code << s
|
81
|
+
end
|
30
82
|
end
|
31
83
|
|
32
84
|
def new_line
|
33
85
|
@code << "\n"
|
34
86
|
end
|
87
|
+
alias :nl :new_line
|
35
88
|
|
36
89
|
def indent
|
37
|
-
@indent +=
|
90
|
+
@indent += 2
|
38
91
|
end
|
39
92
|
|
40
93
|
def dedent
|
41
94
|
raise "Cannot dedent, already 0." if @indent == 0
|
42
|
-
@indent -=
|
95
|
+
@indent -= 2
|
43
96
|
end
|
44
97
|
|
45
|
-
def
|
46
|
-
@code << "
|
47
|
-
|
98
|
+
def write_instance_method klass: , method_name: , method_c_name:
|
99
|
+
@code << " "*@indent + "rb_define_method(" + klass + " ,\"" +
|
100
|
+
method_name + "\", " + method_c_name + ", -1);"
|
101
|
+
new_line
|
102
|
+
end
|
103
|
+
|
104
|
+
def write_singleton_method klass:, method_name:, method_c_name:
|
105
|
+
@code << " "*@indent + "rb_define_singleton_method(" + klass + " ,\"" +
|
106
|
+
method_name + "\", " + method_c_name + ", -1);"
|
107
|
+
new_line
|
48
108
|
end
|
49
109
|
|
50
110
|
def to_s
|
51
111
|
@code
|
52
112
|
end
|
53
113
|
|
114
|
+
def lbrace
|
115
|
+
@code << (" "*@indent + "{")
|
116
|
+
end
|
117
|
+
|
118
|
+
def rbrace
|
119
|
+
@code << (" "*@indent + "}")
|
120
|
+
end
|
121
|
+
|
122
|
+
def block str="", &block
|
123
|
+
new_line
|
124
|
+
lbrace
|
125
|
+
indent
|
126
|
+
new_line
|
127
|
+
block.call
|
128
|
+
dedent
|
129
|
+
rbrace
|
130
|
+
@code << str
|
131
|
+
new_line
|
132
|
+
new_line
|
133
|
+
end
|
134
|
+
|
54
135
|
private
|
55
136
|
|
56
|
-
def write_func_prototype return_type, c_name, args
|
57
|
-
@code << "#{return_type} #{c_name} "
|
137
|
+
def write_func_prototype return_type, c_name, args, static: true
|
138
|
+
@code << "#{static ? "static " : ""}#{return_type} #{c_name} "
|
58
139
|
@code << "("
|
59
|
-
|
60
|
-
|
61
|
-
else
|
62
|
-
@code << args
|
63
|
-
end
|
64
|
-
@code << ")"
|
140
|
+
@code << args.map { |type_arg| type_arg.join(" ") }.join(",")
|
141
|
+
@code << ")"
|
65
142
|
end
|
66
143
|
end
|
67
144
|
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Rubex
|
2
|
+
class Compiler
|
3
|
+
CONFIG = Rubex::CompilerConfig.new
|
4
|
+
|
5
|
+
class << self
|
6
|
+
def compile path, test: false, directory: nil
|
7
|
+
tree = ast path, test: test
|
8
|
+
target_name = extract_target_name path
|
9
|
+
code = generate_code tree, target_name
|
10
|
+
ext = extconf target_name, directory: directory
|
11
|
+
CONFIG.flush
|
12
|
+
|
13
|
+
return [tree, code, ext] if test
|
14
|
+
write_files target_name, code, ext, directory: directory
|
15
|
+
end
|
16
|
+
|
17
|
+
def ast path, test: false
|
18
|
+
if test
|
19
|
+
parser = Rubex::Parser.new
|
20
|
+
parser.parse(path)
|
21
|
+
parser.do_parse
|
22
|
+
else
|
23
|
+
begin
|
24
|
+
parser = Rubex::Parser.new
|
25
|
+
parser.parse(path)
|
26
|
+
parser.do_parse
|
27
|
+
rescue Racc::ParseError => e
|
28
|
+
error_msg = "\nPARSE ERROR:\n"
|
29
|
+
error_msg << "Line: #{parser.string.split("\n")[parser.lineno-1]}\n"
|
30
|
+
error_msg << "Location: #{parser.location}\n"
|
31
|
+
error_msg << "Error:\n#{e}"
|
32
|
+
STDERR.puts error_msg
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def extconf target_name, directory: nil
|
38
|
+
path = directory ? directory : "#{Dir.pwd}/#{target_name}"
|
39
|
+
extconf = ""
|
40
|
+
extconf << "require 'mkmf'\n"
|
41
|
+
extconf << "$libs += \" #{CONFIG.link_flags}\"\n"
|
42
|
+
extconf << "create_makefile('#{path}/#{target_name}')\n"
|
43
|
+
extconf
|
44
|
+
end
|
45
|
+
|
46
|
+
def generate_code tree, target_name
|
47
|
+
code = Rubex::CodeWriter.new target_name
|
48
|
+
raise "Must be a Rubex::AST::Node, not #{tree.class}" unless
|
49
|
+
tree.is_a? Rubex::AST::Node
|
50
|
+
tree.process_statements target_name, code
|
51
|
+
code
|
52
|
+
end
|
53
|
+
|
54
|
+
def extract_target_name path
|
55
|
+
File.basename(path).split('.')[0]
|
56
|
+
end
|
57
|
+
|
58
|
+
def write_files target_name, code, ext, directory: nil
|
59
|
+
path = directory ? directory : "#{Dir.pwd}/#{target_name}"
|
60
|
+
Dir.mkdir(path) unless directory
|
61
|
+
|
62
|
+
code_file = File.new "#{path}/#{target_name}.c", "w+"
|
63
|
+
code_file.puts code.to_s
|
64
|
+
code_file.close
|
65
|
+
|
66
|
+
extconf_file = File.new "#{path}/extconf.rb", "w+"
|
67
|
+
extconf_file.puts ext
|
68
|
+
extconf_file.close
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Rubex
|
2
|
+
class CompilerConfig
|
3
|
+
def initialize
|
4
|
+
@links = []
|
5
|
+
end
|
6
|
+
|
7
|
+
def add_link link_str
|
8
|
+
@links << link_str
|
9
|
+
end
|
10
|
+
|
11
|
+
def link_flags
|
12
|
+
@links.map { |l| l.dup.prepend('-l') }.join(' ')
|
13
|
+
end
|
14
|
+
|
15
|
+
def flush
|
16
|
+
@links = []
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
data/lib/rubex/constants.rb
CHANGED
@@ -1,17 +1,154 @@
|
|
1
1
|
module Rubex
|
2
2
|
RUBEX_PREFIX = "__rubex_"
|
3
|
-
|
4
|
-
|
3
|
+
GLOBAL_PREFIX = "global_"
|
4
|
+
|
5
|
+
TEMP_PREFIX = RUBEX_PREFIX + "temp_"
|
6
|
+
RUBY_FUNC_PREFIX = RUBEX_PREFIX + "rb_f_"
|
7
|
+
C_FUNC_PREFIX = RUBEX_PREFIX + "c_f_"
|
5
8
|
VAR_PREFIX = RUBEX_PREFIX + "v_"
|
6
|
-
|
9
|
+
RUBY_CLASS_PREFIX = RUBEX_PREFIX + "rb_cls_"
|
10
|
+
ATTACH_CLASS_PREFIX = RUBEX_PREFIX + "attach_rb_cls"
|
7
11
|
ARG_PREFIX = RUBEX_PREFIX + "arg_"
|
12
|
+
ARRAY_PREFIX = RUBEX_PREFIX + "arr_"
|
13
|
+
POINTER_PREFIX = RUBEX_PREFIX + "ptr_"
|
14
|
+
TYPE_PREFIX = RUBEX_PREFIX + "t_"
|
15
|
+
|
16
|
+
ACTUAL_ARGS_SUFFIX = "_actual_args"
|
8
17
|
|
9
18
|
TYPE_MAPPINGS = {
|
10
|
-
'
|
11
|
-
'
|
19
|
+
'char' => Rubex::DataType::Char,
|
20
|
+
'bool' => Rubex::DataType::CBoolean,
|
21
|
+
'unsigned char' => Rubex::DataType::UChar,
|
22
|
+
'i8' => Rubex::DataType::Int8,
|
23
|
+
'i16' => Rubex::DataType::Int16,
|
24
|
+
'i32' => Rubex::DataType::Int32,
|
25
|
+
'i64' => Rubex::DataType::Int64,
|
26
|
+
'u8' => Rubex::DataType::UInt8,
|
27
|
+
'u16' => Rubex::DataType::UInt16,
|
28
|
+
'u32' => Rubex::DataType::UInt32,
|
29
|
+
'u64' => Rubex::DataType::UInt64,
|
30
|
+
'int' => Rubex::DataType::Int,
|
31
|
+
'unsigned int' => Rubex::DataType::UInt,
|
32
|
+
'long int' => Rubex::DataType::LInt,
|
33
|
+
'long' => Rubex::DataType::LInt,
|
34
|
+
'unsigned long int' => Rubex::DataType::ULInt,
|
35
|
+
'long long int' => Rubex::DataType::LLInt,
|
36
|
+
'long long' => Rubex::DataType::LLInt,
|
37
|
+
'unsigned long long int' => Rubex::DataType::ULLInt,
|
38
|
+
'f32' => Rubex::DataType::F32,
|
39
|
+
'float' => Rubex::DataType::F32,
|
40
|
+
'f64' => Rubex::DataType::F64,
|
41
|
+
'double' => Rubex::DataType::F64,
|
42
|
+
'object' => Rubex::DataType::RubyObject,
|
43
|
+
'void' => Rubex::DataType::Void,
|
44
|
+
'size_t' => Rubex::DataType::Size_t,
|
45
|
+
'str' => Rubex::DataType::RubyString,
|
46
|
+
'arr' => Rubex::DataType::RubyArray,
|
47
|
+
'hsh' => Rubex::DataType::RubyHash
|
48
|
+
}
|
49
|
+
|
50
|
+
CUSTOM_TYPES = {}
|
51
|
+
|
52
|
+
DEFAULT_CLASS_MAPPINGS = {
|
53
|
+
"Kernel" => "rb_mKernel",
|
54
|
+
"Comparable" => "rb_mComparable",
|
55
|
+
"Enumerable" => "rb_mEnumerable",
|
56
|
+
"Errno" => "rb_mErrno",
|
57
|
+
"FileTest" => "rb_mFileTest",
|
58
|
+
"GC" => "rb_mGC",
|
59
|
+
"Math" => "rb_mMath",
|
60
|
+
"Process" => "rb_mProcess",
|
61
|
+
"WaitReadable" => "rb_mWaitReadable",
|
62
|
+
"WaitWritable" => "rb_mWaitWritable",
|
63
|
+
"BasicObject" => "rb_cBasicObject",
|
64
|
+
"Object" => "rb_cObject",
|
65
|
+
"Array" => "rb_cArray",
|
66
|
+
"Bignum" => "rb_cBignum",
|
67
|
+
"Binding" => "rb_cBinding",
|
68
|
+
"Class" => "rb_cClass",
|
69
|
+
"Cont" => "rb_cCont",
|
70
|
+
"Dir" => "rb_cDir",
|
71
|
+
"Data" => "rb_cData",
|
72
|
+
"FalseClass" => "rb_cFalseClass",
|
73
|
+
"Encoding" => "rb_cEncoding",
|
74
|
+
"Enumerator" => "rb_cEnumerator",
|
75
|
+
"File" => "rb_cFile",
|
76
|
+
"Fixnum" => "rb_cFixnum",
|
77
|
+
"Float" => "rb_cFloat",
|
78
|
+
"Hash" => "rb_cHash",
|
79
|
+
"Integer" => "rb_cInteger",
|
80
|
+
"IO" => "rb_cIO",
|
81
|
+
"Match" => "rb_cMatch",
|
82
|
+
"Method" => "rb_cMethod",
|
83
|
+
"Module" => "rb_cModule",
|
84
|
+
"NameErrorMesg" => "rb_cNameErrorMesg",
|
85
|
+
"NilClass" => "rb_cNilClass",
|
86
|
+
"Numeric" => "rb_cNumeric",
|
87
|
+
"Proc" => "rb_cProc",
|
88
|
+
"Random" => "rb_cRandom",
|
89
|
+
"Range" => "rb_cRange",
|
90
|
+
"Rational" => "rb_cRational",
|
91
|
+
"Complex" => "rb_cComplex",
|
92
|
+
"Regexp" => "rb_cRegexp",
|
93
|
+
"Stat" => "rb_cStat",
|
94
|
+
"String" => "rb_cString",
|
95
|
+
"Struct" => "rb_cStruct",
|
96
|
+
"Symbol" => "rb_cSymbol",
|
97
|
+
"Thread" => "rb_cThread",
|
98
|
+
"Time" => "rb_cTime",
|
99
|
+
"TrueClass" => "rb_cTrueClass",
|
100
|
+
"UnboundMethod" => "rb_cUnboundMethod",
|
101
|
+
"Exception" => "rb_eException",
|
102
|
+
"StandardError" => "rb_eStandardError",
|
103
|
+
"SystemExit" => "rb_eSystemExit",
|
104
|
+
"Interrupt" => "rb_eInterrupt",
|
105
|
+
"Signal" => "rb_eSignal",
|
106
|
+
"Fatal" => "rb_eFatal",
|
107
|
+
"ArgumentError" => "rb_eArgError",
|
108
|
+
"EOFError" => "rb_eEOFError",
|
109
|
+
"IndexError" => "rb_eIndexError",
|
110
|
+
"StopIteration" => "rb_eStopIteration",
|
111
|
+
"KeyError" => "rb_eKeyError",
|
112
|
+
"RangeError" => "rb_eRangeError",
|
113
|
+
"IOError" => "rb_eIOError",
|
114
|
+
"RuntimeError" => "rb_eRuntimeError",
|
115
|
+
"SecurityError" => "rb_eSecurityError",
|
116
|
+
"SystemCallError" => "rb_eSystemCallError",
|
117
|
+
"ThreadError" => "rb_eThreadError",
|
118
|
+
"TypeError" => "rb_eTypeError",
|
119
|
+
"ZeroDivError" => "rb_eZeroDivError",
|
120
|
+
"NotImpError" => "rb_eNotImpError",
|
121
|
+
"NoMemError" => "rb_eNoMemError",
|
122
|
+
"NoMethodError" => "rb_eNoMethodError",
|
123
|
+
"FloatDomainError" => "rb_eFloatDomainError",
|
124
|
+
"LocalJumpError" => "rb_eLocalJumpError",
|
125
|
+
"SysStackError" => "rb_eSysStackError",
|
126
|
+
"RegexpError" => "rb_eRegexpError",
|
127
|
+
"EncodingError" => "rb_eEncodingError",
|
128
|
+
"EncCompatError" => "rb_eEncCompatError",
|
129
|
+
"ScriptError" => "rb_eScriptError",
|
130
|
+
"NameError" => "rb_eNameError",
|
131
|
+
"SyntaxError" => "rb_eSyntaxError",
|
132
|
+
"LoadError" => "rb_eLoadError",
|
133
|
+
"MathDomainError" => "rb_eMathDomainError",
|
134
|
+
"STDIN" => "rb_stdin",
|
135
|
+
"STDOUT" => "rb_stdout",
|
136
|
+
"STDERR" => "rb_stderr",
|
12
137
|
}
|
13
138
|
|
14
|
-
|
15
|
-
|
139
|
+
C_MACRO_INT2BOOL = Rubex::RUBEX_PREFIX + "INT2BOOL"
|
140
|
+
C_FUNC_CHAR2RUBYSTR = Rubex::RUBEX_PREFIX + "char2rubystr"
|
141
|
+
|
142
|
+
ALLOC_FUNC_NAME = 'allocate'
|
143
|
+
DEALLOC_FUNC_NAME = 'deallocate'
|
144
|
+
MEMCOUNT_FUNC_NAME = 'memcount'
|
145
|
+
GET_STRUCT_FUNC_NAME = 'get_struct'
|
146
|
+
|
147
|
+
# Maps regexes to the type of the variable for conversion from literal
|
148
|
+
# to the correct type of Ruby object.
|
149
|
+
LITERAL_MAPPINGS = {
|
150
|
+
/'.\'/ => Rubex::DataType::Char,
|
151
|
+
/-?\d+/ => Rubex::DataType::Int,
|
152
|
+
/-?\d+\.\d+/ => Rubex::DataType::F64
|
16
153
|
}
|
17
|
-
end
|
154
|
+
end
|
data/lib/rubex/data_type.rb
CHANGED
@@ -1,15 +1,678 @@
|
|
1
1
|
module Rubex
|
2
2
|
module DataType
|
3
|
+
# Citations
|
4
|
+
# Printf arguments:
|
5
|
+
# http://www.thinkage.ca/english/gcos/expl/c/lib/printf.html
|
6
|
+
module Helpers
|
7
|
+
include ::Comparable
|
8
|
+
[
|
9
|
+
:float?, :float32?, :float64?,
|
10
|
+
:int?, :int8?, :int16?, :int32?, :int64?,
|
11
|
+
:uint?, :uint8?, :uint16?, :uint32?, :uint64?,
|
12
|
+
:lint?, :ulint?, :llint?, :ullint?,
|
13
|
+
:char?, :object?, :bool?, :carray?, :cbool?,
|
14
|
+
:cptr?, :nil_type?, :struct_or_union?,
|
15
|
+
:alias_type?, :string?, :cstr?, :ruby_class?,
|
16
|
+
:ruby_method?, :c_function?, :ruby_constant?, :void?,
|
17
|
+
:ruby_string?, :uchar?, :ruby_array?, :ruby_hash?
|
18
|
+
].each do |dtype|
|
19
|
+
define_method(dtype) { return false }
|
20
|
+
end
|
21
|
+
|
22
|
+
def == other
|
23
|
+
self.class == other.class
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_ruby_object(arg); arg; end
|
27
|
+
|
28
|
+
def from_ruby_object(arg); arg; end
|
29
|
+
|
30
|
+
def base_type; self; end
|
31
|
+
|
32
|
+
# Helper function to know if a dtype is a char pointer.
|
33
|
+
def char_ptr?
|
34
|
+
if self.cptr? && self.base_type.char?
|
35
|
+
true
|
36
|
+
else
|
37
|
+
false
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def c_function_ptr?
|
42
|
+
if self.cptr? && self.base_type.c_function?
|
43
|
+
true
|
44
|
+
else
|
45
|
+
false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
module IntHelpers
|
51
|
+
include Helpers
|
52
|
+
def to_ruby_object(arg); "INT2NUM(#{arg})"; end
|
53
|
+
end
|
54
|
+
|
55
|
+
module UIntHelpers
|
56
|
+
include Helpers
|
57
|
+
def to_ruby_object(arg); "UINT2NUM(#{arg})"; end
|
58
|
+
end
|
59
|
+
|
60
|
+
module FloatHelpers
|
61
|
+
include Helpers
|
62
|
+
end
|
63
|
+
|
64
|
+
class Void
|
65
|
+
include Helpers
|
66
|
+
|
67
|
+
def void?; true; end
|
68
|
+
|
69
|
+
def to_s; "void"; end
|
70
|
+
end
|
71
|
+
|
3
72
|
class RubyObject
|
73
|
+
include Helpers
|
4
74
|
def to_s; "VALUE"; end
|
75
|
+
|
76
|
+
def object?; true; end
|
77
|
+
|
78
|
+
def p_formatter; "%s"; end
|
79
|
+
end
|
80
|
+
|
81
|
+
class RubySymbol < RubyObject
|
82
|
+
def ruby_symbol?; true; end
|
83
|
+
end
|
84
|
+
|
85
|
+
class RubyString < RubyObject
|
86
|
+
def ruby_string?; true; end
|
87
|
+
end
|
88
|
+
|
89
|
+
class RubyArray < RubyObject
|
90
|
+
def ruby_array?; true; end
|
91
|
+
end
|
92
|
+
|
93
|
+
class RubyHash < RubyObject
|
94
|
+
def ruby_hash?; true; end
|
95
|
+
end
|
96
|
+
|
97
|
+
class Char
|
98
|
+
include Helpers
|
99
|
+
def to_s; "char"; end
|
100
|
+
|
101
|
+
def to_ruby_object(arg, literal=false)
|
102
|
+
"#{Rubex::C_FUNC_CHAR2RUBYSTR}(#{arg})"
|
103
|
+
end
|
104
|
+
|
105
|
+
def from_ruby_object(arg); "(char)NUM2INT(#{arg})"; end
|
106
|
+
|
107
|
+
def p_formatter; "%c"; end
|
108
|
+
|
109
|
+
def char?; true; end
|
110
|
+
|
111
|
+
def <=> other
|
112
|
+
if other.char?
|
113
|
+
return 0
|
114
|
+
else
|
115
|
+
return 1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
class UChar
|
121
|
+
include Helpers
|
122
|
+
|
123
|
+
def to_s; "unsigned char"; end
|
124
|
+
|
125
|
+
def from_ruby_object(arg); "(unsigned char)NUM2INT(#{arg})"; end
|
126
|
+
|
127
|
+
def p_formatter; "%d"; end
|
128
|
+
|
129
|
+
def uchar?; true; end
|
130
|
+
|
131
|
+
def <=> other
|
132
|
+
if other.char? || other.uchar?
|
133
|
+
return 0
|
134
|
+
else
|
135
|
+
return 1
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
class Int8
|
141
|
+
include IntHelpers
|
142
|
+
|
143
|
+
def to_s; "int8_t"; end
|
144
|
+
|
145
|
+
def from_ruby_object(arg); "(int8_t)NUM2INT(#{arg})"; end
|
146
|
+
|
147
|
+
def int8?; true; end
|
148
|
+
|
149
|
+
def p_formatter; "%d"; end
|
150
|
+
|
151
|
+
def <=> other
|
152
|
+
if other.char?
|
153
|
+
return 1
|
154
|
+
elsif other.int8?
|
155
|
+
return 0
|
156
|
+
else
|
157
|
+
return -1
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
class Int16
|
163
|
+
include IntHelpers
|
164
|
+
def to_s; "int16_t"; end
|
165
|
+
|
166
|
+
def from_ruby_object(arg); "(int16_t)NUM2INT(#{arg})"; end
|
167
|
+
|
168
|
+
def int16?; true; end
|
169
|
+
|
170
|
+
def p_formatter; "%d"; end
|
171
|
+
|
172
|
+
def <=> other
|
173
|
+
if other.char? || other.int8?
|
174
|
+
return 1
|
175
|
+
elsif other.int16?
|
176
|
+
return 0
|
177
|
+
else
|
178
|
+
return -1
|
179
|
+
end
|
180
|
+
end
|
5
181
|
end
|
6
182
|
|
7
|
-
class
|
183
|
+
class Int32
|
184
|
+
include IntHelpers
|
8
185
|
def to_s; "int32_t"; end
|
9
186
|
|
10
|
-
def
|
187
|
+
def from_ruby_object(arg); "(int32_t)NUM2INT(#{arg})"; end
|
188
|
+
|
189
|
+
def int32?; true; end
|
190
|
+
|
191
|
+
def p_formatter; "%d"; end
|
192
|
+
|
193
|
+
def <=> other
|
194
|
+
if other.char? || other.int8? || other.int16?
|
195
|
+
return 1
|
196
|
+
elsif other.int32? || other.int?
|
197
|
+
return 0
|
198
|
+
else
|
199
|
+
return -1
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
class Int64
|
205
|
+
include IntHelpers
|
206
|
+
def to_s; "int64_t"; end
|
207
|
+
|
208
|
+
def to_ruby_object(arg); "LONG2NUM(#{arg})"; end
|
209
|
+
|
210
|
+
def from_ruby_object(arg); "(int64_t)NUM2LONG(#{arg})"; end
|
211
|
+
|
212
|
+
def p_formatter; "%ld"; end
|
213
|
+
|
214
|
+
def int64?; true; end
|
215
|
+
|
216
|
+
def <=> other
|
217
|
+
if other.char? || other.int8? || other.int16? || other.int32? ||
|
218
|
+
other.int?
|
219
|
+
return 1
|
220
|
+
elsif other.int64?
|
221
|
+
return 0
|
222
|
+
else
|
223
|
+
return -1
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
class UInt8
|
229
|
+
include UIntHelpers
|
230
|
+
def to_s; "uint8_t"; end
|
231
|
+
|
232
|
+
def from_ruby_object(arg); "(uint8_t)NUM2UINT(#{arg})"; end
|
233
|
+
|
234
|
+
def uint8?; true; end
|
235
|
+
|
236
|
+
def p_formatter; "%u"; end
|
237
|
+
end
|
238
|
+
|
239
|
+
class UInt16
|
240
|
+
include UIntHelpers
|
241
|
+
def to_s; "uint16_t"; end
|
242
|
+
|
243
|
+
def from_ruby_object(arg); "(uint16_t)NUM2UINT(#{arg})"; end
|
244
|
+
|
245
|
+
def uint16?; true; end
|
246
|
+
|
247
|
+
def p_formatter; "%u"; end
|
248
|
+
end
|
249
|
+
|
250
|
+
class UInt32
|
251
|
+
include UIntHelpers
|
252
|
+
def to_s; "uint32_t"; end
|
253
|
+
|
254
|
+
def from_ruby_object(arg); "(int32_t)NUM2UINT(#{arg})"; end
|
255
|
+
|
256
|
+
def uint32?; true; end
|
257
|
+
|
258
|
+
def p_formatter; "%u"; end
|
259
|
+
end
|
260
|
+
|
261
|
+
class UInt64
|
262
|
+
include UIntHelpers
|
263
|
+
def to_s; "uint64_t"; end
|
264
|
+
|
265
|
+
def to_ruby_object(arg); "ULONG2NUM(#{arg})"; end
|
266
|
+
|
267
|
+
def from_ruby_object(arg); "(int64_t)NUM2UINT(#{arg})"; end
|
268
|
+
|
269
|
+
def uint64?; true; end
|
270
|
+
|
271
|
+
def p_formatter; "%lu"; end
|
272
|
+
end
|
273
|
+
|
274
|
+
class Int
|
275
|
+
include IntHelpers
|
276
|
+
def to_s; "int"; end
|
277
|
+
|
278
|
+
def from_ruby_object(arg); "NUM2INT(#{arg})"; end
|
279
|
+
|
280
|
+
def int?; true; end
|
281
|
+
|
282
|
+
def p_formatter; "%d"; end
|
283
|
+
|
284
|
+
def <=> other
|
285
|
+
if other.char? || other.int8? || other.int16?
|
286
|
+
return 1
|
287
|
+
elsif other.int? || other.int32?
|
288
|
+
return 0
|
289
|
+
else # other is int64 or greater
|
290
|
+
return -1
|
291
|
+
end
|
292
|
+
end
|
293
|
+
end
|
294
|
+
|
295
|
+
class CBoolean < Int
|
296
|
+
def cbool?; true; end
|
297
|
+
|
298
|
+
def to_ruby_object arg
|
299
|
+
Rubex::C_MACRO_INT2BOOL + "(" + arg + ")"
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
class UInt
|
304
|
+
include UIntHelpers
|
305
|
+
def to_s; "unsigned int"; end
|
306
|
+
|
307
|
+
def from_ruby_object(arg); "(unsigned int)NUM2UINT(#{arg})"; end
|
308
|
+
|
309
|
+
def uint?; true; end
|
310
|
+
|
311
|
+
def p_formatter; "%u"; end
|
312
|
+
|
313
|
+
def <=> other
|
314
|
+
if other.char? || other.int8? || other.int16? || other.uint8? || other.uint16?
|
315
|
+
return 1
|
316
|
+
elsif other.uint? || other.int? || other.int32? || other.uint32?
|
317
|
+
return 0
|
318
|
+
else
|
319
|
+
return -1
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
class LInt
|
325
|
+
include IntHelpers
|
326
|
+
def to_s; "long int"; end
|
11
327
|
|
12
|
-
def
|
328
|
+
def to_ruby_object(arg); "LONG2NUM(#{arg})"; end
|
329
|
+
|
330
|
+
def from_ruby_object(arg); "NUM2LONG(#{arg})"; end
|
331
|
+
|
332
|
+
def lint?; true; end
|
333
|
+
|
334
|
+
def p_formatter; "%ld"; end
|
335
|
+
|
336
|
+
def <=> other
|
337
|
+
if other.char? || other.int8? || other.int16? || other.int32? ||
|
338
|
+
other .int64? || other.uint8? || other.uint16? || other.uint32? ||
|
339
|
+
other.int?
|
340
|
+
return 1
|
341
|
+
elsif other.lint?
|
342
|
+
return 0
|
343
|
+
else
|
344
|
+
return -1
|
345
|
+
end
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
class ULInt
|
350
|
+
include UIntHelpers
|
351
|
+
def to_s; "unsigned long int"; end
|
352
|
+
|
353
|
+
def to_ruby_object(arg); "ULONG2NUM(#{arg})"; end
|
354
|
+
|
355
|
+
def from_ruby_object(arg); "NUM2ULONG(#{arg})"; end
|
356
|
+
|
357
|
+
def ulint?; true; end
|
358
|
+
|
359
|
+
def p_formatter; "%lu"; end
|
360
|
+
|
361
|
+
def <=> other
|
362
|
+
if other.char? || other.int8? || other.int16? || other.int32? ||
|
363
|
+
other .int64? || other.uint8? || other.uint16? || other.uint32? ||
|
364
|
+
other.int?
|
365
|
+
return 1
|
366
|
+
elsif other.ulint?
|
367
|
+
return 0
|
368
|
+
else
|
369
|
+
return -1
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
class Size_t < ULInt
|
375
|
+
def to_s
|
376
|
+
"size_t"
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
class LLInt
|
381
|
+
include IntHelpers
|
382
|
+
def to_s; "long long int"; end
|
383
|
+
|
384
|
+
def to_ruby_object(arg); "LL2NUM(#{arg})"; end
|
385
|
+
|
386
|
+
def from_ruby_object(arg); "NUM2LL(#{arg})"; end
|
387
|
+
|
388
|
+
def llint?; true; end
|
389
|
+
|
390
|
+
def p_formatter; "%ll"; end
|
391
|
+
end
|
392
|
+
|
393
|
+
class ULLInt
|
394
|
+
include UIntHelpers
|
395
|
+
def to_s; "unsigned long long int"; end
|
396
|
+
|
397
|
+
def to_ruby_object(arg); "ULL2NUM(#{arg})"; end
|
398
|
+
|
399
|
+
def from_ruby_object(arg); "NUM2ULL(#{arg})"; end
|
400
|
+
|
401
|
+
def ullint?; true; end
|
402
|
+
|
403
|
+
def p_formatter; "%llu"; end
|
404
|
+
end
|
405
|
+
|
406
|
+
class F32
|
407
|
+
include FloatHelpers
|
408
|
+
def to_s; "float"; end
|
409
|
+
|
410
|
+
def to_ruby_object(arg); "rb_float_new((double)(#{arg}))"; end
|
411
|
+
|
412
|
+
def from_ruby_object(arg); "(float)NUM2DBL(#{arg})"; end
|
413
|
+
|
414
|
+
def float32?; true; end
|
415
|
+
|
416
|
+
def p_formatter; "%f"; end
|
417
|
+
|
418
|
+
def <=> other
|
419
|
+
if other.char? || other.int8? || other.int16? || other.int32? ||
|
420
|
+
other.int64? || other.int? || other.uint8? || other.uint16?||
|
421
|
+
other.uint32? || other.uint64?
|
422
|
+
return 1
|
423
|
+
elsif other.float32?
|
424
|
+
return 0
|
425
|
+
else # other is float64
|
426
|
+
return -1
|
427
|
+
end
|
428
|
+
end
|
429
|
+
|
430
|
+
end
|
431
|
+
|
432
|
+
class F64
|
433
|
+
include FloatHelpers
|
434
|
+
def to_s; "double"; end
|
435
|
+
|
436
|
+
def to_ruby_object(arg); "rb_float_new(#{arg})"; end
|
437
|
+
|
438
|
+
def from_ruby_object(arg); "NUM2DBL(#{arg})"; end
|
439
|
+
|
440
|
+
def float64?; true; end
|
441
|
+
|
442
|
+
def p_formatter; "%f"; end
|
443
|
+
|
444
|
+
def <=> other
|
445
|
+
if other.char? || other.int8? || other.int16? || other.int32? ||
|
446
|
+
other.int64? || other.int? || other.uint8? || other.uint16?||
|
447
|
+
other.uint32? || other.uint64? || other.float32?
|
448
|
+
return 1
|
449
|
+
elsif other.float64?
|
450
|
+
return 0
|
451
|
+
else
|
452
|
+
return -1
|
453
|
+
end
|
454
|
+
end
|
455
|
+
end
|
456
|
+
|
457
|
+
class CArray
|
458
|
+
include Helpers
|
459
|
+
# Dimension of the array
|
460
|
+
attr_reader :dimension
|
461
|
+
# Type of elements stored in array
|
462
|
+
attr_reader :type # FIXME: Make this base_type to make it more explicit.
|
463
|
+
|
464
|
+
def initialize dimension, type
|
465
|
+
@dimension, @type = dimension, type
|
466
|
+
end
|
467
|
+
|
468
|
+
def carray?; true; end
|
469
|
+
|
470
|
+
def <=> other
|
471
|
+
if self.class == other.class
|
472
|
+
@type <=> other.type
|
473
|
+
else
|
474
|
+
@type <=> other
|
475
|
+
end
|
476
|
+
end
|
477
|
+
|
478
|
+
def base_type
|
479
|
+
@type
|
480
|
+
end
|
481
|
+
end
|
482
|
+
|
483
|
+
class CPtr
|
484
|
+
include Helpers
|
485
|
+
# The data type that this pointer is pointing to.
|
486
|
+
attr_reader :type
|
487
|
+
|
488
|
+
def initialize type
|
489
|
+
@type = type
|
490
|
+
end
|
491
|
+
|
492
|
+
def p_formatter
|
493
|
+
"%s" if char_ptr?
|
494
|
+
end
|
495
|
+
|
496
|
+
def cptr?; true; end
|
497
|
+
|
498
|
+
def to_s
|
499
|
+
base_type = @type.base_type
|
500
|
+
if base_type.c_function?
|
501
|
+
ptr = ptr_level
|
502
|
+
|
503
|
+
str = "#{base_type.type.to_s} (#{ptr} #{base_type.c_name.to_s})"
|
504
|
+
str << "(" + base_type.arg_list.map { |e| e.type.to_s }.join(',') + ")"
|
505
|
+
else
|
506
|
+
t = @type
|
507
|
+
str = "*"
|
508
|
+
if t.cptr?
|
509
|
+
str << "*"
|
510
|
+
t = t.type
|
511
|
+
end
|
512
|
+
str.prepend t.to_s
|
513
|
+
str
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
def base_type
|
518
|
+
return @type if !@type.is_a?(self.class)
|
519
|
+
return @type.base_type
|
520
|
+
end
|
521
|
+
|
522
|
+
def ptr_level
|
523
|
+
temp = @type
|
524
|
+
ptr = "*"
|
525
|
+
while temp.cptr?
|
526
|
+
ptr << "*"
|
527
|
+
temp = @type.type
|
528
|
+
end
|
529
|
+
|
530
|
+
ptr
|
531
|
+
end
|
532
|
+
|
533
|
+
# from a Ruby function get a pointer to some value.
|
534
|
+
def from_ruby_object arg
|
535
|
+
return "StringValueCStr(#{arg})" if @type.char?
|
536
|
+
arg
|
537
|
+
end
|
538
|
+
|
539
|
+
def to_ruby_object arg
|
540
|
+
return "rb_str_new2(#{arg})" if @type.char?
|
541
|
+
arg
|
542
|
+
end
|
543
|
+
|
544
|
+
def <=> other
|
545
|
+
return -1
|
546
|
+
end
|
547
|
+
end
|
548
|
+
|
549
|
+
class Boolean < RubyObject
|
550
|
+
include Helpers
|
551
|
+
|
552
|
+
def bool?; true; end
|
553
|
+
end
|
554
|
+
|
555
|
+
class TrueType < Boolean; end
|
556
|
+
|
557
|
+
class FalseType < Boolean; end
|
558
|
+
|
559
|
+
class NilType < RubyObject
|
560
|
+
def nil_type?; true; end
|
561
|
+
end
|
562
|
+
|
563
|
+
class CStructOrUnion
|
564
|
+
include Helpers
|
565
|
+
attr_reader :kind, :name, :c_name, :scope
|
566
|
+
|
567
|
+
def initialize kind, name, c_name, scope
|
568
|
+
@kind, @name, @c_name, @scope = kind, name, c_name, scope
|
569
|
+
end
|
570
|
+
|
571
|
+
def struct_or_union?; true; end
|
572
|
+
|
573
|
+
def to_s; "#{@c_name}"; end
|
13
574
|
end
|
575
|
+
|
576
|
+
# FIXME: Find out a better way to generically find the old type of a typedef
|
577
|
+
# when the new type is encountered. Should cover cases where the new type
|
578
|
+
# is aliased with some other name too. In other words, reach the actual
|
579
|
+
# type in the most generic way possible without too many checks.
|
580
|
+
class TypeDef
|
581
|
+
# include Helpers
|
582
|
+
attr_reader :type, :old_type, :new_type
|
583
|
+
|
584
|
+
def initialize old_type, new_type, type
|
585
|
+
@old_type, @new_type, @type = old_type, new_type, type
|
586
|
+
end
|
587
|
+
|
588
|
+
def alias_type?; true; end
|
589
|
+
|
590
|
+
def to_s
|
591
|
+
@new_type.to_s
|
592
|
+
end
|
593
|
+
|
594
|
+
def base_type
|
595
|
+
@old_type
|
596
|
+
end
|
597
|
+
|
598
|
+
def method_missing meth, *args, &block
|
599
|
+
@old_type.send(meth, *args, &block)
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
class CStr
|
604
|
+
include Helpers
|
605
|
+
|
606
|
+
def cstr?; true; end
|
607
|
+
|
608
|
+
def p_formatter; "%s"; end
|
609
|
+
|
610
|
+
def from_ruby_object arg
|
611
|
+
"StringValueCStr(#{arg})"
|
612
|
+
end
|
613
|
+
|
614
|
+
def to_ruby_object arg
|
615
|
+
"rb_str_new_cstr(#{arg})"
|
616
|
+
end
|
617
|
+
end
|
618
|
+
|
619
|
+
class RubyConstant < RubyObject
|
620
|
+
attr_reader :name, :type
|
621
|
+
|
622
|
+
def initialize name
|
623
|
+
@name = name
|
624
|
+
# FIXME: make this flexible so that consts set to primitive types can be
|
625
|
+
# easily converted to C types.
|
626
|
+
@type = RubyObject.new
|
627
|
+
end
|
628
|
+
|
629
|
+
def ruby_constant?; true; end
|
630
|
+
end
|
631
|
+
|
632
|
+
class RubyClass < RubyConstant
|
633
|
+
attr_reader :name, :c_name, :scope, :ancestor
|
634
|
+
|
635
|
+
def initialize name, c_name, scope, ancestor
|
636
|
+
@name, @c_name, @scope, @ancestor = name, c_name, scope, ancestor
|
637
|
+
end
|
638
|
+
|
639
|
+
def ruby_class?; true; end
|
640
|
+
end
|
641
|
+
|
642
|
+
class RubyMethod
|
643
|
+
include Helpers
|
644
|
+
|
645
|
+
attr_reader :name, :c_name, :type
|
646
|
+
attr_accessor :scope, :arg_list
|
647
|
+
|
648
|
+
def initialize name, c_name, scope, arg_list
|
649
|
+
@name, @c_name, @scope, @arg_list = name, c_name, scope, arg_list
|
650
|
+
@type = RubyObject.new
|
651
|
+
end
|
652
|
+
|
653
|
+
def ruby_method?; true; end
|
654
|
+
end
|
655
|
+
|
656
|
+
class CFunction
|
657
|
+
include Helpers
|
658
|
+
attr_reader :name, :type, :c_name
|
659
|
+
attr_accessor :scope, :arg_list
|
660
|
+
|
661
|
+
# FIXME: all attributes should be initialized upon class creation to maintain
|
662
|
+
# sanity and consistency.
|
663
|
+
def initialize name, c_name, arg_list, type, scope
|
664
|
+
@name, @c_name, @arg_list, @type, @scope = name, c_name, arg_list, type, scope
|
665
|
+
end
|
666
|
+
|
667
|
+
def c_function?; true; end
|
668
|
+
end
|
669
|
+
# TODO: How to store this in a Ruby class? Use BigDecimal?
|
670
|
+
# class LF64
|
671
|
+
# def to_s; "long double"; end
|
672
|
+
|
673
|
+
# def to_ruby_object(arg); "INT2NUM"; end
|
674
|
+
|
675
|
+
# def from_ruby_object(arg); "(int32_t)NUM2INT"; end
|
676
|
+
# end
|
14
677
|
end
|
15
|
-
end
|
678
|
+
end
|