packages feed

Grow-1.1: Language/Syntax/Grow.hs

{-# LANGUAGE UndecidableInstances #-}
module Language.Syntax.Grow(
  module Data.Syntax,
  growExpr
  ) where

import Definitive
import Language.Parser
import Data.Containers
import Data.Syntax
import Data.Char
import Language.Grow

instance MonadReader a Id where
  ask = Id undefined
  local _ = id
instance Monoid m => MonadWriter m Id where
  tell _ = pure ()
  listen (Id a) = Id (zero,a)
  censor (Id (a,f)) = Id a
instance MonadIO Id where
  liftIO a = pure undefined

-- ^ For debugging purposes
instance MonadGrow Id

growExpr :: MonadGrow m => Parser String [SyntaxT m]
growExpr = free expr `sepBy1` free (single ';')
  where
    decl = (,)<$>symbol<*>(free (single '=') >> free expr)
    free = (skipMany space >> )
    symbol = many1 (satisfy symChar) <+> quotedString '"'
      where symChar c = isAlphaNum c || (c`elem`".-_/+~%*!")
    funAp = (atom`sepBy1`spaces) <&> call
      where call [x] = x
            call t = ValList $ b_dollar : map pure t
    expr = chainr funAp (op <$> free (single ':' >> (atom <* space))) funAp 
      where op f a b = ValList [b_dollar,pure f,pure a,pure b]
    atom :: MonadGrow m => Parser String (SyntaxT m)
    atom = sum [
      between (single '(') (free $ single ')') (free inParen)
      ,list,dictionary,Text<$>symbol,dollar]
      where dollar = single '$' >> (atom <&> \e -> ValList [b_dollar,pure e])
    inParen = Function . lambdaSum<$>many1 (free (single '|' >> abstract))
              <+> expr
    abstract = lambda<$>atom<*>free (several "~>")*>free expr
    
    list = Quote . ValList . map pure
           <$>between (single '[') (free $ single ']') (free expr`sepBy`free (single ','))
    dictionary = mkDict<$>between (single '{') (free $ single '}') (free decl`sepBy`free (single ','))
    mkDict = Dictionary . fromList . map (\(s,v) -> (s,pure v))