User:JayCampbell/smatiny.rb

From Esolang
Jump to navigation Jump to search

smanity.rb - An interpreter by User:JayCampbell for iHope's SMATINY esoteric programming language

#!/usr/bin/ruby
#
# smatiny.rb
#
# An interpreter by JayCampbell 2008
#   for iHope's SMATINY esoteric programming language

filename = ARGV[0]
memory = Array.new
pointer = 0

# parse supplied file
File.open(filename) do |f|
   while line = f.gets

       # remove comments
       line.gsub!(/#.*/, '')

       # spaces and puntuations are optional, case-insensitive
       if line =~ /(\d+)\.?\s*swap\s*(\d+)\s*with\s*(\d+)\s*\.?/i
          memory[$1.to_i] = [ $2.to_i, $3.to_i ]

       elsif line =~ /(\d+)\.?\s*do\s*nothing\s*\.?/i
          # don't really need this except if a strange program overwrites its own input
          memory[$1.to_i] = nil

       elsif line =~ /(\d+)\.?\s*output\s*this\s*block's\s*position\s*\.?/i
          memory[$1.to_i] = 'print'

       elsif line =~ /[\d\w]/
          $stderr.puts "Bad line: #{line}"
       end
   end
end

k=0; memory.each {|m| if m != nil then $stderr.print "#{k}=#{m.inspect} " end; k += 1}; puts
$stderr.puts "Max cell: #{memory.size - 1}" # starting at 1, not 0
$stderr.puts "Non-NOP: #{memory.select{ |m| m != nil }.size}"

# run it
while pointer += 1

  instruction = memory[pointer]

  if instruction == 'print'
     putc pointer

  elsif instruction.class == Array
     x = pointer
     y = instruction[0]
     z = instruction[1]

     memory[y], memory[z] = memory[z], memory[y]

     if x == y then pointer = z
     elsif x == z then pointer = y end

  end

  break if pointer > memory.size

  # very verbose - uncomment for step-by-step dump
  # print "\nP=#{pointer} "; k=0; memory.each {|m| if m != nil then print "#{k}=#{m.inspect} " end; k += 1}; puts

end