lib/haskell.rb in haskell-0.2.3 vs lib/haskell.rb in haskell-1.0.0
- old
+ new
@@ -1,48 +1,73 @@
-# Builtin Contracts
-class Any; end
-module Boolean; end
-TrueClass.send(:include, Boolean)
-FalseClass.send(:include, Boolean)
+module Haskell
+ # TODO:
+ class HaskellCompileError < StandardError; end
-class Module
- private
- def __haskell__
- prepend (@__haskell__ = Module.new) unless @__haskell__
- @__haskell__
- end
+ class << self
+ def invoke_sandbox!
+ file_path = File.expand_path('../', __FILE__)
+ $sandbox_path = "#{file_path}/haskell_executing_sandbox"
+ FileUtils.mkdir($sandbox_path) unless Dir.exist?($sandbox_path)
+ end
- def typesig(hash)
- meth = hash.keys.first
- *arg_types, type_pair = hash.values.first
-
- __haskell__.send(:define_method, meth) do |*args, &block|
- ::Haskell.assert_arg_type(meth, args, arg_types << type_pair.keys.first)
- rtn = super(*args, &block)
- ::Haskell.assert_trn_type(meth, rtn, type_pair.values.first)
- rtn
+ def revoke_sandbox!
+ FileUtils.rm_rf($sandbox_path)
end
- self
- end
-end
-module Haskell
- class << self
- def assert_arg_type(meth, args, klasses)
- args.each_with_index do |arg, i|
- if wrong_type?(arg, klasses[i])
- raise ArgumentError, "Wrong type of argument, type of #{arg.inspect} should be #{klasses[i]}"
+ def compile(hs_code)
+ FileUtils.touch("#{$sandbox_path}/COMPILING")
+ #TODO: need inform user prefer message
+ Thread.abort_on_exception = true
+ Thread.new do
+ begin
+ executable_code = executable_code(hs_code)
+ puts_notation(executable_code)
+ File.write("#{$sandbox_path}/tmp.hs", executable_code)
+ Kernel.system("ghc #{$sandbox_path}/tmp.hs")
+ raise HaskellCompileError unless compiled?
+ ensure
+ FileUtils.rm("#{$sandbox_path}/COMPILING")
end
end
+ rescue
+ raise "Something wrong...https://github.com/Azabuhs/Ruby/issues"
end
- def assert_trn_type(meth, rtn, klass)
- if wrong_type?(rtn, klass)
- raise TypeError, "Expected #{meth} to return #{klass} but got #{rtn.inspect} instead"
- end
+ def compiling?
+ File.exist?("#{$sandbox_path}/COMPILING")
end
- def wrong_type?(obj, klass)
- !(obj.is_a?(klass) || klass == Any)
+ def compiled?
+ File.exist?("#{$sandbox_path}/tmp")
+ end
+
+ def execute
+ `#{$sandbox_path}/tmp`.gsub(/\n\z/, '')
+ end
+
+ private
+
+ def executable_code(hs_code)
+ # TODO: other white space
+ hs_code =~/\A\n( *)/
+ hs_code.gsub!(/\n#{$1}/, "\n")
+<<-HASKELL_CODE
+module Main where
+#{hs_code}
+main = do putStrLn $ show result
+HASKELL_CODE
+ end
+
+ def puts_notation(executable_code)
+puts <<-NOTATION
+# GHC will compile below code
+###############################
+NOTATION
+
+puts '# ' + executable_code.gsub("\n", "\n# ")
+
+puts <<-NOTATION
+###############################
+NOTATION
end
end
end