rubex 0.1.1 → 0.1.2
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 +5 -5
- data/.gitignore +1 -0
- data/CONTRIBUTING.md +73 -9
- data/HISTORY.md +19 -0
- data/README.md +53 -8
- data/REFERENCE.md +112 -44
- data/benchmarks/no_gil/no_gil.rb +24 -0
- data/benchmarks/no_gil/no_gil.rubex +22 -0
- data/bin/rubex +1 -1
- data/examples/c_struct_interface/c_struct_interface.rubex +1 -0
- data/lib/rubex.rb +1 -0
- data/lib/rubex/ast.rb +11 -7
- data/lib/rubex/ast/expression.rb +1 -1
- data/lib/rubex/ast/expression/actual_arg_list.rb +7 -0
- data/lib/rubex/ast/expression/analysed_element_ref/c_var_element_ref.rb +5 -2
- data/lib/rubex/ast/expression/analysed_element_ref/ruby_object_element_ref.rb +26 -9
- data/lib/rubex/ast/expression/binary/binary_boolean.rb +1 -1
- data/lib/rubex/ast/expression/binary/binary_expo.rb +34 -0
- data/lib/rubex/ast/expression/binary/colon2.rb +34 -0
- data/lib/rubex/ast/expression/binary/empty_classes.rb +0 -3
- data/lib/rubex/ast/expression/command_call.rb +24 -0
- data/lib/rubex/ast/{statement → expression/command_call}/print.rb +4 -5
- data/lib/rubex/ast/{statement → expression/command_call}/raise.rb +29 -24
- data/lib/rubex/ast/expression/command_call/require.rb +27 -0
- data/lib/rubex/ast/expression/command_call/yield.rb +36 -0
- data/lib/rubex/ast/expression/element_ref.rb +10 -5
- data/lib/rubex/ast/expression/instance_var.rb +33 -0
- data/lib/rubex/ast/expression/method_call.rb +4 -2
- data/lib/rubex/ast/expression/method_call/c_function_call.rb +4 -3
- data/lib/rubex/ast/expression/method_call/ruby_method_call.rb +7 -5
- data/lib/rubex/ast/expression/name.rb +10 -1
- data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_array_element_ref.rb +5 -2
- data/lib/rubex/ast/expression/ruby_object_element_ref/ruby_hash_element_ref.rb +10 -2
- data/lib/rubex/ast/expression/to_ruby_object.rb +1 -0
- data/lib/rubex/ast/expression/unary.rb +7 -3
- data/lib/rubex/ast/expression/unary_base/ampersand.rb +5 -0
- data/lib/rubex/ast/node.rb +213 -185
- data/lib/rubex/ast/node/file_node.rb +25 -0
- data/lib/rubex/ast/node/main_node.rb +56 -0
- data/lib/rubex/ast/statement/begin_block/begin.rb +4 -3
- data/lib/rubex/ast/statement/c_array_decl.rb +1 -1
- data/lib/rubex/ast/statement/c_ptr_decl.rb +2 -0
- data/lib/rubex/ast/statement/no_gil_block.rb +70 -0
- data/lib/rubex/ast/statement/return.rb +1 -0
- data/lib/rubex/ast/top_statement.rb +1 -1
- data/lib/rubex/ast/top_statement/klass.rb +4 -0
- data/lib/rubex/ast/top_statement/klass/attached_klass.rb +88 -10
- data/lib/rubex/ast/top_statement/method_def.rb +2 -3
- data/lib/rubex/ast/top_statement/method_def/c_function_def.rb +10 -4
- data/lib/rubex/cli.rb +11 -6
- data/lib/rubex/code_supervisor.rb +49 -0
- data/lib/rubex/code_writer.rb +22 -1
- data/lib/rubex/compiler.rb +109 -30
- data/lib/rubex/compiler_config.rb +14 -1
- data/lib/rubex/constants.rb +3 -0
- data/lib/rubex/data_type.rb +2 -3
- data/lib/rubex/data_type/ruby_object/ruby_symbol.rb +0 -1
- data/lib/rubex/error.rb +4 -0
- data/lib/rubex/helpers/writers.rb +33 -4
- data/lib/rubex/lexer.rex +9 -1
- data/lib/rubex/lexer.rex.rb +15 -2
- data/lib/rubex/parser.racc +125 -49
- data/lib/rubex/parser.racc.rb +1526 -1376
- data/lib/rubex/rake_task.rb +42 -6
- data/lib/rubex/symbol_table/entry.rb +6 -0
- data/lib/rubex/symbol_table/scope.rb +28 -3
- data/lib/rubex/version.rb +1 -1
- data/rubex.gemspec +1 -0
- data/spec/basic_ruby_method_spec.rb +2 -2
- data/spec/blocks_spec.rb +2 -2
- data/spec/box_op_multi_args_spec.rb +34 -0
- data/spec/c_function_ptrs_spec.rb +2 -2
- data/spec/c_functions_spec.rb +2 -0
- data/spec/c_struct_interface_spec.rb +8 -3
- data/spec/default_args_spec.rb +2 -2
- data/spec/external_c_struct_spec.rb +33 -0
- data/spec/fixtures/api/consumer.rubex +0 -0
- data/spec/fixtures/api/implementation.rubex +0 -0
- data/spec/fixtures/api/implementation.rubexd +0 -0
- data/spec/fixtures/box_op_multi_args/box_op_multi_args.rubex +3 -0
- data/spec/fixtures/c_functions/c_functions.rubex +13 -0
- data/spec/fixtures/c_struct_interface/c_struct_interface.rubex +28 -0
- data/spec/fixtures/class_methods/class_methods.rubex +1 -1
- data/spec/fixtures/error_handling/error_handling.rubex +2 -2
- data/spec/fixtures/external_c_struct/external_c_struct.rubex +16 -0
- data/spec/fixtures/if_else/if_else.rubex +1 -1
- data/spec/fixtures/init_ruby_objects_with_literal_syntax/init_ruby_objects_with_literal_syntax.rubex +1 -1
- data/spec/fixtures/instance_variables/instance_variables.rubex +25 -0
- data/spec/fixtures/loops/loops.rubex +2 -2
- data/spec/fixtures/module/module.rubex +28 -0
- data/spec/fixtures/multi_file_programs/Rakefile +8 -0
- data/spec/fixtures/multi_file_programs/a.rubex +5 -0
- data/spec/fixtures/multi_file_programs/b.rubex +5 -0
- data/spec/fixtures/multi_file_programs/multi_file_programs.rubex +14 -0
- data/spec/fixtures/no_gil/no_gil.rubex +24 -0
- data/spec/fixtures/no_gil_attach_class/no_gil_attach_class.rubex +23 -0
- data/spec/fixtures/no_gil_compile_check/no_gil_compile_check.rubex +4 -0
- data/spec/fixtures/outside_stmts/outside_stmts.rubex +6 -0
- data/spec/fixtures/pow/pow.rubex +4 -0
- data/spec/fixtures/rake_task/single_file/test.rubex +3 -0
- data/spec/fixtures/recursion/recursion.rubex +1 -1
- data/spec/fixtures/ruby_constant_scoping/ruby_constant_scoping.rubex +7 -0
- data/spec/fixtures/ruby_operators/ruby_operators.rubex +1 -1
- data/spec/fixtures/ruby_raise/ruby_raise.rubex +2 -2
- data/spec/fixtures/ruby_types/ruby_types.rubex +4 -4
- data/spec/fixtures/statement_expression/statement_expression.rubex +2 -2
- data/spec/fixtures/static_array/static_array.rubex +3 -3
- data/spec/fixtures/string_literals/string_literals.rubex +12 -2
- data/spec/fixtures/struct/struct.rubex +1 -1
- data/spec/fixtures/var_declarations/var_declarations.rubex +1 -1
- data/spec/implicit_lib_include_spec.rb +2 -2
- data/spec/init_ruby_objects_with_literal_syntax_spec.rb +2 -2
- data/spec/instance_variables_spec.rb +33 -0
- data/spec/loops_spec.rb +2 -2
- data/spec/module_spec.rb +39 -0
- data/spec/multi_file_programs_spec.rb +41 -0
- data/spec/no_gil_attach_class_spec.rb +33 -0
- data/spec/no_gil_compile_check_spec.rb +25 -0
- data/spec/no_gil_spec.rb +36 -0
- data/spec/outside_stmts_spec.rb +34 -0
- data/spec/pow_spec.rb +33 -0
- data/spec/rake_task_spec.rb +142 -0
- data/spec/recursion_spec.rb +4 -4
- data/spec/ruby_constant_scoping_spec.rb +42 -0
- data/spec/ruby_raise_spec.rb +2 -2
- data/spec/ruby_symbols_spec.rb +2 -2
- data/spec/ruby_types_spec.rb +2 -2
- data/spec/spec_helper.rb +17 -3
- data/spec/string_literals_spec.rb +1 -0
- metadata +90 -6
- data/lib/rubex/ast/statement/yield.rb +0 -41
data/lib/rubex/cli.rb
CHANGED
@@ -2,25 +2,30 @@ require 'thor'
|
|
2
2
|
module Rubex
|
3
3
|
# Cli for rubex using Thor(http://whatisthor.com/)
|
4
4
|
class Cli < Thor
|
5
|
-
|
5
|
+
|
6
|
+
desc 'generate FILE',
|
7
|
+
'generates directory with name specified in the argument and creates an extconf.rb file which is required for C extensions'
|
6
8
|
option :force, aliases: '-f', desc: 'replace existing files and directories'
|
7
9
|
option :dir, aliases: '-d', desc: 'specify a directory for generating files', type: :string
|
8
|
-
option :install, aliases: '-i',
|
10
|
+
option :install, aliases: '-i',
|
11
|
+
desc: 'automatically run install command after generating Makefile'
|
9
12
|
option :debug, aliases: '-g', desc: 'enable debugging symbols when compiling with GCC'
|
10
13
|
def generate(file)
|
11
14
|
if (force = options[:force])
|
12
|
-
directory = (options[:dir] ? options[:dir].to_s : Dir.pwd) +
|
15
|
+
directory = (options[:dir] ? options[:dir].to_s : Dir.pwd) +
|
16
|
+
"/#{Rubex::Compiler.extract_target_name(file)}"
|
13
17
|
STDOUT.puts "Warning! you are about to replace contents in the directory '#{directory}', Are you sure? [Yn] "
|
14
18
|
confirmation = STDIN.gets.chomp
|
15
19
|
force = (confirmation == 'Y')
|
16
20
|
end
|
17
|
-
Rubex::Compiler.compile file,
|
21
|
+
Rubex::Compiler.compile file, target_dir: options[:dir], force: force,
|
22
|
+
make: options[:install], debug: options[:debug]
|
18
23
|
end
|
19
24
|
|
20
|
-
desc 'install PATH',
|
25
|
+
desc 'install PATH',
|
26
|
+
'run "make" utility to generate a shared object file required for C extensions'
|
21
27
|
def install(path)
|
22
28
|
Rubex::Compiler.run_make path
|
23
29
|
end
|
24
|
-
|
25
30
|
end
|
26
31
|
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
module Rubex
|
2
|
+
# Class for storing Rubex files and their corresponding code writer objects.
|
3
|
+
# Each file has two code writers - header_writer and code_writer. The
|
4
|
+
# header_writer stores the file header of the outputted C code (the .h file)
|
5
|
+
# and the code_writer stores the actual implementation (the .c file).
|
6
|
+
#
|
7
|
+
# It is created only once in the execution of the compiler by the Compiler class.
|
8
|
+
# Data is stored in the @data class in the form:
|
9
|
+
# @data = {
|
10
|
+
# "file1.rubex" => {
|
11
|
+
# header: header_writer, # Rubex::CodeWriter instance.
|
12
|
+
# code: code_writer, # Rubex:: CodeWriter instance.
|
13
|
+
# },
|
14
|
+
# "file2.rubex" => {
|
15
|
+
# header: header_writer, # Rubex::CodeWriter instance.
|
16
|
+
# code: code_writer, # Rubex:: CodeWriter instance.
|
17
|
+
# }
|
18
|
+
# }
|
19
|
+
class CodeSupervisor
|
20
|
+
def initialize
|
21
|
+
@data = {}
|
22
|
+
end
|
23
|
+
|
24
|
+
def init_file(file_name)
|
25
|
+
header_writer = Rubex::CodeWriter.new(file_name, is_header: true)
|
26
|
+
header_writer << "/*Header file for #{file_name}*/\n\n"
|
27
|
+
|
28
|
+
code_writer = Rubex::CodeWriter.new(file_name)
|
29
|
+
code_writer << "/*Code file for #{file_name}*/\n\n"
|
30
|
+
|
31
|
+
@data[file_name] = {
|
32
|
+
header: header_writer,
|
33
|
+
code: code_writer
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def header(file_name)
|
38
|
+
@data[file_name][:header]
|
39
|
+
end
|
40
|
+
|
41
|
+
def code(file_name)
|
42
|
+
@data[file_name][:code]
|
43
|
+
end
|
44
|
+
|
45
|
+
def files
|
46
|
+
@data.keys
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
data/lib/rubex/code_writer.rb
CHANGED
@@ -2,12 +2,28 @@ module Rubex
|
|
2
2
|
class CodeWriter
|
3
3
|
attr_reader :code
|
4
4
|
|
5
|
-
def initialize target_name
|
5
|
+
def initialize target_name, is_header: false
|
6
6
|
@code = "/* C extension for #{target_name}.\n"\
|
7
7
|
"This file in generated by Rubex::Compiler. Do not change!\n"\
|
8
8
|
"File generation time: #{Time.now}."\
|
9
9
|
"*/\n\n"
|
10
10
|
@indent = 0
|
11
|
+
@is_header = is_header
|
12
|
+
end
|
13
|
+
|
14
|
+
def header?
|
15
|
+
@is_header
|
16
|
+
end
|
17
|
+
|
18
|
+
def in_header_guard guard, &block
|
19
|
+
if header?
|
20
|
+
@code << "#ifndef #{guard}\n"
|
21
|
+
@code << "#define #{guard}\n"
|
22
|
+
block.call
|
23
|
+
@code << "#endif\n"
|
24
|
+
else
|
25
|
+
raise "file is not a header file."
|
26
|
+
end
|
11
27
|
end
|
12
28
|
|
13
29
|
# type - Return type of the method.
|
@@ -19,6 +35,11 @@ module Rubex
|
|
19
35
|
new_line
|
20
36
|
end
|
21
37
|
|
38
|
+
def write_include file_name
|
39
|
+
@code << "#include \"#{file_name}.h\""
|
40
|
+
new_line
|
41
|
+
end
|
42
|
+
|
22
43
|
def colon
|
23
44
|
@code << ";"
|
24
45
|
new_line
|
data/lib/rubex/compiler.rb
CHANGED
@@ -4,24 +4,73 @@ module Rubex
|
|
4
4
|
CONFIG = Rubex::CompilerConfig.new
|
5
5
|
|
6
6
|
class << self
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
7
|
+
# Compile the Rubex file(s) into .c file(s). Do not use this function directly
|
8
|
+
# unless you're contributing to Rubex. Use the Rake tasks or command line
|
9
|
+
# interface instead.
|
10
|
+
#
|
11
|
+
# @param path [String] Full path to file. Main file in case of multiple
|
12
|
+
# file compilation.
|
13
|
+
# @param test [Boolean] false Set to true if compiling rubex files for
|
14
|
+
# a test case.
|
15
|
+
# @param multi_file [Boolean] false If true, return the CodeSupervisor
|
16
|
+
# object for code analysis by user. Applicable only if test: opt is true.
|
17
|
+
# @param directory [String] nil Directory where the compiled rubex files
|
18
|
+
# should be placed.
|
19
|
+
# @param force [Boolean] false If set to true, will forcefully overwrite
|
20
|
+
# any .c files that were previously generated.
|
21
|
+
# @param make [Boolean] false If true, will automatically generate the .so
|
22
|
+
# file from compiled C binaries.
|
23
|
+
# @param debug [Boolean] false If true, will compile C programs with gcc
|
24
|
+
# using the -g option.
|
25
|
+
# @param source_dir [String] nil String specifying the source directory
|
26
|
+
# inside which the source Rubex files will be placed in case of multi-file
|
27
|
+
# programs.
|
28
|
+
# @param files [Array[String]] nil An Array specifying the file names to
|
29
|
+
# compile w.r.t the source_dir directory.
|
30
|
+
#
|
31
|
+
# TODO: The path can be relative to the source_dir if source_dir is specified.
|
32
|
+
def compile path,
|
33
|
+
test: false,
|
34
|
+
multi_file: false,
|
35
|
+
target_dir: nil,
|
36
|
+
force: false,
|
37
|
+
make: false,
|
38
|
+
debug: false,
|
39
|
+
source_dir: nil,
|
40
|
+
files: nil
|
12
41
|
CONFIG.flush
|
13
42
|
CONFIG.debug = debug
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
43
|
+
CONFIG.add_link "m" # link cmath libraries
|
44
|
+
target_name = extract_target_name path
|
45
|
+
CONFIG.add_dep target_name
|
46
|
+
|
47
|
+
tree = ast path, source_dir: source_dir, test: test
|
48
|
+
supervisor = generate_code tree, target_name
|
49
|
+
ext = extconf target_name, target_dir: target_dir
|
50
|
+
|
51
|
+
if test && !multi_file
|
52
|
+
return [tree, supervisor.code(target_name), ext,
|
53
|
+
supervisor.header(target_name)]
|
54
|
+
elsif test && multi_file
|
55
|
+
return [tree, supervisor, ext]
|
56
|
+
end
|
57
|
+
write_files target_name, supervisor, ext, target_dir: target_dir, force: force
|
58
|
+
full_path = build_path(target_dir, target_name)
|
18
59
|
load_extconf full_path
|
19
60
|
run_make full_path if make
|
20
61
|
end
|
21
62
|
|
22
|
-
|
63
|
+
# Generate the AST from Rubex source code. Do not use this function unless
|
64
|
+
# contributing to Rubex. Use CLI or rake tasks instead.
|
65
|
+
#
|
66
|
+
# @param path [String] Full path name of the rubex file.
|
67
|
+
# @param test [Boolean] false Set to true if compiling rubex files for
|
68
|
+
# a test case.
|
69
|
+
# @param source_dir [String] nil Path of the directory that contains the
|
70
|
+
# source files.
|
71
|
+
def ast path, test: false, source_dir: nil
|
23
72
|
parser = Rubex::Parser.new
|
24
|
-
parser.parse(path)
|
73
|
+
parser.parse(path, source_dir, false)
|
25
74
|
parser.do_parse
|
26
75
|
rescue Racc::ParseError => e
|
27
76
|
raise e if test
|
@@ -33,40 +82,57 @@ module Rubex
|
|
33
82
|
STDERR.puts error_msg
|
34
83
|
end
|
35
84
|
|
36
|
-
def extconf target_name,
|
37
|
-
path = build_path(
|
85
|
+
def extconf target_name, target_dir: nil
|
86
|
+
path = build_path(target_dir, target_name)
|
38
87
|
extconf = ""
|
39
88
|
extconf << "require 'mkmf'\n"
|
40
89
|
extconf << "$libs += \" #{CONFIG.link_flags}\"\n"
|
41
90
|
extconf << "$CFLAGS += \" -g \"\n" if CONFIG.debug
|
91
|
+
|
92
|
+
srcs_config = CONFIG.srcs.map { |s| "\"#{s}\""}.join(',')
|
93
|
+
extconf << "$srcs = [#{srcs_config}]\n"
|
94
|
+
|
95
|
+
objs_config = CONFIG.objs.map { |o| "\"#{o}\""}.join(',')
|
96
|
+
extconf << "$objs = [#{objs_config}]\n"
|
97
|
+
|
42
98
|
extconf << "create_makefile('#{path}/#{target_name}')\n"
|
43
99
|
extconf
|
44
100
|
end
|
45
101
|
|
46
102
|
def generate_code tree, target_name
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
103
|
+
supervisor = Rubex::CodeSupervisor.new
|
104
|
+
supervisor.init_file(target_name)
|
105
|
+
raise "Must be a Rubex::AST::Node::MainNode, not #{tree.class}" unless
|
106
|
+
tree.is_a? Rubex::AST::Node::MainNode
|
107
|
+
tree.process_statements target_name, supervisor
|
108
|
+
supervisor
|
52
109
|
end
|
53
110
|
|
54
111
|
def extract_target_name path
|
55
112
|
File.basename(path).split('.')[0]
|
56
113
|
end
|
57
114
|
|
58
|
-
|
59
|
-
|
115
|
+
# Write .c and .h files from the generated C code from rubex files.
|
116
|
+
#
|
117
|
+
# @param target_name [String] Target name of the root file.
|
118
|
+
# @param supervisor [Rubex::CodeSupervisor] Container for code.
|
119
|
+
# @param ext [String] A String representing the extconf file.
|
120
|
+
# @param directory [String] nil Target directory in which files are to be placed.
|
121
|
+
# @param force [Boolean] false Recreate the target directory and rewrite the
|
122
|
+
# files whether they are already present or not.
|
123
|
+
def write_files target_name, supervisor, ext, target_dir: nil, force: false
|
124
|
+
path = build_path(target_dir, target_name)
|
60
125
|
FileUtils.rm_rf(path) if force && Dir.exist?(path)
|
61
126
|
Dir.mkdir(path) unless Dir.exist?(path)
|
62
127
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
128
|
+
write_to_file "#{path}/#{Rubex::COMMON_UTILS_FILE}.h",
|
129
|
+
supervisor.header(Rubex::COMMON_UTILS_FILE).to_s
|
130
|
+
supervisor.files.each do |file|
|
131
|
+
write_to_file "#{path}/#{file}.c", supervisor.code(file).to_s
|
132
|
+
write_to_file "#{path}/#{file}.h", supervisor.header(file).to_s
|
133
|
+
end
|
134
|
+
|
135
|
+
write_to_file "#{path}/extconf.rb", ext
|
70
136
|
end
|
71
137
|
|
72
138
|
def load_extconf path
|
@@ -81,13 +147,26 @@ module Rubex
|
|
81
147
|
end
|
82
148
|
end
|
83
149
|
|
150
|
+
# Create build path for outputting .c and .h files. Will check whether the calling
|
151
|
+
# process is a rake task or cmd.
|
152
|
+
#
|
153
|
+
# @param directory [String] The directory inside which this build path will exist.
|
154
|
+
# @param target_name [String] Name of the folder inside the directory.
|
84
155
|
def build_path directory, target_name
|
85
156
|
directory = (directory ? directory.to_s : Dir.pwd)
|
86
|
-
|
87
|
-
|
88
|
-
|
157
|
+
unless directory.end_with?(target_name)
|
158
|
+
directory += "/#{target_name}"
|
159
|
+
end
|
89
160
|
directory
|
90
161
|
end
|
162
|
+
|
163
|
+
private
|
164
|
+
|
165
|
+
def write_to_file path, contents
|
166
|
+
f = File.new path, "w+"
|
167
|
+
f.puts contents
|
168
|
+
f.close
|
169
|
+
end
|
91
170
|
end
|
92
171
|
end
|
93
172
|
end
|
@@ -1,9 +1,14 @@
|
|
1
1
|
module Rubex
|
2
|
+
# Class for storing configuration of the compiler (gcc) that will compile
|
3
|
+
# the generated C code. This includes file names, compiler flags and other
|
4
|
+
# options required by Rubex.
|
2
5
|
class CompilerConfig
|
3
|
-
attr_accessor :debug
|
6
|
+
attr_accessor :debug, :srcs, :objs
|
4
7
|
|
5
8
|
def initialize
|
6
9
|
@links = []
|
10
|
+
@srcs = []
|
11
|
+
@objs = []
|
7
12
|
end
|
8
13
|
|
9
14
|
def add_link link_str
|
@@ -16,6 +21,14 @@ module Rubex
|
|
16
21
|
|
17
22
|
def flush
|
18
23
|
@links = []
|
24
|
+
@srcs = []
|
25
|
+
@objs = []
|
26
|
+
end
|
27
|
+
|
28
|
+
# add dependency on file so extconf will recognise it.
|
29
|
+
def add_dep(file_name)
|
30
|
+
@srcs << "#{file_name}.c"
|
31
|
+
@objs << "#{file_name}.o"
|
19
32
|
end
|
20
33
|
end
|
21
34
|
end
|
data/lib/rubex/constants.rb
CHANGED
@@ -15,6 +15,9 @@ module Rubex
|
|
15
15
|
|
16
16
|
ACTUAL_ARGS_SUFFIX = "_actual_args"
|
17
17
|
|
18
|
+
COMMON_UTILS_CONST = RUBEX_PREFIX + "_COMMON_UTILS_H"
|
19
|
+
COMMON_UTILS_FILE = RUBEX_PREFIX + "_common_utils_"
|
20
|
+
|
18
21
|
TYPE_MAPPINGS = {
|
19
22
|
'char' => Rubex::DataType::Char,
|
20
23
|
'bool' => Rubex::DataType::CBoolean,
|
data/lib/rubex/data_type.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require_relative 'data_type_helpers/helpers'
|
2
|
-
Dir[
|
3
|
-
Dir[
|
4
|
-
|
2
|
+
Dir[File.join(File.dirname(File.dirname(__FILE__)), "rubex", "data_type_helpers", "**", "*.rb" )].sort.each { |f| require f }
|
3
|
+
Dir[File.join(File.dirname(File.dirname(__FILE__)), "rubex", "data_type", "**", "*.rb" )].sort.each { |f| require f }
|
5
4
|
# TODO: How to store this in a Ruby class? Use BigDecimal?
|
6
5
|
# class LF64
|
7
6
|
# def to_s; "long double"; end
|
data/lib/rubex/error.rb
CHANGED
@@ -29,9 +29,8 @@ module Rubex
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
def declare_types(code,
|
33
|
-
|
34
|
-
# if !entry.extern
|
32
|
+
def declare_types(code, type_entries)
|
33
|
+
type_entries.each do |entry|
|
35
34
|
type = entry.type
|
36
35
|
|
37
36
|
if type.alias_type?
|
@@ -54,7 +53,6 @@ module Rubex
|
|
54
53
|
end
|
55
54
|
end
|
56
55
|
code.nl
|
57
|
-
# end
|
58
56
|
end
|
59
57
|
end
|
60
58
|
|
@@ -74,6 +72,37 @@ module Rubex
|
|
74
72
|
code.declare_variable type: var.type.to_s, c_name: var.c_name
|
75
73
|
end
|
76
74
|
end
|
75
|
+
|
76
|
+
def write_usability_macros(code)
|
77
|
+
code.nl
|
78
|
+
code.c_macro Rubex::RUBEX_PREFIX + 'INT2BOOL(arg) (arg ? Qtrue : Qfalse)'
|
79
|
+
code.nl
|
80
|
+
end
|
81
|
+
|
82
|
+
def write_usability_functions_header(header)
|
83
|
+
header.nl
|
84
|
+
write_char_2_ruby_str_header header
|
85
|
+
end
|
86
|
+
|
87
|
+
def write_usability_functions_code(code)
|
88
|
+
code.nl
|
89
|
+
write_char_2_ruby_str_code(code)
|
90
|
+
end
|
91
|
+
|
92
|
+
def write_char_2_ruby_str_header(header)
|
93
|
+
header.nl
|
94
|
+
header << "VALUE #{Rubex::C_FUNC_CHAR2RUBYSTR}(char ch);"
|
95
|
+
end
|
96
|
+
|
97
|
+
def write_char_2_ruby_str_code(code)
|
98
|
+
code << "VALUE #{Rubex::C_FUNC_CHAR2RUBYSTR}(char ch)"
|
99
|
+
code.block do
|
100
|
+
code << "char s[2];\n"
|
101
|
+
code << "s[0] = ch;\n"
|
102
|
+
code << "s[1] = '\\0';\n"
|
103
|
+
code << "return rb_str_new2(s);\n"
|
104
|
+
end
|
105
|
+
end
|
77
106
|
end
|
78
107
|
end
|
79
108
|
end
|
data/lib/rubex/lexer.rex
CHANGED
@@ -29,8 +29,11 @@ macros
|
|
29
29
|
NULL /NULL/
|
30
30
|
ATTACH /attach/
|
31
31
|
BLOCK_GIVEN /block_given\?/
|
32
|
+
NO_GIL /no_gil/
|
33
|
+
REQUIRE_RUBEX /require_rubex/
|
32
34
|
|
33
35
|
IDENTIFIER /[a-zA-Z_][a-zA-Z_0-9]*/
|
36
|
+
COLON2 /::/
|
34
37
|
LPAREN /\(/
|
35
38
|
RPAREN /\)/
|
36
39
|
LSQUARE /\[/
|
@@ -126,6 +129,7 @@ rules
|
|
126
129
|
# Method hacks
|
127
130
|
|
128
131
|
/data\$/ { [:kDATA_VAR, text] }
|
132
|
+
/#{REQUIRE_RUBEX}/ { [:kREQUIRE_RUBEX, text] }
|
129
133
|
/#{DOT}#{EACH}/ { [:kDOT_EACH, text] }
|
130
134
|
|
131
135
|
# Data Types
|
@@ -144,8 +148,10 @@ rules
|
|
144
148
|
/#{STRUCT}\ / { [:kSTRUCT, text] }
|
145
149
|
/#{UNION}\ / { [:kUNION, text] }
|
146
150
|
/#{ALIAS}\ / { [:kALIAS, text] }
|
151
|
+
/#{NO_GIL}/ { [:kNO_GIL, text] }
|
147
152
|
|
148
153
|
/:#{IDENTIFIER}/ { [:tSYMBOL, text] }
|
154
|
+
/@#{IDENTIFIER}/ { [:tINSTANCE_VAR, text] }
|
149
155
|
/#{IDENTIFIER}/ { [:tIDENTIFIER, text] }
|
150
156
|
/#{LBRACE}/ { [:tLBRACE, text] }
|
151
157
|
/#{RBRACE}/ { [:tRBRACE, text] }
|
@@ -158,21 +164,23 @@ rules
|
|
158
164
|
/#{NL}/ { [:tNL, text] }
|
159
165
|
/#{QMARK}/ { [:tQMARK, text]}
|
160
166
|
/#{DOT}/ { [:tDOT, text] }
|
167
|
+
/#{COLON2}/ { [:tCOLON2, text] }
|
161
168
|
/#{COLON}/ { [:tCOLON, text] }
|
162
169
|
|
163
170
|
# operators
|
164
171
|
|
172
|
+
/#{EXPOASSIGN}/ { [:tOP_ASSIGN, text]}
|
165
173
|
/#{PLUSASSIGN}/ { [:tOP_ASSIGN, text]}
|
166
174
|
/#{MINUSASSIGN}/ { [:tOP_ASSIGN, text]}
|
167
175
|
/#{STARASSIGN}/ { [:tOP_ASSIGN, text]}
|
168
176
|
/#{DIVIDEASSIGN}/ { [:tOP_ASSIGN, text]}
|
169
177
|
/#{EXPOASSIGN}/ { [:tOP_ASSIGN, text]}
|
170
178
|
/#{MODULUSASSIGN}/ { [:tOP_ASSIGN, text]}
|
179
|
+
/#{EXPO}/ { [:tEXPO, text]}
|
171
180
|
/#{PLUS}/ { [:tPLUS, text]}
|
172
181
|
/#{MINUS}/ { [:tMINUS, text]}
|
173
182
|
/#{STAR}/ { [:tSTAR, text]}
|
174
183
|
/#{DIVIDE}/ { [:tDIVIDE, text]}
|
175
|
-
/#{EXPO}/ { [:tEXPO, text]}
|
176
184
|
/#{MODULUS}/ { [:tMODULUS, text]}
|
177
185
|
/#{EXPO}/ { [:tEXPO, text]}
|
178
186
|
/#{EQ}/ { [:tEQ, text] }
|