Class: Haskell
- Inherits:
-
Object
- Object
- Haskell
- Defined in:
- lib/rubiskell.rb
Defined Under Namespace
Classes: Signeture
Constant Summary collapse
- TYPE_TABLE =
[ ["Int", Integer], ["String", String], ]
Class Method Summary collapse
Instance Method Summary collapse
- #call(sig, *args) ⇒ Object
- #convert_result(result, type) ⇒ Object
-
#initialize(code, option = {}) ⇒ Haskell
constructor
A new instance of Haskell.
- #make_cmd(path, args) ⇒ Object
- #make_src(code, sig) ⇒ Object
- #make_tempfile(src) ⇒ Object
- #parse_signetures(code) ⇒ Object
- #run(*args) ⇒ Object (also: #[])
Constructor Details
#initialize(code, option = {}) ⇒ Haskell
Returns a new instance of Haskell.
13 14 15 16 17 18 |
# File 'lib/rubiskell.rb', line 13 def initialize(code, option={}) @interpreter = option[:interpreter] || "runghc" @signetures = parse_signetures(code) @code = code @k = 0 end |
Class Method Details
.load(fname) ⇒ Object
4 5 6 |
# File 'lib/rubiskell.rb', line 4 def self.load(fname) new(File.read(fname)) end |
.tuple_form(args) ⇒ Object
8 9 10 11 |
# File 'lib/rubiskell.rb', line 8 def self.tuple_form(args) a = args.join(",") return args.size == 1 ? a : "(#{a})" end |
Instance Method Details
#call(sig, *args) ⇒ Object
20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/rubiskell.rb', line 20 def call(sig, *args) if String === sig sig = @signetures.find{|sig| sig.name == sig} raise ArgumentError, "unknown method" if sig.nil? end src = make_src(@code, sig) path = make_tempfile(src) cmd = make_cmd(path, args) convert_result(`#{cmd}`.chomp, sig.ret) end |
#convert_result(result, type) ⇒ Object
43 44 45 46 47 48 49 50 51 52 |
# File 'lib/rubiskell.rb', line 43 def convert_result(result, type) case type.to_s when "Integer" result.to_i when "String" result[1..-2] #cut \" else raise "unknown type: #{type}" end end |
#make_cmd(path, args) ⇒ Object
37 38 39 40 41 |
# File 'lib/rubiskell.rb', line 37 def make_cmd(path, args) arg_list = Haskell.tuple_form(args.map{|x| x.inspect}) arg_list.gsub!(/"/, '\\"') %Q<#{@interpreter} "#{path}" "#{arg_list}"> end |
#make_src(code, sig) ⇒ Object
94 95 96 97 98 99 100 101 102 103 104 |
# File 'lib/rubiskell.rb', line 94 def make_src(code, sig) src = "import System\n" src << code src << "\n" src << "main = do args <- getArgs\n" src << " print $ apply #{sig.name} $ _read $ head args\n" src << " where\n" src << " _read :: String -> #{sig.tuple_form}\n" src << " _read = read\n" src << " apply f #{sig.tuple_vars} = f #{sig.list_vars}\n" end |
#make_tempfile(src) ⇒ Object
106 107 108 109 110 111 112 113 |
# File 'lib/rubiskell.rb', line 106 def make_tempfile(src) while File.exist?(fname = "rubiskell.#{Process.pid}.#{@k}.hs") @k += 1 end open(fname, "w"){|f| f.write src } at_exit{ File.unlink(fname) } fname end |
#parse_signetures(code) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/rubiskell.rb', line 82 def parse_signetures(code) code.scan(/^(\w+)\s*::\s*(\w+(\s*->\s*\w+)*)\s*$/).map do |sig| name = $1.strip args = $2.split(/->/).map{|x| pair = TYPE_TABLE.assoc(x.strip) pair ? pair[1] : (raise ArgumentError, "unknown Haskell type #{x.strip}") } ret = args.pop Signeture.new(name, args, ret) end end |
#run(*args) ⇒ Object Also known as: []
32 33 34 |
# File 'lib/rubiskell.rb', line 32 def run(*args) call(@signetures[0], *args) end |