1 class Preprocessor 2 def initialize(input, output, filename) 3 @input = input 4 @output = output 5 @filename = filename 6 @linenum = 1 7 end 8 9 def getline 10 line = @input.gets 11 @linenum += 1 if not line.nil? 12 return line 13 end 14 15 def preprocess 16 success = false 17 begin 18 loop do 19 line = getline 20 break if line.nil? 21 case line 22 when /(.*[^\\]|^)\#\{(.*?)\}(.*)/ 23 puts "#{$1}#{evaluate($2, @linenum)}#{$3}" 24 when /^\#ruby\s+<<(.*)/ 25 marker = $1 26 str = '' 27 evalstart = @linenum 28 loop do 29 line = getline 30 if line.nil? then 31 raise "End of input without #{marker}" 32 end 33 break if line.chomp == marker 34 str << line 35 end 36 result = evaluate(str, evalstart) 37 puts result if not result.nil? 38 when /^\#ruby\s+(.*)/ 39 str = line = $1 40 while line[-1] == ?\\ 41 str.chop! 42 line = getline 43 break if line.nil? 44 line.chomp! 45 str << line 46 end 47 result = evaluate(str, @linenum) 48 puts result if not result.nil? 49 else 50 puts line 51 end 52 end 53 success = true 54 ensure 55 if not success then 56 $stderr.puts "Error on line #{@linenum}:" 57 end 58 end 59 end 60 61 def evaluate(str, linenum) 62 result = eval(str, TOPLEVEL_BINDING, @filename, linenum) 63 success = true 64 return result 65 end 66 67 def puts(line) 68 @output.puts(line) 69 end 70 end 71 72 def puts(line) 73 $preprocessor.puts(line) 74 end 75 76 if __FILE__ == $0 then 77 input_file = ARGV[0] 78 output_file = ARGV[1] 79 80 input = input_file ? File.open(input_file) : $stdin 81 output = output_file ? File.open(output_file, 'w') : $stdout 82 83 success = false 84 begin 85 $preprocessor = Preprocessor.new(input, output, input_file || "(stdin)") 86 $preprocessor.preprocess() 87 success = true 88 ensure 89 if not success then 90 File.unlink(output_file) rescue Errno::ENOENT 91 end 92 end 93 end