User:JayCampbell/walp.rb
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)