Class: Rubex::Compiler
- Inherits:
-
Object
- Object
- Rubex::Compiler
- Defined in:
- lib/rubex/compiler.rb
Constant Summary collapse
- CONFIG =
Rubex::CompilerConfig.new
Class Method Summary collapse
-
.ast(path, test: false, source_dir: nil) ⇒ Object
Generate the AST from Rubex source code.
-
.build_path(directory, target_name) ⇒ Object
Create build path for outputting .c and .h files.
-
.compile(path, test: false, multi_file: false, target_dir: nil, force: false, make: false, debug: false, source_dir: nil, files: nil) ⇒ Object
Compile the Rubex file(s) into .c file(s).
- .extconf(target_name, target_dir: nil) ⇒ Object
- .extract_target_name(path) ⇒ Object
- .generate_code(tree, target_name) ⇒ Object
- .load_extconf(path) ⇒ Object
- .run_make(path) ⇒ Object
-
.write_files(target_name, supervisor, ext, target_dir: nil, force: false) ⇒ Object
Write .c and .h files from the generated C code from rubex files.
Class Method Details
.ast(path, test: false, source_dir: nil) ⇒ Object
Generate the AST from Rubex source code. Do not use this function unless
contributing to Rubex. Use CLI or rake tasks instead.
71 72 73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/rubex/compiler.rb', line 71 def ast path, test: false, source_dir: nil parser = Rubex::Parser.new parser.parse(path, source_dir, false) parser.do_parse rescue Racc::ParseError => e raise e if test error_msg = "\nPARSE ERROR:\n" error_msg << "Line: #{parser.string.split("\n")[parser.lineno-1]}\n" error_msg << "Location: #{parser.location}\n" error_msg << "Error:\n#{e}" STDERR.puts error_msg end |
.build_path(directory, target_name) ⇒ Object
Create build path for outputting .c and .h files. Will check whether the calling
process is a rake task or cmd.
155 156 157 158 159 160 161 |
# File 'lib/rubex/compiler.rb', line 155 def build_path directory, target_name directory = (directory ? directory.to_s : Dir.pwd) unless directory.end_with?(target_name) directory += "/#{target_name}" end directory end |
.compile(path, test: false, multi_file: false, target_dir: nil, force: false, make: false, debug: false, source_dir: nil, files: nil) ⇒ Object
Compile the Rubex file(s) into .c file(s). Do not use this function directly
unless you're contributing to Rubex. Use the Rake tasks or command line
interface instead.
TODO: The path can be relative to the source_dir if source_dir is specified.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/rubex/compiler.rb', line 32 def compile path, test: false, multi_file: false, target_dir: nil, force: false, make: false, debug: false, source_dir: nil, files: nil CONFIG.flush CONFIG.debug = debug CONFIG.add_link "m" # link cmath libraries target_name = extract_target_name path CONFIG.add_dep target_name tree = ast path, source_dir: source_dir, test: test supervisor = generate_code tree, target_name ext = extconf target_name, target_dir: target_dir if test && !multi_file return [tree, supervisor.code(target_name), ext, supervisor.header(target_name)] elsif test && multi_file return [tree, supervisor, ext] end write_files target_name, supervisor, ext, target_dir: target_dir, force: force full_path = build_path(target_dir, target_name) load_extconf full_path run_make full_path if make end |
.extconf(target_name, target_dir: nil) ⇒ Object
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
# File 'lib/rubex/compiler.rb', line 85 def extconf target_name, target_dir: nil path = build_path(target_dir, target_name) extconf = "" extconf << "require 'mkmf'\n" extconf << "$libs += \" #{CONFIG.link_flags}\"\n" extconf << "$CFLAGS += \" -g \"\n" if CONFIG.debug srcs_config = CONFIG.srcs.map { |s| "\"#{s}\""}.join(',') extconf << "$srcs = [#{srcs_config}]\n" objs_config = CONFIG.objs.map { |o| "\"#{o}\""}.join(',') extconf << "$objs = [#{objs_config}]\n" extconf << "create_makefile('#{path}/#{target_name}')\n" extconf end |
.extract_target_name(path) ⇒ Object
111 112 113 |
# File 'lib/rubex/compiler.rb', line 111 def extract_target_name path File.basename(path).split('.')[0] end |
.generate_code(tree, target_name) ⇒ Object
102 103 104 105 106 107 108 109 |
# File 'lib/rubex/compiler.rb', line 102 def generate_code tree, target_name supervisor = Rubex::CodeSupervisor.new supervisor.init_file(target_name) raise "Must be a Rubex::AST::Node::MainNode, not #{tree.class}" unless tree.is_a? Rubex::AST::Node::MainNode tree.process_statements target_name, supervisor supervisor end |
.load_extconf(path) ⇒ Object
138 139 140 141 142 |
# File 'lib/rubex/compiler.rb', line 138 def load_extconf path Dir.chdir(path) do system("ruby #{path}/extconf.rb") end end |
.run_make(path) ⇒ Object
144 145 146 147 148 |
# File 'lib/rubex/compiler.rb', line 144 def run_make path Dir.chdir(path) do system("make -C #{path}") end end |
.write_files(target_name, supervisor, ext, target_dir: nil, force: false) ⇒ Object
Write .c and .h files from the generated C code from rubex files.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/rubex/compiler.rb', line 123 def write_files target_name, supervisor, ext, target_dir: nil, force: false path = build_path(target_dir, target_name) FileUtils.rm_rf(path) if force && Dir.exist?(path) Dir.mkdir(path) unless Dir.exist?(path) write_to_file "#{path}/#{Rubex::COMMON_UTILS_FILE}.h", supervisor.header(Rubex::COMMON_UTILS_FILE).to_s supervisor.files.each do |file| write_to_file "#{path}/#{file}.c", supervisor.code(file).to_s write_to_file "#{path}/#{file}.h", supervisor.header(file).to_s end write_to_file "#{path}/extconf.rb", ext end |