lib/bones/preprocessor.rb in bones-compiler-1.3.1 vs lib/bones/preprocessor.rb in bones-compiler-1.6.0

- old
+ new

@@ -65,123 +65,153 @@ def process algorithm_code = '' species = nil found = 0 alloc_index, free_index = 0, 0 + block_comment = false + a_scop_was_found = false + scop = 0 + scop_copies = [] # Process the file line by line @source_code.each_line.with_index do |line,index| - if line =~ /^#{WHITESPACE}#/ - - # Keep 'include' statements as header code - if line =~ /^#{WHITESPACE}#include/ - @header_code += line - if line =~ /"(.*)"/ - process_header($1) + + # Don't consider one-line comments + if !(line =~ /^#{WHITESPACE}\/\//) + + # Found the start of a block comment + if line =~ /\/\*/ + block_comment = true + end + + # Search for the end of the block comment + if block_comment + if line =~ /\*\// + block_comment = false end - - # Process 'define' statements for the algorithm code, but also keep as header code - elsif line =~ /^#{WHITESPACE}#define/ - @header_code += line - @device_header += line - match = line.split(/\/\//)[0].scan(/^#{WHITESPACE}#define\s+(\w+)\s+(\S*)/) - @defines[match.first[0].to_sym] = match.first[1] - - # Found the start of algorithm marker - elsif line =~ /^#{WHITESPACE}#{SPECIES_START}/ - if found == 0 - line = replace_defines(line,@defines) - prefix, input, output = marker_to_algorithm(line) - puts MESSAGE+'Found algorithm "'+(prefix+' '+input+' '+ARROW+' '+output).lstrip+'"' if VERBOSE - species = Bones::Species.new(prefix,input,output) - @found_algorithms = @found_algorithms + 1 + @target_code << line + + # Not in a block-comment + else + + if line =~ /^#{WHITESPACE}#/ + + # Keep 'include' statements as header code + if line =~ /^#{WHITESPACE}#include/ + @header_code += line + if line =~ /"(.*)"/ + process_header($1) + end + + # Process 'define' statements for the algorithm code, but also keep as header code + elsif line =~ /^#{WHITESPACE}#define/ + @header_code += line + @device_header += line + match = line.split(/\/\//)[0].scan(/^#{WHITESPACE}#define\s+(\w+)\s+(\S*)/) + @defines[match.first[0].to_sym] = match.first[1] + + # Found the start of algorithm marker + elsif line =~ /^#{WHITESPACE}#{SPECIES_START}/ + if found == 0 + line = replace_defines(line,@defines) + prefix, input, output = marker_to_algorithm(line) + puts MESSAGE+'Found algorithm "'+(prefix+' '+input+' '+ARROW+' '+output).lstrip+'"' if VERBOSE + species = Bones::Species.new(prefix,input,output) + @found_algorithms = @found_algorithms + 1 + end + found = found + 1 + #@target_code << "int bones_temp_species_start = '#{line.gsub(NL,'')}';"+NL + + # Found the end of algorithm marker + elsif line =~ /^#{WHITESPACE}#{SPECIES_END}/ + if found == 1 + name = line.strip.scan(/^#{WHITESPACE}#{SPECIES_END} (.+)/).join + name = DEFAULT_NAME if name == '' + @algorithms.push(Bones::Algorithm.new(name,@filename,index.to_s,species,algorithm_code)) + algorithm_code = '' + end + found = found - 1 + #@target_code << "int bones_temp_species_end = '#{line.gsub(NL,'')}';"+NL + + # Found a sync marker + elsif @scheduler && line =~ /^#{WHITESPACE}#{SYNC}/ + sync = line.strip.scan(/^#{WHITESPACE}#{SYNC} (.+)/).join + @target_code << "bones_synchronize(#{sync});"+NL + + # Found a copyin marker + elsif @scheduler && line =~ /^#{WHITESPACE}#{COPYIN}/ + copies = line.strip.scan(/^#{WHITESPACE}#{COPYIN} (.+)/).join.split(WEDGE).map{ |c| c.strip } + copies.each_with_index do |copy,copynum| + name = copy.split('[').first + domain = copy.scan(/\[(.+)\]/).join.split(DIM_SEP) + deadline = copy.split('|').last + @copies.push(Bones::Copy.new(scop,name,domain,deadline,'in',"#{index*100+copynum}")) + scop_copies.push(@copies[-1]) + @target_code << "bones_copyin_#{index*100+copynum}_#{name}(#{name});"+NL + end + + # Found a copyout marker + elsif @scheduler && line =~ /^#{WHITESPACE}#{COPYOUT}/ + copies = line.strip.scan(/^#{WHITESPACE}#{COPYOUT} (.+)/).join.split(WEDGE).map{ |c| c.strip } + copies.each_with_index do |copy,copynum| + name = copy.split('[').first + domain = copy.scan(/\[(.+)\]/).join.split(DIM_SEP) + deadline = copy.split('|').last + @copies.push(Bones::Copy.new(scop,name,domain,deadline,'out',"#{index*100+copynum}")) + scop_copies.push(@copies[-1]) + @target_code << "bones_copyout_#{index*100+copynum}_#{name}(#{name});"+NL + end + end + + # Check if it was a 'pragma scop' / 'pragma endscop' line + if line =~ /^#{WHITESPACE}#{SCOP_START}/ + scop += 1 + scop_copies = [] + alloc_index = @target_code.length + a_scop_was_found = true + @target_code << 'bones_timer_start();'+NL + elsif line =~ /^#{WHITESPACE}#{SCOP_END}/ + free_index = @target_code.length + @target_code << 'bones_timer_stop();'+NL + + # Add frees and mallocs + if @scheduler + alloc_code, free_code = '', '' + included_copies = [] + scop_copies.each do |copy| + if !included_copies.include?(copy.name) + alloc_code += copy.get_function_call('alloc')+NL + free_code += copy.get_function_call('free')+NL + included_copies << copy.name + end + end + @target_code.insert(alloc_index, alloc_code) + @target_code << free_code + end + end + + else + if found > 0 + algorithm_line = replace_defines(line,@defines) + @target_code << algorithm_line + algorithm_code += algorithm_line if line !~ /^#{WHITESPACE}#/ + else + @target_code << line + end end - found = found + 1 - #@target_code << "int bones_temp_species_start = '#{line.gsub(NL,'')}';"+NL - - # Found the end of algorithm marker - elsif line =~ /^#{WHITESPACE}#{SPECIES_END}/ - if found == 1 - name = line.strip.scan(/^#{WHITESPACE}#{SPECIES_END} (.+)/).join - name = DEFAULT_NAME if name == '' - @algorithms.push(Bones::Algorithm.new(name,@filename,index.to_s,species,algorithm_code)) - algorithm_code = '' - end - found = found - 1 - #@target_code << "int bones_temp_species_end = '#{line.gsub(NL,'')}';"+NL - - # Found a sync marker - elsif @scheduler && line =~ /^#{WHITESPACE}#{SYNC}/ - sync = line.strip.scan(/^#{WHITESPACE}#{SYNC} (.+)/).join - @target_code << "bones_synchronize(#{sync});"+NL - - # Found a copyin marker - elsif @scheduler && line =~ /^#{WHITESPACE}#{COPYIN}/ - copies = line.strip.scan(/^#{WHITESPACE}#{COPYIN} (.+)/).join.split(WEDGE).map{ |c| c.strip } - copies.each_with_index do |copy,copynum| - name = copy.split('[').first - domain = copy.scan(/\[(.+)\]/).join.split(DIM_SEP) - deadline = copy.split('|').last - @copies.push(Bones::Copy.new(name,domain,deadline,'in',"#{index*100+copynum}")) - @target_code << "bones_copyin_#{index*100+copynum}_#{name}(#{name});"+NL - end - - # Found a copyout marker - elsif @scheduler && line =~ /^#{WHITESPACE}#{COPYOUT}/ - copies = line.strip.scan(/^#{WHITESPACE}#{COPYOUT} (.+)/).join.split(WEDGE).map{ |c| c.strip } - copies.each_with_index do |copy,copynum| - name = copy.split('[').first - domain = copy.scan(/\[(.+)\]/).join.split(DIM_SEP) - deadline = copy.split('|').last - @copies.push(Bones::Copy.new(name,domain,deadline,'out',"#{index*100+copynum}")) - @target_code << "bones_copyout_#{index*100+copynum}_#{name}(#{name});"+NL - end end - - # Check if it was a 'pragma scop' / 'pragma endscop' line - if line =~ /^#{WHITESPACE}#{SCOP_START}/ - alloc_index = index - elsif line =~ /^#{WHITESPACE}#{SCOP_END}/ - free_index = @target_code.length - end - else - if found > 0 - algorithm_line = replace_defines(line,@defines) - @target_code << algorithm_line - algorithm_code += algorithm_line if line !~ /^#{WHITESPACE}#/ - else - @target_code << line - end + @target_code << line end end puts WARNING+'Begin/end kernel mismatch ('+@found_algorithms.to_s+' versus '+@algorithms.length.to_s+'), probably missing a "'+SPECIES_END+'"' unless @algorithms.length == @found_algorithms - # Add frees and mallocs - if @scheduler - alloc_code, free_code = '', '' - included_copies = [] - copies.each do |copy| - if !included_copies.include?(copy.name) - alloc_code += copy.get_function_call('alloc')+NL - free_code += copy.get_function_call('free')+NL - included_copies << copy.name - end - end + # Print warning if there is no SCoP found + if !a_scop_was_found + puts WARNING+'No "#pragma scop" and "#pragma endscop" found!' end - # Add timers (whole scop timing) and frees/mallocs to the code - offset = @header_code.lines.count - @target_code.insert(alloc_index-offset, 'bones_timer_start();'+NL) - if @scheduler - @target_code.insert(alloc_index-offset+1, alloc_code) - @target_code.insert(free_index+2, free_code) - @target_code.insert(free_index+3, 'bones_timer_stop();'+NL) - else - @target_code.insert(free_index+2, 'bones_timer_stop();'+NL) - end - # Join the array @target_code = @target_code.join('') end # This is the method to preprocess a header file. Currently, @@ -189,31 +219,51 @@ # the meanwhile, it also handles ifdef's. def process_header(filename) ifdefs = [true] # Process the file line by line + block_comment = false File.read(File.join(@directory,filename)).each_line.with_index do |line,index| - if line =~ /^#{WHITESPACE}#/ - - # Process 'include' statements - if line =~ /^#{WHITESPACE}#include/ && ifdefs.last - if line =~ /"(.*)"/ - process_header($1) + + # Don't consider one-line comments + if !(line =~ /^#{WHITESPACE}\/\//) + + # Found the start of a block comment + if line =~ /\/\*/ + block_comment = true + end + + # Search for the end of the block comment + if block_comment + if line =~ /\*\// + block_comment = false end - - # Process 'define' statements - elsif line =~ /^#{WHITESPACE}#define/ && ifdefs.last - match = line.split(/\/\//)[0].scan(/^#{WHITESPACE}#define\s+(\w+)\s+(\S*)/) - @defines[match.first[0].to_sym] = match.first[1].strip - - # Process 'ifdef' statements - elsif line =~ /^#{WHITESPACE}#ifdef#{WHITESPACE}(\w+)/ - valid = (ifdefs.last) ? @defines.has_key?($1.to_sym) : false - ifdefs.push(valid) - - # Process 'endif' statements - elsif line =~ /^#{WHITESPACE}#endif/ - ifdefs.pop + + # Not in a block-comment + else + if line =~ /^#{WHITESPACE}#/ + + # Process 'include' statements + if line =~ /^#{WHITESPACE}#include/ && ifdefs.last + if line =~ /"(.*)"/ + process_header($1) + end + + # Process 'define' statements + elsif line =~ /^#{WHITESPACE}#define/ && ifdefs.last + match = line.split(/\/\//)[0].scan(/^#{WHITESPACE}#define\s+(\w+)\s+(\S*)/) + @defines[match.first[0].to_sym] = match.first[1].strip + + # Process 'ifdef' statements + elsif line =~ /^#{WHITESPACE}#ifdef#{WHITESPACE}(\w+)/ + valid = (ifdefs.last) ? @defines.has_key?($1.to_sym) : false + ifdefs.push(valid) + + # Process 'endif' statements + elsif line =~ /^#{WHITESPACE}#endif/ + ifdefs.pop + end + end end end end end