From: Matt Maycock Date: 2004-10-15T23:37:05+09:00 Subject: Re: Can one simulate go to in Ruby? Is it possible? --- code --- #!/home/ummaycoc/bin/ruby -w # 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 = nil 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 code[prev] = [] unless code.include? prev code[prev] << line if doPrev } code.each_key {|key| code[key] = code[key].join(" \n") } code end def execute(code) lastline = code.keys.max until @line.nil? || @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 --- a usage --- [ummaycoc@queen ummaycoc]$ echo ' 10 x = 1 11 x += 1 12 puts x 15 goto 18 if x == 10 16 goto 11 18 puts "done" stop' | nruby 2 3 4 5 6 7 8 9 10 done [ummaycoc@queen ummaycoc]$ --- usage 2 & 3 --- [ummaycoc@queen bin]$ echo 'puts "hi"' | nruby NRubyErr: No Previous Line! [ummaycoc@queen bin]$ echo 'puts "hi"' | nruby -z hi [ummaycoc@queen bin]$ ------------------------------- -- There's no word in the English language for what you do to a dead thing to make it stop chasing you.