Warning: this is an htmlized version!
The original is here, and the conversion rules are here. |
# ============================================================================== # # RubyFORTH -- Copyright (C) 2007-8, Marc Simpson (GPL). # # File IO. # # ============================================================================== require 'kernel.rb' # --[ File Inclusion ]---------------------------------------------------------- $included = {} def root_filename(filename) return $rubyforth_root + "/" + filename end def _forth_include(filename, root) begin f = File.open(filename) f.each do |line| $current_line = line code $current_line end $included[filename] = true rescue if ! root return _forth_include(root_filename(filename), true) end puts "Error: could not include Forth file '#{filename}'" throw("toplevel") end end def forth_include forth # ensure we're in the forth context filename = parse_word line = $current_line # altered by _forth_include _forth_include(filename, false) $current_line = line # restore forth end def forth_included(filename) # is filename already included? inc1 = $included[filename] inc2 = $included[root_filename(filename)] return inc1 | inc2 end def forth_needs # include a file unless already included. forth # ensure we're in the forth context filename = parse_word line = $current_line # altered by _forth_include already = forth_included(filename) if ! already _forth_include(filename, false) end $current_line = line # restore forth end def _ruby_include(filename, root) begin require(filename) rescue LoadError if ! root return _ruby_include(root_filename(filename), true) end puts "Error: could not load Ruby file" puts "Ruby reported the following error: '#{$!}'" throw("toplevel") end end def ruby_include filename = parse_word _ruby_include(filename, false) end prim "needs" , "forth_needs" prim "include" , "forth_include" prim "included?" , "push(forth_flag(forth_included(pop)))" prim "ruby-include" , "ruby_include" # --[ File Access ]------------------------------------------------------------- # # The problem: we want to use file descriptors from Forth to allow for simple # numerical referencing. Ruby uses File instances. # # The solution: file descriptors are indices into the $file array; elements in # this array are File instances. $file = Array.new(128) def forth_open # ( filename$ mode$ -- fd ) mode = pop name = pop begin inst = File.open(name, mode) fd = inst.to_i $file[fd]=inst push(fd) rescue puts "Error: could not open file: '#{name}' with mode: '#{mode}'" end end prim "open" , "forth_open" prim "read" , "swap ; push($file[pop].read(pop))" prim "eof?" , "push(forth_flag($file[pop].eof?))" prim "seek" , "swap ; $file[pop].seek(pop, IO::SEEK_SET)" prim "write" , "$file[pop].print(pop)" prim "close" , "$file[pop].close" prim "position" , "push($file[pop].pos)" prim "readline" , "push($file[pop].gets)"