User:JayCampbell/walp.rb

From Esolang
Jump to navigation Jump to search

An interpreter and text graphic debugger for WALP.

This version has other features not included in the What A Limited Programming language spec:

  • Grid not limited to 16x16 - pads columns to fit longest source code line
  • Place tokens anywhere on the grid - chunks are flexes and are not pinned down
  • Input: the '?' token is a flex that sets the pool to the next available stdin character
  • 'o' and 'O' are aliases to the accented-o 'branch not zero' and 'branch if zero' symbols

Real Programmers are encouraged to stick to the original 16x16 grid with 3 static chunks. The examples below don't.

Setup

  • Cut-n-paste the sections below into hihi.wlp and walp.rb
  • On unix, set the script permissions to run: chmod 755 wlp.rb
  • Run the script: ./walp.rb hihi.wlp -OR- ruby walp.rb hihi.wlp


hihi.wlp

Endlessly outputs HI. This was an attempt to produce recognizable output within the original 16x16 constraints. The horizontal bars are rightward runs to increment the pool up to the letter H, looping back across (and overlapping with) empty leftbound rows. Two downward passes through hash marks in the lower right print the characters; the pointer accidentally bounce back to the top and repeats, which is where the author left off.

Requires the extended WALP interpreter below. There is no known 'Hello World' solution in classic WALP.

$##############@
@#############@
@              @
@############@ #
@             @#
@############ #@
@            @
@############@@
@              @
@########@ @   @
@            @##
        @#@   @@
       @@@     #
 @######### ###@
 #     @      @
 @        @@   @

walp.rb

You can change a few variables at the top, like whether to show the verbose debugger during running (on by default).

#!/usr/bin/ruby
# Interpreter by Jay Campbell 2008
#  for the WALP esoteric programming language
# Usage: ./walp.rb hihi.walp

$verbose = true          # not much to see otherwise
$sleep = 0.1             # pause between ticks
$clear_screen = 'clear'  # for dos/windows use 'cls'

class Walp

    def initialize
        @grid = Array.new
        @pool = 0
        @start = nil
        @direction = 'right'
        @output = ''
        @biggest = 0
        @rows = 0
    end

    def turn_from(direction, count)
        dirs = ['right','down','left','up','right','down']
        current = dirs.index(direction)
        return dirs[dirs.index(direction) + count]
    end

    def parse( input )

        # measure and store input lines
        input.each do |line|
            parts = line.split(//)
            size = parts.size
            @biggest = size if size > @biggest
            if dollar = parts.index('$') then @pointer = [@rows, dollar] end
            @grid << parts
            @rows += 1
        end
        return 'No starting point.' unless @pointer

        # fill truncated lines
        @grid.each do |line| line << ' ' while @biggest > line.size end

        # run
        loop do
                  @here = @grid[@pointer[0]][@pointer[1]]

               if @here == '!' then break
            elsif @here == '?' then @pool = getc
            elsif @here == '#'
                   if @direction == 'left' then @pool -=1
                elsif @direction == 'right' then @pool += 1
                elsif @direction == 'down' then @output << @pool.chr
                elsif @direction == 'up' then @pool = 0
                  end
            elsif @here == '@' then @direction = turn_from(@direction, 1)
            elsif @here == '/' or
                ((@here ==  'o' or @here == 243.chr) and @pool == 0) or
                ((@here == 'O' or @here == 242.chr) and @pool != 0)
                     @direction = turn_from(@direction, 2)
            end

               if @direction == 'right' then @pointer[1] += 1
            elsif @direction == 'left'  then @pointer[1] -= 1
            elsif @direction == 'up'    then @pointer[0] -= 1
            elsif @direction == 'down'  then @pointer[0] += 1
              end

            @pointer[0] += @biggest if @pointer[0] < 0
            @pointer[0] -= @biggest if @pointer[0] >= @biggest
            @pointer[1] += @rows    if @pointer[1] < 0
            @pointer[1] -= @rows    if @pointer[1] >= @rows
            @pool -= 255 if @pool > 255
            @pool += 255 if @pool < 0

            if $verbose
                system($clear_screen)
                c = 0
                @grid.each do |line|
                    row = line.join
                    if c == @pointer[0] then row[@pointer[1]] = 'X' end
                    c += 1
                    puts row
                end
                puts "Grid:#{@biggest}x#{@rows} Pointer: #{@pointer[0]},#{@pointer[1]}='#{@here}' Pool:#{@pool} Output:#{@output}"
                sleep $sleep
            end
        end

        return @output
    end

end

file = ARGV[0]
input = Array.new
File.open(file, 'r') do |f| while not f.eof? do input << f.gets.chomp end end

walp = Walp.new
print walp.parse(input)