From: Matt Maycock Date: 2004-10-16T03:21:09+09:00 Subject: Re: Can one simulate go to in Ruby? Is it possible? Actually, I made the fatal mistake of leaving some of that code in the middle of a fix (a few months ago). Here's the good stuff: http://www.cs.drexel.edu/~ummaycoc/nruby (was changing how stop() works, and taking care of a case of the -z and -s i arguments (beginning line empty...)) -- There's no word in the English language for what you do to a dead thing to make it stop chasing you. --- code --- #!/usr/bin/env ruby # Number stuff down the side # REM means remark (NO number) # No number means continue last number # \ is same as no number... # -d debug mode. class NRuby def initialize(debug = false) @line = 0 @next = nil @debug = debug end def goto(line) @next = line end def stop() @next = :stop end def NRuby.error(msg) $stderr.puts("NRubyErr: #{msg}") exit(-1) end def debug(code, line) if @debug then puts "NO CODE #{line}" unless code[line] puts "**#{line}**\n#{code[line]}\n" if code[line] end end def NRuby.read(input, start) code, prev = Hash.new(false), start input.each {|line| doPrev = false case line when /^\s*REM(\s+|(\s*$))/i then ; when /^\s*$/ then ; when /^\s*(\d+)\s+(.*)$/ then prev = $1.to_i code[prev] = [$2] when /^\s*\\\s+(.*)$/ then doPrev, line = true, $1 else doPrev = true end error "No Previous Line!" if prev.nil? && doPrev unless prev.nil? then code[prev] = [] unless code.include? prev code[prev] << line if doPrev end } code.each_key {|key| code[key] = code[key].join(" \n") } code end def execute(code) lastline = code.keys.max until @line == :stop || @line > lastline debug(code, @line) @next = nil eval(code[@line]) if code[@line] @line = @next || @line + 1 end end end debug = false if ARGV.length > 0 then if ARGV.include? "-d" then debug = true ARGV.delete "-d" end end @___nruby___, start = NRuby.new(debug), nil if ARGV.length > 0 then stdin_read, lines = false, nil until ARGV.empty? do arg = ARGV.shift case arg when /^-+h/i $stderr.puts <<-END_HELP #{File.basename($0)} [-z|-s num] [-d] [files+] -z sets the first number label to zero - for unlabeled code at beginning of program. -s num sets the first number label to num. Same use as -z. -d debug mode. files list what files to read from. - is stdin. If no inputs are given, a program is read from stdin and executed. END_HELP exit(-1) when '-' NRuby.error "Already read from stdin." if stdin_read stdin_read = true lines = $stdin.readlines when '-z' start = 0 when '-s' NRuby.error "No argument given with -s." if ARGV.empty? start = ARGV.shift NRuby.error "Argument to -s must be integer." unless start =~ /-?\d+$/ start = start.to_i else NRuby.error "#{arg} doesn't exist..." unless FileTest.exists?(arg) NRuby.error "#{arg} isn't a file..." unless FileTest.file?(arg) NRuby.error "#{arg} isn't readable..." unless FileTest.readable?(arg) lines = File.readlines(arg) end lines ||= $stdin.readlines lines.each {|l| l.chomp!} @___nruby___.execute(NRuby.read(lines, start)) end else lines = $stdin.readlines.map {|l| l.chomp} if lines.nil? || lines.empty? then NRuby.error "No input given." else @___nruby___.execute(NRuby.read(lines, start)) end end -------------