haskellish (empty) → 0.1.0
raw patch · 4 files changed
+225/−0 lines, 4 filesdep +basedep +haskell-src-extssetup-changed
Dependencies added: base, haskell-src-exts
Files
- LICENSE +29/−0
- Language/Haskellish.hs +161/−0
- Setup.hs +2/−0
- haskellish.cabal +33/−0
+ LICENSE view
@@ -0,0 +1,29 @@+BSD 3-Clause License++Copyright (c) 2019, David Ogborn+All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++1. Redistributions of source code must retain the above copyright notice, this+ list of conditions and the following disclaimer.++2. Redistributions in binary form must reproduce the above copyright notice,+ this list of conditions and the following disclaimer in the documentation+ and/or other materials provided with the distribution.++3. Neither the name of the copyright holder nor the names of its+ contributors may be used to endorse or promote products derived from+ this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ Language/Haskellish.hs view
@@ -0,0 +1,161 @@+module Language.Haskellish where++import Language.Haskell.Exts+import Control.Applicative+import Data.Either (isRight)+import Data.Maybe (catMaybes)+++data Haskellish a = Haskellish { runHaskellish :: Exp SrcSpanInfo -> Either String a }+++instance Functor Haskellish where+ fmap f x = Haskellish (fmap f . runHaskellish x)+++instance Applicative Haskellish where+ pure x = Haskellish (const (Right x))+ f <*> x = Haskellish (\e -> do -- ie. in (Either String) monad+ (e1,e2) <- applicationExpressions e+ f' <- runHaskellish f e1+ x' <- runHaskellish x e2+ return (f' x')+ )+++applicationExpressions :: Exp SrcSpanInfo -> Either String (Exp SrcSpanInfo,Exp SrcSpanInfo)+applicationExpressions (Paren _ x) = applicationExpressions x+applicationExpressions (App _ e1 e2) = Right (e1,e2)+applicationExpressions (InfixApp _ e1 (QVarOp _ (UnQual _ (Symbol _ "$"))) e2) = Right (e1,e2)+applicationExpressions (InfixApp l e1 (QVarOp _ (UnQual _ (Symbol _ x))) e2) = Right (App l x' e1,e2)+ where x' = (Var l (UnQual l (Ident l x)))+applicationExpressions (LeftSection l e1 (QVarOp _ (UnQual _ (Symbol _ x)))) = Right (x',e1)+ where x' = (Var l (UnQual l (Ident l x)))+applicationExpressions _ = Left ""+++instance Alternative Haskellish where+ empty = Haskellish (const (Left ""))+ a <|> b = Haskellish (\e -> do+ let a' = runHaskellish a e+ if isRight a' then a' else runHaskellish b e+ )+++instance Monad Haskellish where+ x >>= f = Haskellish (\e -> do+ x' <- runHaskellish x e+ runHaskellish (f x') e+ )+++identifier :: Haskellish String -- note: we don't distinguish between identifiers and symbols+identifier = Haskellish f+ where f (Paren _ x) = f x+ f (Var _ (UnQual _ (Ident _ x))) = Right x+ f (Var _ (UnQual _ (Symbol _ x))) = Right x+ f _ = Left ""++reserved :: String -> Haskellish ()+reserved x = Haskellish (\e -> do -- in (Either String)+ e' <- runHaskellish identifier e+ if e' == x then Right () else Left ""+ )++string :: Haskellish String+string = Haskellish f+ where f (Paren _ x) = f x+ f (Lit _ (String _ x _)) = Right x+ f _ = Left ""++integer :: Haskellish Integer+integer = Haskellish f+ where f (Paren _ x) = f x+ f (NegApp _ (Lit _ (Int _ x _))) = Right (x * (-1))+ f (Lit _ (Int _ x _)) = Right x+ f _ = Left ""++rational :: Haskellish Rational+rational = Haskellish f+ where f (Paren _ x) = f x+ f (NegApp _ (Lit _ (Frac _ x _))) = Right (x * (-1))+ f (Lit _ (Frac _ x _)) = Right x+ f _ = Left ""++rationalOrInteger :: Haskellish Rational+rationalOrInteger = Haskellish f+ where f (Paren _ x) = f x+ f (NegApp _ (Lit _ (Frac _ x _))) = Right (x * (-1))+ f (Lit _ (Frac _ x _)) = Right x+ f (NegApp _ (Lit _ (Int _ x _))) = Right (fromIntegral $ x * (-1))+ f (Lit _ (Int _ x _)) = Right $ fromIntegral x+ f _ = Left ""++list :: Haskellish a -> Haskellish [a]+list p = Haskellish (\e -> f e >>= mapM (runHaskellish p))+ where+ f (Paren _ x) = f x+ f (List _ xs) = Right xs+ f _ = Left ""++tuple :: Haskellish a -> Haskellish b -> Haskellish (a,b)+tuple p1 p2 = Haskellish (\e -> do+ (a,b) <- f e+ a' <- runHaskellish p1 a+ b' <- runHaskellish p2 b+ return (a',b')+ )+ where+ f (Paren _ x) = f x+ f (Tuple _ Boxed (a:b:[])) = Right (a,b)+ f _ = Left ""++asRightSection :: Haskellish (a -> b -> c) -> Haskellish b -> Haskellish (a -> c)+asRightSection opP bP = Haskellish (\e -> do+ (opExp,bExp) <- f e+ op <- runHaskellish opP opExp+ b <- runHaskellish bP bExp+ return $ flip op b+ )+ where+ f (Paren _ x) = f x+ f (RightSection _ (QVarOp l (UnQual _ (Symbol _ x))) e1) = Right (g l x,e1)+ f _ = Left ""+ g l x = (Var l (UnQual l (Ident l x)))+++collectDoStatements :: Exp SrcSpanInfo -> [Exp SrcSpanInfo]+collectDoStatements (Do _ xs) = catMaybes $ fmap f xs+ where+ f (Qualifier _ e) = Just e+ f _ = Nothing++listOfDoStatements :: Haskellish a -> Haskellish [a]+listOfDoStatements p = Haskellish (\e -> mapM (runHaskellish p) $ collectDoStatements e)++type Span = ((Int,Int),(Int,Int))++askSpan :: Haskellish Span+askSpan = Haskellish $ return . expToSpan++expToSpan :: Exp SrcSpanInfo -> Span+expToSpan (Var x _) = srcSpanInfoToSpan x+expToSpan (Paren x _) = srcSpanInfoToSpan x+expToSpan (App x _ _) = srcSpanInfoToSpan x+expToSpan (InfixApp x _ _ _) = srcSpanInfoToSpan x+expToSpan (LeftSection x _ _) = srcSpanInfoToSpan x+expToSpan (NegApp x _) = srcSpanInfoToSpan x+expToSpan (Lit x _) = srcSpanInfoToSpan x+expToSpan (List x _) = srcSpanInfoToSpan x+expToSpan (RightSection x _ _) = srcSpanInfoToSpan x+expToSpan (Tuple x _ _) = srcSpanInfoToSpan x+expToSpan (Do x _) = srcSpanInfoToSpan x+expToSpan _ = ((0,0),(0,0))++srcSpanInfoToSpan :: SrcSpanInfo -> Span+srcSpanInfoToSpan x = ((bx,by),(ex,ey))+ where+ bx = srcSpanStartColumn $ srcInfoSpan x+ by = srcSpanStartLine $ srcInfoSpan x+ ex = srcSpanEndColumn $ srcInfoSpan x+ ey = srcSpanEndLine $ srcInfoSpan x
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ haskellish.cabal view
@@ -0,0 +1,33 @@+name: haskellish+version: 0.1.0+synopsis: For parsing Haskell-ish languages+homepage: http://github.com/dktr0/Haskellish+license: BSD3+license-file: LICENSE+author: David Ogborn+maintainer: David Ogborn <ogbornd@mcmaster.ca>+Stability: Experimental+Copyright: (c) 2019- David Ogborn+Category: Language+Build-type: Simple+cabal-version: >=1.10+tested-with: GHC == 8.6.3++Description: A library for parsing miniature and esoteric languages that are similar to Haskell++library+ ghc-options: -Wall+ hs-source-dirs:+ .++ default-language: Haskell2010++ Exposed-modules: Language.Haskellish++ Build-depends:+ base >=4.8 && <5+ , haskell-src-exts >=1.17.1 && <1.23++source-repository head+ type: git+ location: https://github.com/dktr0/Haskellish