ghc-lib-parser-9.14.1.20251220: The GHC API, decoupled from GHC versions

Copyright | (c) The University of Glasgow 2001
License | BSD-style (see the file LICENSE)
Maintainer | Jeffrey Young <jeffrey.young@iohk.io> Luite Stegeman <luite.stegeman@iohk.io> Sylvain Henry <sylvain.henry@iohk.io> Josh Meredith <josh.meredith@iohk.io>
Stability | experimental
Safe Haskell | Ignore
Language | GHC2021

GHC.JS.Make

Contents

- Injection Type classes
- Introduction functions
- Combinators
  - Hash combinators
- Literals
  - Math functions
- Statement helpers
- Orphan instances

Description

- Domain and Purpose

  GHC.JS.Make defines helper functions to ease the creation of JavaScript ASTs as defined in `Syntax`. Its purpose is twofold: make the EDSL more ergonomic to program in, and make errors in the EDSL look obvious because the EDSL is untyped. It is primarily concerned with injecting terms into the domain of the EDSL to construct JS programs in Haskell.

- Strategy

  The strategy for this module comes straight from gentzen; where we have two types of helper functions. Functions which inject terms into the EDSL, and combinator functions which operate on terms in the EDSL to construct new terms in the EDSL. Crucially, missing from this module are corresponding elimination or destructing functions which would project information from the EDSL back to Haskell. See `Utils` for such functions.

  - Introduction functions

    We define various primitive helpers which introduce terms in the EDSL, for example `jVar`, `jLam`, and `var` and `jString`. Similarly this module exports four typeclasses `ToExpr`, `ToStat`, `JVarMagic`, `JSArgument`. `ToExpr` injects values as a JS expression into the EDSL. `ToStat` injects values as JS statements into the EDSL. `JVarMagic` provides a polymorphic way to introduce a new name into the EDSL and `JSArgument` provides a polymorphic way to bind variable names for use in JS functions with different arities.

  - Combinator functions

    The rest of the module defines combinators which create terms in the EDSL from terms in the EDSL. Notable examples are `|=` and `||=`, `|=` is sugar for `AssignStat`, it is a binding form that declares `foo = bar` assuming foo has been already declared. `||=` is more sugar on top of `|=`, it is also a binding form that declares the LHS of `|=` before calling `|=` to bind a value, bar, to a variable foo. Other common examples are the `if_` and `math_` helpers such as `math_cos`.

- Consumers

  The entire JS backend consumes this module, e.g., the modules in GHC.StgToJS.*.

- Notation

  In this module we use `==>` in docstrings to show the translation from the JS EDSL domain to JS code. For example, `foo ||= bar ==> var foo; foo = bar;` should be read as `foo ||= bar` is in the EDSL domain and results in the JS code `var foo; foo = bar;` when compiled.

  In most cases functions prefixed with a `j` are monadic because the observably allocate. Notable exceptions are `jwhenS`, `jString` and the helpers for HashMaps.

Synopsis

- class ToJExpr a where
  - toJExpr :: a -> JStgExpr
  - toJExprFromList :: [a] -> JStgExpr
- class ToStat a where
  - toStat :: a -> JStgStat
- class JVarMagic a where
  - fresh :: JSM a
- class JSArgument args where
  - argList :: args -> [Ident]
  - args :: JSM args
