source: trunk/lib_c/cpp2c/cpp2c.rb @ 3393

Last change on this file since 3393 was 3393, checked in by linmengl, 6 years ago

add cpp2c.rb script offically, add testing framework

  • Property svn:executable set to *
File size: 3.7 KB
Line 
1#!/home/linmengl/.rvm/rubies/ruby-1.9.3-p327/bin/ruby
2
3# Translate Cpp header files to C
4# Change IDISA calling signatures like esimd<8>::mergel into esimd_mergel_8
5# Ruby version 1.9.3
6
7# Opt parse, run me with `ruby cpp2c.rb -h` to see help
8require 'optparse'
9
10options = {:del_origin => false}
11OptionParser.new do |opts|
12        opts.banner = "Translate Cpp header files to C\nUsage: cpp2c.rb cpp_file [options]"
13
14        opts.on("-v", "--[no-]version", "Show version") do
15                puts "cpp2c.rb, Ver 1.0. By Meng Lin"
16                exit
17        end
18
19        opts.on("-o", "--output [OutFile]", String, "Output file") do |o_file|
20                options[:output] = o_file
21        end
22
23        opts.on("-d", "--delete", "Delete original file [Default: NO]") do 
24                options[:del_origin] = true
25        end
26
27        opts.on_tail("-h", "--help", "Show this message") do
28                puts opts
29                exit
30        end
31end.parse!
32
33if ARGV.size != 1
34        puts "Wrong arguments, run with -h to see help info."
35        exit
36end
37
38options[:input] = ARGV[0]
39
40unless options.has_key? :output
41        t = options[:input].gsub(/\.hpp/, ".h").gsub(/\.cpp/, ".c")
42        if t == options[:input]
43                t << ".c"
44        end
45        options[:output] = t
46end
47
48puts "Running with #{options.inspect}"
49
50class LineTranslator   
51        # Those 3 functions are used as pipeline.       
52
53        # Basic regex translation, including head files, calling signatures
54        def self.t_basic_line line
55                if line =~ /^\#/
56                        line.gsub!(/_HPP/, "_H")
57                        line.gsub!("idisa.hpp", "idisa128_c.h")
58                        line.gsub!("idisa128.hpp", "idisa128_c.h")
59                        line.gsub!(/.hpp\"/, ".h\"")
60                end
61
62                # format_2: opPattern = 0
63                #       class_name<fw>::op(data_type arg, ...)
64                f2 = /(simd\d*|hsimd\d*|esimd\d*|mvmd\d*|bitblock\d*)\<([^>]*)\>::(\w*)\(/
65                m = line.match f2
66                if m
67                        calling = "#{m[1]}_#{m[3]}_{{{#{m[2]}}}}("
68                        line.gsub!(m[0], calling)
69                end
70
71                # format_3: opPattern = 1
72                #       class_name<fw>::op<x>(data_type arg, ...)               
73                f3 = /(simd\d*|hsimd\d*|esimd\d*|mvmd\d*|bitblock\d*)\<([^>]*)\>::(\w*)\<([^>]*)\>\(/
74                m = line.match f3
75                if m
76                        calling = "#{m[1]}_#{m[3]}_{{{#{m[2]}}}}(#{m[4]}, "
77                        line.gsub! m[0], calling
78                end
79
80                # format_4: opPattern = 3
81                #       class_name::op(data_type arg, ...)
82                f4 = /(bitblock\d*)::(\w*)\(/
83                m = line.match f4
84                if m
85                        calling = "#{m[1]}_#{m[2]}("
86                        line.gsub! m[0], calling
87                end
88
89                # format_5: opPattern = 4
90                #       class_name::op<x>(data_type arg, ...)           
91                f5 = /(bitblock\d*)::(\w*)\<([^>]*)\>\(/
92                m = line.match f5
93                if m
94                        calling = "#{m[1]}_#{m[2]}(#{m[3]}, "
95                        line.gsub! m[0], calling
96                end
97
98                # remove redundant comma, e.g. simd_op(, 1) into simd_op(1)
99                line.gsub! /(?<=\(),\s(?=\w+)/, ""
100                # cont. bitblock_srli(sh, ) into bitlblock_srli()
101                line.gsub! /(?<=[\s\w]),\s+(?=\))/, ""
102
103                # Another hack here. simd128 class is basically simd in IDISA C
104                line.gsub! /\b(simd|hsimd|mvmd|esimd)128/, "\\1"
105
106                line
107        end
108
109        # Dealing with BLOCK_SIZE as a template variable.
110        # Also merge continous lines into one "#if #else #endif" block.
111        def self.t_with_line_store line         
112                begin
113                        last = line.clone
114                        line = self.t_basic_line line
115                end while last != line
116
117                if line =~ /\{\{\{BLOCK_SIZE\b/
118                        LineStore.store_line line
119                else 
120                        dump = LineStore.dump                   
121                        dump + line
122                end             
123        end
124
125        # Template Evaluation
126        def self.t line
127                line = self.t_with_line_store line
128
129                # Eval all the math inside {{{ }}}, I LOVE RUBY!!!!
130                line.gsub!(/\{\{\{([^\{\}]*)\}\}\}/) { eval($1) }
131
132                line
133        end
134end
135
136require_relative 'passes'
137
138class FullPass < BasePass
139        def t line
140                LineTranslator.t line
141        end
142end
143
144# Translation Starts here
145
146begin
147        passes = [SharpPass.new, IDISAPass.new,
148                                ConditionWrapPass.new("BLOCK_SIZE", [128, 256]),
149                                EvaluationPass.new]
150
151        passes.each     do |pass|
152                pass.translate options
153                options[:input] = options[:output]
154        end
155
156        if options[:del_origin]
157                puts `rm #{options[:input]}`   
158        end
159# rescue => err
160#       puts "Exception: #{err}"
161#       err
162end
Note: See TracBrowser for help on using the repository browser.