fork download
  1. class A0A0
  2. OPS = Hash[*%w[S + D - M * L <=>]]
  3.  
  4. def initialize source
  5. @program = *source.lines
  6. @line = @program.index { |p| p['>'] } || 0
  7. @program.map! { |p| p.scan /\w-?\d+/ }
  8. end
  9.  
  10. def debug
  11. @program.each_with_index do |p, i|
  12. puts "%c%d\t%s" % ['* '[i <=> @line], i, (p || []) * ' ']
  13. end
  14. puts '-' * 20
  15. end
  16.  
  17. def line
  18. @program[@line]
  19. end
  20.  
  21. def operand modify
  22. v = line.index { |l| l['V'] }
  23. line[v] = line[v].sub(/-?\d+/) { |o| modify[o.to_i] } rescue nil
  24. end
  25.  
  26. def run
  27. until line.empty?
  28. debug if $DEBUG
  29. insn = line.shift or exit
  30. arg = insn[1..-1].to_i
  31.  
  32. case insn
  33. when /A/ then (@program[@line + arg] ||= []).concat line
  34. when /C/ then @program[@line + arg] = []
  35. when /G/ then @line += arg
  36. when /V/ then line[0].sub! /-?\d+/, arg.to_s
  37. when /O/ then print arg
  38. when /P/ then print (arg % 256).chr
  39. when /I/ then operand -> _ { STDIN.getc.send %w[to_i ord][arg] }
  40. when /([SDML])/ then operand -> o { o.send OPS[$1], arg }
  41. end
  42.  
  43. @line += 1 unless insn['G']
  44. break unless line
  45. end
  46. end
  47. end
  48.  
  49. cat = "A0 A0
  50. A0 C3 G1 G1 A0
  51. A0 I1 V0 P0 A0
  52. A0 A1 G-3 G-3 A0
  53. G-3"
  54. A0A0.new(cat).run
Success #stdin #stdout 0.02s 7480KB
stdin
Soft kitty,
warm kitty,
little ball of fur.
Happy kitty,
sleepy kitty,
purr, purr, purr.
stdout
Soft kitty,
warm kitty,
little ball of fur.
Happy kitty,
sleepy kitty,
purr, purr, purr.