gabriele renzi wrote: > Damn, now I have to write the COW one.. > givent that brainf**k and OOk! are already there maybe we should start > a section on the wiki :) Now I just *have* to post my Brainfuck interpreter where all instructions can dynamically be changed and new ones can be added without problems: > begin > require 'simplecc' > rescue LoadError > def Continuation.create(*args, &block) > cc = nil; result = callcc {|c| cc = c; block.call(cc) if block and args.empty?} > result ||= args > return *[cc, *result] > end > end > > class BrainfuckContext > def initialize(code = nil, instructions = {}) > @data, @pointer, @jumps = Hash.new { 0 }, 0, [] > @instructions = Instructions.merge(instructions) > execute code if code > end > > def execute(code) > code.split(//).each do |instruction| > instance_eval(&@instructions[instruction]) > end > end > > def getc; STDIN.getc || 0; end > > Instructions = Hash.new { proc {} }.update({ > '>' => proc { @pointer += 1 }, > '<' => proc { @pointer -= 1 }, > '+' => proc { @data[@pointer] += 1 }, > '-' => proc { @data[@pointer] -= 1 }, > '.' => proc { putc @data[@pointer] }, > ',' => proc { @data[@pointer] = getc }, > '[' => proc do > jump, jumped = Continuation.create(false) > @jumps << jump > unless jumped > @depth ||= 0 > @depth += 1 > # make all instructions but ']' noops > @old_instructions = @instructions.dup > new_instructions = { > '[' => proc { @depth += 1 }, > ']' => proc do > @depth = [0, @depth - 1].max > if @depth == 0 > # restore standard instruction table > @instructions.update(@old_instructions) if @old_instructions > @old_instructions = nil > > jump = @jumps.pop > jump.call(true) if jump and @data[@pointer] != 0 > end > end > } > @instructions = @old_instructions.dup.clear.update(new_instructions) > end > end, > ']' => proc do > jump = @jumps.pop > jump.call(true) if jump and @data[@pointer] != 0 > end, > '#' => proc do > data = @data.to_a.sort_by { |(key, value)| > key > }.map { |(key, value)| > "#{key} = #{value}" > }.join(", ") > puts "#{@pointer} @ [#{data}]" > end > }) > end > > def bf(code) > BrainfuckContext.new(code) > end