packages feed

axel 0.0.11 → 0.0.12

raw patch · 38 files changed

+915/−1246 lines, 38 filesdep +extradep −singletons

Dependencies added: extra

Dependencies removed: singletons

Files

README.org view
@@ -1,14 +1,14 @@ #+OPTIONS: num:nil toc:nil #+STARTUP: inlineimages * Axel-  Haskell + Lisp + JVM/Node/... = Profit!+  Haskell + Lisp (+ JVM/Node/..., soon) = Profit!    See [[https://axellang.github.io]].   #+CAPTION: Build Status   [[https://travis-ci.org/axellang/axel.svg?branch=master]] ** Code Style-   Use ~hindent~ to format code and ~hlint~ to catch errors.+   Run ~scripts/format.sh~ to format code and ~scripts/lint.sh~ to maintain code quality. ** Running-   Run ~scripts/build.sh~ to build the project, and ~stack run <arguments>~ to run ~app/Main.hs~. The executable takes as arguments either ~file <path to file>~ (which is the path of the Axel program to build and execute) or ~project~ (in which case an Axel project in the current directory will be built and executed).+   Run ~scripts/build.sh~ to build the project, ~stack run -- <arguments>~ to run the project, and ~scripts/test.sh~ to test the project. ** Examples-   See the ~examples~ folder for example Axel programs.+   See the `.axel` files in this repository for example Axel programs.
app/Main.hs view
@@ -1,15 +1,13 @@ module Main where-import qualified Prelude as GHCPrelude-import qualified Axel.Parse.AST as AST+import Axel import qualified Prelude as GHCPrelude import qualified Axel.Parse.AST as AST import Axel.Eff.App(AppEffs,runApp) import Axel.Eff.Console(putStrLn)-import Axel.Eff.Ghci(withGhci)+import Axel.Eff.Ghci(withStackGhci) import Axel.Haskell.File(convertFileInPlace,formatFileInPlace,transpileFileInPlace) import Axel.Haskell.Project(buildProject,convertProject,formatProject,runProject) import Axel.Haskell.Stack(axelStackageVersion)-import qualified Axel.Parse.AST as AST import Axel.Parse.Args(Command(FileCommand,ProjectCommand,Version),FileCommand(ConvertFile,RunFile,FormatFile),ProjectCommand(ConvertProject,FormatProject,RunProject),commandParserInfo) import Control.Monad(void) import qualified Data.Map as Map(empty)@@ -17,9 +15,9 @@ import qualified Polysemy as Sem import qualified Polysemy.State as Sem import Prelude hiding (putStrLn)-app (FileCommand fileCommand) = (case fileCommand of {(ConvertFile filePath) -> (void (convertFileInPlace filePath));(FormatFile filePath) -> (formatFileInPlace filePath);(RunFile filePath) -> (void (Sem.evalState Map.empty (withGhci (transpileFileInPlace filePath))))})-app (ProjectCommand projectCommand) = (case projectCommand of {ConvertProject -> convertProject;FormatProject -> formatProject;RunProject -> ((>>) buildProject runProject)})+app :: () => (((->) Command) (Sem.Sem AppEffs ()))+app (FileCommand fileCommand) = (case fileCommand of {(ConvertFile filePath) -> (void (convertFileInPlace filePath));(FormatFile filePath) -> (formatFileInPlace filePath);(RunFile filePath) -> (void (Sem.evalState Map.empty (withStackGhci (transpileFileInPlace filePath))))})+app (ProjectCommand projectCommand) = (case projectCommand of {(ConvertProject ) -> convertProject;(FormatProject ) -> formatProject;(RunProject ) -> ((>>) buildProject runProject)}) app (Version ) = (putStrLn ((<>) "Axel version " axelStackageVersion))-app :: (((->) Command) (Sem.Sem AppEffs ()))+main :: () => (IO ()) main  = ((>>=) (execParser commandParserInfo) (\modeCommand -> (runApp (app modeCommand))))-main :: (IO ())
axel.cabal view
@@ -4,10 +4,10 @@ -- -- see: https://github.com/sol/hpack ----- hash: 3e7daf9876df4b7735920d7b3ecbfb5174adfc24b9d4245f3d0cbfbc17b2ee59+-- hash: 99fb260a0ae2149443c78e919a5b97d138da340591cfc306a8345e114b4ae538  name:           axel-version:        0.0.11+version:        0.0.12 synopsis:       The Axel programming language. description:    Haskell's semantics, plus Lisp's macros. Meet Axel – a purely functional, extensible, and powerful programming language. category:       Language, Lisp, Macros, Transpiler@@ -21,7 +21,6 @@ build-type:     Simple extra-source-files:     README.org-    scripts/build.sh     scripts/clean.sh     scripts/depDocs.sh     scripts/format.sh@@ -85,7 +84,6 @@       Axel.Utils.Display       Axel.Utils.FilePath       Axel.Utils.Foldable-      Axel.Utils.Function       Axel.Utils.Json       Axel.Utils.List       Axel.Utils.Maybe@@ -110,6 +108,7 @@     , bytestring     , containers     , directory+    , extra     , filepath     , freer-simple     , ghcid@@ -128,7 +127,6 @@     , process     , profunctors     , random-    , singletons     , split     , tasty     , tasty-discover@@ -165,6 +163,7 @@     , bytestring     , containers     , directory+    , extra     , filepath     , freer-simple     , ghcid@@ -183,7 +182,6 @@     , process     , profunctors     , random-    , singletons     , split     , tasty     , tasty-discover@@ -243,6 +241,7 @@     , bytestring     , containers     , directory+    , extra     , filepath     , freer-simple     , ghcid@@ -261,7 +260,6 @@     , process     , profunctors     , random-    , singletons     , split     , tasty     , tasty-discover
− scripts/build.sh
@@ -1,12 +0,0 @@-set -eu-set -o pipefail--echo "[WIP] Transpile *.axel files..."-# If we run this in the context of the current project, Cabal will try to globally symlink the local package (which is not what we want).-cd ~-cabal new-install axel --overwrite-policy=always-cd --axel-exe project-echo "[WIP] *.axel files transpiled!\n"--stack build --ghc-options "-g"
src/Axel.hs view
@@ -3,35 +3,37 @@ import qualified Prelude as GHCPrelude import qualified Axel.Parse.AST as AST import Axel.Prelude-import qualified Axel.Parse.AST as AST+import Axel.Parse(hygenisizeIdentifier) import qualified Axel.Sourcemap as SM import Axel.Utils.FilePath(takeFileName) import Data.IORef(IORef,modifyIORef,newIORef,readIORef) import qualified Data.Text as T import System.IO.Unsafe(unsafePerformIO)-import Control.Lens.Cons(snoc)-expandDo' ((:) (AST.SExpression _ [(AST.Symbol _ "<-"),var,val]) rest) = (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 45 8))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/8056614292560291696/result.axel" (SM.Position 1 157))) ">>=")],[val],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 45 18))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/8056614292560291696/result.axel" (SM.Position 1 255))) "\\")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 45 21))) (concat [[var]]))],[(expandDo' rest)]]))]]))-expandDo' ((:) (AST.SExpression _ ((:) (AST.Symbol _ "let") bindings)) rest) = (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 47 8))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/8056614292560291696/result.axel" (SM.Position 2 161))) "let")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 47 13))) (concat [(AST.toExpressionList bindings)]))],[(expandDo' rest)]]))-expandDo' ((:) val rest) = (case rest of {[] -> val;_ -> (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 51 13))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/8056614292560291696/result.axel" (SM.Position 3 138))) ">>")],[val],[(expandDo' rest)]]))})-expandDo' :: ((->) ([] SM.Expression) SM.Expression)+aXEL_SYMBOL_IF_ :: () => ((->) Bool ((->) a ((->) a a)))+aXEL_SYMBOL_IF_ True x _ = x+aXEL_SYMBOL_IF_ False _ x = x+expandDo :: () => ((->) ([] SM.Expression) SM.Expression)+expandDo ((:) (AST.SExpression _ [(AST.Symbol _ "<-"),var,val]) rest) = (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 45 8))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/4333779294880851293/result.axel" (SM.Position 2 156))) ">>=")],[val],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 45 18))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/4333779294880851293/result.axel" (SM.Position 2 254))) "\\")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 45 21))) (concat [[var]]))],[(expandDo rest)]]))]]))+expandDo ((:) (AST.SExpression _ ((:) (AST.Symbol _ "aXEL_SYMBOL_LET_") bindings)) rest) = (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 47 8))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/4333779294880851293/result.axel" (SM.Position 3 173))) "aXEL_SYMBOL_LET_")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 47 13))) (concat [(AST.toExpressionList bindings)]))],[(expandDo rest)]]))+expandDo ((:) val rest) = (case rest of {[] -> val;_ -> (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 51 13))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/4333779294880851293/result.axel" (SM.Position 4 137))) ">>")],[val],[(expandDo rest)]]))})+gensymCounter :: () => (IORef Int) gensymCounter  = (unsafePerformIO (newIORef 0))-gensymCounter :: (IORef Int) {-# NOINLINE gensymCounter #-}+gensym :: () => (IO SM.Expression) gensym  = ((>>=) (readIORef gensymCounter) (\suffix -> (let {identifier = ((<>) "aXEL_AUTOGENERATED_IDENTIFIER_" (showText suffix))} in ((>>) (modifyIORef gensymCounter succ) (pure (AST.Symbol Nothing (T.unpack identifier)))))))-gensym :: (IO SM.Expression)+isPrelude :: () => ((->) FilePath Bool) isPrelude  = ((.) ((==) (FilePath "Axel.axel")) takeFileName)-isPrelude :: ((->) FilePath Bool)-preludeMacros  = ["applyInfix","defmacro","def","do'","\\case","syntaxQuote"]-preludeMacros :: ([] Text)-applyInfix_AXEL_AUTOGENERATED_MACRO_DEFINITION [x,op,y] = (pure [(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 19 17))) (concat [[op],[x],[y]]))])-defmacro_AXEL_AUTOGENERATED_MACRO_DEFINITION ((:) name cases) = (pure (map (\(AST.SExpression _ ((:) args body)) -> (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 24 55))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 28 17))) "=macro")],[name],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 24 69))) (concat [[args]]))],(AST.toExpressionList body)]))) cases))-def_AXEL_AUTOGENERATED_MACRO_DEFINITION ((:) name ((:) typeSig cases)) = (pure (snoc (map (\x -> (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 32 32))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/3023196837319215740/result.axel" (SM.Position 1 152))) "=")],[name],(AST.toExpressionList x)]))) cases) (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 34 20))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/3023196837319215740/result.axel" (SM.Position 1 284))) "::")],[name],[typeSig]]))))+preludeMacros :: () => ([] Text)+preludeMacros  = (map ((.) T.pack hygenisizeIdentifier) ["applyInfix","defmacro","def","do","\\case","syntaxQuote"])+applyInfix_AXEL_AUTOGENERATED_MACRO_DEFINITION [x,op,y] = (pure [(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 17 17))) (concat [[op],[x],[y]]))])+defmacro_AXEL_AUTOGENERATED_MACRO_DEFINITION ((:) name cases) = (pure (map (\(AST.SExpression _ ((:) args body)) -> (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 22 55))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 22 56))) "aXEL_VALUE_aXEL_SYMBOL_EQUALS_macro")],[name],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 22 69))) (concat [[args]]))],(AST.toExpressionList body)]))) cases))+def_AXEL_AUTOGENERATED_MACRO_DEFINITION ((:) name ((:) typeSig cases)) = (pure ((:) (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 28 17))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/6581439545403261561/result.axel" (SM.Position 1 166))) "::")],[name],(AST.toExpressionList typeSig)])) (map (\(AST.SExpression _ ((:) args xs)) -> (AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 29 59))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/6581439545403261561/result.axel" (SM.Position 1 339))) "=")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 29 62))) (concat [[name],(AST.toExpressionList args)]))],(AST.toExpressionList xs)]))) cases))) syntaxQuote_AXEL_AUTOGENERATED_MACRO_DEFINITION [x] = (pure [(AST.quoteExpression (const (AST.Symbol Nothing "_")) x)])-do'_AXEL_AUTOGENERATED_MACRO_DEFINITION input = (pure [(expandDo' input)])-aXEL_SYMBOL_BACKSLASH_case_AXEL_AUTOGENERATED_MACRO_DEFINITION cases = (fmap (\varId -> [(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 70 15))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/8873645910751190435/result.axel" (SM.Position 1 127))) "\\")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 70 18))) (concat [[varId]]))],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 70 27))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/8873645910751190435/result.axel" (SM.Position 1 314))) "case")],[varId],(AST.toExpressionList cases)]))]]))]) gensym)-applyInfix_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]-defmacro_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]-def_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]-syntaxQuote_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]-do'_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]-aXEL_SYMBOL_BACKSLASH_case_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]+aXEL_SYMBOL_DO__AXEL_AUTOGENERATED_MACRO_DEFINITION input = (pure [(expandDo input)])+aXEL_VALUE_aXEL_SYMBOL_BACKSLASH_case_AXEL_AUTOGENERATED_MACRO_DEFINITION cases = (fmap (\varId -> [(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 70 15))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/1949692869127002033/result.axel" (SM.Position 1 188))) "\\")],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 70 18))) (concat [[varId]]))],[(AST.SExpression (GHCPrelude.Just ((,) "src/Axel.axel" (SM.Position 70 27))) (concat [[(AST.Symbol (GHCPrelude.Just ((,) "axelTemp/1949692869127002033/result.axel" (SM.Position 1 375))) "case")],[varId],(AST.toExpressionList cases)]))]]))]) gensym)+applyInfix_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]+defmacro_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]+def_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]+syntaxQuote_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]+aXEL_SYMBOL_DO__AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]+aXEL_VALUE_aXEL_SYMBOL_BACKSLASH_case_AXEL_AUTOGENERATED_MACRO_DEFINITION :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]
src/Axel/AST.hs view
@@ -10,9 +10,6 @@ import Axel.Haskell.Language (isOperator) import Axel.Haskell.Macros (hygenisizeMacroName) import qualified Axel.Parse.AST as Parse-  ( Expression(LiteralChar, LiteralInt, LiteralString, SExpression,-           Symbol)-  ) import Axel.Sourcemap   ( Bracket(CurlyBraces, DoubleQuotes, Parentheses, SingleQuotes,         SquareBrackets)@@ -61,15 +58,6 @@     }   deriving (Data, Eq, Functor, Show) -data IfBlock ann =-  IfBlock-    { _ann :: ann-    , _cond :: Expression ann-    , _ifTrue :: Expression ann-    , _ifFalse :: Expression ann-    }-  deriving (Data, Eq, Functor, Show)- data TopLevel ann =   TopLevel     { _ann :: ann@@ -86,7 +74,7 @@   DataDeclaration     { _ann :: ann     , _typeDefinition :: TypeDefinition ann-    , _constructors :: [FunctionApplication ann]+    , _constructors :: [Expression ann]     }   deriving (Data, Eq, Functor, Show) @@ -94,7 +82,7 @@   NewtypeDeclaration     { _ann :: ann     , _typeDefinition :: TypeDefinition ann-    , _constructor :: FunctionApplication ann+    , _wrappedType :: Expression ann     }   deriving (Data, Eq, Functor, Show) @@ -104,7 +92,7 @@     , _name :: Identifier     , _arguments :: [Expression ann]     , _body :: Expression ann-    , _whereBindings :: [FunctionDefinition ann]+    , _whereBindings :: [Statement ann]     }   deriving (Data, Eq, Functor, Show) @@ -200,6 +188,7 @@   TypeclassInstance     { _ann :: ann     , _instanceName :: Expression ann+    , _constraints :: [Expression ann]     , _definitions :: [FunctionDefinition ann]     }   deriving (Data, Eq, Functor, Show)@@ -208,6 +197,7 @@   TypeSignature     { _ann :: ann     , _name :: Identifier+    , _constraints :: [Expression ann]     , _typeDefinition :: Expression ann     }   deriving (Data, Eq, Functor, Show)@@ -220,12 +210,18 @@     }   deriving (Data, Eq, Functor, Show) +data Literal ann+  = LChar ann Char+  | LFloat ann Float+  | LInt ann Int+  | LString ann Text+  deriving (Data, Eq, Functor, Show)+ data Expression ann   = ECaseBlock (CaseBlock ann)   | EEmptySExpression ann   | EFunctionApplication (FunctionApplication ann)   | EIdentifier ann Identifier-  | EIfBlock (IfBlock ann)   | ELambda (Lambda ann)   | ELetBlock (LetBlock ann)   | ELiteral (Literal ann)@@ -234,12 +230,6 @@   | ERecordType (RecordType ann)   deriving (Data, Eq, Functor, Show) -data Literal ann-  = LChar ann Char-  | LInt ann Int-  | LString ann Text-  deriving (Data, Eq, Functor, Show)- data Statement ann   = STopLevel (TopLevel ann)   | SDataDeclaration (DataDeclaration ann)@@ -260,6 +250,8 @@  type Program ann = [Statement ann] +makePrisms ''Expression+ makePrisms ''Statement  makeFieldsNoPrefix ''CaseBlock@@ -276,8 +268,6 @@  makeFieldsNoPrefix ''LetBlock -makeFieldsNoPrefix ''IfBlock- makeFieldsNoPrefix ''MacroDefinition  makeFieldsNoPrefix ''MacroImport@@ -323,7 +313,6 @@   getAnn (EEmptySExpression ann') = ann'   getAnn (EFunctionApplication fnApp) = fnApp ^. ann   getAnn (EIdentifier ann' _) = ann'-  getAnn (EIfBlock ifBlock) = ifBlock ^. ann   getAnn (ELambda lambda) = lambda ^. ann   getAnn (ELetBlock letBlock) = letBlock ^. ann   getAnn (ELiteral literal) = getAnn literal@@ -351,15 +340,12 @@  instance {-# OVERLAPPING #-} HasAnnotation (Parse.Expression ann) ann where   getAnn :: Parse.Expression ann -> ann-  getAnn (Parse.LiteralChar ann' _) = ann'-  getAnn (Parse.LiteralInt ann' _) = ann'-  getAnn (Parse.LiteralString ann' _) = ann'-  getAnn (Parse.SExpression ann' _) = ann'-  getAnn (Parse.Symbol ann' _) = ann'+  getAnn = Parse.getAnn  instance {-# OVERLAPPING #-} HasAnnotation (Literal ann) ann where   getAnn :: Literal ann -> ann   getAnn (LChar ann' _) = ann'+  getAnn (LFloat ann' _) = ann'   getAnn (LInt ann' _) = ann'   getAnn (LString ann' _) = ann' @@ -437,6 +423,7 @@   toHaskell literal@(LChar _ x) =     mkHaskell literal $     Display.surround SingleQuotes (handleCharEscapes (T.singleton x))+  toHaskell literal@(LFloat _ x) = mkHaskell literal $ showText x   toHaskell literal@(LInt _ x) = mkHaskell literal $ showText x   toHaskell literal@(LString _ x) =     mkHaskell literal $ Display.surround DoubleQuotes (handleCharEscapes x)@@ -446,6 +433,8 @@   toHaskell typeSignature =     toHaskell (EIdentifier (typeSignature ^. ann) (typeSignature ^. name)) <>     mkHaskell typeSignature " :: " <>+    constraintsToHaskell (typeSignature ^. constraints) <>+    mkHaskell typeSignature " => " <>     toHaskell (typeSignature ^. typeDefinition)  instance ToHaskell (FunctionDefinition (Maybe SM.Expression)) where@@ -472,8 +461,13 @@     mkHaskell dataDeclaration " = " <>     SM.delimit       Pipes-      (map (removeSurroundingParentheses . toHaskell) $ dataDeclaration ^.+      (map (tryRemoveSurroundingParentheses . toHaskell) $ dataDeclaration ^.        constructors)+    where+      tryRemoveSurroundingParentheses xs =+        if "(" `T.isPrefixOf` (xs ^. _Wrapped . _head . unannotated)+          then removeSurroundingParentheses xs+          else xs  removeSurroundingParentheses :: SM.Output -> SM.Output removeSurroundingParentheses = removeOpen . removeClosed@@ -481,22 +475,19 @@     removeOpen = _Wrapped . _head . unannotated %~ T.tail     removeClosed = _Wrapped . _last . unannotated %~ T.init -instance ToHaskell (IfBlock (Maybe SM.Expression)) where-  toHaskell :: IfBlock (Maybe SM.Expression) -> SM.Output-  toHaskell ifBlock =-    mkHaskell ifBlock "if " <> toHaskell (ifBlock ^. cond) <>-    mkHaskell ifBlock " then " <>-    toHaskell (ifBlock ^. ifTrue) <>-    mkHaskell ifBlock " else " <>-    toHaskell (ifBlock ^. ifFalse)- instance ToHaskell (NewtypeDeclaration (Maybe SM.Expression)) where   toHaskell :: NewtypeDeclaration (Maybe SM.Expression) -> SM.Output   toHaskell newtypeDeclaration =     mkHaskell newtypeDeclaration "newtype " <>     toHaskell (newtypeDeclaration ^. typeDefinition) <>     mkHaskell newtypeDeclaration " = " <>-    removeSurroundingParentheses (toHaskell (newtypeDeclaration ^. constructor))+    constructor <>+    toHaskell (newtypeDeclaration ^. wrappedType)+    where+      constructor =+        case newtypeDeclaration ^. typeDefinition of+          ProperType _ x -> mkHaskell newtypeDeclaration x+          TypeConstructor _ (FunctionApplication _ fn _) -> toHaskell fn  instance ToHaskell (Lambda (Maybe SM.Expression)) where   toHaskell :: Lambda (Maybe SM.Expression) -> SM.Output@@ -561,10 +552,9 @@   toHaskell (EFunctionApplication x) = toHaskell x   toHaskell expr'@(EIdentifier _ x) =     mkHaskell expr' $-    if isOperator x+    if isOperator $ T.unpack x       then Display.surround Parentheses x       else x-  toHaskell (EIfBlock x) = toHaskell x   toHaskell (ELambda x) = toHaskell x   toHaskell (ELetBlock x) = toHaskell x   toHaskell (ELiteral x) = toHaskell x@@ -593,7 +583,7 @@   toHaskell :: Import (Maybe SM.Expression) -> SM.Output   toHaskell import'@(ImportItem _ x) =     mkHaskell import' $-    if isOperator x+    if isOperator $ T.unpack x       then Display.surround Parentheses x       else x   toHaskell import'@(ImportType _ typeName imports') =@@ -611,13 +601,15 @@   toHaskell topLevel =     SM.delimit Newlines $ map toHaskell (topLevel ^. statements) +constraintsToHaskell :: [SMExpression] -> SM.Output+constraintsToHaskell =+  SM.surround Parentheses . SM.delimit Commas . map toHaskell+ instance ToHaskell (TypeclassDefinition (Maybe SM.Expression)) where   toHaskell :: TypeclassDefinition (Maybe SM.Expression) -> SM.Output   toHaskell typeclassDefinition =     mkHaskell typeclassDefinition "class " <>-    SM.surround-      Parentheses-      (SM.delimit Commas (map toHaskell (typeclassDefinition ^. constraints))) <>+    constraintsToHaskell (typeclassDefinition ^. constraints) <>     mkHaskell typeclassDefinition " => " <>     toHaskell (typeclassDefinition ^. name) <>     mkHaskell typeclassDefinition " where " <>@@ -627,6 +619,8 @@   toHaskell :: TypeclassInstance (Maybe SM.Expression) -> SM.Output   toHaskell typeclassInstance =     mkHaskell typeclassInstance "instance " <>+    constraintsToHaskell (typeclassInstance ^. constraints) <>+    mkHaskell typeclassInstance " => " <>     toHaskell (typeclassInstance ^. instanceName) <>     mkHaskell typeclassInstance " where " <>     SM.renderBlock (map toHaskell $ typeclassInstance ^. definitions)
src/Axel/Denormalize.hs view
@@ -4,11 +4,11 @@  import Axel.AST   ( Expression(ECaseBlock, EEmptySExpression, EFunctionApplication,-           EIdentifier, EIfBlock, ELambda, ELetBlock, ELiteral,-           ERawExpression, ERecordDefinition, ERecordType)+           EIdentifier, ELambda, ELetBlock, ELiteral, ERawExpression,+           ERecordDefinition, ERecordType)   , Import(ImportItem, ImportType)   , ImportSpecification(ImportAll, ImportOnly)-  , Literal(LChar, LInt, LString)+  , Literal(LChar, LFloat, LInt, LString)   , SMExpression   , SMStatement   , Statement(SDataDeclaration, SFunctionDefinition, SMacroDefinition,@@ -22,9 +22,7 @@   , arguments   , bindings   , body-  , cond   , constraints-  , constructor   , constructors   , definition   , definitions@@ -33,8 +31,6 @@   , function   , functionDefinition   , getAnn'-  , ifFalse-  , ifTrue   , imports   , instanceName   , matches@@ -44,12 +40,10 @@   , signatures   , typeDefinition   , whereBindings+  , wrappedType   ) import qualified Axel.Parse.AST as Parse-  ( Expression(LiteralChar, LiteralInt, LiteralString, SExpression,-           Symbol)-  )-import qualified Axel.Sourcemap as SM (Expression)+import qualified Axel.Sourcemap as SM  import Control.Lens.Operators ((^.)) @@ -79,15 +73,6 @@   map denormalizeExpression (functionApplication ^. arguments) denormalizeExpression expr'@(EIdentifier _ x) =   Parse.Symbol (getAnn' expr') (T.unpack x)-denormalizeExpression (EIfBlock ifBlock) =-  let ann' = getAnn' ifBlock-   in Parse.SExpression-        ann'-        [ Parse.Symbol ann' "if"-        , denormalizeExpression (ifBlock ^. cond)-        , denormalizeExpression (ifBlock ^. ifTrue)-        , denormalizeExpression (ifBlock ^. ifFalse)-        ] denormalizeExpression (ELambda lambda) =   let ann' = getAnn' lambda       denormalizedArguments =@@ -117,6 +102,7 @@ denormalizeExpression (ELiteral x) =   case x of     LChar _ char -> Parse.LiteralChar (getAnn' x) char+    LFloat _ float -> Parse.LiteralFloat (getAnn' x) float     LInt _ int -> Parse.LiteralInt (getAnn' x) int     LString _ string -> Parse.LiteralString (getAnn' x) (T.unpack string) denormalizeExpression expr'@(ERawExpression _ rawSource) =@@ -177,16 +163,16 @@    in Parse.SExpression         ann'         (Parse.Symbol ann' "data" : denormalizedTypeDefinition :-         map-           (denormalizeExpression . EFunctionApplication)-           (dataDeclaration ^. constructors))+         map denormalizeExpression (dataDeclaration ^. constructors)) denormalizeStatement (SFunctionDefinition fnDef) =   let ann' = getAnn' fnDef    in Parse.SExpression ann' $ Parse.Symbol ann' "=" :-      Parse.Symbol ann' (T.unpack $ fnDef ^. name) :-      Parse.SExpression ann' (map denormalizeExpression (fnDef ^. arguments)) :+      Parse.SExpression+        ann'+        (Parse.Symbol ann' (T.unpack $ fnDef ^. name) :+         map denormalizeExpression (fnDef ^. arguments)) :       denormalizeExpression (fnDef ^. body) :-      map (denormalizeStatement . SFunctionDefinition) (fnDef ^. whereBindings)+      map denormalizeStatement (fnDef ^. whereBindings) denormalizeStatement (SMacroDefinition macroDef) =   let ann' = getAnn' macroDef    in Parse.SExpression ann' $ Parse.Symbol ann' "=macro" :@@ -195,9 +181,7 @@         ann'         (map denormalizeExpression (macroDef ^. functionDefinition . arguments)) :       denormalizeExpression (macroDef ^. functionDefinition . body) :-      map-        (denormalizeStatement . SFunctionDefinition)-        (macroDef ^. functionDefinition . whereBindings)+      map denormalizeStatement (macroDef ^. functionDefinition . whereBindings) denormalizeStatement (SMacroImport macroImport) =   let ann' = getAnn' macroImport    in Parse.SExpression@@ -226,8 +210,7 @@         ann'         [ Parse.Symbol ann' "newtype"         , denormalizedTypeDefinition-        , denormalizeExpression $-          EFunctionApplication (newtypeDeclaration ^. constructor)+        , denormalizeExpression $ newtypeDeclaration ^. wrappedType         ] denormalizeStatement (SPragma pragma) =   let ann' = getAnn' pragma@@ -269,8 +252,7 @@         (Parse.Symbol ann' "class" :          Parse.SExpression            ann'-           (Parse.Symbol ann' "list" :-            map denormalizeExpression (typeclassDefinition ^. constraints)) :+           (map denormalizeExpression (typeclassDefinition ^. constraints)) :          denormalizeExpression (typeclassDefinition ^. name) :          map            (denormalizeStatement . STypeSignature)@@ -280,6 +262,9 @@    in Parse.SExpression         ann'         (Parse.Symbol ann' "instance" :+         Parse.SExpression+           ann'+           (map denormalizeExpression (typeclassInstance ^. constraints)) :          denormalizeExpression (typeclassInstance ^. instanceName) :          map            (denormalizeStatement . SFunctionDefinition)@@ -290,6 +275,9 @@         ann'         [ Parse.Symbol ann' "::"         , Parse.Symbol ann' (T.unpack $ typeSig ^. name)+        , Parse.SExpression+            ann'+            (map denormalizeExpression (typeSig ^. constraints))         , denormalizeExpression (typeSig ^. typeDefinition)         ] denormalizeStatement (STypeSynonym typeSynonym) =
src/Axel/Eff/App.hs view
@@ -5,7 +5,7 @@ import Axel.Eff.Console (Console, runConsole) import Axel.Eff.Error (Error, renderError, unsafeRunError) import Axel.Eff.FileSystem (FileSystem, runFileSystem)-import Axel.Eff.Ghci (Ghci, runGhci)+import Axel.Eff.Ghci (Ghci, runStackGhci) import Axel.Eff.Log (Log, runLogAsFileSystem) import Axel.Eff.Process (Process, runProcess) import Axel.Eff.Random (Random, runRandom)@@ -25,7 +25,7 @@   runRandom .   runResource .   runProcess .-  runGhci .+  runStackGhci .   runFileSystem .   unsafeRunError renderError .   runConsole . runLogAsFileSystem (FilePath "axelCompilation.log")
src/Axel/Eff/Error.hs view
@@ -47,6 +47,7 @@ renderError (ParseError filePath err) = mkFileErrorMsg filePath err renderError (ProjectError err) = err +-- | This should ONLY be used for truly impossible situations. fatal :: Text -> Text -> a fatal context message = error $ "[FATAL] " <> context <> " - " <> message 
src/Axel/Eff/Ghci.hs view
@@ -24,11 +24,11 @@  Sem.makeSem ''Ghci -runGhci ::+runStackGhci ::      (Sem.Member (Sem.Embed IO) effs)   => Sem.Sem (Ghci ': effs) a   -> Sem.Sem effs a-runGhci =+runStackGhci =   Sem.interpret $ \case     Exec ghci command ->       Sem.embed $ map T.pack <$> Ghci.exec ghci (T.unpack command)@@ -51,11 +51,11 @@ enableJsonErrors :: (Sem.Member Ghci effs) => Ghci.Ghci -> Sem.Sem effs () enableJsonErrors ghci = void $ exec ghci ":set -ddump-json" -withGhci ::+withStackGhci ::      (Sem.Member Ghci effs)   => Sem.Sem (Sem.Reader Ghci.Ghci ': effs) a   -> Sem.Sem effs a-withGhci x = do+withStackGhci x = do   ghci <- start   enableJsonErrors ghci   result <- Sem.runReader ghci x
src/Axel/Eff/Process.hs view
@@ -1,61 +1,31 @@-{-# LANGUAGE AllowAmbiguousTypes #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE TypeFamilies #-}  module Axel.Eff.Process where  import Axel.Prelude -import qualified Axel.Utils.Text as T (decodeUtf8Lazy, encodeUtf8Lazy)--import qualified Polysemy as Sem+import Control.Monad ((>=>)) -import Data.Kind (Type)-import Data.Singletons (Sing, SingI, sing)-import Data.Singletons.TH (singletons) import qualified Data.Text as T +import qualified Polysemy as Sem+ import qualified System.Environment (getArgs) import System.Exit (ExitCode)-import qualified System.Process.Typed as P-  ( byteStringInput-  , readProcess-  , runProcess-  , setStdin-  , shell-  )--$(singletons-    [d|-  -  data StreamSpecification = CreateStreams-                           | InheritStreams-  |])--type family StreamsHandler (a :: StreamSpecification) (f :: Type -> Type) :: Type--type instance StreamsHandler 'CreateStreams f =-     Text -> f (ExitCode, Text, Text)--type instance StreamsHandler 'InheritStreams f = f ExitCode--type ProcessRunner' (streamSpec :: StreamSpecification) f-   = forall streamsHandler. (streamsHandler ~ StreamsHandler streamSpec f) =>-                              streamsHandler--type ProcessRunnerPrimitive (streamSpec :: StreamSpecification) (f :: Type -> Type)-   = FilePath -> [Text] -> ProcessRunner' streamSpec f--type ProcessRunner (streamSpec :: StreamSpecification) (f :: Type -> Type)-   = (SingI streamSpec) =>-       ProcessRunner' streamSpec f+import System.IO (Handle, hGetContents, hGetLine, hIsEOF)+import qualified System.Process as P  data Process m a where+  CreateIndependentProcess+    :: Text -> Process m (Handle, Handle, Handle, P.ProcessHandle)+  CreatePassthroughProcess :: Text -> Process m P.ProcessHandle   GetArgs :: Process m [Text]-  RunProcessCreatingStreams :: Text -> Text -> Process m (ExitCode, Text, Text)-  RunProcessInheritingStreams :: Text -> Process m ExitCode+  HandleGetContents :: Handle -> Process m Text+  HandleGetLine :: Handle -> Process m Text+  HandleIsAtEnd :: Handle -> Process m Bool+  WaitOnProcess :: P.ProcessHandle -> Process m ExitCode  Sem.makeSem ''Process @@ -65,21 +35,37 @@   -> Sem.Sem effs a runProcess =   Sem.interpret $ \case-    GetArgs -> Sem.embed $ map T.pack <$> System.Environment.getArgs-    RunProcessCreatingStreams cmd stdin ->+    CreateIndependentProcess cmd ->       Sem.embed $ do-        let stdinStream = P.byteStringInput (T.encodeUtf8Lazy stdin)-        let config = P.setStdin stdinStream $ P.shell (T.unpack cmd)-        (exitCode, stdout, stderr) <- P.readProcess config-        pure (exitCode, T.decodeUtf8Lazy stdout, T.decodeUtf8Lazy stderr)-    RunProcessInheritingStreams cmd ->-      Sem.embed $ P.runProcess (P.shell $ T.unpack cmd)+        let config =+              (P.shell (T.unpack cmd))+                { P.std_in = P.CreatePipe+                , P.std_out = P.CreatePipe+                , P.std_err = P.CreatePipe+                }+        -- The handles will always be created because of `CreatePipe`, so we can safely unwrap them.+        (Just stdinHandle, Just stdoutHandle, Just stderrHandle, processHandle) <-+          P.createProcess config+        pure (stdinHandle, stdoutHandle, stderrHandle, processHandle)+    CreatePassthroughProcess cmd ->+      Sem.embed $ do+        let config = P.shell (T.unpack cmd)+        (_, _, _, processHandle) <- P.createProcess config+        pure processHandle+    GetArgs -> Sem.embed $ map T.pack <$> System.Environment.getArgs+    HandleGetContents handle -> Sem.embed $ T.pack <$> hGetContents handle+    HandleGetLine handle -> Sem.embed $ T.pack <$> hGetLine handle+    HandleIsAtEnd handle -> Sem.embed $ hIsEOF handle+    WaitOnProcess processHandle -> Sem.embed $ P.waitForProcess processHandle -execProcess ::-     forall (streamSpec :: StreamSpecification) effs. (Sem.Member Process effs)-  => Text-  -> ProcessRunner streamSpec (Sem.Sem effs)-execProcess cmd =-  case sing :: Sing streamSpec of-    SCreateStreams -> runProcessCreatingStreams cmd-    SInheritStreams -> runProcessInheritingStreams cmd+readProcess ::+     (Sem.Member Process effs) => Text -> Sem.Sem effs (ExitCode, Text, Text)+readProcess cmd = do+  (_, stdoutHandle, stderrHandle, processHandle) <- createIndependentProcess cmd+  exitCode <- waitOnProcess processHandle+  stdout <- handleGetContents stdoutHandle+  stderr <- handleGetContents stderrHandle+  pure (exitCode, stdout, stderr)++passthroughProcess :: (Sem.Member Process effs) => Text -> Sem.Sem effs ExitCode+passthroughProcess = createPassthroughProcess >=> waitOnProcess
src/Axel/Haskell/Convert.hs view
@@ -17,15 +17,16 @@ import qualified Axel.Parse.AST as Parse import Axel.Pretty (prettifyProgram) import qualified Axel.Sourcemap as SM-import Axel.Utils.List (removeOut, stablyGroupAllWith, unsafeHead)+import Axel.Utils.List (removeOut, stablyGroupAllWith) import Axel.Utils.Tuple (flattenAnnotations, unannotated)  import Control.Category ((>>>))-import Control.Lens ((<|), op)+import Control.Lens (op) import Control.Lens.Extras (is) import Control.Lens.Operators ((%~), (^.))  import Data.Data.Lens (biplate, uniplate)+import Data.Maybe (fromMaybe) import qualified Data.Text as T  import qualified Polysemy as Sem@@ -60,536 +61,6 @@   let AST.EIdentifier _ sym = toExpr x    in sym -instance ToExpr HSE.Name where-  toExpr (HSE.Ident _ name) = AST.EIdentifier Nothing $ T.pack name-  toExpr (HSE.Symbol _ name) = AST.EIdentifier Nothing $ T.pack name--instance ToExpr HSE.ModuleName where-  toExpr (HSE.ModuleName _ name) = AST.EIdentifier Nothing $ T.pack name--instance ToExpr HSE.CName where-  toExpr (HSE.VarName _ name) = toExpr name-  toExpr (HSE.ConName _ name) = toExpr name--instance ToExpr HSE.SpecialCon where-  toExpr HSE.UnitCon {} = AST.EIdentifier Nothing "Unit"-  toExpr HSE.ListCon {} = AST.EIdentifier Nothing "List"-  toExpr HSE.FunCon {} = AST.EIdentifier Nothing "->"-  toExpr (HSE.TupleCon _ _ arity) =-    AST.EIdentifier Nothing $ T.replicate arity ","-  toExpr HSE.Cons {} = AST.EIdentifier Nothing ":"-  toExpr expr@HSE.UnboxedSingleCon {} = unsupportedExpr expr-  toExpr HSE.ExprHole {} = AST.EIdentifier Nothing "_"--instance ToExpr HSE.QName where-  toExpr (HSE.Qual _ moduleName name) =-    AST.EIdentifier Nothing $ toId moduleName <> "." <> toId name-  toExpr (HSE.UnQual _ name) = toExpr name-  toExpr (HSE.Special _ specialCon) = toExpr specialCon--instance ToExpr HSE.TyVarBind where-  toExpr (HSE.UnkindedVar _ name) = toExpr name-  toExpr expr@HSE.KindedVar {} = unsupportedExpr expr--instance ToExpr HSE.MaybePromotedName where-  toExpr expr@HSE.PromotedName {} = unsupportedExpr expr-  toExpr (HSE.UnpromotedName _ name) = toExpr name--instance ToExpr HSE.Promoted where-  toExpr expr@HSE.PromotedInteger {} = unsupportedExpr expr-  toExpr expr@HSE.PromotedString {} = unsupportedExpr expr-  toExpr (HSE.PromotedCon _ _ con) = AST.EIdentifier Nothing $ '\'' <| toId con-  toExpr expr@HSE.PromotedList {} = unsupportedExpr expr-  toExpr expr@HSE.PromotedTuple {} = unsupportedExpr expr-  toExpr expr@HSE.PromotedUnit {} = unsupportedExpr expr--instance ToExpr HSE.Type where-  toExpr expr@HSE.TyForall {} = unsupportedExpr expr-  toExpr (HSE.TyFun _ tyA tyB) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing "->")-      [toExpr tyA, toExpr tyB]-  toExpr (HSE.TyTuple _ _ tys) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing ",")-      (map toExpr tys)-  toExpr expr@HSE.TyUnboxedSum {} = unsupportedExpr expr-  toExpr (HSE.TyList _ ty) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (AST.EIdentifier Nothing "[]") [toExpr ty]-  toExpr expr@HSE.TyParArray {} = unsupportedExpr expr-  toExpr (HSE.TyApp _ tyA tyB) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr tyA) [toExpr tyB]-  toExpr (HSE.TyVar _ x) = toExpr x-  toExpr (HSE.TyCon _ x) = toExpr x-  toExpr (HSE.TyParen _ x) = toExpr x-  toExpr (HSE.TyInfix _ tyA mpn tyB) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr mpn) [toExpr tyA, toExpr tyB]-  toExpr expr@HSE.TyKind {} = unsupportedExpr expr-  toExpr (HSE.TyPromoted _ promoted) = toExpr promoted-  toExpr expr@HSE.TyEquals {} = unsupportedExpr expr-  toExpr expr@HSE.TySplice {} = unsupportedExpr expr-  toExpr expr@HSE.TyBang {} = unsupportedExpr expr-  toExpr (HSE.TyWildCard _ name) =-    AST.EIdentifier Nothing $ "_" <> maybe mempty toId name-  toExpr expr@HSE.TyQuasiQuote {} = unsupportedExpr expr--instance ToExpr HSE.ModuleHead where-  toExpr (HSE.ModuleHead _ name _ _) = toExpr name--instance ToStmts HSE.ModulePragma where-  toStmts (HSE.LanguagePragma _ pragmas) =-    map-      (\pragma -> AST.SPragma . AST.Pragma Nothing $ "LANGUAGE " <> toId pragma)-      pragmas-  toStmts stmt@HSE.OptionsPragma {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.AnnModulePragma {} = [unsupportedStmt stmt]--instance ToStmts HSE.ImportDecl where-  toStmts stmt@(HSE.ImportDecl _ _ _ _ _ _ _ (Just (HSE.ImportSpecList _ True _))) =-    [unsupportedStmt stmt]-  toStmts stmt@(HSE.ImportDecl _ moduleName isQualified _ _ _ alias spec) =-    [ let moduleId = toId moduleName-       in if isQualified-            then case alias of-                   Just aliasName ->-                     AST.SQualifiedImport $-                     AST.QualifiedImport-                       Nothing-                       moduleId-                       (toId aliasName)-                       (importSpecListToExpr spec)-                   Nothing -> unsupportedStmt stmt-            else case alias of-                   Nothing ->-                     let importSpec =-                           case importSpecListToExpr spec of-                             AST.ImportAll _ -> AST.ImportAll Nothing-                             AST.ImportOnly _ imports ->-                               AST.ImportOnly Nothing imports-                      in AST.SRestrictedImport $-                         AST.RestrictedImport Nothing moduleId importSpec-                   Just _ -> unsupportedStmt stmt-    ]-    where-      importSpecListToExpr Nothing = AST.ImportAll Nothing-      importSpecListToExpr (Just (HSE.ImportSpecList _ False importSpecs)) =-        AST.ImportOnly Nothing $-        map-          (\case-             HSE.IVar _ name -> AST.ImportItem Nothing (toId name)-             HSE.IAbs _ _ name -> AST.ImportItem Nothing (toId name)-             HSE.IThingAll _ name -> AST.ImportType Nothing (toId name) [".."]-             HSE.IThingWith _ name items ->-               AST.ImportType Nothing (toId name) (map toId items))-          importSpecs--instance ToStmts HSE.Module where-  toStmts (HSE.Module _ moduleHead pragmas imports decls) =-    concat-      [ concatMap toStmts pragmas-      , case moduleHead of-          Just moduleId -> [AST.SModuleDeclaration Nothing (toId moduleId)]-          Nothing -> []-      , concatMap toStmts imports-      , concatMap toStmts decls-      ]--instance ToExpr HSE.QualConDecl where-  toExpr (HSE.QualConDecl _ _ _ conDecl) =-    case conDecl of-      HSE.ConDecl _ name args ->-        AST.EFunctionApplication $-        AST.FunctionApplication-          Nothing-          (AST.EIdentifier Nothing $ toId name)-          (map toExpr args)-      HSE.InfixConDecl _ argA name argB ->-        AST.EFunctionApplication $-        AST.FunctionApplication-          Nothing-          (AST.EIdentifier Nothing $ toId name)-          [toExpr argA, toExpr argB]-      HSE.RecDecl {} -> unsupportedExpr conDecl--instance ToExpr HSE.Literal where-  toExpr (HSE.Char _ char _) = AST.ELiteral $ AST.LChar Nothing char-  toExpr (HSE.String _ string _) =-    AST.ELiteral $ AST.LString Nothing $ T.pack string-  toExpr (HSE.Int _ int _) = AST.ELiteral $ AST.LInt Nothing (fromInteger int)-  toExpr expr@HSE.Frac {} = unsupportedExpr expr-  toExpr expr@HSE.PrimInt {} = unsupportedExpr expr-  toExpr expr@HSE.PrimWord {} = unsupportedExpr expr-  toExpr expr@HSE.PrimFloat {} = unsupportedExpr expr-  toExpr expr@HSE.PrimDouble {} = unsupportedExpr expr-  toExpr expr@HSE.PrimChar {} = unsupportedExpr expr-  toExpr expr@HSE.PrimString {} = unsupportedExpr expr--instance ToExpr HSE.Pat where-  toExpr (HSE.PVar _ name) = toExpr name-  toExpr (HSE.PLit _ _ literal) = toExpr literal-  toExpr expr@HSE.PNPlusK {} = unsupportedExpr expr-  toExpr (HSE.PInfixApp _ patA name patB) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr name) [toExpr patA, toExpr patB]-  toExpr (HSE.PApp _ name pats) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr name) (map toExpr pats)-  toExpr (HSE.PTuple _ _ pats) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing ",")-      (map toExpr pats)-  toExpr expr@HSE.PUnboxedSum {} = unsupportedExpr expr-  toExpr (HSE.PList _ pats) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing "list")-      (map toExpr pats)-  toExpr (HSE.PParen _ pat) = toExpr pat-  toExpr expr@HSE.PRec {} = unsupportedExpr expr-  toExpr expr@HSE.PAsPat {} = unsupportedExpr expr-  toExpr HSE.PWildCard {} = AST.EIdentifier Nothing "_"-  toExpr expr@HSE.PIrrPat {} = unsupportedExpr expr-  toExpr expr@HSE.PatTypeSig {} = unsupportedExpr expr-  toExpr expr@HSE.PViewPat {} = unsupportedExpr expr-  toExpr expr@HSE.PRPat {} = unsupportedExpr expr-  toExpr expr@HSE.PXTag {} = unsupportedExpr expr-  toExpr expr@HSE.PXETag {} = unsupportedExpr expr-  toExpr expr@HSE.PXPcdata {} = unsupportedExpr expr-  toExpr expr@HSE.PXPatTag {} = unsupportedExpr expr-  toExpr expr@HSE.PXRPats {} = unsupportedExpr expr-  toExpr expr@HSE.PSplice {} = unsupportedExpr expr-  toExpr expr@HSE.PQuasiQuote {} = unsupportedExpr expr-  toExpr expr@HSE.PBangPat {} = unsupportedExpr expr--declHeadToTyDef :: HSE.DeclHead a -> AST.TypeDefinition (Maybe SM.Expression)-declHeadToTyDef (HSE.DHead _ name) = AST.ProperType Nothing $ toId name-declHeadToTyDef HSE.DHInfix {} =-  error "Postfix type declarations not supported!"-declHeadToTyDef (HSE.DHParen _ dh) = declHeadToTyDef dh-declHeadToTyDef (HSE.DHApp _ dh tvb) =-  AST.TypeConstructor Nothing $-  case dh of-    HSE.DHInfix _ tvb' name ->-      AST.FunctionApplication Nothing (toExpr name) [toExpr tvb', toExpr tvb]-    _ ->-      AST.FunctionApplication-        Nothing-        (tyDefToExpr $ declHeadToTyDef dh)-        [toExpr tvb]--tyDefToExpr ::-     AST.TypeDefinition (Maybe SM.Expression)-  -> AST.Expression (Maybe SM.Expression)-tyDefToExpr (AST.TypeConstructor _ tyCon) = AST.EFunctionApplication tyCon-tyDefToExpr (AST.ProperType _ ty) = AST.EIdentifier Nothing ty--exprToTyDef ::-     AST.Expression (Maybe SM.Expression)-  -> AST.TypeDefinition (Maybe SM.Expression)-exprToTyDef (AST.EIdentifier _ identifier) = AST.ProperType Nothing identifier-exprToTyDef (AST.EFunctionApplication funApp) =-  AST.TypeConstructor Nothing funApp--toFunApp ::-     AST.Expression (Maybe SM.Expression)-  -> AST.FunctionApplication (Maybe SM.Expression)-toFunApp (AST.EFunctionApplication funApp) = funApp-toFunApp (AST.EIdentifier _ sym) =-  AST.FunctionApplication Nothing (AST.EIdentifier Nothing sym) []--bindsToFunDefs ::-     Maybe (HSE.Binds a) -> [AST.FunctionDefinition (Maybe SM.Expression)]-bindsToFunDefs Nothing = []-bindsToFunDefs (Just (HSE.BDecls _ decls)) =-  map-    (\decl ->-       case toStmts decl of-         [AST.SFunctionDefinition funDef] -> funDef)-    decls-bindsToFunDefs (Just HSE.IPBinds {}) =-  error "Implicit parameters not supported!"--altToClause ::-     HSE.Alt a-  -> ( AST.Expression (Maybe SM.Expression)-     , AST.Expression (Maybe SM.Expression))-altToClause (HSE.Alt _ pat rhs _) = (toExpr pat, toExpr rhs)--instance ToExpr HSE.QOp where-  toExpr (HSE.QVarOp _ name) = toExpr name-  toExpr (HSE.QConOp _ name) = toExpr name--instance ToExpr HSE.Exp where-  toExpr (HSE.Var _ name) = toExpr name-  toExpr expr@HSE.OverloadedLabel {} = unsupportedExpr expr-  toExpr expr@HSE.IPVar {} = unsupportedExpr expr-  toExpr (HSE.Con _ name) = toExpr name-  toExpr (HSE.Lit _ lit) = toExpr lit-  toExpr (HSE.InfixApp _ a op' b) =-    if toId op' == "$"-      then AST.EFunctionApplication $-           AST.FunctionApplication Nothing (toExpr a) [toExpr b]-      else AST.EFunctionApplication $-           AST.FunctionApplication-             Nothing-             (AST.EIdentifier Nothing "applyInfix")-             [toExpr a, toExpr op', toExpr b]-  toExpr (HSE.App _ (HSE.App _ f a) b) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr f) [toExpr a, toExpr b]-  toExpr (HSE.App _ f x) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr f) [toExpr x]-  toExpr expr@HSE.NegApp {} = unsupportedExpr expr-  toExpr (HSE.Lambda _ args body) =-    AST.ELambda $ AST.Lambda Nothing (map toExpr args) (toExpr body)-  toExpr (HSE.Let _ binds body) =-    AST.ELetBlock $ AST.LetBlock Nothing (bindsToClauses binds) (toExpr body)-  toExpr (HSE.If _ cond ifTrue ifFalse) =-    AST.EIfBlock $-    AST.IfBlock Nothing (toExpr cond) (toExpr ifTrue) (toExpr ifFalse)-  toExpr expr@HSE.MultiIf {} = unsupportedExpr expr-  toExpr (HSE.Case _ expr matches) =-    AST.ECaseBlock $-    AST.CaseBlock Nothing (toExpr expr) (map altToClause matches)-  toExpr (HSE.Do _ stmts) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing "do'")-      (map handleStmt stmts)-    where-      handleStmt (HSE.Generator _ pat expr) =-        AST.EFunctionApplication $-        AST.FunctionApplication-          Nothing-          (AST.EIdentifier Nothing "<-")-          [toExpr pat, toExpr expr]-      handleStmt (HSE.Qualifier _ expr) = toExpr expr-      handleStmt (HSE.LetStmt _ binds) =-        AST.EFunctionApplication $-        AST.FunctionApplication-          Nothing-          (AST.EIdentifier Nothing "let")-          (map handleClause $ bindsToClauses binds)-      handleClause (var, val) =-        AST.EFunctionApplication $ AST.FunctionApplication Nothing var [val]-  toExpr expr@HSE.MDo {} = unsupportedExpr expr-  toExpr (HSE.Tuple _ _ exps) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing $ T.replicate (length exps) ",")-      (map toExpr exps)-  toExpr expr@HSE.UnboxedSum {} = unsupportedExpr expr-  toExpr expr@HSE.TupleSection {} = unsupportedExpr expr-  toExpr (HSE.List _ items) =-    AST.EFunctionApplication $-    AST.FunctionApplication-      Nothing-      (AST.EIdentifier Nothing "list")-      (map toExpr items)-  toExpr expr@HSE.ParArray {} = unsupportedExpr expr-  toExpr (HSE.Paren _ expr) = toExpr expr-  toExpr expr@HSE.LeftSection {} = unsupportedExpr expr-  toExpr expr@HSE.RightSection {} = unsupportedExpr expr-  toExpr expr@HSE.RecConstr {} = unsupportedExpr expr-  toExpr expr@HSE.RecUpdate {} = unsupportedExpr expr-  toExpr expr@HSE.EnumFrom {} = unsupportedExpr expr-  toExpr expr@HSE.EnumFromTo {} = unsupportedExpr expr-  toExpr expr@HSE.EnumFromThen {} = unsupportedExpr expr-  toExpr expr@HSE.EnumFromThenTo {} = unsupportedExpr expr-  toExpr expr@HSE.ListComp {} = unsupportedExpr expr-  toExpr expr@HSE.ParComp {} = unsupportedExpr expr-  toExpr expr@HSE.ParArrayComp {} = unsupportedExpr expr-  toExpr expr@HSE.ParArrayFromTo {} = unsupportedExpr expr-  toExpr expr@HSE.ParArrayFromThenTo {} = unsupportedExpr expr-  toExpr expr@HSE.ExpTypeSig {} = unsupportedExpr expr-  toExpr expr@HSE.VarQuote {} = unsupportedExpr expr-  toExpr expr@HSE.TypQuote {} = unsupportedExpr expr-  toExpr expr@HSE.BracketExp {} = unsupportedExpr expr-  toExpr expr@HSE.SpliceExp {} = unsupportedExpr expr-  toExpr expr@HSE.QuasiQuote {} = unsupportedExpr expr-  toExpr expr@HSE.TypeApp {} = unsupportedExpr expr-  toExpr expr@HSE.XTag {} = unsupportedExpr expr-  toExpr expr@HSE.XETag {} = unsupportedExpr expr-  toExpr expr@HSE.XPcdata {} = unsupportedExpr expr-  toExpr expr@HSE.XExpTag {} = unsupportedExpr expr-  toExpr expr@HSE.XChildTag {} = unsupportedExpr expr-  toExpr expr@HSE.CorePragma {} = unsupportedExpr expr-  toExpr expr@HSE.SCCPragma {} = unsupportedExpr expr-  toExpr expr@HSE.GenPragma {} = unsupportedExpr expr-  toExpr expr@HSE.Proc {} = unsupportedExpr expr-  toExpr expr@HSE.LeftArrApp {} = unsupportedExpr expr-  toExpr expr@HSE.RightArrApp {} = unsupportedExpr expr-  toExpr expr@HSE.LeftArrHighApp {} = unsupportedExpr expr-  toExpr expr@HSE.RightArrHighApp {} = unsupportedExpr expr-  toExpr expr@HSE.LCase {} = unsupportedExpr expr--instance ToExpr HSE.Rhs where-  toExpr (HSE.UnGuardedRhs _ expr) = toExpr expr-  toExpr expr@HSE.GuardedRhss {} = unsupportedExpr expr--bindsToClauses ::-     HSE.Binds a-  -> [( AST.Expression (Maybe SM.Expression)-      , AST.Expression (Maybe SM.Expression))]-bindsToClauses (HSE.BDecls _ decls) =-  map (\(HSE.PatBind _ pat body _) -> (toExpr pat, toExpr body)) decls--instance ToStmts HSE.Match where-  toStmts (HSE.Match _ fn pats body whereBinds) =-    [ AST.SFunctionDefinition $-      AST.FunctionDefinition-        Nothing-        (toId fn)-        (map toExpr pats)-        (toExpr body)-        (bindsToFunDefs whereBinds)-    ]-  toStmts (HSE.InfixMatch _ pat fn pats body whereBinds) =-    [ AST.SFunctionDefinition $-      AST.FunctionDefinition-        Nothing-        (toId fn)-        (toExpr pat : map toExpr pats)-        (toExpr body)-        (bindsToFunDefs whereBinds)-    ]--instance ToExpr HSE.InstHead where-  toExpr (HSE.IHCon _ name) = toExpr name-  toExpr (HSE.IHInfix _ ty name) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr ty) [toExpr name]-  toExpr (HSE.IHParen _ instHead) = toExpr instHead-  toExpr (HSE.IHApp _ instHead ty) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr instHead) [toExpr ty]--instance ToExpr HSE.InstRule where-  toExpr (HSE.IRule _ _ Nothing instHead) = toExpr instHead-  toExpr (HSE.IParen _ rule) = toExpr rule--instance ToStmts HSE.Decl where-  toStmts (HSE.TypeDecl _ declHead ty) =-    [ AST.STypeSynonym $-      AST.TypeSynonym-        Nothing-        (tyDefToExpr $ declHeadToTyDef declHead)-        (toExpr ty)-    ]-  toStmts stmt@HSE.TypeFamDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.ClosedTypeFamDecl {} = [unsupportedStmt stmt]-  toStmts (HSE.DataDecl _ dataOrNew _ declHead cases _) =-    [ case dataOrNew of-        HSE.NewType _ ->-          AST.SNewtypeDeclaration $-          AST.NewtypeDeclaration-            Nothing-            (declHeadToTyDef declHead)-            (toFunApp $ toExpr $ unsafeHead cases)-        HSE.DataType _ ->-          AST.SDataDeclaration $-          AST.DataDeclaration-            Nothing-            (declHeadToTyDef declHead)-            (map (toFunApp . toExpr) cases)-    ]-  toStmts stmt@HSE.GDataDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.DataFamDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.TypeInsDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.DataInsDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.GDataInsDecl {} = [unsupportedStmt stmt]-  toStmts (HSE.ClassDecl _ ctxt declHead _ decls) =-    [ AST.STypeclassDefinition $-      AST.TypeclassDefinition-        Nothing-        (tyDefToExpr $ declHeadToTyDef declHead)-        (contextToExprs ctxt)-        (maybe [] (map classDeclToTySig) decls)-    ]-  toStmts (HSE.InstDecl _ _ rule decls) =-    [ AST.STypeclassInstance $-      AST.TypeclassInstance-        Nothing-        (toExpr rule)-        (maybe [] (map instDeclToFunDef) decls)-    ]-  toStmts stmt@HSE.DerivDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.InfixDecl {} = [unsupportedStmt stmt]-  toStmts (HSE.TypeSig _ names ty) =-    map-      (\name ->-         AST.STypeSignature $ AST.TypeSignature Nothing (toId name) (toExpr ty))-      names-  toStmts stmt@HSE.PatSynSig {} = [unsupportedStmt stmt]-  toStmts (HSE.FunBind _ cases) = concatMap toStmts cases-  toStmts (HSE.PatBind _ fn body whereBinds) =-    [ AST.SFunctionDefinition $-      AST.FunctionDefinition-        Nothing-        (toId fn)-        []-        (toExpr body)-        (bindsToFunDefs whereBinds)-    ]-  toStmts stmt@HSE.ForImp {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.ForExp {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.RulePragmaDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.DeprPragmaDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.WarnPragmaDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.InlineSig {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.InlineConlikeSig {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.SpecSig {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.SpecInlineSig {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.InstSig {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.AnnPragma {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.MinimalPragma {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.RoleAnnotDecl {} = [unsupportedStmt stmt]-  toStmts stmt@HSE.CompletePragma {} = [unsupportedStmt stmt]--instDeclToFunDef ::-     HSE.InstDecl a -> AST.FunctionDefinition (Maybe SM.Expression)-instDeclToFunDef (HSE.InsDecl _ decl) =-  case unsafeHead $ toStmts decl of-    AST.SFunctionDefinition funDef -> funDef-instDeclToFunDef HSE.InsType {} = error "Type families not supported!"-instDeclToFunDef HSE.InsData {} = error "Type families not supported!"-instDeclToFunDef HSE.InsGData {} = error "Type families not supported!"--classDeclToTySig :: HSE.ClassDecl a -> AST.TypeSignature (Maybe SM.Expression)-classDeclToTySig (HSE.ClsDecl _ decl) =-  case toStmts decl of-    [AST.STypeSignature tySig] -> tySig-classDeclToTySig HSE.ClsDataFam {} = error "Type families not supported!"-classDeclToTySig HSE.ClsTyFam {} = error "Type families not supported!"-classDeclToTySig HSE.ClsTyDef {} = error "Type families not supported!"-classDeclToTySig HSE.ClsDefSig {} = error "Default signatures not supported!"--instance ToExpr HSE.Asst where-  toExpr (HSE.ClassA _ name tys) =-    AST.EFunctionApplication $-    AST.FunctionApplication Nothing (toExpr name) (map toExpr tys)-  toExpr (HSE.WildCardA _ _) = AST.EIdentifier Nothing "_"--contextToExprs ::-     Maybe (HSE.Context a) -> [AST.Expression (Maybe SM.Expression)]-contextToExprs Nothing = []-contextToExprs (Just (HSE.CxSingle _ asst)) = [toExpr asst]-contextToExprs (Just (HSE.CxTuple _ assts)) = map toExpr assts-contextToExprs (Just (HSE.CxEmpty _)) = []- convertFile ::      (Sem.Members '[ Effs.Console, Effs.FileSystem, Sem.Error Error, Effs.FileSystem] effs)   => FilePath@@ -604,11 +75,14 @@   putStrLn $ "Writing " <> op FilePath newPath <> "..."   let newContents =         prettifyProgram $-        groupFunctionDefinitions $-        flattenFunctionApplications $ toStmts parsedModule+        groupFunctionDefinitions $ flattenFunctionApplications []   FS.writeFile newPath newContents+  _ <-+    error+      "Haskell to Axel conversion is in construction, see https://app.gitkraken.com/glo/board/Wunz108ztxUAEpyt/card/XYmtRxPb5QAPb0H9."   pure newPath +-- convertFile path newPath = do flattenFunctionApplications :: [AST.SMStatement] -> [AST.SMStatement] flattenFunctionApplications = map (biplate %~ (uniplate %~ handleExpr))   where@@ -628,9 +102,7 @@       extractTySig = unannotated %~ removeOut (is AST._STypeSignature)       transformFnDef (AST.SFunctionDefinition fnDef) =         let whereBindings =-              case map-                     (denormalizeStatement . AST.SFunctionDefinition)-                     (fnDef ^. AST.whereBindings) of+              case map denormalizeStatement (fnDef ^. AST.whereBindings) of                 [] -> []                 xs -> [Parse.SExpression Nothing xs]          in Parse.SExpression Nothing $@@ -644,17 +116,18 @@       map (flattenAnnotations . extractTySig . (unannotated %~ NE.toList)) >>>       concatMap         (\(stmts, (tySigs, maybeFnName)) ->-           case maybeFnName of-             Nothing -> map denormalizeStatement stmts-             Just fnName ->-               case tySigs of-                 [AST.STypeSignature tySig] ->+           fromMaybe (map denormalizeStatement stmts) $ do+             fnName <- maybeFnName+             case tySigs of+               [] -> Nothing+               [AST.STypeSignature tySig] ->+                 Just                    [ Parse.SExpression Nothing $                      Parse.Symbol Nothing "def" :                      Parse.Symbol Nothing (T.unpack fnName) :                      denormalizeExpression (tySig ^. AST.typeDefinition) :                      map transformFnDef stmts                    ]-                 _ ->-                   error $-                   "Multiple type signatures found for: `" <> fnName <> "`!")+               _ ->+                 error $+                 "Multiple type signatures found for: `" <> fnName <> "`!")
src/Axel/Haskell/Error.hs view
@@ -35,11 +35,6 @@  makeFieldsNoPrefix ''GhcError -processErrors :: ModuleInfo -> Text -> Text-processErrors moduleInfo stackOutput =-  T.unlines $ concatMap (processStackOutputLine moduleInfo) $-  T.lines stackOutput- processStackOutputLine :: ModuleInfo -> Text -> [Text] processStackOutputLine moduleInfo line =   fromMaybe [line] (tryProcessGhcOutput moduleInfo line)
src/Axel/Haskell/File.hs view
@@ -24,7 +24,7 @@ import Axel.Haskell.Convert (convertFile) import Axel.Macros (handleFunctionApplication, processProgram) import Axel.Normalize (normalizeStatement, withExprCtxt)-import Axel.Parse (parseMultiple, parseSource)+import Axel.Parse (parseMultiple', parseSource) import Axel.Parse.AST (Expression(Symbol)) import Axel.Pretty (prettifyProgram) import qualified Axel.Sourcemap as SM@@ -153,6 +153,6 @@ formatFileInPlace path = do   contents <- FS.readFile path   putStrLn $ "Formatting " <> op FilePath path <> "..."-  program <- parseMultiple (Just path) contents+  program <- parseMultiple' id (Just path) contents   let prettifiedContents = prettifyProgram program   FS.writeFile path prettifiedContents
src/Axel/Haskell/Language.hs view
@@ -3,23 +3,20 @@ import Axel.Prelude  import Data.Char (isSymbol, toUpper)-import qualified Data.Text as T  -- https://stackoverflow.com/questions/10548170/what-characters-are-permitted-for-haskell-operators-isOperator :: Text -> Bool-isOperator =-  T.all $ \x ->-    isSymbol x || x `elem` map fst haskellOperatorSymbols || x == ','+isOperator :: String -> Bool+isOperator = all $ \x -> isSymbol x || x `elem` map fst haskellOperatorSymbols -type SymbolReplacementMap = [(Char, Text)]+type SymbolReplacementMap = [(String, String)] -mkHygenicSymbolReplacementMap :: SymbolReplacementMap -> SymbolReplacementMap-mkHygenicSymbolReplacementMap =-  map (\(symbol, name) -> (symbol, "aXEL_SYMBOL_" <> T.map toUpper name <> "_"))+mkHygenicReplacementMap :: [(a, String)] -> [(a, String)]+mkHygenicReplacementMap =+  map (\(symbol, name) -> (symbol, "aXEL_SYMBOL_" <> map toUpper name <> "_")) -haskellOperatorSymbols :: SymbolReplacementMap+haskellOperatorSymbols :: [(Char, String)] haskellOperatorSymbols =-  mkHygenicSymbolReplacementMap+  mkHygenicReplacementMap     [ (':', "colon")     , ('!', "bang")     , ('#', "hash")@@ -40,16 +37,21 @@     , ('|', "pipe")     , ('~', "tilde")     , ('.', "dot")+    , (',', "comma")     ] -haskellSyntaxSymbols :: SymbolReplacementMap+haskellSyntaxSymbols :: [(Char, String)] haskellSyntaxSymbols =-  mkHygenicSymbolReplacementMap-    [ (',', "comma")-    , (';', "semicolon")+  mkHygenicReplacementMap+    [ (';', "semicolon")     , ('[', "leftBracket")     , (']', "rightBracket")     , ('{', "rightBrace")     , ('}', "leftBrace")     , ('`', "tilde")     ]++-- TODO Add a test that this list has no duplicates.+haskellKeywords :: [(String, String)]+haskellKeywords =+  mkHygenicReplacementMap $ map (\x -> (x, x)) ["do", "if", "let"]
src/Axel/Haskell/Macros.hs view
@@ -1,11 +1,9 @@ module Axel.Haskell.Macros where+import Axel import qualified Prelude as GHCPrelude import qualified Axel.Parse.AST as AST import Axel.Prelude-import Axel.Haskell.Language(haskellOperatorSymbols,haskellSyntaxSymbols,isOperator)-import qualified Axel.Parse as Parse(syntaxSymbols)-import Data.List(foldl')-import Data.MonoTraversable(onotElem)+import Axel.Haskell.Language(isOperator) import qualified Data.Text as T-hygenisizeMacroName oldName = (let {suffix = if (isOperator oldName) then "%%%%%%%%%%" else "_AXEL_AUTOGENERATED_MACRO_DEFINITION";suffixedName = if (T.isSuffixOf suffix oldName) then oldName else ((<>) oldName suffix);symbolReplacementMap = if (isOperator oldName) then haskellSyntaxSymbols else ((<>) haskellSyntaxSymbols haskellOperatorSymbols)} in (foldl' (\acc ((,) old new) -> (T.replace (T.singleton old) new acc)) suffixedName (filter (\((,) sym _) -> (onotElem sym Parse.syntaxSymbols)) symbolReplacementMap)))-hygenisizeMacroName :: ((->) Text Text)+hygenisizeMacroName :: () => ((->) Text Text)+hygenisizeMacroName oldName = (let {suffix = (aXEL_SYMBOL_IF_ (isOperator (T.unpack oldName)) "%%%%%%%%%%" "_AXEL_AUTOGENERATED_MACRO_DEFINITION")} in (aXEL_SYMBOL_IF_ (T.isSuffixOf suffix oldName) oldName ((<>) oldName suffix)))
src/Axel/Haskell/Project.hs view
@@ -35,10 +35,10 @@   ) import Axel.Sourcemap (ModuleInfo) import Axel.Utils.FilePath ((<.>), (</>))-import Axel.Utils.Monad (concatMapM)  import Control.Lens (op) import Control.Monad (void)+import Control.Monad.Extra (concatMapM)  import qualified Data.Text as T @@ -93,7 +93,7 @@      (Sem.Members '[ Effs.Console, Sem.Error Error, Effs.FileSystem, Effs.Ghci, Effs.Log, Effs.Process, Effs.Resource] effs)   => Sem.Sem effs ModuleInfo transpileProject =-  Ghci.withGhci $ do+  Ghci.withStackGhci $ do     axelFiles <- getProjectFiles Axel     initialModuleInfo <- readModuleInfo axelFiles     (moduleInfo, _) <-
src/Axel/Haskell/Stack.hs view
@@ -6,21 +6,25 @@  import Axel.Prelude -import Axel.Eff.Console (putStrLn)+import Axel.Eff.Console (putStr, putStrLn) import qualified Axel.Eff.Console as Effs import Axel.Eff.Error (Error(ProjectError), fatal) import qualified Axel.Eff.FileSystem as FS import qualified Axel.Eff.FileSystem as Effs import Axel.Eff.Process-  ( ProcessRunner-  , StreamSpecification(CreateStreams, InheritStreams)-  , execProcess+  ( createIndependentProcess+  , handleGetLine+  , handleIsAtEnd+  , passthroughProcess+  , readProcess+  , waitOnProcess   ) import qualified Axel.Eff.Process as Effs-import Axel.Haskell.Error (processErrors)+import Axel.Haskell.Error (processStackOutputLine) import Axel.Parse (Parser) import Axel.Sourcemap (ModuleInfo) import Axel.Utils.FilePath (takeFileName)+import Axel.Utils.Monad (whileM)  import Control.Lens (op) import Control.Lens.Operators ((%~))@@ -70,7 +74,7 @@   -> Sem.Sem effs [Target] getStackProjectTargets projectPath =   FS.withCurrentDirectory projectPath $ do-    (_, _, stderr) <- execProcess @'CreateStreams "stack ide targets" ""+    (_, _, stderr) <- readProcess "stack ide targets"     pure $ T.lines stderr  addStackDependency ::@@ -97,27 +101,24 @@   -> ProjectPath   -> Sem.Sem effs () buildStackProject moduleInfo projectPath = do-  putStrLn ("Building " <> op FilePath (takeFileName projectPath) <> "...")-  result <--    FS.withCurrentDirectory projectPath $-    execProcess @'CreateStreams "stack build --ghc-options='-ddump-json'" ""-  case result of-    (ExitSuccess, _, _) -> pure ()-    (ExitFailure _, _, stderr) ->-      Sem.throw $-      ProjectError-        ("Project failed to build.\n\n" <> processErrors moduleInfo stderr)+  FS.withCurrentDirectory projectPath $ do+    putStrLn ("Building " <> op FilePath (takeFileName projectPath) <> "...")+    (_, _, stderrHandle, processHandle) <-+      createIndependentProcess "stack build --ghc-options='-ddump-json'"+    whileM (not <$> handleIsAtEnd stderrHandle) $ do+      stackOutputLine <- handleGetLine stderrHandle+      putStr $ T.unlines $ processStackOutputLine moduleInfo stackOutputLine+    exitCode <- waitOnProcess processHandle+    case exitCode of+      ExitSuccess -> pure ()+      ExitFailure _ -> Sem.throw $ ProjectError "Project failed to build."  createStackProject ::      (Sem.Members '[ Effs.FileSystem, Effs.Process] effs)   => Text   -> Sem.Sem effs () createStackProject projectName = do-  void $-    execProcess-      @'CreateStreams-      ("stack new " <> projectName <> " new-template")-      ""+  void $ readProcess ("stack new " <> projectName <> " new-template")   setStackageResolver (FilePath projectName) stackageResolverWithAxel  runStackProject ::@@ -129,7 +130,7 @@   case findExeTargets targets of     [target] -> do       putStrLn $ "Running " <> target <> "..."-      void $ execProcess @'InheritStreams ("stack exec " <> target)+      void $ passthroughProcess ("stack exec " <> target)     _ ->       Sem.throw $ ProjectError "No executable target was unambiguously found!"   where@@ -151,28 +152,11 @@   -> StackageResolver   -> Sem.Sem effs () setStackageResolver projectPath resolver =-  void $ FS.withCurrentDirectory projectPath $-  execProcess @'CreateStreams ("stack config set resolver " <> resolver) ""+  void $ FS.withCurrentDirectory projectPath $ readProcess $+  "stack config set resolver " <>+  resolver  includeAxelArguments :: Text includeAxelArguments =   T.unwords     ["--resolver", stackageResolverWithAxel, "--package", axelStackageId]--compileFile ::-     forall (streamSpec :: StreamSpecification) effs.-     (Sem.Member Effs.Process effs)-  => FilePath-  -> ProcessRunner streamSpec (Sem.Sem effs)-compileFile (FilePath filePath) =-  let cmd = T.unwords ["stack", "ghc", includeAxelArguments, "--", filePath]-   in execProcess @streamSpec @effs cmd--interpretFile ::-     forall (streamSpec :: StreamSpecification) effs.-     (Sem.Member Effs.Process effs)-  => FilePath-  -> ProcessRunner streamSpec (Sem.Sem effs)-interpretFile (FilePath filePath) =-  let cmd = T.unwords ["stack", "runghc", includeAxelArguments, "--", filePath]-   in execProcess @streamSpec @effs cmd
src/Axel/Macros.hs view
@@ -14,8 +14,8 @@   , Identifier   , ImportSpecification(ImportAll)   , MacroDefinition-  , MacroImport(MacroImport)   , QualifiedImport(QualifiedImport)+  , RestrictedImport(RestrictedImport)   , SMStatement   , Statement(SFunctionDefinition, SMacroDefinition, SMacroImport,           SMacroImport, SModuleDeclaration, SQualifiedImport,@@ -32,7 +32,7 @@   ) import Axel.Denormalize (denormalizeStatement) import qualified Axel.Eff as Effs-import Axel.Eff.Error (Error(MacroError), fatal)+import Axel.Eff.Error (Error(MacroError, ParseError), fatal) import qualified Axel.Eff.FileSystem as Effs (FileSystem) import qualified Axel.Eff.FileSystem as FS import qualified Axel.Eff.Ghci as Effs (Ghci)@@ -42,7 +42,7 @@ import qualified Axel.Eff.Process as Effs (Process) import qualified Axel.Eff.Restartable as Effs (Restartable) import Axel.Eff.Restartable (restart, runRestartable)-import Axel.Haskell.Error (processErrors)+import Axel.Haskell.Error (processStackOutputLine) import Axel.Haskell.Macros (hygenisizeMacroName) import Axel.Normalize   ( normalizeExpression@@ -66,19 +66,20 @@ import qualified Axel.Sourcemap as SM import Axel.Utils.FilePath ((<.>), (</>), replaceExtension, takeFileName) import Axel.Utils.List (filterMap, filterMapOut, head')-import Axel.Utils.Maybe (whenMaybe) import Axel.Utils.Recursion (bottomUpFmap, zipperTopDownTraverse) import Axel.Utils.Zipper (unsafeLeft, unsafeUp) -import Control.Lens (_1, op, snoc)+import Control.Lens (_1, isn't, op, snoc) import Control.Lens.Extras (is) import Control.Lens.Operators ((%~), (^.), (^?)) import Control.Monad (guard, unless, when)+import Control.Monad.Extra (whenJust)  import Data.Function (on) import Data.Generics.Uniplate.Zipper (Zipper, fromZipper, hole, replaceHole, up) import Data.Hashable (hash) import Data.List (intersperse, nub)+import Data.List.Extra (mconcatMap) import Data.List.Split (split, whenElt) import qualified Data.Map as M import Data.Maybe (isNothing)@@ -127,14 +128,9 @@     mapM       (Sem.runReader filePath . withExprCtxt . normalizeStatement)       (unwrapCompoundExpressions newProgramExpr)-  let addAstImport =-        insertImports-          [ SQualifiedImport $-            QualifiedImport Nothing "Prelude" "GHCPrelude" (ImportAll Nothing)-          , SQualifiedImport $-            QualifiedImport Nothing "Axel.Parse.AST" "AST" (ImportAll Nothing)-          ]-  pure $ finalizeProgram $ addAstImport newStmts+  withAstImports <-+    insertImports filePath (autogeneratedImports filePath) newStmts+  pure $ finalizeProgram withAstImports  finalizeProgram :: [SMStatement] -> [SMStatement] finalizeProgram stmts =@@ -313,7 +309,7 @@             Just $ qualifiedImport ^. moduleName           SMacroImport macroImport -> Just $ macroImport ^. moduleName           _ -> Nothing-  whenMaybe maybeDependencyName $+  whenJust maybeDependencyName $     ensureCompiledDependency @fileExpanderEffs expandFile   Sem.modify @[SMStatement] (`snoc` stmt) @@ -357,18 +353,31 @@ hygenisizeMacroDefinition :: MacroDefinition ann -> MacroDefinition ann hygenisizeMacroDefinition = functionDefinition . name %~ hygenisizeMacroName -insertImports :: [SMStatement] -> [SMStatement] -> [SMStatement]-insertImports newStmts program =+insertImports ::+     (Sem.Member (Sem.Error Error) effs)+  => FilePath+  -> [SMStatement]+  -> [SMStatement]+  -> Sem.Sem effs [SMStatement]+insertImports filePath newStmts program =   case split (whenElt $ is _SModuleDeclaration) program of-    [preEnv, moduleDeclaration, postEnv] ->-      preEnv <> moduleDeclaration <> newStmts <> postEnv-    [_] -> newStmts <> program-    _ -> fatal "insertImports" "0001" -- TODO Replace with error message indicating that only one module declaration is allowed!+    [preEnv, [moduleDecl@(SModuleDeclaration _ _)], postEnv] ->+      pure $ preEnv <> [moduleDecl] <> newStmts <> postEnv+    [preEnv, [moduleDecl@(SModuleDeclaration _ _)]] ->+      pure $ preEnv <> [moduleDecl] <> newStmts+    [[moduleDecl@(SModuleDeclaration _ _)], postEnv] ->+      pure $ [moduleDecl] <> newStmts <> postEnv+    [[moduleDecl@(SModuleDeclaration _ _)]] -> pure $ [moduleDecl] <> newStmts+    _ ->+      Sem.throw $+      ParseError+        filePath+        "Axel files must contain exactly one module declaration!"  mkMacroTypeSignature :: Identifier -> SMStatement mkMacroTypeSignature =   SRawStatement Nothing .-  (<> " :: [AST.Expression SM.SourceMetadata] -> IO [AST.Expression SM.SourceMetadata]")+  (<> " :: [AST.Expression SM.SourceMetadata] -> GHCPrelude.IO [AST.Expression SM.SourceMetadata]")  newtype ExpansionId =   ExpansionId Text@@ -381,6 +390,19 @@ mkScaffoldModuleName (ExpansionId expansionId) =   "AutogeneratedAxelScaffold" <> expansionId +autogeneratedImports :: FilePath -> [SMStatement]+autogeneratedImports filePath+  -- We can't import the Axel prelude if we're actually compiling it.+ =+  [ SRestrictedImport $ RestrictedImport Nothing "Axel" (ImportAll Nothing)+  | not $ isPrelude filePath+  ] <>+  [ SQualifiedImport $+    QualifiedImport Nothing "Prelude" "GHCPrelude" (ImportAll Nothing) -- (in case `-XNoImplicitPrelude` is enabled)+  , SQualifiedImport $+    QualifiedImport Nothing "Axel.Parse.AST" "AST" (ImportAll Nothing)+  ]+ generateMacroProgram ::      (Sem.Members '[ Sem.Error Error, Effs.FileSystem, Sem.Reader ExpansionId, Sem.State [SMStatement]] effs)   => FilePath@@ -401,12 +423,11 @@             mkQualImport moduleName' alias =               SQualifiedImport $               QualifiedImport Nothing moduleName' alias (ImportAll Nothing)-            mkMacroImport moduleName' macros =-              SMacroImport $ MacroImport Nothing moduleName' macros             mkId = EIdentifier Nothing             mkQualId moduleName' identifier =               EIdentifier Nothing $ moduleName' <> "." <> identifier-            mkTySig fnName ty = STypeSignature $ TypeSignature Nothing fnName ty+            mkTySig fnName ty =+              STypeSignature $ TypeSignature Nothing fnName [] ty             mkFnDef fnName args' body =               SFunctionDefinition $               FunctionDefinition Nothing fnName args' body []@@ -415,15 +436,10 @@             mkRawExpr = ERawExpression Nothing             mkList xs =               mkFnApp (mkId "[") $ intersperse (mkRawExpr ",") xs <> [mkId "]"] -- This is VERY hacky, but it'll work without too much effort for now.-         in ( [mkMacroImport "Axel" preludeMacros | not $ isPrelude filePath'] <> -- We can't import the Axel prelude if we're actually compiling it.-              [ mkQualImport "Prelude" "GHCPrelude" -- (in case `-XNoImplicitPrelude` is enabled)-              , mkQualImport "Axel.Parse.AST" "AST"-              , mkQualImport "Axel.Sourcemap" "SM"-              ]-            , [ mkModuleDecl scaffoldModuleName-              , mkQualImport "Prelude" "GHCPrelude" -- (in case `-XNoImplicitPrelude` is enabled)-              , mkQualImport macroDefAndEnvModuleName macroDefAndEnvModuleName-              , mkQualImport "Axel.Parse.AST" "AST"+         in ( autogeneratedImports filePath' <>+              [mkQualImport "Axel.Sourcemap" "SM"]+            , mkModuleDecl scaffoldModuleName : autogeneratedImports filePath' <>+              [ mkQualImport macroDefAndEnvModuleName macroDefAndEnvModuleName               , mkQualImport "Axel.Sourcemap" "SM"               , mkTySig "main" $ mkFnApp (mkId "GHCPrelude.IO") [mkId "()"]               , mkFnDef "main" [] $@@ -450,17 +466,20 @@                       ]                   ]               ])-  auxEnv <- Sem.get @[SMStatement]+  prevStmts <- Sem.get @[SMStatement]+  -- Mitigate the `::`/`=`-ordering problem (see the description of issue #65).+  let auxEnv =+        reverse . dropWhile (isn't _SMacroDefinition) . reverse $ prevStmts   -- TODO If the file being transpiled has pragmas but no explicit module declaration,   --      they will be erroneously included *after* the module declaration.   --      Should we just require Axel files to have module declarations, or is there a   --      less intrusive alternate solution?-  let macroDefAndEnv =-        let moduleDecl = SModuleDeclaration Nothing macroDefAndEnvModuleName-            programStmts =-              replaceModuleDecl moduleDecl $ insertImports header $ auxEnv <>-              footer-         in finalizeProgram programStmts+  macroDefAndEnv <-+    do let moduleDecl = SModuleDeclaration Nothing macroDefAndEnvModuleName+       programStmts <-+         insertImports filePath' header $ replaceModuleDecl moduleDecl $ auxEnv <>+         footer+       pure $ finalizeProgram programStmts   pure $     uncurry       ((,) `on` toHaskell . statementsToProgram)@@ -560,7 +579,8 @@       if any ("*** Exception:" `T.isPrefixOf`) (T.lines result)         then throwMacroError result         else pure (resultFile, result)-    else throwMacroError (processErrors moduleInfo $ T.unlines loadResult)+    else throwMacroError $ mconcat $+         mconcatMap (processStackOutputLine moduleInfo) loadResult   where     macroDefAndEnv = SM.raw macroDefAndEnvProgram     scaffold = SM.raw scaffoldProgram
src/Axel/Normalize.hs view
@@ -9,17 +9,16 @@   ( CaseBlock(CaseBlock)   , DataDeclaration(DataDeclaration)   , Expression(ECaseBlock, EEmptySExpression, EFunctionApplication,-           EIdentifier, EIfBlock, ELambda, ELetBlock, ELiteral,-           ERawExpression, ERecordDefinition, ERecordType)+           EIdentifier, ELambda, ELetBlock, ELiteral, ERawExpression,+           ERecordDefinition, ERecordType)   , FunctionApplication(FunctionApplication)   , FunctionDefinition(FunctionDefinition)   , Identifier-  , IfBlock(IfBlock)   , Import(ImportItem, ImportType)   , ImportSpecification(ImportAll, ImportOnly)   , Lambda(Lambda)   , LetBlock(LetBlock)-  , Literal(LChar, LInt, LString)+  , Literal(LChar, LFloat, LInt, LString)   , MacroDefinition(MacroDefinition)   , MacroImport(MacroImport)   , NewtypeDeclaration(NewtypeDeclaration)@@ -28,6 +27,7 @@   , RecordDefinition(RecordDefinition)   , RecordType(RecordType)   , RestrictedImport(RestrictedImport)+  , SMExpression   , SMStatement   , Statement(SDataDeclaration, SFunctionDefinition, SMacroDefinition,           SMacroImport, SModuleDeclaration, SNewtypeDeclaration, SPragma,@@ -42,9 +42,10 @@   , TypeclassInstance(TypeclassInstance)   ) import Axel.Eff.Error (Error(NormalizeError), renderError, unsafeRunError)+import Axel.Parse (unhygenisizeIdentifier) import qualified Axel.Parse.AST as Parse-  ( Expression(LiteralChar, LiteralInt, LiteralString, SExpression,-           Symbol)+  ( Expression(LiteralChar, LiteralFloat, LiteralInt, LiteralString,+           SExpression, Symbol)   ) import qualified Axel.Sourcemap as SM (Expression) @@ -81,6 +82,8 @@   -> Sem.Sem effs (Expression (Maybe SM.Expression)) normalizeExpression expr@(Parse.LiteralChar _ char) =   pure $ ELiteral (LChar (Just expr) char)+normalizeExpression expr@(Parse.LiteralFloat _ float) =+  pure $ ELiteral (LFloat (Just expr) float) normalizeExpression expr@(Parse.LiteralInt _ int) =   pure $ ELiteral (LInt (Just expr) int) normalizeExpression expr@(Parse.LiteralString _ string) =@@ -88,75 +91,104 @@ normalizeExpression expr@(Parse.SExpression _ items) =   pushCtxt expr $   case items of-    Parse.Symbol _ "case":var:cases ->-      let normalizedCases =-            traverse-              (\case-                 Parse.SExpression _ [pat, body] ->-                   (,) <$> normalizeExpression pat <*> normalizeExpression body-                 x -> pushCtxt x $ throwNormalizeError "Invalid case!")-              cases-       in ECaseBlock <$>-          (CaseBlock (Just expr) <$> normalizeExpression var <*> normalizedCases)-    [Parse.Symbol _ "\\", Parse.SExpression _ args, body] -- TODO Fail if num args /= 2-     ->-      let normalizedArguments = traverse normalizeExpression args-       in ELambda <$>-          (Lambda (Just expr) <$> normalizedArguments <*>-           normalizeExpression body)-    [Parse.Symbol _ "if", cond, ifTrue, ifFalse] -- TODO Fail if num args /= 3-     ->-      EIfBlock <$>-      (IfBlock (Just expr) <$> normalizeExpression cond <*>-       normalizeExpression ifTrue <*>-       normalizeExpression ifFalse)-    [Parse.Symbol _ "let", Parse.SExpression _ bindings, body] -- TODO Fail if num args /= 2-     ->-      let normalizedBindings =-            traverse-              (\case-                 Parse.SExpression _ [name, value] ->-                   (,) <$> normalizeExpression name <*>-                   normalizeExpression value-                 x -> pushCtxt x $ throwNormalizeError "Invalid pattern!")-              bindings-       in ELetBlock <$>-          (LetBlock (Just expr) <$> normalizedBindings <*>-           normalizeExpression body)-    [Parse.Symbol _ "raw", rawSource] -- TODO Fail if num args /= 1-     ->-      let normalizedRawSource =-            case rawSource of-              Parse.LiteralString _ x -> pure x-              x ->-                pushCtxt x $-                throwNormalizeError-                  "`raw` takes strings representing the code to inject directly."-       in ERawExpression (Just expr) . T.pack <$> normalizedRawSource-    Parse.Symbol _ "record":bindings ->-      let normalizedBindings =-            traverse-              (\x ->-                 normalizeExpression x >>= \case-                   EFunctionApplication (FunctionApplication _ (EIdentifier _ field) [val]) ->-                     pure (field, val)-                   _ ->-                     pushCtxt x $ throwNormalizeError "Invalid field binding!")-              bindings-       in ERecordDefinition <$>-          (RecordDefinition (Just expr) <$> normalizedBindings)-    Parse.Symbol _ "recordType":fields ->-      let normalizedFields =-            traverse-              (\x ->-                 normalizeExpression x >>= \case-                   EFunctionApplication (FunctionApplication _ (EIdentifier _ field) [ty]) ->-                     pure (field, ty)-                   _ ->-                     pushCtxt x $-                     throwNormalizeError "Invalid field definition!")-              fields-       in ERecordType <$> (RecordType (Just expr) <$> normalizedFields)+    (Parse.Symbol sourceMetadata special):args ->+      case unhygenisizeIdentifier special of+        "case" ->+          case args of+            var:cases ->+              let normalizedCases =+                    traverse+                      (\case+                         Parse.SExpression _ [pat, body] ->+                           (,) <$> normalizeExpression pat <*>+                           normalizeExpression body+                         x ->+                           pushCtxt x $+                           throwNormalizeError+                             "A `case` clause must be an s-expression containing: 1) a pattern and 2) a body.")+                      cases+               in ECaseBlock <$>+                  (CaseBlock (Just expr) <$> normalizeExpression var <*>+                   normalizedCases)+            _ ->+              throwNormalizeError+                "`case` takes an expression followed by `case` clauses."+        "\\" ->+          case args of+            [Parse.SExpression _ args', body] ->+              let normalizedArguments = traverse normalizeExpression args'+               in ELambda <$>+                  (Lambda (Just expr) <$> normalizedArguments <*>+                   normalizeExpression body)+            _ ->+              throwNormalizeError+                "`\\` takes exactly two arguments: 1) an argument list and 2) a body."+        "let" ->+          case args of+            [Parse.SExpression _ bindings, body] ->+              let normalizedBindings =+                    traverse+                      (\case+                         Parse.SExpression _ [name, value] ->+                           (,) <$> normalizeExpression name <*>+                           normalizeExpression value+                         x ->+                           pushCtxt x $+                           throwNormalizeError+                             "Each `let` binding must be an s-expression containing: 1) a pattern and 2) a value!")+                      bindings+               in ELetBlock <$>+                  (LetBlock (Just expr) <$> normalizedBindings <*>+                   normalizeExpression body)+            _ ->+              throwNormalizeError+                "`let` takes exactly two arguments: 1) a bindings list and 2) a body."+        "raw" ->+          case args of+            [rawSource] ->+              let normalizedRawSource =+                    case rawSource of+                      Parse.LiteralString _ x -> pure x+                      x ->+                        pushCtxt x $+                        throwNormalizeError+                          "`raw` takes strings representing the code to inject directly."+               in ERawExpression (Just expr) . T.pack <$> normalizedRawSource+            _ ->+              throwNormalizeError+                "`raw` takes exactly one argument: a string literal."+        "record" ->+          let normalizedBindings =+                traverse+                  (\x ->+                     normalizeExpression x >>= \case+                       EFunctionApplication (FunctionApplication _ (EIdentifier _ field) [val]) ->+                         pure (field, val)+                       _ ->+                         pushCtxt x $+                         throwNormalizeError+                           "Each `record` field setter must be an s-expression containing: 1) a field name and 2) a value!")+                  args+           in ERecordDefinition <$>+              (RecordDefinition (Just expr) <$> normalizedBindings)+        "recordType" ->+          let normalizedFields =+                traverse+                  (\x ->+                     normalizeExpression x >>= \case+                       EFunctionApplication (FunctionApplication _ (EIdentifier _ field) [ty]) ->+                         pure (field, ty)+                       _ ->+                         pushCtxt x $+                         throwNormalizeError+                           "Each `recordType` field descriptor must be an s-expression containing: 1) a field name and 2) a type!")+                  args+           in ERecordType <$> (RecordType (Just expr) <$> normalizedFields)+        _ ->+          EFunctionApplication <$>+          (FunctionApplication (Just expr) <$>+           normalizeExpression (Parse.Symbol sourceMetadata special) <*>+           traverse normalizeExpression args)     fn:args ->       EFunctionApplication <$>       (FunctionApplication (Just expr) <$> normalizeExpression fn <*>@@ -180,10 +212,28 @@   traverse     (\x ->        normalizeStatement x >>= \case-         SFunctionDefinition funDef -> pure funDef-         _ -> pushCtxt x $ throwNormalizeError "Invalid where binding!")+         stmt@(SFunctionDefinition _) -> pure stmt+         stmt@(STypeSignature _) -> pure stmt+         _ ->+           pushCtxt x $+           throwNormalizeError+             "Each `where` binding must be either a function definition or a type signature!")     whereDefs +normalizeConstraints ::+     (Sem.Members '[ Sem.Error Error, Sem.Reader FilePath, Sem.Reader ExprCtxt] effs)+  => SM.Expression+  -> Sem.Sem effs [SMExpression]+normalizeConstraints constraints =+  normalizeExpression constraints >>= \case+    EEmptySExpression _ -> pure []+    EFunctionApplication (FunctionApplication _ constraintsHead constraintsRest) ->+      pure $ constraintsHead : constraintsRest+    _ ->+      pushCtxt constraints $+      throwNormalizeError+        "Constraint lists must only contain type constructors!"+ normalizeStatement ::      (Sem.Members '[ Sem.Error Error, Sem.Reader FilePath, Sem.Reader ExprCtxt] effs)   => SM.Expression@@ -191,127 +241,215 @@ normalizeStatement expr@(Parse.SExpression _ items) =   pushCtxt expr $   case items of-    [Parse.Symbol _ "::", Parse.Symbol _ fnName, typeDef] ->-      STypeSignature <$>-      (TypeSignature (Just expr) (T.pack fnName) <$> normalizeExpression typeDef)-    Parse.Symbol _ "=":Parse.Symbol _ fnName:Parse.SExpression _ arguments:body:whereDefs ->-      SFunctionDefinition <$>-      normalizeFunctionDefinition expr (T.pack fnName) arguments body whereDefs-    Parse.Symbol _ "begin":stmts ->-      let normalizedStmts = traverse normalizeStatement stmts-       in STopLevel . TopLevel (Just expr) <$> normalizedStmts-    Parse.Symbol _ "class":classConstraints:className:sigs ->-      let normalizedConstraints =-            normalizeExpression classConstraints >>= \case-              EFunctionApplication (FunctionApplication _ (EIdentifier _ "list") constraints) ->-                pure constraints-              _ ->-                pushCtxt classConstraints $-                throwNormalizeError "Invalid constraints!"-          normalizedSigs =-            traverse-              (\x ->-                 normalizeStatement x >>= \case-                   STypeSignature tySig -> pure tySig-                   _ ->-                     pushCtxt x $ throwNormalizeError "Invalid type signature!")-              sigs-       in STypeclassDefinition <$>-          (TypeclassDefinition (Just expr) <$> normalizeExpression className <*>-           normalizedConstraints <*>-           normalizedSigs)-    Parse.Symbol _ "data":typeDef:constructors ->-      let normalizedConstructors =-            traverse-              (\x ->-                 normalizeExpression x >>= \case-                   EFunctionApplication functionApplication ->-                     pure functionApplication-                   _ ->-                     pushCtxt x $-                     throwNormalizeError "Invalid type constructor!")-              constructors-       in normalizeExpression typeDef >>= \case-            EFunctionApplication typeConstructor ->-              SDataDeclaration <$>-              (DataDeclaration-                 (Just expr)-                 (TypeConstructor (Just expr) typeConstructor) <$>-               normalizedConstructors)-            EIdentifier _ properType ->-              SDataDeclaration <$>-              (DataDeclaration (Just expr) (ProperType (Just expr) properType) <$>-               normalizedConstructors)-            _ -> pushCtxt typeDef $ throwNormalizeError "Invalid type!"-    [Parse.Symbol _ "newtype", typeDef, constructor] ->-      let normalizedConstructor =-            normalizeExpression constructor >>= \case-              EFunctionApplication funApp -> pure funApp-              _ ->-                pushCtxt constructor $-                throwNormalizeError "Invalid type constructor!"-       in normalizeExpression typeDef >>= \case-            EFunctionApplication typeConstructor ->-              SNewtypeDeclaration <$>-              (NewtypeDeclaration-                 (Just expr)-                 (TypeConstructor (Just expr) typeConstructor) <$>-               normalizedConstructor)-            EIdentifier _ properType ->-              SNewtypeDeclaration <$>-              (NewtypeDeclaration-                 (Just expr)-                 (ProperType (Just expr) properType) <$>-               normalizedConstructor)-            _ -> pushCtxt typeDef $ throwNormalizeError "Invalid type!"-    [Parse.Symbol _ "import", Parse.Symbol _ moduleName, importSpec] ->-      SRestrictedImport <$>-      (RestrictedImport (Just expr) (T.pack moduleName) <$>-       normalizeImportSpec importSpec)-    [Parse.Symbol _ "importm", Parse.Symbol _ moduleName, macroImportSpec] ->-      SMacroImport . MacroImport (Just expr) (T.pack moduleName) <$>-      normalizeMacroImportSpec macroImportSpec-    [Parse.Symbol _ "importq", Parse.Symbol _ moduleName, Parse.Symbol _ alias, importSpec] ->-      SQualifiedImport <$>-      (QualifiedImport (Just expr) (T.pack moduleName) (T.pack alias) <$>-       normalizeImportSpec importSpec)-    Parse.Symbol _ "instance":instanceName:defs ->-      let normalizedDefs =-            traverse-              (\x ->-                 normalizeStatement x >>= \case-                   SFunctionDefinition fnDef -> pure fnDef-                   _ -> pushCtxt x $ throwNormalizeError "Invalid definition!")-              defs-       in STypeclassInstance <$>-          (TypeclassInstance (Just expr) <$> normalizeExpression instanceName <*>-           normalizedDefs)-    [Parse.Symbol _ "pragma", Parse.LiteralString _ pragma] ->-      pure $ SPragma (Pragma (Just expr) (T.pack pragma))-    Parse.Symbol _ "=macro":Parse.Symbol _ macroName:Parse.SExpression _ arguments:body:whereBindings ->-      SMacroDefinition . MacroDefinition (Just expr) <$>-      normalizeFunctionDefinition-        expr-        (T.pack macroName)-        arguments-        body-        whereBindings-    [Parse.Symbol _ "module", Parse.Symbol _ moduleName] ->-      pure $ SModuleDeclaration (Just expr) (T.pack moduleName)-    [Parse.Symbol _ "raw", rawSource] ->-      let normalizedRawSource =-            case rawSource of-              Parse.LiteralString _ x -> pure $ T.pack x-              x ->-                pushCtxt x $-                throwNormalizeError-                  "`raw` takes strings representing the code to inject directly."-       in SRawStatement (Just expr) <$> normalizedRawSource-    [Parse.Symbol _ "type", alias, def] ->-      let normalizedAlias = normalizeExpression alias-          normalizedDef = normalizeExpression def-       in STypeSynonym <$>-          (TypeSynonym (Just expr) <$> normalizedAlias <*> normalizedDef)+    Parse.Symbol _ special:args ->+      case unhygenisizeIdentifier special of+        "::" ->+          case args of+            [Parse.Symbol _ fnName, constraints, typeDef] ->+              STypeSignature <$>+              (TypeSignature (Just expr) (T.pack fnName) <$>+               normalizeConstraints constraints <*>+               normalizeExpression typeDef)+            _ ->+              throwNormalizeError+                "`::` takes three arguments: 1) a function name, 2) a list of constraints, and 3) a type."+        "=" ->+          case args of+            fnSpecifier:body:whereDefs -> do+              (fnName, arguments) <-+                case fnSpecifier of+                  Parse.Symbol _ fnName -> pure (fnName, [])+                  Parse.SExpression _ (Parse.Symbol _ fnName:args') ->+                    pure (fnName, args')+                  _ ->+                    throwNormalizeError+                      "A function head specifier takes 1) a function name, followed by argument patterns."+              SFunctionDefinition <$>+                normalizeFunctionDefinition+                  expr+                  (T.pack fnName)+                  arguments+                  body+                  whereDefs+            _ ->+              throwNormalizeError+                "`=` takes 1) a function head specifier 2) and an expression, followed by `where` bindings."+        "begin" ->+          let normalizedStmts = traverse normalizeStatement args+           in STopLevel . TopLevel (Just expr) <$> normalizedStmts+        "class" ->+          case args of+            classConstraints:className:sigs ->+              let normalizedConstraints =+                    normalizeExpression classConstraints >>= \case+                      EEmptySExpression _ -> pure []+                      EFunctionApplication (FunctionApplication _ constraintsHead constraintsRest) ->+                        pure $ constraintsHead : constraintsRest+                      _ ->+                        pushCtxt classConstraints $+                        throwNormalizeError+                          "A `class` constraint list must only contain type constructors!"+                  normalizedSigs =+                    traverse+                      (\x ->+                         normalizeStatement x >>= \case+                           STypeSignature tySig -> pure tySig+                           _ ->+                             pushCtxt x $+                             throwNormalizeError+                               "`class`'s body must contain type signatures!")+                      sigs+               in STypeclassDefinition <$>+                  (TypeclassDefinition (Just expr) <$>+                   normalizeExpression className <*>+                   normalizedConstraints <*>+                   normalizedSigs)+            _ ->+              throwNormalizeError+                "`class` takes a constraint list, a type constructor, and type signatures!"+        "data" ->+          case args of+            typeDef:constructors ->+              normalizeExpression typeDef >>= \case+                EFunctionApplication typeConstructor ->+                  SDataDeclaration <$>+                  (DataDeclaration+                     (Just expr)+                     (TypeConstructor (Just expr) typeConstructor) <$>+                   traverse normalizeExpression constructors)+                EIdentifier _ properType ->+                  SDataDeclaration <$>+                  (DataDeclaration+                     (Just expr)+                     (ProperType (Just expr) properType) <$>+                   traverse normalizeExpression constructors)+                _ ->+                  pushCtxt typeDef $+                  throwNormalizeError "Invalid type constructor!"+            _ ->+              throwNormalizeError+                "`data` takes a type constructor followed by type constructors!"+        "newtype" ->+          case args of+            [typeDef, wrappedType] ->+              normalizeExpression typeDef >>= \case+                EFunctionApplication typeConstructor ->+                  SNewtypeDeclaration <$>+                  (NewtypeDeclaration+                     (Just expr)+                     (TypeConstructor (Just expr) typeConstructor) <$>+                   normalizeExpression wrappedType)+                EIdentifier _ properType ->+                  SNewtypeDeclaration <$>+                  (NewtypeDeclaration+                     (Just expr)+                     (ProperType (Just expr) properType) <$>+                   normalizeExpression wrappedType)+                _ ->+                  pushCtxt typeDef $+                  throwNormalizeError "Invalid type constructor!"+            _ ->+              throwNormalizeError+                "`newtype` takes exactly two arguments: 1) a type constructor and 2) a type."+        "import" ->+          case args of+            [Parse.Symbol _ moduleName, importSpec] ->+              SRestrictedImport <$>+              (RestrictedImport (Just expr) (T.pack moduleName) <$>+               normalizeImportSpec importSpec)+            _ ->+              throwNormalizeError+                "`import` takes exactly two arguments: 1) a module name and 2) an import specification."+        "importm" ->+          case args of+            [Parse.Symbol _ moduleName, macroImportSpec] ->+              SMacroImport . MacroImport (Just expr) (T.pack $ moduleName) <$>+              normalizeMacroImportSpec macroImportSpec+            _ ->+              throwNormalizeError+                "`importm` takes exactly two arguments: 1) a module name and 2) a list of macro names."+        "importq" ->+          case args of+            [Parse.Symbol _ moduleName, Parse.Symbol _ alias, importSpec] ->+              SQualifiedImport <$>+              (QualifiedImport (Just expr) (T.pack moduleName) (T.pack alias) <$>+               normalizeImportSpec importSpec)+            _ ->+              throwNormalizeError+                "`importq` takes exactly three arguments: 1) a module name, 2) a module name, and 3) an import specification."+        "instance" ->+          case args of+            instanceConstraints:instanceName:defs ->+              let normalizedDefs =+                    traverse+                      (\x ->+                         normalizeStatement x >>= \case+                           SFunctionDefinition fnDef -> pure fnDef+                           _ ->+                             pushCtxt x $+                             throwNormalizeError+                               "`instance`'s body must only contain function definitions!")+                      defs+               in STypeclassInstance <$>+                  (TypeclassInstance (Just expr) <$>+                   normalizeExpression instanceName <*>+                   normalizeConstraints instanceConstraints <*>+                   normalizedDefs)+            _ ->+              throwNormalizeError+                "`instance` takes a constraint list, an expression, and a list of function definitions!"+        "pragma" ->+          case args of+            [Parse.LiteralString _ pragma] ->+              pure $ SPragma (Pragma (Just expr) (T.pack pragma))+            _ ->+              throwNormalizeError+                "`pragma` takes exactly one argument: a string literal."+        "=macro" ->+          case args of+            Parse.Symbol _ macroName:Parse.SExpression _ arguments:body:whereBindings ->+              SMacroDefinition . MacroDefinition (Just expr) <$>+              normalizeFunctionDefinition+                expr+                (T.pack macroName)+                arguments+                body+                whereBindings+            _ ->+              throwNormalizeError+                "`=macro` takes 1) an identifier, 2) an argument list, 3) an expression, and 4) a list of statements."+        "module" ->+          case args of+            [Parse.Symbol _ moduleName] ->+              pure $ SModuleDeclaration (Just expr) (T.pack moduleName)+            _ ->+              throwNormalizeError+                "`module` takes exactly one argument: a module name."+        "raw" ->+          case args of+            [rawSource] ->+              let normalizedRawSource =+                    case rawSource of+                      Parse.LiteralString _ x -> pure $ T.pack x+                      x ->+                        pushCtxt x $+                        throwNormalizeError+                          "`raw` takes strings representing the code to inject directly."+               in SRawStatement (Just expr) <$> normalizedRawSource+            _ ->+              throwNormalizeError+                "`raw` takes exactly one argument: a string literal."+        "type" ->+          case args of+            [alias, def] ->+              let normalizedAlias = normalizeExpression alias+                  normalizedDef = normalizeExpression def+               in STypeSynonym <$>+                  (TypeSynonym (Just expr) <$> normalizedAlias <*> normalizedDef)+            _ ->+              throwNormalizeError+                "`type` takes exactly two arguments: 1) a type constructor and 2) a type."+        _ -> throwNormalizeError "Invalid statement!"     _ -> throwNormalizeError "Invalid statement!"   where     normalizeMacroImportSpec importSpec =@@ -320,15 +458,22 @@           traverse             (\case                Parse.Symbol _ import' -> pure $ T.pack import'-               x -> pushCtxt x $ throwNormalizeError "Invalid macro import!")+               x ->+                 pushCtxt x $+                 throwNormalizeError "A macro import must be an identifier!")             macroImportList         x ->-          pushCtxt x $ throwNormalizeError "Invalid macro import specification!"+          pushCtxt x $+          throwNormalizeError+            "`importm`'s import specification must be a list of identifiers (`all` is not valid for macro imports)!"     normalizeImportSpec importSpec =       case importSpec of         Parse.Symbol _ "all" -> pure $ ImportAll (Just expr)         Parse.SExpression _ importList -> normalizeImportList importList-        x -> pushCtxt x $ throwNormalizeError "Invalid import specification!"+        x ->+          pushCtxt x $+          throwNormalizeError+            "An import specification must be either `all` or a list of import items!"     normalizeImportList input =       ImportOnly (Just expr) <$>       traverse@@ -343,10 +488,14 @@                        (\case                           Parse.Symbol _ import' -> pure $ T.pack import'                           x ->-                            pushCtxt x $ throwNormalizeError "Invalid import!")+                            pushCtxt x $+                            throwNormalizeError+                              "An import subitem must be an identifier!")                        imports                 in ImportType (Just expr) (T.pack type') <$> normalizedImports-             _ -> throwNormalizeError "Invalid import!")+             _ ->+               throwNormalizeError+                 "An import item must be either an identifier or an s-expression of identifiers!")         input normalizeStatement expr =   pushCtxt expr $ throwNormalizeError "Invalid top-level form!"
src/Axel/Parse.hs view
@@ -5,10 +5,15 @@ import Axel.Prelude  import Axel.Eff.Error (Error(ParseError))-import Axel.Haskell.Language (haskellOperatorSymbols, haskellSyntaxSymbols)+import Axel.Haskell.Language+  ( haskellKeywords+  , haskellOperatorSymbols+  , haskellSyntaxSymbols+  , isOperator+  ) import Axel.Parse.AST-  ( Expression(LiteralChar, LiteralInt, LiteralString, SExpression,-           Symbol)+  ( Expression(LiteralChar, LiteralFloat, LiteralInt, LiteralString,+           SExpression, Symbol)   , bottomUpFmapSplicing   , getAnn   )@@ -19,13 +24,16 @@   , quoteSourceMetadata   , wrapCompoundExpressions   )+import Axel.Utils.List (remove, unsafeHead)+import qualified Axel.Utils.Text as T (remove)  import Control.Applicative ((<|>)) import Control.Lens (op) import Control.Monad (void) -import Data.List ((\\))+import Data.List ((\\), foldl') import Data.Maybe (fromMaybe)+import Data.MonoTraversable (onotElem) import qualified Data.Text as T import Data.Void (Void) @@ -34,7 +42,12 @@  import qualified Text.Megaparsec as P import qualified Text.Megaparsec.Char as P-import qualified Text.Megaparsec.Char.Lexer as P (charLiteral)+import qualified Text.Megaparsec.Char.Lexer as P+  ( charLiteral+  , decimal+  , float+  , signed+  )  type Parser = P.Parsec Void Text @@ -59,17 +72,20 @@   ann SExpression (pure [Symbol Nothing (T.unpack wrapper), expr])  eol :: Parser ()-eol = P.try (void P.eol) <|> P.eof+eol = void P.eol <|> P.eof  ignored :: Parser () ignored = P.skipMany $ P.try comment <|> void P.spaceChar  literalChar :: Parser SM.Expression-literalChar = ann LiteralChar (P.string "#\\" *> P.anySingle)+literalChar = ann LiteralChar (P.string "#\\" *> P.charLiteral)  literalInt :: Parser SM.Expression-literalInt = ann LiteralInt (read <$> P.some P.digitChar)+literalInt = ann LiteralInt (P.signed mempty P.decimal) +literalFloat :: Parser SM.Expression+literalFloat = ann LiteralFloat (P.signed mempty P.float)+ literalList :: Parser SM.Expression literalList =   ann@@ -105,12 +121,12 @@  symbol :: Parser SM.Expression symbol =-  ann-    Symbol-    (P.some-       (P.try P.alphaNumChar <|> P.try (P.oneOf ['\'', '_']) <|>-        P.try (P.oneOf (map fst haskellSyntaxSymbols \\ syntaxSymbols)) <|>-        P.oneOf (map fst haskellOperatorSymbols)))+  ann Symbol $+  hygenisizeIdentifier <$>+  P.some+    (P.alphaNumChar <|> P.oneOf ['\'', '_'] <|>+     P.oneOf (map fst haskellSyntaxSymbols \\ syntaxSymbols) <|>+     P.oneOf (map fst haskellOperatorSymbols))  unquotedExpression :: Parser SM.Expression unquotedExpression = parseReadMacro "~" "unquote"@@ -122,14 +138,14 @@  expression :: Parser SM.Expression expression =-  P.try literalChar <|> P.try literalInt <|> P.try literalList <|>-  P.try literalString <|>-  P.try quotedExpression <|>-  P.try quasiquotedExpression <|>-  P.try spliceUnquotedExpression <|>-  P.try unquotedExpression <|>-  P.try sExpression <|>-  P.try infixSExpression <|>+  P.try literalFloat <|> P.try literalInt <|> sExpression <|> infixSExpression <|>+  literalList <|>+  literalString <|>+  quotedExpression <|>+  quasiquotedExpression <|>+  spliceUnquotedExpression <|>+  unquotedExpression <|>+  literalChar <|>   symbol  -- Adapted from Appendix A of "Quasiquotation in Lisp" by Alan Bawden.@@ -161,18 +177,27 @@   let ann' = getAnn expr    in SExpression ann' [Symbol ann' "list", expandQuasiquote expr] -parseMultiple ::+parseMultiple' ::      (Sem.Member (Sem.Error Error) effs)-  => Maybe FilePath+  => ([SM.Expression] -> [SM.Expression])+  -> Maybe FilePath   -> Text   -> Sem.Sem effs [SM.Expression]-parseMultiple maybeFilePath input =-  either throwErr (pure . expandQuasiquotes) $+parseMultiple' postProcess maybeFilePath input =+  either throwErr (pure . postProcess) $   P.parse program (T.unpack $ op FilePath filePath) input   where     filePath = fromMaybe (FilePath "") maybeFilePath     program = P.some (ignored *> expression <* ignored) <* P.eof     throwErr = Sem.throw . ParseError filePath . T.pack . P.errorBundlePretty++parseMultiple ::+     (Sem.Member (Sem.Error Error) effs)+  => Maybe FilePath+  -> Text+  -> Sem.Sem effs [SM.Expression]+parseMultiple = parseMultiple' expandQuasiquotes+  where     expandQuasiquotes =       map $       bottomUpFmapSplicing@@ -189,4 +214,50 @@   wrapCompoundExpressions <$> parseMultiple filePath input  syntaxSymbols :: String-syntaxSymbols = "()[]{}"+syntaxSymbols = "()[]{}\""++charReplacements ::+     [(Char, String)] -> [(Char, String)] -> String -> [(Char, String)]+charReplacements syntaxCharReplacements operatorCharReplacements x =+  let targetCharReplacements =+        syntaxCharReplacements <>+        if isOperator x+          then []+          else operatorCharReplacements+   in allowQualifiedNames $+      filter (\(sym, _) -> sym `onotElem` syntaxSymbols) targetCharReplacements+  where+    allowQualifiedNames = remove $ (== '.') . fst++valueHygienePrefix :: Text+valueHygienePrefix = "aXEL_VALUE_"++hygenisizeIdentifier :: String -> String+hygenisizeIdentifier x+  | [(_, new)] <- filter ((x ==) . fst) haskellKeywords = new+  | otherwise =+    let prefix =+          if unsafeHead x `elem` map fst replacements+            then valueHygienePrefix+            else ""+     in T.unpack $+        prefix <>+        foldl'+          (\acc (old, new) -> T.replace (T.singleton old) (T.pack new) acc)+          (T.pack x)+          replacements+  where+    replacements =+      charReplacements haskellSyntaxSymbols haskellOperatorSymbols x++unhygenisizeIdentifier :: String -> String+unhygenisizeIdentifier x+  | [(old, _)] <- filter ((x ==) . snd) haskellKeywords = old+  | otherwise -- There _could_ be multiple matches, but that would be VERY, VERY BAD™.+   =+    T.unpack $+    T.remove valueHygienePrefix $ -- The prefix isn't always there, in which case this just no-ops.+    foldl'+      (\acc (old, new) -> T.replace (T.pack new) (T.singleton old) acc)+      (T.pack x) $+    charReplacements haskellSyntaxSymbols haskellOperatorSymbols x
src/Axel/Parse/AST.hs view
@@ -42,6 +42,7 @@ --      on `Axel.Prelude` in user-facing code. data Expression ann   = LiteralChar ann Char+  | LiteralFloat ann Float   | LiteralInt ann Int   | LiteralString ann String   | SExpression ann [Expression ann]@@ -55,6 +56,7 @@ -- TODO Derive this automatically. getAnn :: Expression ann -> ann getAnn (LiteralChar ann _) = ann+getAnn (LiteralFloat ann _) = ann getAnn (LiteralInt ann _) = ann getAnn (LiteralString ann _) = ann getAnn (SExpression ann _) = ann@@ -73,6 +75,7 @@         let recurse =               case hole z of                 LiteralChar _ _ -> pure+                LiteralFloat _ _ -> pure                 LiteralInt _ _ -> pure                 LiteralString _ _ -> pure                 SExpression _ [] -> pure@@ -96,6 +99,7 @@         let recurse =               case x of                 LiteralChar _ _ -> pure+                LiteralFloat _ _ -> pure                 LiteralInt _ _ -> pure                 LiteralString _ _ -> pure                 SExpression _ [] -> pure@@ -116,6 +120,7 @@  toAxel :: Expression ann -> Text toAxel (LiteralChar _ x) = "#\\" <> T.singleton x+toAxel (LiteralFloat _ x) = showText x toAxel (LiteralInt _ x) = showText x toAxel (LiteralString _ xs) = "\"" <> handleCharEscapes (T.pack xs) <> "\"" toAxel (SExpression _ (Symbol _ "applyInfix":xs)) =@@ -140,6 +145,10 @@   SExpression     ann     [Symbol ann "AST.LiteralChar", quoteAnn ann, LiteralChar ann x]+quoteExpression quoteAnn (LiteralFloat ann x) =+  SExpression+    ann+    [Symbol ann "AST.LiteralFloat", quoteAnn ann, LiteralFloat ann x] quoteExpression quoteAnn (LiteralInt ann x) =   SExpression ann [Symbol ann "AST.LiteralInt", quoteAnn ann, LiteralInt ann x] quoteExpression quoteAnn (LiteralString ann x) =
src/Axel/Parse/Args.hs view
@@ -1,4 +1,5 @@ module Axel.Parse.Args where+import Axel import qualified Prelude as GHCPrelude import qualified Axel.Parse.AST as AST import Axel.Prelude@@ -8,15 +9,15 @@ import qualified Data.Text as T import Options.Applicative(Parser,ParserInfo,argument,command,fullDesc,helper,hsubparser,info,metavar,progDesc,str) data FileCommand = ConvertFile FilePath|RunFile FilePath|FormatFile FilePath-data ProjectCommand = ConvertProject |FormatProject |RunProject -data Command = FileCommand FileCommand|ProjectCommand ProjectCommand|Version +data ProjectCommand = ConvertProject|FormatProject|RunProject+data Command = FileCommand FileCommand|ProjectCommand ProjectCommand|Version+experimental :: () => ((->) String String) experimental  = ((<>) "(EXPERIMENTAL) ")-experimental :: ((->) String String)+command' :: () => ((->) String ((->) (ParserInfo a) (Parser a))) command' name parserInfo = (hsubparser ((<>) (command name parserInfo) (metavar name)))-command' :: ((->) String ((->) (ParserInfo a) (Parser a)))+fileCommandParser :: () => (Parser FileCommand) fileCommandParser  = (asum [convertFileCommand,formatFileCommand,runFileCommand]) where {convertFileCommand  = (command' "convert" (filePathParser ConvertFile (experimental "Convert a Haskell file to Axel")));runFileCommand  = (command' "run" (filePathParser RunFile "Transpile and run an Axel file"));formatFileCommand  = (command' "format" (filePathParser FormatFile "Format an Axel file"));filePathParser ctor desc = (info ((<$>) ((.) ctor ((.) FilePath T.pack)) (argument str (metavar "FILE"))) (progDesc desc))}-fileCommandParser :: (Parser FileCommand)+projectCommandParser :: () => (Parser ProjectCommand) projectCommandParser  = (asum [convertProjectCommand,formatProjectCommand,runProjectCommand]) where {convertProjectCommand  = (command' "convert" (info (pure ConvertProject) (progDesc "Convert the Haskell project to Axel")));formatProjectCommand  = (command' "format" (info (pure FormatProject) (progDesc "Format the project")));runProjectCommand  = (command' "run" (info (pure RunProject) (progDesc "Build and run the project")))}-projectCommandParser :: (Parser ProjectCommand)+commandParserInfo :: () => (ParserInfo Command) commandParserInfo  = (let {subparsers = (asum [fileCommand,projectCommand,versionCommand])} in (info ((<**>) subparsers helper) fullDesc)) where {fileCommand  = (command' "file" (info ((<$>) FileCommand fileCommandParser) (progDesc "Run file-specific commands")));projectCommand  = (command' "project" (info ((<$>) ProjectCommand projectCommandParser) (progDesc "Run project-wide commands")));versionCommand  = (command' "version" (info (pure Version) (progDesc "Display the version of the Axel compiler")))}-commandParserInfo :: (ParserInfo Command)
src/Axel/Pretty.hs view
@@ -2,8 +2,11 @@  import Axel.Prelude +import Axel.Parse (unhygenisizeIdentifier) import Axel.Parse.AST+import qualified Axel.Sourcemap as SM import Axel.Utils.Foldable (mapWithPrev)+import Axel.Utils.Recursion (bottomUpFmap) import Axel.Utils.Text (handleCharEscapes)  import Control.Lens (ala, under)@@ -74,6 +77,7 @@  toAxelPretty :: Expression ann -> P.Doc a toAxelPretty (LiteralChar _ x) = "#\\" <> P.pretty x+toAxelPretty (LiteralFloat _ x) = P.pretty x toAxelPretty (LiteralInt _ x) = P.pretty x toAxelPretty (LiteralString _ x) =   P.dquotes $ P.pretty (under unpacked handleCharEscapes x)@@ -89,7 +93,7 @@ toAxelPretty (Symbol _ x) = P.pretty x toAxelPretty (SExpression _ xs) = P.parens $ privilegedFormToAxelPretty xs -spaceStatements :: [Expression ann] -> [P.Doc a]+spaceStatements :: [SM.Expression] -> [P.Doc a] spaceStatements =   mapWithPrev $ \prev x ->     let isImport (SExpression _ (Symbol _ id':_)) =@@ -100,7 +104,11 @@           if needsSpacing             then P.line             else mempty-     in toAxelPretty x <> maybeSpacer+        unhygenisize =+          bottomUpFmap $ \case+            Symbol ann symbol -> Symbol ann $ unhygenisizeIdentifier symbol+            node -> node+     in toAxelPretty (unhygenisize x) <> maybeSpacer -prettifyProgram :: [Expression ann] -> Text+prettifyProgram :: [SM.Expression] -> Text prettifyProgram = render . P.vsep . spaceStatements
src/Axel/Sourcemap.hs view
@@ -13,10 +13,10 @@   ( Expression(LiteralInt, LiteralString, SExpression, Symbol)   , quoteExpression   )-import Axel.Utils.Foldable (intercalate) import Axel.Utils.Text (Renderer) import Axel.Utils.Tuple (Annotated, annotate, annotation, unannotate) +import Control.Lens ((|>)) import Control.Lens.Operators ((^.)) import Control.Lens.TH (makeFieldsNoPrefix, makeWrapped) import Control.Monad (when)@@ -100,14 +100,19 @@  surround :: Bracket -> Output -> Output surround bracket x =-  let (open, closed) =+  let (startMetadata, endMetadata) =+        case x of+          Output [] -> (Nothing, Nothing)+          Output xs -> (head xs ^. annotation, last xs ^. annotation)+      (open, closed) =         case bracket of           CurlyBraces -> ("{", "}")           DoubleQuotes -> ("\"", "\"")           Parentheses -> ("(", ")")           SingleQuotes -> ("'", "'")           SquareBrackets -> ("[", "]")-   in unassociated open <> x <> unassociated closed+   in Output [annotate startMetadata open] <>+      x <> Output [annotate endMetadata closed]  data Delimiter   = Commas@@ -117,8 +122,21 @@   | Spaces  delimit :: Delimiter -> [Output] -> Output-delimit delimiter = intercalate (unassociated $ renderDelimiter delimiter)+delimit delimiter =+  Output .+  tryInit . -- Remove unneeded final delimiter+  concatMap+    (\(Output x) ->+       let metadata =+             case x of+               [] -> Nothing+               (x':_) -> x' ^. annotation+        in x |> annotate metadata (renderDelimiter delimiter))   where+    tryInit :: [a] -> [a]+    tryInit [] = []+    tryInit xs = init xs+    renderDelimiter :: Delimiter -> Text     renderDelimiter Commas = ","     renderDelimiter Newlines = "\n"     renderDelimiter Pipes = "|"
− src/Axel/Utils/Function.hs
@@ -1,4 +0,0 @@-module Axel.Utils.Function where--uncurry3 :: (a -> b -> c -> d) -> (a, b, c) -> d-uncurry3 f (a, b, c) = f a b c
src/Axel/Utils/List.hs view
@@ -21,7 +21,7 @@ head' :: [a] -> Maybe a head' = listToMaybe --- Alternatively, `unsafeHead = head`.+-- | 'unsafeHead' == 'head'. unsafeHead :: [a] -> a unsafeHead = fromJust . listToMaybe @@ -73,6 +73,3 @@  filterMap :: (a -> Maybe b) -> [a] -> [b] filterMap f xs = snd $ filterMapOut f xs--only :: a -> [a]-only x = [x]
src/Axel/Utils/Maybe.hs view
@@ -14,7 +14,3 @@ foldUntilNothing :: (a -> Maybe a) -> (a -> a) -> a -> a foldUntilNothing move modify =   runIdentity . foldMUntilNothing move (pure . modify)--whenMaybe :: (Applicative f) => Maybe a -> (a -> f ()) -> f ()-whenMaybe (Just x) f = f x-whenMaybe Nothing _ = pure ()
src/Axel/Utils/Monad.hs view
@@ -2,5 +2,9 @@  import Axel.Prelude -concatMapM :: (Monad m) => (a -> m [b]) -> [a] -> m [b]-concatMapM f xs = concat <$> mapM f xs+import Control.Monad (when)++whileM :: (Monad m) => (m Bool) -> m () -> m ()+whileM cond action = do+  cond' <- cond+  when cond' $ action >> whileM cond action
src/Axel/Utils/Text.hs view
@@ -59,3 +59,6 @@  decodeUtf8Lazy :: B.ByteString -> Text decodeUtf8Lazy = T.decodeUtf8 . B.toStrict++remove :: Text -> Text -> Text+remove needle haystack = T.replace needle "" haystack
test/Axel/Test/ASTGen.hs view
@@ -7,6 +7,9 @@ import qualified Axel.AST as AST import qualified Axel.Sourcemap as SM +import Control.Applicative+import Control.Lens (isn't)+ import qualified Hedgehog.Gen as Gen import qualified Hedgehog.Range as Range @@ -19,6 +22,7 @@ genLiteral =   Gen.choice     [ AST.LChar Nothing <$> Gen.unicode+    , AST.LFloat Nothing <$> Gen.float (Range.exponentialFloat (-10000) 10000)     , AST.LInt Nothing <$> Gen.int Range.constantBounded     , AST.LString Nothing <$> Gen.text (Range.linear 0 5) Gen.unicode     ]@@ -26,27 +30,24 @@ genCaseBlock :: (MonadGen m) => m (AST.CaseBlock (Maybe SM.Expression)) genCaseBlock =   AST.CaseBlock Nothing <$> genExpression <*>-  Gen.list (Range.linear 0 3) ((,) <$> genExpression <*> genExpression)+  Gen.list (Range.linear 0 10) ((,) <$> genExpression <*> genExpression)  genFunctionApplication ::      (MonadGen m) => m (AST.FunctionApplication (Maybe SM.Expression)) genFunctionApplication =-  AST.FunctionApplication Nothing <$> genExpression <*>-  Gen.list (Range.linear 0 3) genExpression--genIfBlock :: (MonadGen m) => m (AST.IfBlock (Maybe SM.Expression))-genIfBlock =-  AST.IfBlock Nothing <$> genExpression <*> genExpression <*> genExpression+  AST.FunctionApplication Nothing <$>+  Gen.filter (isn't AST._EEmptySExpression) genExpression <*>+  Gen.list (Range.linear 0 10) genExpression  genLambda :: (MonadGen m) => m (AST.Lambda (Maybe SM.Expression)) genLambda =-  AST.Lambda Nothing <$> Gen.list (Range.linear 0 3) genExpression <*>+  AST.Lambda Nothing <$> Gen.list (Range.linear 0 10) genExpression <*>   genExpression  genLetBlock :: (MonadGen m) => m (AST.LetBlock (Maybe SM.Expression)) genLetBlock =   AST.LetBlock Nothing <$>-  Gen.list (Range.linear 0 3) ((,) <$> genExpression <*> genExpression) <*>+  Gen.list (Range.linear 0 10) ((,) <$> genExpression <*> genExpression) <*>   genExpression  genRawExpression :: (MonadGen m) => m Text@@ -56,12 +57,12 @@      (MonadGen m) => m (AST.RecordDefinition (Maybe SM.Expression)) genRecordDefinition =   AST.RecordDefinition Nothing <$>-  Gen.list (Range.linear 0 3) ((,) <$> genIdentifier <*> genExpression)+  Gen.list (Range.linear 0 10) ((,) <$> genIdentifier <*> genExpression)  genRecordType :: (MonadGen m) => m (AST.RecordType (Maybe SM.Expression)) genRecordType =   AST.RecordType Nothing <$>-  Gen.list (Range.linear 0 3) ((,) <$> genIdentifier <*> genExpression)+  Gen.list (Range.linear 0 10) ((,) <$> genIdentifier <*> genExpression)  genExpression :: (MonadGen m) => m (AST.Expression (Maybe SM.Expression)) genExpression =@@ -75,7 +76,6 @@     , AST.ELambda <$> genLambda     , AST.ELetBlock <$> genLetBlock     , AST.ELiteral <$> genLiteral-    , AST.EIfBlock <$> genIfBlock     , AST.ERawExpression Nothing <$> genRawExpression     , AST.ERecordDefinition <$> genRecordDefinition     , AST.ERecordType <$> genRecordType@@ -93,21 +93,26 @@      (MonadGen m) => m (AST.DataDeclaration (Maybe SM.Expression)) genDataDeclaration =   AST.DataDeclaration Nothing <$> genTypeDefinition <*>-  Gen.list (Range.linear 0 3) genFunctionApplication+  Gen.list (Range.linear 0 10) genExpression  genFunctionDefinition ::-     (MonadGen m) => m (AST.FunctionDefinition (Maybe SM.Expression))+     (Alternative m, MonadGen m)+  => m (AST.FunctionDefinition (Maybe SM.Expression)) genFunctionDefinition =   AST.FunctionDefinition Nothing <$> genIdentifier <*>-  Gen.list (Range.linear 0 3) genExpression <*>+  Gen.list (Range.linear 0 10) genExpression <*>   genExpression <*>-  Gen.list (Range.linear 0 3) genFunctionDefinition+  Gen.list+    (Range.linear 0 10)+    ((AST.STypeSignature <$> genTypeSignature) <|>+     (AST.SFunctionDefinition <$> genFunctionDefinition))  genPragma :: (MonadGen m) => m (AST.Pragma (Maybe SM.Expression)) genPragma = AST.Pragma Nothing <$> Gen.text (Range.linear 0 10) Gen.ascii  genMacroDefinition ::-     (MonadGen m) => m (AST.MacroDefinition (Maybe SM.Expression))+     (Alternative m, MonadGen m)+  => m (AST.MacroDefinition (Maybe SM.Expression)) genMacroDefinition = AST.MacroDefinition Nothing <$> genFunctionDefinition  genImport :: (MonadGen m) => m (AST.Import (Maybe SM.Expression))@@ -115,14 +120,14 @@   Gen.choice     [ AST.ImportItem Nothing <$> genIdentifier     , AST.ImportType Nothing <$> genIdentifier <*>-      Gen.list (Range.linear 0 3) genIdentifier+      Gen.list (Range.linear 0 10) genIdentifier     ]  genImportSpecification ::      (MonadGen m) => Bool -> m (AST.ImportSpecification (Maybe SM.Expression)) genImportSpecification importAll =   let options =-        (AST.ImportOnly Nothing <$> Gen.list (Range.linear 0 3) genImport) :+        (AST.ImportOnly Nothing <$> Gen.list (Range.linear 0 10) genImport) :         [pure $ AST.ImportAll Nothing | importAll]    in Gen.choice options @@ -135,13 +140,12 @@ genMacroImport :: (MonadGen m) => m (AST.MacroImport (Maybe SM.Expression)) genMacroImport =   AST.MacroImport Nothing <$> genIdentifier <*>-  Gen.list (Range.linear 0 3) genIdentifier+  Gen.list (Range.linear 0 10) genIdentifier  genNewtypeDeclaration ::      (MonadGen m) => m (AST.NewtypeDeclaration (Maybe SM.Expression)) genNewtypeDeclaration =-  AST.NewtypeDeclaration Nothing <$> genTypeDefinition <*>-  genFunctionApplication+  AST.NewtypeDeclaration Nothing <$> genTypeDefinition <*> genExpression  genRawStatement :: (MonadGen m) => m Text genRawStatement = Gen.text (Range.linear 0 10) Gen.unicode@@ -152,29 +156,47 @@   AST.RestrictedImport Nothing <$> genIdentifier <*>   genImportSpecification importAll -genTopLevel :: (MonadGen m) => m (AST.TopLevel (Maybe SM.Expression))-genTopLevel = AST.TopLevel Nothing <$> Gen.list (Range.linear 0 3) genStatement+genTopLevel ::+     (Alternative m, MonadGen m) => m (AST.TopLevel (Maybe SM.Expression))+genTopLevel = AST.TopLevel Nothing <$> Gen.list (Range.linear 0 10) genStatement +genConstraints :: (Alternative m, MonadGen m) => m [AST.SMExpression]+genConstraints =+  Gen.list+    (Range.linear 0 10)+    ((AST.EIdentifier Nothing <$> genIdentifier) <|>+     (AST.EFunctionApplication <$> genFunctionApplication))+ genTypeclassDefinition ::-     (MonadGen m) => m (AST.TypeclassDefinition (Maybe SM.Expression))+     (Alternative m, MonadGen m)+  => m (AST.TypeclassDefinition (Maybe SM.Expression)) genTypeclassDefinition =-  AST.TypeclassDefinition Nothing <$> genExpression <*>-  Gen.list (Range.linear 0 3) genExpression <*>-  Gen.list (Range.linear 0 3) genTypeSignature+  AST.TypeclassDefinition Nothing <$>+  ((AST.EFunctionApplication <$> genFunctionApplication) <|>+   (AST.EIdentifier Nothing <$> genIdentifier)) <*>+  genConstraints <*>+  Gen.list (Range.linear 0 10) genTypeSignature  genTypeclassInstance ::-     (MonadGen m) => m (AST.TypeclassInstance (Maybe SM.Expression))+     (Alternative m, MonadGen m)+  => m (AST.TypeclassInstance (Maybe SM.Expression)) genTypeclassInstance =-  AST.TypeclassInstance Nothing <$> genExpression <*>-  Gen.list (Range.linear 0 3) genFunctionDefinition+  AST.TypeclassInstance Nothing <$>+  ((AST.EFunctionApplication <$> genFunctionApplication) <|>+   (AST.EIdentifier Nothing <$> genIdentifier)) <*>+  genConstraints <*>+  Gen.list (Range.linear 0 10) genFunctionDefinition -genTypeSignature :: (MonadGen m) => m (AST.TypeSignature (Maybe SM.Expression))-genTypeSignature = AST.TypeSignature Nothing <$> genIdentifier <*> genExpression+genTypeSignature ::+     (Alternative m, MonadGen m) => m (AST.TypeSignature (Maybe SM.Expression))+genTypeSignature =+  AST.TypeSignature Nothing <$> genIdentifier <*> genConstraints <*>+  genExpression  genTypeSynonym :: (MonadGen m) => m (AST.TypeSynonym (Maybe SM.Expression)) genTypeSynonym = AST.TypeSynonym Nothing <$> genExpression <*> genExpression -genStatement :: (MonadGen m) => m AST.SMStatement+genStatement :: (Alternative m, MonadGen m) => m AST.SMStatement genStatement =   Gen.recursive     Gen.choice
test/Axel/Test/Eff/GhciMock.hs view
@@ -42,6 +42,6 @@           modify @GhciState $ ghciMockResults .~ newMockResults           pure mockResult         Nothing ->-          throwInterpretError @GhciState "Exec" "No mock result available"+          throwInterpretError @GhciState "Exec" "Mock result not available"     go Start = throwInterpretError @GhciState "Start" "Not implemented!"     go (Stop _) = throwInterpretError @GhciState "Stop" "Not implemented!"
test/Axel/Test/Eff/ProcessMock.hs view
@@ -16,8 +16,6 @@ import qualified Polysemy.Error as Sem import qualified Polysemy.State as Sem -import Data.Functor- import System.Exit  import TestUtils@@ -61,32 +59,34 @@ runProcess origProcessState = Sem.runState origProcessState . Sem.reinterpret go   where     go :: Process m a' -> Sem.Sem (Sem.State (ProcessState effs) ': effs) a'+    go (CreateIndependentProcess _) =+      throwInterpretError+        @(ProcessState effs)+        "CreateIndependentProcess"+        "Not implemented!"+    go (CreatePassthroughProcess _) =+      throwInterpretError+        @(ProcessState effs)+        "CreatePassthroughProcess"+        "Not implemented!"     go GetArgs = Sem.gets (^. procMockArgs)-    go (RunProcessCreatingStreams cmd stdin) = do-      Sem.modify $ procExecutionLog %~ (|> (cmd, Just stdin))-      Sem.gets (uncons . (^. procMockResults)) >>= \case-        Just (ProcessResult (mockResult, fsAction), newMockResults) -> do-          Sem.modify $ procMockResults .~ newMockResults-          case mockResult of-            (exitCode, Just (stdout, stderr)) ->-              Sem.raise fsAction $> (exitCode, stdout, stderr)-            _ ->-              throwInterpretError-                "RunProcess"-                ("Wrong type for mock result: " <> showText mockResult)-        Nothing -> throwInterpretError "RunProcess" "No mock result available"-    go (RunProcessInheritingStreams cmd) = do-      Sem.modify $ procExecutionLog %~ (|> (cmd, Nothing))-      Sem.gets (uncons . (^. procMockResults)) >>= \case-        Just (ProcessResult (mockResult, fsAction), newMockResults) -> do-          Sem.modify $ procMockResults .~ newMockResults-          case mockResult of-            (exitCode, Nothing) -> Sem.raise fsAction $> exitCode-            _ ->-              throwInterpretError-                "RunProcessInheritingStreams"-                ("Wrong type for mock result: " <> showText mockResult)-        Nothing ->-          throwInterpretError-            "RunProcessInheritingStreams"-            "No mock result available"+    go (HandleGetContents _) =+      throwInterpretError+        @(ProcessState effs)+        "HandleGetContents"+        "Not implemented!"+    go (HandleGetLine _) =+      throwInterpretError+        @(ProcessState effs)+        "HandleGetLine"+        "Not implemented!"+    go (HandleIsAtEnd _) =+      throwInterpretError+        @(ProcessState effs)+        "HandleIsAtEnd"+        "Not implemented!"+    go (WaitOnProcess _) =+      throwInterpretError+        @(ProcessState effs)+        "WaitOnProcess"+        "Not implemented!"
test/Axel/Test/Haskell/StackSpec.hs view
@@ -6,6 +6,14 @@  import Axel.Prelude +import Test.Tasty.Hspec++-- TODO Flesh out `ProcessMock.runProcess` with the new `Process` actions,+--      so that we can re-enable this test suite.+spec_Stack :: SpecWith ()+spec_Stack = pure ()+{-+ import Axel.Eff.Error import Axel.Eff.FileSystem as FS import Axel.Eff.Process@@ -16,6 +24,7 @@  import Control.Lens +import Data.Functor import qualified Data.Map as M  import qualified Polysemy as Sem@@ -23,8 +32,6 @@  import System.Exit -import Test.Tasty.Hspec- import TestUtils  spec_Stack :: SpecWith ()@@ -148,57 +155,4 @@         Right (Left err) -> failSpec err         Right (Right (fsState, (procState, (consoleState, x)))) ->           expectation x (consoleState, fsState, procState)-  describe "compileFile" $ do-    it "compiles a file with GHC" $ do-      let action =-            Stack.compileFile-              @'CreateStreams-              (FilePath "projectFoo/app/Main.hs")-              ""-      let origFSState = Mock.mkFileSystemState []-      let origProcState =-            Mock.mkProcessState-              []-              [ProcessResult ((ExitSuccess, Just ("testStdout", "")), pure ())]-      let expectation stdout (procState, _) = do-            stdout `shouldBe` "testStdout"-            procState ^. Mock.procExecutionLog `shouldBe`-              [ ( "stack ghc --resolver " <> Stack.stackageResolverWithAxel <>-                  " --package " <>-                  Stack.axelStackageId <>-                  " -- projectFoo/app/Main.hs"-                , Just "")-              ]-      case Sem.run . Sem.runError @Text . Mock.runFileSystem origFSState .-           Mock.runProcess origProcState $-           action of-        Left err -> failSpec err-        Right (fsState, (procState, (_, stdout, _))) ->-          expectation stdout (procState, fsState)-  describe "interpretFile" $ do-    it "interprets a file with GHC" $ do-      let action =-            Stack.interpretFile-              @'CreateStreams-              (FilePath "projectFoo/app/Main.hs")-              ""-      let origFSState = Mock.mkFileSystemState []-      let origProcState =-            Mock.mkProcessState-              []-              [ProcessResult ((ExitSuccess, Just ("testStdout", "")), pure ())]-      let expectation stdout (procState, _) = do-            stdout `shouldBe` "testStdout"-            procState ^. Mock.procExecutionLog `shouldBe`-              [ ( "stack runghc --resolver " <> Stack.stackageResolverWithAxel <>-                  " --package " <>-                  Stack.axelStackageId <>-                  " -- projectFoo/app/Main.hs"-                , Just "")-              ]-      case Sem.run . Sem.runError @Text . Mock.runFileSystem origFSState .-           Mock.runProcess origProcState $-           action of-        Left err -> failSpec err-        Right (fsState, (procState, (_, stdout, _))) ->-          expectation stdout (procState, fsState)+-}
test/Axel/Test/Parse/ASTGen.hs view
@@ -17,6 +17,8 @@   Gen.recursive     Gen.choice     [ AST.LiteralChar Nothing <$> Gen.unicode+    , AST.LiteralFloat Nothing <$>+      Gen.float (Range.exponentialFloat (-10000) 10000)     , AST.LiteralInt Nothing <$> Gen.int Range.constantBounded     , AST.LiteralString Nothing <$> Gen.string (Range.linear 0 5) Gen.unicode     , AST.Symbol Nothing <$> Gen.string (Range.linear 0 5) Gen.alpha
test/Axel/Test/Parse/ASTSpec.hs view
@@ -27,6 +27,7 @@                   ]               ]       let f (LiteralChar ann x) = LiteralChar (succ ann) x+          f (LiteralFloat ann x) = LiteralFloat (succ ann) x           f (LiteralInt ann x) = LiteralInt (succ ann) x           f (LiteralString ann x) = LiteralString (succ ann) x           f (SExpression ann xs) = SExpression (succ ann) xs
test/Axel/Test/ParseSpec.hs view
@@ -24,11 +24,14 @@ spec_Parse = do   describe "parseSingle" $ do     it "can parse a character literal" $ do-      let result = LiteralChar () 'a'-      parseSingle "#\\a" `shouldBe` result+      parseSingle "#\\a" `shouldBe` LiteralChar () 'a'+      parseSingle "#\\\\x1000" `shouldBe` LiteralChar () '\x1000'     it "can parse an integer literal" $ do-      let result = LiteralInt () 123-      parseSingle "123" `shouldBe` result+      parseSingle "-123" `shouldBe` LiteralInt () (-123)+      parseSingle "456" `shouldBe` LiteralInt () 456+    it "can parse a float literal" $ do+      parseSingle "-12.3" `shouldBe` LiteralFloat () (-12.3)+      parseSingle "4.56" `shouldBe` LiteralFloat () 4.56     it "can parse a list literal" $ do       let result =             SExpression@@ -36,8 +39,8 @@               [Symbol () "list", LiteralInt () 1, LiteralChar () 'a']       parseSingle "[1 #\\a]" `shouldBe` result     it "can parse a string literal" $ do-      let result = LiteralString () "a \"b"-      parseSingle "\"a \\\"b\"" `shouldBe` result+      let result = LiteralString () "a \x1000 \"b"+      parseSingle "\"a \x1000 \\\"b\"" `shouldBe` result     it "can parse a quasiquoted expression" $ do       let result =             SExpression@@ -60,8 +63,10 @@     it "can parse a symbol" $ do       let result = Symbol () "abc123'''"       parseSingle "abc123'''" `shouldBe` result-    it "can parse a macro name" $ do-      let result = Symbol () ",;foo"+    it+      "can parse a value-level name that starts with a Haskell-restricted character" $ do+      let result =+            Symbol () "aXEL_VALUE_aXEL_SYMBOL_COMMA_aXEL_SYMBOL_SEMICOLON_foo"       parseSingle ",;foo" `shouldBe` result     it "can parse an unquoted expression" $ do       let result =@@ -124,7 +129,12 @@                   , Symbol () "line"                   , Symbol () "comment"                   ]-              , SExpression () [Symbol () "butThis-->IsASingleSymbol"]+              , SExpression+                  ()+                  [ Symbol+                      ()+                      "butThisaXEL_SYMBOL_HYPHEN_aXEL_SYMBOL_HYPHEN_aXEL_SYMBOL_GREATERTHAN_IsASingleSymbol"+                  ]               ]       case Sem.run . Sem.runError $ parseSource Nothing input of         Left err -> failSpec $ renderError err
test/Axel/Test/Transpilation/TranspilationSpec.hs view
@@ -37,7 +37,7 @@   Effs.runRandom .   Effs.runResource .   Effs.runProcess .-  Effs.runGhci .+  Effs.runStackGhci .   Effs.runFileSystem .   Effs.unsafeRunError Effs.renderError . Effs.runConsole . Effs.ignoreLog @@ -55,9 +55,10 @@             output <-               runApp $               Sem.evalState (M.empty :: ModuleInfo) $-              Ghci.withGhci $ transpileSource (takeBaseName axelFile) axelSource+              Ghci.withStackGhci $+              transpileSource (takeBaseName axelFile) axelSource             let newSource = encodeUtf8Lazy $ SM.raw output-            pure newSource+            pure $ newSource <> "\n"       pure $         goldenVsString           (T.unpack . op FilePath $ takeBaseName axelFile)