- jString :: FastString -> JStgExpr
- jLam :: JSArgument args => (args -> JSM JStgStat) -> JSM JStgExpr
- jLam' :: JStgStat -> JStgExpr
- jFunction :: JSArgument args => Ident -> (args -> JSM JStgStat) -> JSM JStgStat
- jFunctionSized :: Ident -> Int -> ([JStgExpr] -> JSM JStgStat) -> JSM JStgStat
- jFunction' :: Ident -> JSM JStgStat -> JSM JStgStat
- jVar :: (JVarMagic t, ToJExpr t) => (t -> JSM JStgStat) -> JSM JStgStat
- jVars :: JSArgument args => (args -> JSM JStgStat) -> JSM JStgStat
- jFor :: (JStgExpr -> JStgStat) -> (JStgExpr -> JStgExpr) -> (JStgExpr -> JStgStat) -> (JStgExpr -> JStgStat) -> JSM JStgStat
- jForIn :: JStgExpr -> (JStgExpr -> JStgStat) -> JSM JStgStat
- jForEachIn :: JStgExpr -> (JStgExpr -> JStgStat) -> JSM JStgStat
- jTryCatchFinally :: (Ident -> JStgStat) -> (Ident -> JStgStat) -> (Ident -> JStgStat) -> JSM JStgStat
- (||=) :: Ident -> JStgExpr -> JStgStat
- (|=) :: JStgExpr -> JStgExpr -> JStgStat
- (.==.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.===.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.!=.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.!==.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.!) :: JStgExpr -> JStgExpr -> JStgExpr
- (.>.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.>=.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.<.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.<=.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.<<.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.>>.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.>>>.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.|.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.||.) :: JStgExpr -> JStgExpr -> JStgExpr
- (.&&.) :: JStgExpr -> JStgExpr -> JStgExpr
- if_ :: JStgExpr -> JStgExpr -> JStgExpr -> JStgExpr
- if10 :: JStgExpr -> JStgExpr
- if01 :: JStgExpr -> JStgExpr
- ifS :: JStgExpr -> JStgStat -> JStgStat -> JStgStat
- ifBlockS :: JStgExpr -> [JStgStat] -> [JStgStat] -> JStgStat
- jBlock :: Monoid a => [JSM a] -> JSM a
- jIf :: JStgExpr -> JSM JStgStat -> JSM JStgStat -> JSM JStgStat
- jwhenS :: JStgExpr -> JStgStat -> JStgStat
- app :: FastString -> [JStgExpr] -> JStgExpr
- appS :: FastString -> [JStgExpr] -> JStgStat
- returnS :: JStgExpr -> JStgStat
- loop :: JStgExpr -> (JStgExpr -> JStgExpr) -> (JStgExpr -> JSM JStgStat) -> JSM JStgStat
- loopBlockS :: JStgExpr -> (JStgExpr -> JStgExpr) -> (JStgExpr -> [JStgStat]) -> JSM JStgStat
- preIncrS :: JStgExpr -> JStgStat
- postIncrS :: JStgExpr -> JStgStat
- preDecrS :: JStgExpr -> JStgStat
- postDecrS :: JStgExpr -> JStgStat
- off8 :: JStgExpr -> JStgExpr -> JStgExpr
- off16 :: JStgExpr -> JStgExpr -> JStgExpr
- off32 :: JStgExpr -> JStgExpr -> JStgExpr
- off64 :: JStgExpr -> JStgExpr -> JStgExpr
- mask8 :: JStgExpr -> JStgExpr
- mask16 :: JStgExpr -> JStgExpr
- signExtend8 :: JStgExpr -> JStgExpr
- signExtend16 :: JStgExpr -> JStgExpr
- typeOf :: JStgExpr -> JStgExpr
- returnStack :: JStgStat
- assignAllEqual :: HasDebugCallStack => [JStgExpr] -> [JStgExpr] -> JStgStat
- assignAll :: [JStgExpr] -> [JStgExpr] -> JStgStat
- assignAllReverseOrder :: [JStgExpr] -> [JStgExpr] -> JStgStat
- declAssignAll :: [Ident] -> [JStgExpr] -> JStgStat
- nullStat :: JStgStat
- (.^) :: JStgExpr -> FastString -> JStgExpr
- jhEmpty :: Map k JStgExpr
- jhSingle :: (Ord k, ToJExpr a) => k -> a -> Map k JStgExpr
- jhAdd :: (Ord k, ToJExpr a) => k -> a -> Map k JStgExpr -> Map k JStgExpr
- jhFromList :: [(FastString, JStgExpr)] -> JVal
- null_ :: JStgExpr
- undefined_ :: JStgExpr
- false_ :: JStgExpr
- true_ :: JStgExpr
- zero_ :: JStgExpr
- one_ :: JStgExpr
- two_ :: JStgExpr
- three_ :: JStgExpr
- math_log :: [JStgExpr] -> JStgExpr
- math_sin :: [JStgExpr] -> JStgExpr
- math_cos :: [JStgExpr] -> JStgExpr
- math_tan :: [JStgExpr] -> JStgExpr
- math_exp :: [JStgExpr] -> JStgExpr
- math_acos :: [JStgExpr] -> JStgExpr
- math_asin :: [JStgExpr] -> JStgExpr
- math_atan :: [JStgExpr] -> JStgExpr
- math_abs :: [JStgExpr] -> JStgExpr
- math_pow :: [JStgExpr] -> JStgExpr
- math_sqrt :: [JStgExpr] -> JStgExpr
- math_asinh :: [JStgExpr] -> JStgExpr
- math_acosh :: [JStgExpr] -> JStgExpr
- math_atanh :: [JStgExpr] -> JStgExpr
- math_cosh :: [JStgExpr] -> JStgExpr
- math_sinh :: [JStgExpr] -> JStgExpr
- math_tanh :: [JStgExpr] -> JStgExpr
- math_expm1 :: [JStgExpr] -> JStgExpr
- math_log1p :: [JStgExpr] -> JStgExpr
- math_fround :: [JStgExpr] -> JStgExpr
- math_min :: [JStgExpr] -> JStgExpr
- math_max :: [JStgExpr] -> JStgExpr
- data Solo a where
  - MkSolo a
  - pattern Solo :: a -> Solo a
- decl :: Ident -> JStgStat

# Injection Type classes

The `ToJExpr` class handles injection of of things into the EDSL as a JS expression

class ToJExpr a where #

Things that can be marshalled into javascript values. Instantiate for any necessary data structures.

Minimal complete definition

toJExpr

Methods

toJExpr :: a -> JStgExpr #

toJExprFromList :: [a] -> JStgExpr #

#### Instances

Instances details

