summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoreliaslfox <>2017-09-13 08:44:00 (GMT)
committerhdiff <hdiff@hdiff.luite.com>2017-09-13 08:44:00 (GMT)
commit0b92197186fd7595c7c6d404ba65cb53d4903452 (patch)
treea6ca9843d4bc4f1b32ca144c499d50970b72cd36
parentc6066429cbcc1176795ab6255ce500afe433c150 (diff)
version 0.1.0.10.1.0.1
-rw-r--r--language-elm.cabal4
-rw-r--r--src/Elm.hs295
-rw-r--r--src/Elm/GenError.hs4
-rw-r--r--src/Elm/Type.hs2
4 files changed, 300 insertions, 5 deletions
diff --git a/language-elm.cabal b/language-elm.cabal
index a15f9ab..86f8f48 100644
--- a/language-elm.cabal
+++ b/language-elm.cabal
@@ -1,5 +1,5 @@
name: language-elm
-version: 0.1.0.0
+version: 0.1.0.1
synopsis: Generate elm code
description: Generate elm code from an ast
homepage: https://github.com/eliaslfox/language-elm#readme
@@ -15,7 +15,7 @@ cabal-version: >=1.10
library
hs-source-dirs: src
- exposed-modules: Elm.Decleration, Elm.Expression, Elm.Import, Elm.Program, Elm.Type, Elm.Classes, Elm.GenError
+ exposed-modules: Elm, Elm.Decleration, Elm.Expression, Elm.Import, Elm.Program, Elm.Type, Elm.Classes, Elm.GenError
build-depends: base >= 4.9.1 && < 4.10,
pretty >= 1.1.3 && < 1.2,
MissingH >= 1.4.0 && < 1.5,
diff --git a/src/Elm.hs b/src/Elm.hs
new file mode 100644
index 0000000..19270e3
--- /dev/null
+++ b/src/Elm.hs
@@ -0,0 +1,295 @@
+{-# OPTIONS_HADDOCK prune #-}
+{-# OPTIONS_GHC -Wall -Werror #-}
+{-# LANGUAGE NoImplicitPrelude #-}
+{-# LANGUAGE Trustworthy #-}
+
+module Elm
+ (
+ -- * Expressions
+ Expr
+ , bool
+ , string
+ , int
+ , float
+ , under
+ , var
+ , app
+ , list
+ , op
+ , let_
+ , case_
+ , parens
+ -- * Types
+ , Type
+ , tvar
+ , tparam
+ , tparams
+ , tapp
+ , tunit
+ , ttuple
+ , trecord
+ , trecordParam
+ -- * Declerations
+ , Dec
+ , decVariable
+ , decFunction
+ , decType
+ , decTypeAlias
+ -- * Imports
+ , Import
+ , ImportExpr
+ , ImportItem
+ , select
+ , subSelect
+ , subSelectEvery
+ , importSome
+ , importEvery
+ , import_
+ -- * Module
+ , Module
+ , module_
+ -- * Generation
+ , renderModule
+ , render
+ )
+ where
+
+import Prelude (error)
+import Protolude hiding (bool, list)
+
+import Data.String
+import qualified Elm.Decleration
+import qualified Elm.Expression
+import Elm.GenError (GenError (WarningList))
+import qualified Elm.Import
+import qualified Elm.Program
+import qualified Elm.Type (TypeDec (..))
+
+type Expr = Elm.Expression.Expr
+type Type = Elm.Type.TypeDec
+type Dec = Elm.Decleration.Dec
+type Import = Elm.Import.Import
+type ImportExpr = Elm.Import.ImportType
+type ImportItem = Elm.Import.ImportItem
+type Module = Elm.Program.Program
+
+-- | A boolean literal
+bool :: Bool -> Expr
+bool = Elm.Expression.Bool
+
+-- | A string literal
+string :: String -> Expr
+string = Elm.Expression.Str
+
+-- | An integer literal
+int :: Int -> Expr
+int = Elm.Expression.Int
+
+-- | A float literal
+float :: Float -> Expr
+float = Elm.Expression.Float
+
+-- | An _ literal
+under :: Expr
+under = Elm.Expression.Under
+
+-- | A variable
+var :: String -> Expr
+var = Elm.Expression.Var
+
+-- | Function application
+--
+-- >>> render (app [var "a", var "b", var "c"])
+-- "a b c"
+app :: [Expr] -> Expr
+app = Elm.Expression.App
+
+-- | A list literal
+list :: [Expr] -> Expr
+list = Elm.Expression.List
+
+-- | Apply an operator to two sub expressions
+--
+-- >>> render (Op "+" (Int 5) (Int 6))
+-- "5 + 6"
+op :: String -> Expr -> Expr -> Expr
+op = Elm.Expression.Op
+
+-- | A let...in block
+--
+-- >>> render (let_ (var "a") [(var "a", Int 5)])
+-- "let
+-- a = 5
+-- in
+-- a"
+let_ :: Expr -> [(Expr, Expr)] -> Expr
+let_ = Elm.Expression.Let
+
+-- | A case...of block
+--
+-- >>> render (case_ (var "m") [(App [var "Just", var "x"], var "x"), (var "Nothing", var "default")]
+-- "case m of
+-- Just x ->
+-- x
+-- <BLANKLINE>
+-- Nothing ->
+-- default"
+case_ :: Expr -> [(Expr, Expr)] -> Expr
+case_ = Elm.Expression.Case
+
+-- | Wrap a sub expression in parens
+parens :: Expr -> Expr
+parens = Elm.Expression.Parens
+
+-- * Types
+-- Functions for generating type signatures
+
+
+-- | A type or type variable
+--
+-- >>> render (tvar "Nothing")
+-- "Nothing"
+--
+-- >>> render (tvar "a")
+-- "a"
+--
+tvar :: String -> Type
+tvar name = Elm.Type.Params name []
+
+-- | A type with a single paramater
+--
+-- >>> render (tparam "Just" (tvar "a"))
+-- "Just a"
+--
+tparam :: String -> Type -> Type
+tparam name type_ = Elm.Type.Params name [type_]
+
+-- | A type with multiple paramaters
+--
+-- >>> render (tparams "Result" [tvar "String", tvar "Int"])
+-- "Result String Int"
+--
+tparams :: String -> [Type] -> Type
+tparams = Elm.Type.Params
+
+-- | A zero item tuple type
+--
+-- >>> render tunit
+-- "()"
+--
+tunit :: Type
+tunit = Elm.Type.TTuple []
+
+-- | A multiple item tuple
+--
+-- >>> render (ttuple [tvar "a", tvar "b"])
+-- "( a, b )"
+--
+ttuple :: [Type] -> Type
+ttuple = Elm.Type.TTuple
+
+-- | Type application
+--
+-- >>> render (tapp [tvar "a", tvar "b", tvar "c"])
+-- "[a, b, c]"
+--
+tapp :: [Type] -> Type
+tapp = Elm.Type.TApp
+
+
+-- | A record type
+--
+-- >>> render (trecord [("a", tvar "Int"), ("b", tvar "String")]
+-- "{ a : Int, b : String }"
+--
+trecord :: [(String, Type)] -> Type
+trecord = Elm.Type.TRecord Nothing
+
+-- | A paramaterized record type
+--
+-- >>> render (trecord "a" [("b", tvar "Int")])
+-- "{ a | b : Int }"
+--
+trecordParam :: String -> [(String, Type)] -> Type
+trecordParam = Elm.Type.TRecord . Just
+
+-- Declare variables, functions, types, and type aliases
+
+-- | Declare a variable
+decVariable :: String -- ^ The variable name
+ -> Type -- ^ The variable's type
+ -> Expr -- ^ The variable's value
+ -> Dec
+decVariable name type_ expr = Elm.Decleration.Dec name type_ [] expr
+
+-- | Declare a function
+decFunction :: String -- ^ The function name
+ -> Type -- ^ The function's type
+ -> [Expr] -- ^ The fuction's paramaters
+ -> Expr -- ^ The function's value
+ -> Dec
+decFunction = Elm.Decleration.Dec
+
+-- | Declare a type
+decType :: String -- ^ The type name
+ -> [String] -- ^ The type's type paramaters
+ -> [(String, [Type])] -- ^ The type's constructors
+ -> Dec
+decType = Elm.Decleration.DecType
+
+-- | Declare a type alias
+decTypeAlias :: String -- ^ The type alias' name
+ -> [String] -- ^ The type alias's type paramaters
+ -> Type -- ^ The type alias's type
+ -> Dec
+decTypeAlias = Elm.Decleration.DecTypeAlias
+
+-- | Import an item
+select :: String -> ImportItem
+select = Elm.Import.Item
+
+-- | Import an item and some constructors
+subSelect :: String -> [String] -> ImportItem
+subSelect = Elm.Import.ItemExposing
+
+-- | Import an item and all constructors
+subSelectEvery :: String -> ImportItem
+subSelectEvery = Elm.Import.ItemEvery
+
+-- | Import all exports of a module
+importSome :: [ImportItem] -> ImportExpr
+importSome = Elm.Import.Select
+
+-- | Import some exports of a module
+importEvery :: ImportExpr
+importEvery = Elm.Import.Everything
+
+-- | Import a module
+import_ :: String -- ^ The name of the module to import
+ -> (Maybe String) -- ^ A possible alias to import the module as
+ -> (Maybe ImportExpr) -- ^ A possible set of items to expose
+ -> Import
+import_ = Elm.Import.Import
+
+-- | Generate a full module
+module_ :: String -- ^ The module name
+ -> ImportExpr -- ^ The module exports
+ -> [Import] -- ^ The module imports
+ -> [Dec] -- ^ The module decleration
+ -> Module
+module_ = Elm.Program.Program
+
+-- | Render a module, returning possible errors or warnings
+renderModule :: Module -> (String, GenError)
+renderModule = Elm.Program.renderProgram
+
+-- | Render a module, throwing an error if there is an error or warnings
+render :: Module -> String
+render module' =
+ let
+ (str, err) = renderModule module'
+ in
+ if err == WarningList [] then
+ str
+ else
+ error . show $ err
diff --git a/src/Elm/GenError.hs b/src/Elm/GenError.hs
index 6ee0e24..586b939 100644
--- a/src/Elm/GenError.hs
+++ b/src/Elm/GenError.hs
@@ -1,15 +1,15 @@
-{-# OPTIONS_HADDOCK prune #-}
{-# OPTIONS_GHC -Wall -Werror #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE Safe #-}
{-# LANGUAGE Strict #-}
-module Elm.GenError where
+module Elm.GenError (GenError(..)) where
import Protolude
import Data.String
+-- | The error type
data GenError
= WarningList [String]
| Error String
diff --git a/src/Elm/Type.hs b/src/Elm/Type.hs
index 62668cc..dcbf473 100644
--- a/src/Elm/Type.hs
+++ b/src/Elm/Type.hs
@@ -2,7 +2,7 @@
{-# LANGUAGE OverloadedStrings #-}
-- | Ast for declaring types
-module Elm.Type where
+module Elm.Type (TypeDec(..)) where
import Control.Monad.Writer (tell)
import Data.List (intersperse)