daily pastebin goal
40%
SHARE
TWEET

Untitled

a guest Aug 17th, 2018 63 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env ruby
  2.  
  3. require 'optparse'
  4.  
  5. options = Hash.new(false)
  6. option_parser = OptionParser.new do |opts|
  7.     opts.banner = "Usage: bf.rb [options] <bf_file_or_string>"
  8.  
  9.     opts.on '-t', '--[no-]timing', 'Track compilation and execution time' do |v|
  10.         options[:timing] = v
  11.     end
  12.     opts.on '-e', '--echo', 'Echo input file' do |v|
  13.         options[:echo] = v
  14.     end
  15.     opts.on '-c', '--compiled', 'Echo generated Ruby code' do |v|
  16.         options[:compiled] = v
  17.     end
  18.     opts.on '-o', '--optimize', 'Use experimental optimizations' do |v|
  19.         options[:optimize] = v
  20.         puts "Warning: The option --optimize is not yet supported\n"
  21.     end
  22.     opts.on '-d', '--debug', 'Enable debug mode' do |v|
  23.         options[:debug] = v
  24.     end
  25.     opts.on '-i', '--input=INPUT', 'Use given input string instead of STDIN' do |v|
  26.         options[:input] = v.each_byte
  27.     end
  28.     opts.on '--count', 'Count executed instructions' do |v|
  29.         options[:count] = v
  30.     end
  31.  
  32.     if ARGV.empty?
  33.         abort(opts.help)
  34.     end
  35. end.parse!
  36.  
  37. begin
  38.  
  39. ic = 0 if options[:count]
  40.  
  41. t0 = Time.now if options[:timing]
  42. input = File.exists?(ARGV[0]) ? File.open(ARGV[0], 'r').read : ARGV[0]
  43. puts input if options[:echo]
  44. code = 'm=Hash.new(p=0);'+input.gsub(
  45.         /./,
  46.         '>' => 'p+=1;' + (options[:count] ? 'ic+=1;' : ''),
  47.         '<' => 'p-=1;' + (options[:count] ? 'ic+=1;' : ''),
  48.         '+' => 'm[p]+=1;' + (options[:count] ? 'ic+=1;' : ''),
  49.         '-' => 'm[p]-=1;' + (options[:count] ? 'ic+=1;' : ''),
  50.         '[' => '(' + (options[:count] ? 'ic+=1;' : ''),
  51.         ']' => ')while((m[p]&=255)!=0);' + (options[:count] ? 'ic+=1;' : ''),
  52.         '.' => 'putc(m[p]&=255);' + (options[:count] ? 'ic+=1;' : ''),
  53.         ',' => options[:input] ? 'begin m[p]=options[:input].next rescue m[p]=0 end;' : 'm[p]=STDIN.getbyte.ord if !STDIN.eof;' + (options[:count] ? 'ic+=1;' : ''),
  54.         '#' => options[:debug] ? 'print "m="+0.upto(m.keys.max).map{|i|m[i]%256}.to_s+"; p=#{p};\n";' : '',
  55. )
  56. puts code if options[:compiled]
  57. t1 = Time.now if options[:timing]
  58. print "\n"
  59. print "output:\n"
  60. eval code
  61. print "\n"
  62. t2 = Time.now if options[:timing]
  63. if options[:timing]
  64.     puts "Time used:"
  65.     puts "Compilation: " + ((t1-t0)*1000).to_s + "ms"
  66.     puts "Execution: " + ((t2-t1)*1000).to_s + "ms"
  67. end
  68.  
  69. puts "#{ic} instructions" if options[:count]
  70.  
  71. rescue SyntaxError => e
  72.     abort("Syntax Error - Are there unbalanced brackets?")
  73. rescue Interrupt => e
  74.     abort("Interrupted")
  75. end
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top