ToJExpr FastString # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: FastString -> JStgExpr # toJExprFromList :: [FastString] -> JStgExpr #
ToJExpr Ident # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Ident -> JStgExpr # toJExprFromList :: [Ident] -> JStgExpr #
ToJExpr JStgExpr # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: JStgExpr -> JStgExpr # toJExprFromList :: [JStgExpr] -> JStgExpr #
ToJExpr JVal # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: JVal -> JStgExpr # toJExprFromList :: [JVal] -> JStgExpr #
ToJExpr CIStatic # | static refs: array = references, null = nothing to report note: only works after all top-level objects have been created
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: CIStatic -> JStgExpr # toJExprFromList :: [CIStatic] -> JStgExpr #
ToJExpr ClosureType # |
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: ClosureType -> JStgExpr # toJExprFromList :: [ClosureType] -> JStgExpr #
ToJExpr JSRep # |
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: JSRep -> JStgExpr # toJExprFromList :: [JSRep] -> JStgExpr #
ToJExpr StaticLit # |
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: StaticLit -> JStgExpr # toJExprFromList :: [StaticLit] -> JStgExpr #
ToJExpr Integer # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Integer -> JStgExpr # toJExprFromList :: [Integer] -> JStgExpr #
ToJExpr () # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: () -> JStgExpr # toJExprFromList :: [()] -> JStgExpr #
ToJExpr Bool # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Bool -> JStgExpr # toJExprFromList :: [Bool] -> JStgExpr #
ToJExpr Char # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Char -> JStgExpr # toJExprFromList :: [Char] -> JStgExpr #
ToJExpr Double # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Double -> JStgExpr # toJExprFromList :: [Double] -> JStgExpr #
ToJExpr Int # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Int -> JStgExpr # toJExprFromList :: [Int] -> JStgExpr #
ToJExpr a => ToJExpr [a] # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: [a] -> JStgExpr # toJExprFromList :: [[a]] -> JStgExpr #
ToJExpr a => ToJExpr (Map String a) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Map String a -> JStgExpr # toJExprFromList :: [Map String a] -> JStgExpr #
ToJExpr a => ToJExpr (UniqMap FastString a) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: UniqMap FastString a -> JStgExpr # toJExprFromList :: [UniqMap FastString a] -> JStgExpr #
(ToJExpr a, ToJExpr b) => ToJExpr (a, b) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b) -> JStgExpr # toJExprFromList :: [(a, b)] -> JStgExpr #
(ToJExpr a, ToJExpr b, ToJExpr c) => ToJExpr (a, b, c) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b, c) -> JStgExpr # toJExprFromList :: [(a, b, c)] -> JStgExpr #
(ToJExpr a, ToJExpr b, ToJExpr c, ToJExpr d) => ToJExpr (a, b, c, d) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b, c, d) -> JStgExpr # toJExprFromList :: [(a, b, c, d)] -> JStgExpr #
(ToJExpr a, ToJExpr b, ToJExpr c, ToJExpr d, ToJExpr e) => ToJExpr (a, b, c, d, e) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b, c, d, e) -> JStgExpr # toJExprFromList :: [(a, b, c, d, e)] -> JStgExpr #
(ToJExpr a, ToJExpr b, ToJExpr c, ToJExpr d, ToJExpr e, ToJExpr f) => ToJExpr (a, b, c, d, e, f) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b, c, d, e, f) -> JStgExpr # toJExprFromList :: [(a, b, c, d, e, f)] -> JStgExpr #

class ToStat a where #

The `ToStat` class handles injection of of things into the EDSL as a JS statement. This ends up being polymorphic sugar for JS blocks, see helper function `expr2stat`. Instantiate for any necessary data structures.

Methods

toStat :: a -> JStgStat #

#### Instances

Instances details

ToStat JStgExpr # |
Instance details Defined in GHC.JS.Make Methods toStat :: JStgExpr -> JStgStat #
ToStat JStgStat # |
Instance details Defined in GHC.JS.Make Methods toStat :: JStgStat -> JStgStat #
ToStat [JStgExpr] # |
Instance details Defined in GHC.JS.Make Methods toStat :: [JStgExpr] -> JStgStat #
ToStat [JStgStat] # |
Instance details Defined in GHC.JS.Make Methods toStat :: [JStgStat] -> JStgStat #

class JVarMagic a where #

Type class that generates fresh `a`'s for the JS backend. You should almost never need to use this directly. Instead use `JSArgument`, for examples of how to employ these classes please see `jVar`, `jFunction` and call sites in the Rts.

Methods

fresh :: JSM a #

#### Instances

Instances details

JVarMagic Ident # |
Instance details Defined in GHC.JS.Make Methods fresh :: JSM Ident #
JVarMagic JStgExpr # |
Instance details Defined in GHC.JS.Make Methods fresh :: JSM JStgExpr #
JVarMagic JVal # |
Instance details Defined in GHC.JS.Make Methods fresh :: JSM JVal #

class JSArgument args where #

Type class that finds the form of arguments required for a JS syntax object. This class gives us a single interface to generate variables for functions that have different arities. Thus with it, we can have only one `jFunction` which is polymorphic over its arity, instead of `jFunction2`, `jFunction3` and so on.

Methods

argList :: args -> [Ident] #

args :: JSM args #

#### Instances

Instances details

(JVarMagic a, ToJExpr a) => JSArgument (Solo a) # |
Instance details Defined in GHC.JS.Make Methods argList :: Solo a -> [Ident] # args :: JSM (Solo a) #
(JVarMagic a, JVarMagic b, ToJExpr a, ToJExpr b) => JSArgument (a, b) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b) -> [Ident] # args :: JSM (a, b) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c) => JSArgument (a, b, c) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c) -> [Ident] # args :: JSM (a, b, c) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d) => JSArgument (a, b, c, d) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d) -> [Ident] # args :: JSM (a, b, c, d) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d, JVarMagic e, ToJExpr e) => JSArgument (a, b, c, d, e) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d, e) -> [Ident] # args :: JSM (a, b, c, d, e) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d, JVarMagic e, ToJExpr e, JVarMagic f, ToJExpr f) => JSArgument (a, b, c, d, e, f) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d, e, f) -> [Ident] # args :: JSM (a, b, c, d, e, f) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d, JVarMagic e, ToJExpr e, JVarMagic f, ToJExpr f, JVarMagic g, ToJExpr g) => JSArgument (a, b, c, d, e, f, g) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d, e, f, g) -> [Ident] # args :: JSM (a, b, c, d, e, f, g) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d, JVarMagic e, ToJExpr e, JVarMagic f, ToJExpr f, JVarMagic g, ToJExpr g, JVarMagic h, ToJExpr h) => JSArgument (a, b, c, d, e, f, g, h) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d, e, f, g, h) -> [Ident] # args :: JSM (a, b, c, d, e, f, g, h) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d, JVarMagic e, ToJExpr e, JVarMagic f, ToJExpr f, JVarMagic g, ToJExpr g, JVarMagic h, ToJExpr h, JVarMagic i, ToJExpr i) => JSArgument (a, b, c, d, e, f, g, h, i) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d, e, f, g, h, i) -> [Ident] # args :: JSM (a, b, c, d, e, f, g, h, i) #
(JVarMagic a, ToJExpr a, JVarMagic b, ToJExpr b, JVarMagic c, ToJExpr c, JVarMagic d, ToJExpr d, JVarMagic e, ToJExpr e, JVarMagic f, ToJExpr f, JVarMagic g, ToJExpr g, JVarMagic h, ToJExpr h, JVarMagic i, ToJExpr i, JVarMagic j, ToJExpr j) => JSArgument (a, b, c, d, e, f, g, h, i, j) # |
Instance details Defined in GHC.JS.Make Methods argList :: (a, b, c, d, e, f, g, h, i, j) -> [Ident] # args :: JSM (a, b, c, d, e, f, g, h, i, j) #

# Introduction functions

jString :: FastString -> JStgExpr #

Convert a FastString to a Javascript String

jLam :: JSArgument args => (args -> JSM JStgStat) -> JSM JStgExpr #

Create a new anonymous function. The result is a `JExpr` expression. Usage:

    jLam $ \x -> jVar x + one_
    jLam $ \f -> (jLam $ \x -> (f `app` (x `app` x))) `app` (jLam $ \x -> (f `app` (x `app` x)))

jLam' :: JStgStat -> JStgExpr #

Special case of `jLam` where the anonymous function requires no fresh arguments.

jFunction #

Arguments

:: JSArgument args |
=> Ident | global name
-> (args -> JSM JStgStat) | function body, input is locally unique generated variables
-> JSM JStgStat |

Construct a top-level function subject to JS hoisting. This combinator is polymorphic over function arity so you can you use to define a JS syntax object in Haskell, which is a function in JS that takes 2 or 4 or whatever arguments. For a singleton function use the `Solo` constructor `MkSolo`. Usage:

an example from the Rts that defines a 1-arity JS function > jFunction (global "h$getReg") ((MkSolo n) -> return $ SwitchStat n getRegCases mempty)

an example of a two argument function from the Rts > jFunction (global "h$bh_lne") ((x, frameSize) -> bhLneStats s x frameSize)

jFunctionSized #

Arguments

:: Ident | global name
-> Int | Arity
-> ([JStgExpr] -> JSM JStgStat) | function body, input is locally unique generated variables
-> JSM JStgStat |

Construct a top-level function subject to JS hoisting. Special case where the arity cannot be deduced from the `args` parameter (atleast not without dependent types).

jFunction' #

Arguments

:: Ident | global name
-> JSM JStgStat | function body, input is locally unique generated variables
-> JSM JStgStat |

Construct a top-level function subject to JS hoisting. Special case where the function binds no parameters

jVar :: (JVarMagic t, ToJExpr t) => (t -> JSM JStgStat) -> JSM JStgStat #

Introduce only one new variable into scope for the duration of the enclosed expression. The result is a block statement. Usage:

'jVar $ x -> mconcat [jVar x ||= one_, ...'

jVars :: JSArgument args => (args -> JSM JStgStat) -> JSM JStgStat #

Introduce one or many new variables into scope for the duration of the enclosed expression. This function reifies the number of arguments based on the container of the input function. We intentionally avoid lists and instead opt for tuples because lists are not sized in general. The result is a block statement. Usage:

    jVars $ (x,y) -> mconcat [ x |= one_,  y |= two_,  x + y]

jFor #

Arguments

:: (JStgExpr -> JStgStat) | initialization function
-> (JStgExpr -> JStgExpr) | predicate
-> (JStgExpr -> JStgStat) | step function
-> (JStgExpr -> JStgStat) | body
-> JSM JStgStat |

Create a `for` statement given a function for initialization, a predicate to step to, a step and a body Usage:

     jFor (|= zero_) (.<. Int 65536) preIncrS
            (j -> ...something with the counter j...)

