forml-0.1.1: src/hs/Forml/Javascript/Utils.hs
{-# LANGUAGE TypeSynonymInstances #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE FunctionalDependencies #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE OverlappingInstances #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
module Forml.Javascript.Utils where
import Text.InterpolatedString.Perl6
import Language.Javascript.JMacro
import Data.Monoid
import Data.String.Utils
import Prelude hiding (curry, (++), error)
prelude :: String
prelude = show $ renderJs
[jmacro| function !is_array(x) {
return `(InfixExpr "instanceof" x (ref "Array"))`;
}
var !__undefined__ = "undefined";
function !run(x) { return x(); }
function !error(x) { throw x; }
function !exhaust() { error("Pattern Match Exhausted"); }
function !__check(x, y) {
return x.hasOwnProperty(y);
} |]
instance (ToStat a) => ToStat [a] where
toStat [] = mempty
toStat x = foldl1 mappend . map toStat $ x
--------------------------------------------------------------------------------
----
---- Metadata
--------------------------------------------------------------------------------
----
---- Utilities
(++) :: Monoid a => a -> a -> a
(++) = mappend
end :: forall a. [a] -> [a]
end (reverse -> x : xs) = x : reverse xs
end _ = fail "End is not defined for empty lists"
ref :: String -> JExpr
ref name = ValExpr (JVar (StrI name))
func :: String -> JStat -> JStat
func var ex = ReturnStat (ValExpr (JFunc [StrI var] (BlockStat [ex])))
declare_this :: forall a. ToJExpr a => [Char] -> a -> JStat
declare_this name expr =
[jmacro| `(declare (replace " " "_" name) expr)`;
this[`(replace " " "_" name)`] = `(ref (replace " " "_" name))`; |]
declare_window :: forall a. ToJExpr a => [Char] -> a -> JStat
declare_window name expr =
[jmacro| `(declare (replace " " "_" name) expr)`;
(typeof global == "undefined" ? window : global)[`((replace " " "_" name))`] = `(ref (replace " " "_" name))`; |]
declare :: forall a. ToJExpr a => [Char] -> a -> JStat
declare name expr =
[jmacro| `(DeclStat (StrI (replace " " "_" name)) Nothing)`;
`(ref (replace " " "_" name))` = `(expr)`; |]
declare_scope :: String -> JExpr -> JStat -> JStat
declare_scope name expr stat =
BlockStat [ReturnStat (ApplExpr (ValExpr (JFunc [StrI name] stat)) [expr])]
curry :: Int -> (String -> String) -> JStat -> JStat
curry 0 _ jexpr = jexpr
curry n f jexpr = func (f $ local_pool $ n - 1) (curry (n - 1) f jexpr)
local_pool :: Int -> String
local_pool n = [qq|__{ "abcdefghijklmnopqrstuvqxyz" !! n }__|]
scope :: forall a. ToStat a => a -> JExpr
scope x = [jmacroE| (function() { `(x)`; })() |]