Skip to content

Instantly share code, notes, and snippets.

/A0A0.rb Secret

Created January 25, 2013 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/dc6914d587bed8fa8d5e to your computer and use it in GitHub Desktop.
Save anonymous/dc6914d587bed8fa8d5e to your computer and use it in GitHub Desktop.
A0A0 Interpreter
class A0A0
OPS = Hash[*%w[S + D - M * L <=>]]
def initialize source
@program = *source.lines
@line = @program.index { |p| p['>'] } || 0
@program.map! { |p| p.scan /\w-?\d+/ }
end
def debug
@program.each_with_index do |p, i|
puts "%c%d\t%s" % ['* '[i <=> @line], i, (p || []) * ' ']
end
puts '-' * 20
end
def line
@program[@line]
end
def operand modify
v = line.index { |l| l['V'] }
line[v] = line[v].sub(/-?\d+/) { |o| modify[o.to_i] } rescue nil
end
def run
until line.empty?
debug if $DEBUG
insn = line.shift or exit
arg = insn[1..-1].to_i
case insn
when /A/ then (@program[@line + arg] ||= []).concat line
when /C/ then @program[@line + arg] = []
when /G/ then @line += arg
when /V/ then line[0].sub! /-?\d+/, arg.to_s
when /O/ then print arg
when /P/ then print (arg % 256).chr
when /I/ then operand -> _ { STDIN.getc.send %w[to_i ord][arg] }
when /([SDML])/ then operand -> o { o.send OPS[$1], arg }
end
@line += 1 unless insn['G']
break unless line
end
end
end
A0A0.new(ARGF).run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment