-- | @futhark query@
module Futhark.CLI.Query (main) where

import Futhark.Compiler
import Futhark.Util.Loc
import Futhark.Util.Options
import Language.Futhark.Query
import Language.Futhark.Syntax
import Text.Read (readMaybe)

-- | Run @futhark query@.
main :: String -> [String] -> IO ()
main :: String -> [String] -> IO ()
main = ()
-> [FunOptDescr ()]
-> String
-> ([String] -> () -> Maybe (IO ()))
-> String
-> [String]
-> IO ()
forall cfg.
cfg
-> [FunOptDescr cfg]
-> String
-> ([String] -> cfg -> Maybe (IO ()))
-> String
-> [String]
-> IO ()
mainWithOptions () [] String
"program line col" (([String] -> () -> Maybe (IO ())) -> String -> [String] -> IO ())
-> ([String] -> () -> Maybe (IO ())) -> String -> [String] -> IO ()
forall a b. (a -> b) -> a -> b
$ \[String]
args () ->
  case [String]
args of
    [String
file, String
line, String
col] -> do
      line' <- String -> Maybe Int
forall a. Read a => String -> Maybe a
readMaybe String
line
      col' <- readMaybe col
      Just $ do
        (_, imports, _) <- readProgramOrDie file
        -- The 'offset' part of the Pos is not used and can be arbitrary.
        case atPos imports $ Pos file line' col' 0 of
          Maybe AtPos
Nothing -> String -> IO ()
putStrLn String
"No information available."
          Just (AtName QualName VName
qn Maybe BoundTo
def Loc
loc) -> do
            String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Name: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ QualName VName -> String
forall a. Pretty a => a -> String
prettyString QualName VName
qn
            String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Position: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SrcLoc -> String
forall a. Located a => a -> String
locStr (Loc -> SrcLoc
forall a. Located a => a -> SrcLoc
srclocOf Loc
loc)
            case Maybe BoundTo
def of
              Maybe BoundTo
Nothing -> () -> IO ()
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ()
              Just (BoundTerm TermBinding
term Loc
defloc) -> do
                let t :: TypeBase Size NoMode
t = TermBinding -> TypeBase Size NoMode
termBindingType TermBinding
term
                String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Type: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ TypeBase Size NoMode -> String
forall a. Pretty a => a -> String
prettyString TypeBase Size NoMode
t
                String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Definition: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SrcLoc -> String
forall a. Located a => a -> String
locStr (Loc -> SrcLoc
forall a. Located a => a -> SrcLoc
srclocOf Loc
defloc)
              Just (BoundType Loc
defloc) ->
                String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Definition: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SrcLoc -> String
forall a. Located a => a -> String
locStr (Loc -> SrcLoc
forall a. Located a => a -> SrcLoc
srclocOf Loc
defloc)
              Just (BoundModule Loc
defloc) ->
                String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Definition: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SrcLoc -> String
forall a. Located a => a -> String
locStr (Loc -> SrcLoc
forall a. Located a => a -> SrcLoc
srclocOf Loc
defloc)
              Just (BoundModuleType Loc
defloc) ->
                String -> IO ()
putStrLn (String -> IO ()) -> String -> IO ()
forall a b. (a -> b) -> a -> b
$ String
"Definition: " String -> String -> String
forall a. [a] -> [a] -> [a]
++ SrcLoc -> String
forall a. Located a => a -> String
locStr (Loc -> SrcLoc
forall a. Located a => a -> SrcLoc
srclocOf Loc
defloc)
    [String]
_ -> Maybe (IO ())
forall a. Maybe a
Nothing