packages feed

hydra-0.8.0: src/main/haskell/Hydra/Lexical.hs

-- | Functions for retrieving elements and primitive functions from a graph context

module Hydra.Lexical where

import Hydra.Basics
import Hydra.Strip
import Hydra.Core
import Hydra.Extras
import Hydra.Graph
import Hydra.Compute
import Hydra.Tier1
import Hydra.Tier2
import Hydra.Module

import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Maybe as Y
import Control.Monad


dereferenceElement :: Name -> Flow Graph (Maybe Element)
dereferenceElement name = do
  g <- getState
  return $ M.lookup name (graphElements g)

fieldsOf :: Type -> [FieldType]
fieldsOf t = case stripType t of
  TypeLambda (LambdaType _ body) -> fieldsOf body
  TypeRecord rt -> rowTypeFields rt
  TypeUnion rt -> rowTypeFields rt
  _ -> []

requireElement :: Name -> Flow Graph Element
requireElement name = do
    mel <- dereferenceElement name
    case mel of
      Just el -> return el
      Nothing -> getState >>= err
  where
    err g = fail $ "no such element: " ++ unName name
        ++ ". Available elements: {" ++ L.intercalate ", " (ellipsis (unName . elementName <$> M.elems (graphElements g))) ++ "}"
      where
        showAll = False
        ellipsis = id
--        ellipsis strings = if L.length strings > 3 && not showAll
--          then L.take 3 strings ++ ["..."]
--          else strings

requirePrimitive :: Name -> Flow Graph Primitive
requirePrimitive fn = do
    cx <- getState
    Y.maybe err pure $ lookupPrimitive cx fn
  where
    err = fail $ "no such primitive function: " ++ unName fn

-- TODO: distinguish between lambda-bound and let-bound variables
resolveTerm :: Name -> Flow Graph (Maybe Term)
resolveTerm name = do
    g <- getState
    Y.maybe (pure Nothing) recurse $ M.lookup name $ graphElements g
  where
    recurse el = case stripTerm (elementData el) of
      TermVariable name' -> resolveTerm name'
      _ -> pure $ Just $ elementData el

-- Note: assuming for now that primitive functions are the same in the schema graph
schemaContext :: Graph -> Graph
schemaContext g = Y.fromMaybe g (graphSchema g)

toCompactName :: M.Map Namespace String -> Name -> String
toCompactName namespaces name = case mns of
    Nothing -> unName name
    Just ns -> case M.lookup ns namespaces of
      Just pre -> pre ++ ":" ++ local
      Nothing -> local
  where
    (QualifiedName mns local) = qualifyNameLazy name

withSchemaContext :: Flow Graph x -> Flow Graph x
withSchemaContext f = do
  cx <- getState
  withState (schemaContext cx) f