jForIn :: JStgExpr -> (JStgExpr -> JStgStat) -> JSM JStgStat #

Create a 'for in' statement. Usage:

    jForIn {expression} $ x -> {block involving x}

jForEachIn :: JStgExpr -> (JStgExpr -> JStgStat) -> JSM JStgStat #

As with "jForIn" but creating a "for each in" statement.

jTryCatchFinally :: (Ident -> JStgStat) -> (Ident -> JStgStat) -> (Ident -> JStgStat) -> JSM JStgStat #

As with "jForIn" but creating a "for each in" statement.

# Combinators

Combinators operate on terms in the JS EDSL domain to create new terms in the EDSL domain.

(||=) :: Ident -> JStgExpr -> JStgStat infixl 2 #

Declare a variable and then Assign the variable to an expression

    foo |= expr ==> var foo; foo = expr;

(|=) :: JStgExpr -> JStgExpr -> JStgStat infixl 2 #

Assign a variable to an expression

    foo |= expr ==> var foo = expr;

(.==.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 6 #

JS infix Equality operators

(.===.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 6 #

JS infix Equality operators

(.!=.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 6 #

JS infix Equality operators

(.!==.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 6 #

JS infix Equality operators

(.!) :: JStgExpr -> JStgExpr -> JStgExpr infixl 8 #

return the expression at idx of obj

    obj .! idx ==> obj[idx]

(.>.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 7 #

JS infix Ord operators

(.>=.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 7 #

JS infix Ord operators

(.<.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 7 #

JS infix Ord operators

(.<=.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 7 #

JS infix Ord operators

(.<<.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 9 #

JS infix bit shift operators

(.>>.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 9 #

JS infix bit shift operators

(.>>>.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 9 #

JS infix bit shift operators

(.|.) :: JStgExpr -> JStgExpr -> JStgExpr #

JS infix bit operators

(.||.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 8 #

JS infix bit operators

(.&&.) :: JStgExpr -> JStgExpr -> JStgExpr infixl 8 #

JS infix bit operators

if_ :: JStgExpr -> JStgExpr -> JStgExpr -> JStgExpr #

JS if-expression

    if_ e1 e2 e3 ==> e1 ? e2 : e3

if10 :: JStgExpr -> JStgExpr #

if-expression that returns 1 if condition = true, 0 otherwise

    if10 e ==> e ? 1 : 0

if01 :: JStgExpr -> JStgExpr #

if-expression that returns 0 if condition = true, 1 otherwise

    if01 e ==> e ? 0 : 1

ifS :: JStgExpr -> JStgStat -> JStgStat -> JStgStat #

If-expression which returns statements, see related `ifBlockS`

    if e s1 s2 ==> if(e) { s1 } else { s2 }

ifBlockS :: JStgExpr -> [JStgStat] -> [JStgStat] -> JStgStat #

If-expression which returns blocks

    ifBlockS e s1 s2 ==> if(e) { s1 } else { s2 }

jBlock :: Monoid a => [JSM a] -> JSM a #

jIf :: JStgExpr -> JSM JStgStat -> JSM JStgStat -> JSM JStgStat #

Version of a JS if-expression which admits monadic actions in its branches

jwhenS :: JStgExpr -> JStgStat -> JStgStat #

A when-statement as syntactic sugar via `ifS`

    jwhenS cond block ==> if(cond) { block } else {  }

app :: FastString -> [JStgExpr] -> JStgExpr #

an application expression, see related `appS`

    app f xs ==> f(xs)

appS :: FastString -> [JStgExpr] -> JStgStat #

A statement application, see the expression form `app`

returnS :: JStgExpr -> JStgStat #

Return a `JStgExpr`

loop :: JStgExpr -> (JStgExpr -> JStgExpr) -> (JStgExpr -> JSM JStgStat) -> JSM JStgStat #

"for" loop with increment at end of body

loopBlockS :: JStgExpr -> (JStgExpr -> JStgExpr) -> (JStgExpr -> [JStgStat]) -> JSM JStgStat #

"for" loop with increment at end of body

preIncrS :: JStgExpr -> JStgStat #

Prefix-increment a `JStgExpr`

postIncrS :: JStgExpr -> JStgStat #

Postfix-increment a `JStgExpr`

preDecrS :: JStgExpr -> JStgStat #

Prefix-decrement a `JStgExpr`

postDecrS :: JStgExpr -> JStgStat #

Postfix-decrement a `JStgExpr`

off8 :: JStgExpr -> JStgExpr -> JStgExpr #

Byte indexing of o with a 8-bit offset

off16 :: JStgExpr -> JStgExpr -> JStgExpr #

Byte indexing of o with a 16-bit offset

off32 :: JStgExpr -> JStgExpr -> JStgExpr #

Byte indexing of o with a 32-bit offset

off64 :: JStgExpr -> JStgExpr -> JStgExpr #

Byte indexing of o with a 64-bit offset

mask8 :: JStgExpr -> JStgExpr #

a bit mask to retrieve the lower 8-bits

mask16 :: JStgExpr -> JStgExpr #

a bit mask to retrieve the lower 16-bits

signExtend8 :: JStgExpr -> JStgExpr #

Sign-extend/narrow a 8-bit value

signExtend16 :: JStgExpr -> JStgExpr #

Sign-extend/narrow a 16-bit value

typeOf :: JStgExpr -> JStgExpr #

Given a `JStgExpr`, return the its type.

returnStack :: JStgStat #

assignAllEqual :: HasDebugCallStack => [JStgExpr] -> [JStgExpr] -> JStgStat #

assignAll :: [JStgExpr] -> [JStgExpr] -> JStgStat #

assignAllReverseOrder :: [JStgExpr] -> [JStgExpr] -> JStgStat #

declAssignAll :: [Ident] -> [JStgExpr] -> JStgStat #

nullStat :: JStgStat #

The empty JS statement

(.^) :: JStgExpr -> FastString -> JStgExpr infixl 8 #

Select a property `prop`, from and object `obj`

    obj .^ prop ==> obj.prop

## Hash combinators

jhEmpty :: Map k JStgExpr #

The empty JS HashMap

jhSingle :: (Ord k, ToJExpr a) => k -> a -> Map k JStgExpr #

A singleton JS HashMap

jhAdd :: (Ord k, ToJExpr a) => k -> a -> Map k JStgExpr -> Map k JStgExpr #

insert a key-value pair into a JS HashMap

jhFromList :: [(FastString, JStgExpr)] -> JVal #

Construct a JS HashMap from a list of key-value pairs

# Literals

Literals in the JS EDSL are constants in the Haskell domain. These are useful helper values and never change

null_ :: JStgExpr #

The JS literal `null`

undefined_ :: JStgExpr #

The JS literal `undefined`

false_ :: JStgExpr #

The JS literal `false`

true_ :: JStgExpr #

The JS literal `true`

zero_ :: JStgExpr #

The JS literal 0

one_ :: JStgExpr #

The JS literal 1

two_ :: JStgExpr #

The JS literal 2

three_ :: JStgExpr #

The JS literal 3

## Math functions

Math functions in the EDSL are literals, with the exception of `math_` which is the sole math introduction function.

math_log :: [JStgExpr] -> JStgExpr #

math_sin :: [JStgExpr] -> JStgExpr #

math_cos :: [JStgExpr] -> JStgExpr #

math_tan :: [JStgExpr] -> JStgExpr #

math_exp :: [JStgExpr] -> JStgExpr #

math_acos :: [JStgExpr] -> JStgExpr #

math_asin :: [JStgExpr] -> JStgExpr #

math_atan :: [JStgExpr] -> JStgExpr #

math_abs :: [JStgExpr] -> JStgExpr #

math_pow :: [JStgExpr] -> JStgExpr #

math_sqrt :: [JStgExpr] -> JStgExpr #

math_asinh :: [JStgExpr] -> JStgExpr #

math_acosh :: [JStgExpr] -> JStgExpr #

math_atanh :: [JStgExpr] -> JStgExpr #

math_cosh :: [JStgExpr] -> JStgExpr #

math_sinh :: [JStgExpr] -> JStgExpr #

math_tanh :: [JStgExpr] -> JStgExpr #

math_expm1 :: [JStgExpr] -> JStgExpr #

math_log1p :: [JStgExpr] -> JStgExpr #

math_fround :: [JStgExpr] -> JStgExpr #

math_min :: [JStgExpr] -> JStgExpr #

math_max :: [JStgExpr] -> JStgExpr #

# Statement helpers

data Solo a #

`Solo` is the canonical lifted 1-tuple, just like `(,)` is the canonical lifted 2-tuple (pair) and `(,,)` is the canonical lifted 3-tuple (triple).

The most important feature of `Solo` is that it is possible to force its "outside" (usually by pattern matching) without forcing its "inside", because it is defined as a datatype rather than a newtype. One situation where this can be useful is when writing a function to extract a value from a data structure. Suppose you write an implementation of arrays and offer only this function to index into them:

    index :: Array a -> Int -> a

Now imagine that someone wants to extract a value from an array and store it in a lazy-valued finite map/dictionary:

    insert "hello" (arr index 12) m

This can actually lead to a space leak. The value is not actually extracted from the array until that value (now buried in a map) is forced. That means the entire array may be kept live by just that value! Often, the solution is to use a strict map, or to force the value before storing it, but for some purposes that's undesirable.

One common solution is to include an indexing function that can produce its result in an arbitrary `Applicative` context:

    indexA :: Applicative f => Array a -> Int -> f a

When using `indexA` in a pure context, `Solo` serves as a handy `Applicative` functor to hold the result. You could write a non-leaky version of the above example thus:

    case arr indexA 12 of
      Solo a -> insert "hello" a m

While such simple extraction functions are the most common uses for unary tuples, they can also be useful for fine-grained control of strict-spined data structure traversals, and for unifying the implementations of lazy and strict mapping functions.

Constructors

MkSolo a |

Bundled Patterns

pattern Solo :: a -> Solo a |

#### Instances

Instances details

MonadZip Solo | Since: base-4.15.0.0
Instance details Defined in Control.Monad.Zip Methods mzip :: Solo a -> Solo b -> Solo (a, b) # mzipWith :: (a -> b -> c) -> Solo a -> Solo b -> Solo c # munzip :: Solo (a, b) -> (Solo a, Solo b) #
Foldable1 Solo | Since: base-4.18.0.0
Instance details Defined in Data.Foldable1 Methods fold1 :: Semigroup m => Solo m -> m # foldMap1 :: Semigroup m => (a -> m) -> Solo a -> m # foldMap1' :: Semigroup m => (a -> m) -> Solo a -> m # toNonEmpty :: Solo a -> NonEmpty a # maximum :: Ord a => Solo a -> a # minimum :: Ord a => Solo a -> a # head :: Solo a -> a # last :: Solo a -> a # foldrMap1 :: (a -> b) -> (a -> b -> b) -> Solo a -> b # foldlMap1' :: (a -> b) -> (b -> a -> b) -> Solo a -> b # foldlMap1 :: (a -> b) -> (b -> a -> b) -> Solo a -> b # foldrMap1' :: (a -> b) -> (a -> b -> b) -> Solo a -> b #
Eq1 Solo | Since: base-4.15
Instance details Defined in Data.Functor.Classes Methods liftEq :: (a -> b -> Bool) -> Solo a -> Solo b -> Bool #
Ord1 Solo | Since: base-4.15
Instance details Defined in Data.Functor.Classes Methods liftCompare :: (a -> b -> Ordering) -> Solo a -> Solo b -> Ordering #
Read1 Solo | Since: base-4.15
Instance details Defined in Data.Functor.Classes Methods liftReadsPrec :: (Int -> ReadS a) -> ReadS [a] -> Int -> ReadS (Solo a) # liftReadList :: (Int -> ReadS a) -> ReadS [a] -> ReadS [Solo a] # liftReadPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec (Solo a) # liftReadListPrec :: ReadPrec a -> ReadPrec [a] -> ReadPrec [Solo a] #
Show1 Solo | Since: base-4.15
Instance details Defined in Data.Functor.Classes Methods liftShowsPrec :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> Int -> Solo a -> ShowS # liftShowList :: (Int -> a -> ShowS) -> ([a] -> ShowS) -> [Solo a] -> ShowS #
NFData1 Solo | Since: deepseq-1.4.6.0
Instance details Defined in Control.DeepSeq Methods liftRnf :: (a -> ()) -> Solo a -> () #
Applicative Solo | @since base-4.15
Instance details Defined in GHC.Internal.Base Methods pure :: a -> Solo a # (<*>) :: Solo (a -> b) -> Solo a -> Solo b # liftA2 :: (a -> b -> c) -> Solo a -> Solo b -> Solo c # (*>) :: Solo a -> Solo b -> Solo b # (<*) :: Solo a -> Solo b -> Solo a #
Functor Solo | @since base-4.15
Instance details Defined in GHC.Internal.Base Methods fmap :: (a -> b) -> Solo a -> Solo b # (<$) :: a -> Solo b -> Solo a #
Monad Solo | @since base-4.15
Instance details Defined in GHC.Internal.Base Methods (>>=) :: Solo a -> (a -> Solo b) -> Solo b # (>>) :: Solo a -> Solo b -> Solo b # return :: a -> Solo a #
MonadFix Solo | @since base-4.15
Instance details Defined in GHC.Internal.Control.Monad.Fix Methods mfix :: (a -> Solo a) -> Solo a #
Foldable Solo | @since base-4.15
Instance details Defined in GHC.Internal.Data.Foldable Methods fold :: Monoid m => Solo m -> m # foldMap :: Monoid m => (a -> m) -> Solo a -> m # foldMap' :: Monoid m => (a -> m) -> Solo a -> m # foldr :: (a -> b -> b) -> b -> Solo a -> b # foldr' :: (a -> b -> b) -> b -> Solo a -> b # foldl :: (b -> a -> b) -> b -> Solo a -> b # foldl' :: (b -> a -> b) -> b -> Solo a -> b # foldr1 :: (a -> a -> a) -> Solo a -> a # foldl1 :: (a -> a -> a) -> Solo a -> a # toList :: Solo a -> [a] # null :: Solo a -> Bool # length :: Solo a -> Int # elem :: Eq a => a -> Solo a -> Bool # maximum :: Ord a => Solo a -> a # minimum :: Ord a => Solo a -> a # sum :: Num a => Solo a -> a # product :: Num a => Solo a -> a #
Traversable Solo | @since base-4.15
Instance details Defined in GHC.Internal.Data.Traversable Methods traverse :: Applicative f => (a -> f b) -> Solo a -> f (Solo b) # sequenceA :: Applicative f => Solo (f a) -> f (Solo a) # mapM :: Monad m => (a -> m b) -> Solo a -> m (Solo b) # sequence :: Monad m => Solo (m a) -> m (Solo a) #
Generic1 Solo |
Instance details Defined in GHC.Internal.Generics Associated Types
type Rep1 Solo | @since base-4.15
Instance details Defined in GHC.Internal.Generics type Rep1 Solo = D1 ('MetaData "Solo" "GHC.Tuple" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1))
Methods from1 :: Solo a -> Rep1 Solo a # to1 :: Rep1 Solo a -> Solo a #
NFData a => NFData (Solo a) | Since: deepseq-1.4.6.0
Instance details Defined in Control.DeepSeq Methods rnf :: Solo a -> () #
Monoid a => Monoid (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Base Methods mempty :: Solo a # mappend :: Solo a -> Solo a -> Solo a # mconcat :: [Solo a] -> Solo a #
Semigroup a => Semigroup (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Base Methods (<>) :: Solo a -> Solo a -> Solo a # sconcat :: NonEmpty (Solo a) -> Solo a # stimes :: Integral b => b -> Solo a -> Solo a #
Data a => Data (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Data.Data Methods gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b) -> (forall g. g -> c g) -> Solo a -> c (Solo a) # gunfold :: (forall b r. Data b => c (b -> r) -> c r) -> (forall r. r -> c r) -> Constr -> c (Solo a) # toConstr :: Solo a -> Constr # dataTypeOf :: Solo a -> DataType # dataCast1 :: Typeable t => (forall d. Data d => c (t d)) -> Maybe (c (Solo a)) # dataCast2 :: Typeable t => (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c (Solo a)) # gmapT :: (forall b. Data b => b -> b) -> Solo a -> Solo a # gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Solo a -> r # gmapQr :: forall r r'. (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Solo a -> r # gmapQ :: (forall d. Data d => d -> u) -> Solo a -> [u] # gmapQi :: Int -> (forall d. Data d => d -> u) -> Solo a -> u # gmapM :: Monad m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) # gmapMp :: MonadPlus m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) # gmapMo :: MonadPlus m => (forall d. Data d => d -> m d) -> Solo a -> m (Solo a) #
Bounded a => Bounded (Solo a) |
Instance details Defined in GHC.Internal.Enum Methods minBound :: Solo a # maxBound :: Solo a #
Enum a => Enum (Solo a) |
Instance details Defined in GHC.Internal.Enum Methods succ :: Solo a -> Solo a # pred :: Solo a -> Solo a # toEnum :: Int -> Solo a # fromEnum :: Solo a -> Int # enumFrom :: Solo a -> [Solo a] # enumFromThen :: Solo a -> Solo a -> [Solo a] # enumFromTo :: Solo a -> Solo a -> [Solo a] # enumFromThenTo :: Solo a -> Solo a -> Solo a -> [Solo a] #
Generic (Solo a) |
Instance details Defined in GHC.Internal.Generics Associated Types
type Rep (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Generics type Rep (Solo a) = D1 ('MetaData "Solo" "GHC.Tuple" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))
Methods from :: Solo a -> Rep (Solo a) x # to :: Rep (Solo a) x -> Solo a #
Ix a => Ix (Solo a) |
Instance details Defined in GHC.Internal.Ix Methods range :: (Solo a, Solo a) -> [Solo a] # index :: (Solo a, Solo a) -> Solo a -> Int # unsafeIndex :: (Solo a, Solo a) -> Solo a -> Int # inRange :: (Solo a, Solo a) -> Solo a -> Bool # rangeSize :: (Solo a, Solo a) -> Int # unsafeRangeSize :: (Solo a, Solo a) -> Int #
Read a => Read (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Read Methods readsPrec :: Int -> ReadS (Solo a) # readList :: ReadS [Solo a] # readPrec :: ReadPrec (Solo a) # readListPrec :: ReadPrec [Solo a] #
Show a => Show (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Show Methods showsPrec :: Int -> Solo a -> ShowS # show :: Solo a -> String # showList :: [Solo a] -> ShowS #
(JVarMagic a, ToJExpr a) => JSArgument (Solo a) # |
Instance details Defined in GHC.JS.Make Methods argList :: Solo a -> [Ident] # args :: JSM (Solo a) #
Eq a => Eq (Solo a) |
Instance details Defined in GHC.Classes Methods (==) :: Solo a -> Solo a -> Bool # (/=) :: Solo a -> Solo a -> Bool #
Ord a => Ord (Solo a) |
Instance details Defined in GHC.Classes Methods compare :: Solo a -> Solo a -> Ordering # (<) :: Solo a -> Solo a -> Bool # (<=) :: Solo a -> Solo a -> Bool # (>) :: Solo a -> Solo a -> Bool # (>=) :: Solo a -> Solo a -> Bool # max :: Solo a -> Solo a -> Solo a # min :: Solo a -> Solo a -> Solo a #
type Rep1 Solo | @since base-4.15
Instance details Defined in GHC.Internal.Generics type Rep1 Solo = D1 ('MetaData "Solo" "GHC.Tuple" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) Par1))
type Rep (Solo a) | @since base-4.15
Instance details Defined in GHC.Internal.Generics type Rep (Solo a) = D1 ('MetaData "Solo" "GHC.Tuple" "ghc-prim" 'False) (C1 ('MetaCons "MkSolo" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 a)))

decl :: Ident -> JStgStat #

construct a js declaration with the given identifier

# Orphan instances

Num JStgExpr # |
Instance details Methods (+) :: JStgExpr -> JStgExpr -> JStgExpr # (-) :: JStgExpr -> JStgExpr -> JStgExpr # (*) :: JStgExpr -> JStgExpr -> JStgExpr # negate :: JStgExpr -> JStgExpr # abs :: JStgExpr -> JStgExpr # signum :: JStgExpr -> JStgExpr # fromInteger :: Integer -> JStgExpr #
Fractional JStgExpr # |
Instance details Methods (/) :: JStgExpr -> JStgExpr -> JStgExpr # recip :: JStgExpr -> JStgExpr # fromRational :: Rational -> JStgExpr #