Sha256: 04ad504d70d030a7ff9eff75a2c0662d86f8d758142ab61dc1ad6152731f59e9

Contents?: true

Size: 1.97 KB

Versions: 1

Compression:

Stored size: 1.97 KB

Contents

class BrainFuck
  def initialize(options = {})
    self.class.default_mapping.each do |key, default|
      operations[key] = options.has_key?(key) ? options[key] : default
    end
  end

  def self.bf_mapping
    @bf_operations ||= {nxt: '>', prv: '<', inc: '+', dec: '-', put: '.',  get: ',', opn: '[', cls: ']' }
  end

  def self.default_mapping
    @default_mapping ||= bf_mapping.clone
  end

  def operations
    @operations ||= {}
  end

  default_mapping.keys.each do |op|
    define_method(op) do
      instance_variable_get(:@operations)[op]
    end
  end

  def compile(src)
    BrainFuck.new.translate(self, src)
  end

  def translate(other, src)
    other = other.new if other.kind_of?(Class)
    cur = 0
    inv = other.operations.invert
    reg = Regexp.compile "(#{other.operations.values.map{|v| Regexp.quote(v) }.join('|')})"
    dst = ''
    while matches = reg.match(src, cur)
      op = inv[matches[1]]
      dst += operations[op]
      cur = src.index(reg, cur) + matches[1].length
    end
    dst
  end

  def fuck(src)
    src = compile(src)
    ptr = 0
    cur = 0
    cell = Array.new(3000) { 0 }
    output = []
    inv = self.class.bf_mapping.invert
    reg = Regexp.compile "(#{self.class.bf_mapping.values.map{|v| Regexp.quote(v) }.join('|')})"
    while matches = reg.match(src, cur)
      next_cur = nil
      case inv[matches[1]]
      when :nxt
        ptr += 1
      when :prv
        ptr -= 1
      when :inc
        cell[ptr] += 1
      when :dec
        cell[ptr] -= 1
      when :put
        output << cell[ptr].chr
      when :get
      when :opn
        next_cur = src.index(self.class.bf_mapping[:cls], cur) + 1 if cell[ptr] == 0
      when :cls
        next_cur = src.rindex(self.class.bf_mapping[:opn], cur)
      end
      cur = next_cur || src.index(reg, cur) + matches[1].length
    end
    output.join
  end

  class << self
    BrainFuck.default_mapping.keys.each do |op|
      define_method(op) do |val|
        default_mapping[op] = val
      end
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
r-fxxk-0.2.0 lib/r-fxxk.rb