#!/usr/bin/env ruby
require 'pp'
require 'rubygems'
require_gem 'multi'
require 'amulti'
require_gem 'sexp'
require 'sexp'
class Logo
def initialize
@x, @y = 100, 100
@angle = 0
@buffer = ""
@pen = true
amulti(:run, :right, Numeric) {|sym, r, rest| turn(r) ; run(rest) }
amulti(:run, :left, Numeric) {|sym, l, rest| turn(-l) ; run(rest) }
amulti(:run, :forward, Numeric) {|sym, f, rest| move(f) ; run(rest) }
amulti(:run, :penup) {|sym, rest| @pen = true ; run(rest) }
amulti(:run, :pendown) {|sym, rest| @pen = false ; run(rest) }
amulti(:run, :repeat, Numeric, Array) do |sym, i, code, rest|
i.to_i.times{ run(code) }
run(rest)
end
amulti(:run) {}
end
def turn(num)
@angle = (@angle + num) % 360
end
def move(distance)
oldx, oldy = @x, @y
radians = @angle * Math::PI / 180
@x += distance * Math.cos(radians)
@y += distance * Math.sin(radians)
return unless @pen
@buffer += <<-END
END
end
def eval(string)
run("(#{string})".parse_sexp)
end
def render
return <<-END
END
end
end
logo = Logo.new
logo.eval %q{
repeat 4 (forward 100 right 90)
forward 50 right 90 forward 100
}
puts logo.render