-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | QuasiQuotation library for programmatic generation of Javascript code. -- -- Javascript syntax, functional syntax, hygienic names, compile-time -- guarantees of syntactic correctness, limited typechecking. Additional -- documentation available at -- http://www.haskell.org/haskellwiki/Jmacro @package jmacro @version 0.5.7 module Language.Javascript.JMacro.Types data JType JTNum :: JType JTString :: JType JTBool :: JType JTStat :: JType JTFunc :: [JType] -> (JType) -> JType JTList :: JType -> JType JTMap :: JType -> JType JTRecord :: JType -> (Map String JType) -> JType JTRigid :: VarRef -> (Set Constraint) -> JType JTImpossible :: JType JTFree :: VarRef -> JType JTForall :: [VarRef] -> JType -> JType data Constraint Sub :: JType -> Constraint Super :: JType -> Constraint type JLocalType = ([(VarRef, Constraint)], JType) type VarRef = (Maybe String, Int) anyType :: TypeParser JType parseType :: String -> Either ParseError JType runTypeParser :: ParsecT [Char] st' Identity JLocalType instance Typeable Constraint instance Typeable JType instance Eq Constraint instance Ord Constraint instance Read Constraint instance Show Constraint instance Data Constraint instance Eq JType instance Ord JType instance Read JType instance Show JType instance Data JType module Language.Javascript.JMacro.Util (.) :: JExpr -> String -> JExpr (<>) :: ToJExpr a => JExpr -> a -> JExpr (=:) :: ToJExpr a => JExpr -> a -> JStat ($) :: (ToJExpr a, ToJExpr b) => a -> b -> JExpr ($$) :: (ToJExpr a, ToJExpr b) => a -> b -> JStat (==, &&, <, !=) :: JExpr -> JExpr -> JExpr null :: JExpr new :: ToJExpr a => a -> JExpr if' :: (ToJExpr a, ToStat b) => a -> b -> JStat ifElse :: (ToJExpr a, ToStat b, ToStat c) => a -> b -> c -> JStat while :: ToJExpr a => a -> JStat -> JStat return :: ToJExpr a => a -> JStat toJExprList :: ToJExpr a => a -> [JExpr] jstr :: String -> JExpr module Language.Javascript.JMacro.Prelude -- | This provides a set of basic functional programming primitives, a few -- utility functions and, more importantly, a decent sample of idiomatic -- jmacro code. View the source for details. jmPrelude :: JStat module Language.Javascript.JMacro.TypeCheck isLeft :: Either t t1 -> Bool partitionOut :: (a -> Maybe b) -> [a] -> ([b], [a]) zipWithOrChange :: (a -> a -> b) -> (a -> b) -> [a] -> [a] -> [b] zipWithOrIdM :: Monad m => (a -> a -> m a) -> [a] -> [a] -> m [a] unionWithM :: (Monad m, Ord key) => (val -> val -> m val) -> Map key val -> Map key val -> m (Map key val) intersectionWithM :: (Monad m, Ord key) => (val -> val -> m b) -> Map key val -> Map key val -> m (Map key b) data StoreVal SVType :: JType -> StoreVal SVConstrained :: (Set Constraint) -> StoreVal data TCState TCS :: [Map Ident JType] -> Map Int StoreVal -> [Set Int] -> Set Int -> Int -> [TMonad String] -> TCState tc_env :: TCState -> [Map Ident JType] tc_vars :: TCState -> Map Int StoreVal tc_stack :: TCState -> [Set Int] tc_frozen :: TCState -> Set Int tc_varCt :: TCState -> Int tc_context :: TCState -> [TMonad String] tcStateEmpty :: TCState newtype TMonad a TMonad :: (ErrorT String (State TCState) a) -> TMonad a class JTypeCheck a typecheck :: JTypeCheck a => a -> TMonad JType evalTMonad :: TMonad a -> Either String a runTMonad :: TMonad a -> (Either String a, TCState) withContext :: TMonad a -> TMonad String -> TMonad a traversem_ :: (Foldable t, Monad f) => (a -> f b) -> t a -> f () freeVarsWithNames :: JType -> TMonad (Map Int String) prettyType :: JType -> TMonad [Char] tyErr0 :: String -> TMonad a tyErr1 :: String -> JType -> TMonad b tyErr2ext :: String -> String -> String -> JType -> JType -> TMonad a tyErr2Sub :: JType -> JType -> TMonad a prettyEnv :: TMonad [Map Ident String] runTypecheckRaw :: JTypeCheck a => a -> (Either String JType, TCState) runTypecheckFull :: JTypeCheck a => a -> (Either String ([Char], [Map Ident String]), TCState) runTypecheck :: JTypeCheck a => a -> Either String [Char] evalTypecheck :: JTypeCheck a => a -> Either String [Map Ident String] typecheckMain :: JTypeCheck a => a -> TMonad JType addToStack :: Ord a => a -> [Set a] -> [Set a] newVarRef :: TMonad VarRef newTyVar :: TMonad JType mapConstraint :: (Monad m, Functor m) => (JType -> m JType) -> Constraint -> m Constraint partitionCs :: [Constraint] -> ([JType], [JType]) lookupConstraintsList :: VarRef -> TMonad [Constraint] instantiateVarRef :: VarRef -> JType -> TMonad () occursCheck :: Int -> JType -> TMonad () checkConstraints :: JType -> [Constraint] -> TMonad () addConstraint :: VarRef -> Constraint -> TMonad () cannonicalizeConstraints :: [Constraint] -> TMonad [Constraint] tryCloseFrozenVars :: TMonad () withLocalScope :: TMonad a -> TMonad (a, Set Int) setFrozen :: Set Int -> TMonad () frame2VarRefs :: Set t -> [(Maybe a, t)] addEnv :: Ident -> JType -> TMonad () newVarDecl :: Ident -> TMonad JType resolveTypeGen :: ((JType -> TMonad JType) -> JType -> TMonad JType) -> JType -> TMonad JType resolveType :: JType -> TMonad JType resolveTypeShallow :: JType -> TMonad JType integrateLocalType :: JLocalType -> TMonad JType lookupEnv :: Ident -> TMonad JType freeVars :: JType -> TMonad (Set Int) instantiateScheme :: [VarRef] -> JType -> TMonad JType instantiateRigidScheme :: [VarRef] -> JType -> TMonad JType checkEscapedVars :: [VarRef] -> JType -> TMonad () (<:) :: JType -> JType -> TMonad () (<<:>) :: TMonad JType -> TMonad JType -> TMonad () someUpperBound :: [JType] -> TMonad JType someLowerBound :: [JType] -> TMonad JType (=.=) :: JType -> JType -> TMonad JType typecheckWithBlock :: (JsToDoc a, JMacro a, JTypeCheck a) => a -> TMonad JType instance Show StoreVal instance Functor TMonad instance Monad TMonad instance MonadState TCState TMonad instance MonadError String TMonad instance JTypeCheck JStat instance JTypeCheck JVal instance JTypeCheck JExpr instance Applicative TMonad instance Show TCState -- | Allows for the creation of rpc server/client pairs from monomorphic -- functions. The server portion is a function from a json-encoded list -- of parameters to a json response. A list of server functions are -- expected to be wrapped by a dispatch function in the server framework -- of your choice. -- -- The client portion generated from a function of arity n is a function -- from a string identifying a server or a subdirectory on a server to an -- arity n function from javascript expressions (of type JExpr) to -- a single javascript expression. This expression, when evaluated on the -- client side, will call back to the provided server with -- json-serialized arguments and yield the result (deserialized from -- json). This client function is expected to be embedded via -- antiquotation into a larger block of jmacro code. -- -- Client portions must unfortunately be given explicit type signatures. -- -- The following example is a server/client pair providing an ajax call -- to add integers. -- --
--   testRPCCall :: String -> JExpr -> JExpr -> JExpr
--   (testRPC, testRPCCall) = mkWebRPC "test" $ \x y -> asIO $ return (x + (y::Int))
--   
-- -- This code uses a simple request/response type based on strings to be -- as agnostic as possible about choice of web service stack. It can be -- used as is, or used as a model for code which targets a particular web -- stack (Happstack, Snap, FastCGI, etc.). -- -- The jQuery Javascript library is used to handle ajax requests, and -- hence pages which embed RPC calls must have the jQuery javascript -- library loaded. module Language.Javascript.JMacro.Rpc -- | Produce a pair of (ServerFunction, ClientFunction) from a function in -- IO mkWebRPC :: (ToWebRPC a, CallWebRPC a b) => String -> a -> (WebRPCDesc, String -> b) -- | id with a helpful type. asIO :: IO a -> IO a -- | A String containing a json representation of function arguments -- encoded as a list of parameters. Generally would be passed as part of -- an HTTP request. type Request = String -- | Either a success or failure (with code). Generally would be turned -- back into a proper HTTP response. data Response GoodResponse :: String -> Response BadResponse :: Int -> String -> Response type WebRPCDesc = (String, Request -> IO Response) class CallWebRPC a b | a -> b callWebRPC_ :: CallWebRPC a b => [JExpr] -> String -> a -> b class ToWebRPC a toWebRPC_ :: ToWebRPC a => a -> ([JSValue] -> IO Response) instance (CallWebRPC b c, ToJExpr d) => CallWebRPC (a -> b) (d -> c) instance CallWebRPC (IO b) JExpr instance (JSON a, ToWebRPC b) => ToWebRPC (a -> b) instance JSON b => ToWebRPC (IO b) -- | Simple DSL for lightweight (untyped) programmatic generation of -- Javascript. -- -- A number of examples are available in the source of -- Language.Javascript.JMacro.Prelude. -- -- Functions to generate generic RPC wrappers (using json serialization) -- are available in Language.Javascript.JMacro.Rpc. -- -- usage: -- --
--   renderJs [$jmacro|fun id x -> x|]
--   
-- -- The above produces the id function at the top level. -- --
--   renderJs [$jmacro|var id = \x -> x|]
--   
-- -- So does the above here. However, as id is brought into scope by the -- keyword var, you do not get a variable named id in the generated -- javascript, but a variable with an arbitrary unique identifier. -- --
--   renderJs [$jmacro|var !id = \x -> x|]
--   
-- -- The above, by using the bang special form in a var declaration, -- produces a variable that really is named id. -- --
--   renderJs [$jmacro|function id(x) {return x;}|]
--   
-- -- The above is also id. -- --
--   renderJs [$jmacro|function !id(x) {return x;}|]
--   
-- -- As is the above (with the correct name). -- --
--   renderJs [$jmacro|fun id x {return x;}|]
--   
-- -- As is the above. -- --
--   renderJs [$jmacroE|foo(x,y)|]
--   
-- -- The above is an expression representing the application of foo to x -- and y. -- --
--   renderJs [$jmacroE|foo x y|]]
--   
-- -- As is the above. -- --
--   renderJs [$jmacroE|foo (x,y)|]
--   
-- -- While the above is an error. (i.e. standard javascript function -- application cannot seperate the leading parenthesis of the argument -- from the function being applied) -- --
--   \x -> [$jmacroE|foo `(x)`|]
--   
-- -- The above is a haskell expression that provides a function that takes -- an x, and yields an expression representing the application of foo to -- the value of x as transformed to a Javascript expression. -- --
--   [$jmacroE|\x ->`(foo x)`|]
--   
-- -- Meanwhile, the above lambda is in Javascript, and brings the variable -- into scope both in javascript and in the enclosed antiquotes. The -- expression is a Javascript function that takes an x, and yields an -- expression produced by the application of the Haskell function foo as -- applied to the identifier x (which is of type JExpr -- i.e. a -- Javascript expression). -- -- Other than that, the language is essentially Javascript (1.5). Note -- however that one must use semicolons in a principled fashion -- i.e. -- to end statements consistently. Otherwise, the parser will mistake the -- whitespace for a whitespace application, and odd things will occur. A -- further gotcha exists in regex literals, whicch cannot begin with a -- space. x 5 4 parses as ((x 5) 4). However, -- x 5 4 will parse as x(5 , 4). Such are the -- perils of operators used as delimeters in the presence of whitespace -- application. -- -- Additional features in jmacro (documented on the wiki) include an -- infix application operator, and an enhanced destructuring bind. -- -- Additional datatypes can be marshalled to Javascript by proper -- instance declarations for the ToJExpr class. -- -- An experimental typechecker is available in the -- Language.Javascript.JMacro.Typed module. module Language.Javascript.JMacro -- | QuasiQuoter for a block of JMacro statements. jmacro :: QuasiQuoter -- | QuasiQuoter for a JMacro expression. jmacroE :: QuasiQuoter parseJM :: String -> Either ParseError JStat -- | Statements data JStat DeclStat :: Ident -> (Maybe JLocalType) -> JStat ReturnStat :: JExpr -> JStat IfStat :: JExpr -> JStat -> JStat -> JStat WhileStat :: JExpr -> JStat -> JStat ForInStat :: Bool -> Ident -> JExpr -> JStat -> JStat SwitchStat :: JExpr -> [(JExpr, JStat)] -> JStat -> JStat TryStat :: JStat -> Ident -> JStat -> JStat -> JStat BlockStat :: [JStat] -> JStat ApplStat :: JExpr -> [JExpr] -> JStat PPostStat :: Bool -> String -> JExpr -> JStat AssignStat :: JExpr -> JExpr -> JStat UnsatBlock :: (IdentSupply JStat) -> JStat AntiStat :: String -> JStat ForeignStat :: Ident -> JLocalType -> JStat BreakStat :: JStat -- | Expressions data JExpr ValExpr :: JVal -> JExpr SelExpr :: JExpr -> Ident -> JExpr IdxExpr :: JExpr -> JExpr -> JExpr InfixExpr :: String -> JExpr -> JExpr -> JExpr PPostExpr :: Bool -> String -> JExpr -> JExpr IfExpr :: JExpr -> JExpr -> JExpr -> JExpr NewExpr :: JExpr -> JExpr ApplExpr :: JExpr -> [JExpr] -> JExpr UnsatExpr :: (IdentSupply JExpr) -> JExpr AntiExpr :: String -> JExpr TypeExpr :: Bool -> JExpr -> JLocalType -> JExpr -- | Values data JVal JVar :: Ident -> JVal JList :: [JExpr] -> JVal JDouble :: Double -> JVal JInt :: Integer -> JVal JStr :: String -> JVal JRegEx :: String -> JVal JHash :: (Map String JExpr) -> JVal JFunc :: [Ident] -> JStat -> JVal UnsatVal :: (IdentSupply JVal) -> JVal -- | Identifiers newtype Ident StrI :: String -> Ident newtype IdentSupply a IS :: State [Ident] a -> IdentSupply a runIdentSupply :: IdentSupply a -> State [Ident] a -- | Utility class to coerce the ADT into a regular structure. class JMacro a toMC :: JMacro a => a -> MultiComp fromMC :: JMacro a => MultiComp -> a -- | Union type to allow regular traversal by compos. data MultiComp MStat :: JStat -> MultiComp MExpr :: JExpr -> MultiComp MVal :: JVal -> MultiComp MIdent :: Ident -> MultiComp -- | Compos and ops for generic traversal as defined over the JMacro ADT. class Compos t compos :: Compos t => (forall a. a -> m a) -> (forall a b. m (a -> b) -> m a -> m b) -> (t -> m t) -> t -> m t composOp :: Compos t => (t -> t) -> t -> t composOpM :: (Compos t, Monad m) => (t -> m t) -> t -> m t composOpM_ :: (Compos t, Monad m) => (t -> m ()) -> t -> m () composOpFold :: Compos t => b -> (b -> b -> b) -> (t -> b) -> t -> b -- | Apply a transformation to a fully saturated syntax tree, taking care -- to return any free variables back to their free state following the -- transformation. As the transformation preserves free variables, it is -- hygienic. Cannot be used nested. withHygiene :: JMacro a => (a -> a) -> a -> a -- | Takes a fully saturated expression and transforms it to use unique -- variables that respect scope. scopify :: JStat -> JStat -- | Render a syntax tree as a pretty-printable document (simply showing -- the resultant doc produces a nice, well formatted String). renderJs :: (JsToDoc a, JMacro a) => a -> Doc -- | Render a syntax tree as a pretty-printable document, using a given -- prefix to all generated names. Use this with distinct prefixes to -- ensure distinct generated names between independent calls to -- render(Prefix)Js. renderPrefixJs :: (JsToDoc a, JMacro a) => String -> a -> Doc class JsToDoc a jsToDoc :: JsToDoc a => a -> Doc -- | Things that can be marshalled into javascript values. Instantiate for -- any necessary data structures. class ToJExpr a where toJExprFromList = ValExpr . JList . map toJExpr toJExpr :: ToJExpr a => a -> JExpr toJExprFromList :: ToJExpr a => [a] -> JExpr jsv :: String -> JExpr -- | Create a new anonymous function. The result is an expression. Usage: -- jLam $ x y -> {JExpr involving x and y} jLam :: ToSat a => a -> JExpr -- | Introduce a new variable into scope for the duration of the enclosed -- expression. The result is a block statement. Usage: jVar $ x y -- -> {JExpr involving x and y} jVar :: ToSat a => a -> JStat -- | Introduce a new variable with optional type into scope for the -- duration of the enclosed expression. The result is a block statement. -- Usage: jVar $ x y -> {JExpr involving x and y} jVarTy :: ToSat a => a -> (Maybe JLocalType) -> JStat jFor :: (ToJExpr a, ToStat b) => JStat -> a -> JStat -> b -> JStat -- | Create a for in statement. Usage: jForIn {expression} $ x -> -- {block involving x} jForIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat -- | As with jForIn but creating a "for each in" statement. jForEachIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat jTryCatchFinally :: ToSat a => JStat -> a -> JStat -> JStat expr2stat :: JExpr -> JStat class ToStat a toStat :: ToStat a => a -> JStat nullStat :: JStat jhEmpty :: Map String JExpr jhSingle :: ToJExpr a => String -> a -> Map String JExpr jhAdd :: ToJExpr a => String -> a -> Map String JExpr -> Map String JExpr jhFromList :: [(String, JExpr)] -> JVal -- | Given an optional prefix, fills in all free variable names with a -- supply of names generated by the prefix. jsSaturate :: JMacro a => Maybe String -> a -> a jtFromList :: JType -> [(String, JType)] -> JType