rubex 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- 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] }
|