daz [mailto:dooby / d10.karoo.co.uk] wrote:

> puts "Hello World"
> i = 0
> callcc do | $goto160 |
>   callcc {| $goto120 |}
>   $goto160.call if i > 10     # 120;
>   puts "Current i: %d" % [i]
>   i = i + 1
>   $goto120.call
> end
> puts "Done!"                  # 160;

I guess the contest this week is to see who can implement Basic the best
:-). Here's my entry:

  class Basic
    def initialize
      @__lines = {}
    end

    def l(line_no, &block)
      callcc {|@__lines[line_no]|}
      if(@__goto)
        @__goto.call(@__lines[line_no]) if(@__goto_line == line_no)
      else
        @__current_line = line_no
        instance_eval(&block)
      end
    end

    def goto(line_no)
      @__come_from = @__current_line
      cont = @__lines[line_no]
      unless(cont)
        @__goto_line = line_no
        cont = callcc{|@__goto| return}
        @__goto = nil
      end
      cont.call
    end

    def run(&block)
      instance_eval(&block)
      raise "Invalid goto line #@__goto_line called from #@__come_from!"
if(@__goto)
    end

    def self.run(&block)
      self.new.run(&block)
    end
  end

  Basic::run do
    l(10){ @a = 1 }
    l(20){ p @a }
    l(30){ @a += 1 }
    l(40){ goto(20) unless(@a == 10) }
    l(50){ goto(100) }
  end

Not exhaustively tested...

At first, I was using caller to determine the actual file line number and
using that... but whenever I changed something up top, it would break my
basic. I always did hate programming languages that used line numbers :-P


Nathaniel

<:((><