diff options
| author | hallgren <hallgren@chalmers.se> | 2013-12-17 15:55:14 +0000 |
|---|---|---|
| committer | hallgren <hallgren@chalmers.se> | 2013-12-17 15:55:14 +0000 |
| commit | e9e919e6e3bd92ef6c30181817dd9c6e571011de (patch) | |
| tree | c975b2711f1de6c8117fdec2627847cad5e6617f /src/server/exec/MorphoService.hs | |
| parent | c8b8ca33c65720663908f9a9d3516534f6300114 (diff) | |
src/server/gf-server.cabal: compile it as a common library + executables
Diffstat (limited to 'src/server/exec/MorphoService.hs')
| -rw-r--r-- | src/server/exec/MorphoService.hs | 88 |
1 files changed, 88 insertions, 0 deletions
diff --git a/src/server/exec/MorphoService.hs b/src/server/exec/MorphoService.hs new file mode 100644 index 000000000..5c173c868 --- /dev/null +++ b/src/server/exec/MorphoService.hs @@ -0,0 +1,88 @@ +import GF.Compile +import GF.Compile.Rename (renameSourceTerm) +import GF.Compile.Concrete.Compute (computeConcrete) +import GF.Compile.Concrete.TypeCheck (inferLType) +import GF.Data.Operations +import GF.Grammar +import GF.Grammar.Parser +import GF.Infra.Option +import GF.Infra.UseIO +import GF.Infra.Modules (greatestResource) +import GF.Infra.CheckM +import GF.Text.UTF8 + +import Network.FastCGI +import Text.JSON +import Text.PrettyPrint +import qualified Codec.Binary.UTF8.String as UTF8 (decodeString, encodeString) +import Data.ByteString.Char8 as BS + +import Control.Monad +import System.Environment +import System.FilePath + +import Cache +import FastCGIUtils +import URLEncoding + +-- FIXME !!!!!! +grammarFile :: FilePath +grammarFile = "/usr/local/share/gf-3.1/lib/alltenses/ParadigmsFin.gfo" + +grammarPath :: FilePath +grammarPath = "/usr/local/share/gf-3.1/lib/prelude" + +main :: IO () +main = do initFastCGI + r <- newCache readGrammar + loopFastCGI (handleErrors (handleCGIErrors (fcgiMain r))) + +fcgiMain :: Cache SourceGrammar -> CGI CGIResult +fcgiMain cache = liftIO (readCache cache grammarFile) >>= cgiMain + +readGrammar :: FilePath -> IO SourceGrammar +readGrammar file = + do let opts = concatOptions [modifyFlags $ \fs -> fs { optVerbosity = Quiet }, + modifyFlags $ \fs -> fs { optLibraryPath = [grammarPath] }] + mgr <- appIOE $ batchCompile opts [file] + err (fail "Grammar loading error") return mgr + +cgiMain :: SourceGrammar -> CGI CGIResult +cgiMain sgr = + do path <- pathInfo + json <- case path of + "/eval" -> do mjson <- return (doEval sgr) `ap` getTerm + err (throwCGIError 400 "Evaluation error" . (:[])) return mjson + _ -> throwCGIError 404 "Not Found" ["Resource not found: " ++ path] + outputJSON json + where + getTerm :: CGI String + getTerm = do mt <- getInput "term" + maybe (throwCGIError 400 "No term given" ["No term given"]) (return . urlDecodeUnicode . UTF8.decodeString) mt + +doEval :: SourceGrammar -> String -> Err JSValue +doEval sgr t = liftM termToJSValue $ eval sgr t + +termToJSValue :: Term -> JSValue +termToJSValue t = + showJSON [toJSObject [("name", render name), ("value",render value)] | (name,value) <- ppTermTabular Unqualified t] + +eval :: SourceGrammar -> String -> Err Term +eval sgr t = + case runP pExp (BS.pack t) of + Right t -> do mo <- maybe (Bad "no source grammar in scope") return $ greatestResource sgr + (t,_) <- runCheck (renameSourceTerm sgr mo t) + ((t,_),_) <- runCheck (inferLType sgr [] t) + computeConcrete sgr t + Left (_,msg) -> fail msg + +-- * General CGI and JSON stuff + +outputJSON :: JSON a => a -> CGI CGIResult +outputJSON x = do setHeader "Content-Type" "text/json; charset=utf-8" + outputStrict $ UTF8.encodeString $ encode x + +outputStrict :: String -> CGI CGIResult +outputStrict x | x == x = output x + | otherwise = fail "I am the pope." + |
