ghc-lib-parser-9.8.2.20240223: 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 | None
Language | Haskell2010

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`. Notice that the type of each of these functions have the domain `isSat a => a -> ...`; indicating that they each take something that can be injected into the EDSL domain, and the range `JExpr` or `JStat`; indicating the corresponding value in the EDSL domain. Similarly this module exports two typeclasses `ToExpr` and `ToSat`, `ToExpr` injects values as a JS expression into the EDSL. `ToSat` ensures that terms introduced into the EDSL carry identifier information so terms in the EDSL must have meaning.

  - 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.

Synopsis

- class ToJExpr a where
  - toJExpr :: a -> JExpr
  - toJExprFromList :: [a] -> JExpr
- class ToStat a where
  - toStat :: a -> JStat
- var :: FastString -> JExpr
- jString :: FastString -> JExpr
- jLam :: ToSat a => a -> JExpr
- jFun :: ToSat a => Ident -> a -> JStat
- jFunction :: Ident -> [Ident] -> JStat -> JStat
- jVar :: ToSat a => a -> JStat
- jFor :: (JExpr -> JStat) -> (JExpr -> JExpr) -> (JExpr -> JStat) -> (JExpr -> JStat) -> JStat
- jForNoDecl :: Ident -> JExpr -> JExpr -> JStat -> JStat -> JStat
- jForIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat
- jForEachIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat
- jTryCatchFinally :: ToSat a => JStat -> a -> JStat -> JStat
- (||=) :: Ident -> JExpr -> JStat
- (|=) :: JExpr -> JExpr -> JStat
- (.==.) :: JExpr -> JExpr -> JExpr
- (.===.) :: JExpr -> JExpr -> JExpr
- (.!=.) :: JExpr -> JExpr -> JExpr
- (.!==.) :: JExpr -> JExpr -> JExpr
- (.!) :: JExpr -> JExpr -> JExpr
- (.>.) :: JExpr -> JExpr -> JExpr
- (.>=.) :: JExpr -> JExpr -> JExpr
- (.<.) :: JExpr -> JExpr -> JExpr
- (.<=.) :: JExpr -> JExpr -> JExpr
- (.<<.) :: JExpr -> JExpr -> JExpr
- (.>>.) :: JExpr -> JExpr -> JExpr
- (.>>>.) :: JExpr -> JExpr -> JExpr
- (.|.) :: JExpr -> JExpr -> JExpr
- (.||.) :: JExpr -> JExpr -> JExpr
- (.&&.) :: JExpr -> JExpr -> JExpr
- if_ :: JExpr -> JExpr -> JExpr -> JExpr
- if10 :: JExpr -> JExpr
- if01 :: JExpr -> JExpr
- ifS :: JExpr -> JStat -> JStat -> JStat
- ifBlockS :: JExpr -> [JStat] -> [JStat] -> JStat
- jwhenS :: JExpr -> JStat -> JStat
- app :: FastString -> [JExpr] -> JExpr
- appS :: FastString -> [JExpr] -> JStat
- returnS :: JExpr -> JStat
- loop :: JExpr -> (JExpr -> JExpr) -> (JExpr -> JStat) -> JStat
- loopBlockS :: JExpr -> (JExpr -> JExpr) -> (JExpr -> [JStat]) -> JStat
- preIncrS :: JExpr -> JStat
- postIncrS :: JExpr -> JStat
- preDecrS :: JExpr -> JStat
- postDecrS :: JExpr -> JStat
- off8 :: JExpr -> JExpr -> JExpr
- off16 :: JExpr -> JExpr -> JExpr
- off32 :: JExpr -> JExpr -> JExpr
- off64 :: JExpr -> JExpr -> JExpr
- mask8 :: JExpr -> JExpr
- mask16 :: JExpr -> JExpr
- signExtend8 :: JExpr -> JExpr
- signExtend16 :: JExpr -> JExpr
- typeof :: JExpr -> JExpr
- returnStack :: JStat
- assignAllEqual :: HasDebugCallStack => [JExpr] -> [JExpr] -> JStat
- assignAll :: [JExpr] -> [JExpr] -> JStat
- assignAllReverseOrder :: [JExpr] -> [JExpr] -> JStat
- declAssignAll :: [Ident] -> [JExpr] -> JStat
- nullStat :: JStat
- (.^) :: JExpr -> FastString -> JExpr
- trace :: ToJExpr a => a -> JStat
- jhEmpty :: Map k JExpr
- jhSingle :: (Ord k, ToJExpr a) => k -> a -> Map k JExpr
- jhAdd :: (Ord k, ToJExpr a) => k -> a -> Map k JExpr -> Map k JExpr
- jhFromList :: [(FastString, JExpr)] -> JVal
- null_ :: JExpr
- undefined_ :: JExpr
- false_ :: JExpr
- true_ :: JExpr
- zero_ :: JExpr
- one_ :: JExpr
- two_ :: JExpr
- three_ :: JExpr
- math_log :: [JExpr] -> JExpr
- math_sin :: [JExpr] -> JExpr
- math_cos :: [JExpr] -> JExpr
- math_tan :: [JExpr] -> JExpr
- math_exp :: [JExpr] -> JExpr
- math_acos :: [JExpr] -> JExpr
- math_asin :: [JExpr] -> JExpr
- math_atan :: [JExpr] -> JExpr
- math_abs :: [JExpr] -> JExpr
- math_pow :: [JExpr] -> JExpr
- math_sqrt :: [JExpr] -> JExpr
- math_asinh :: [JExpr] -> JExpr
- math_acosh :: [JExpr] -> JExpr
- math_atanh :: [JExpr] -> JExpr
- math_cosh :: [JExpr] -> JExpr
- math_sinh :: [JExpr] -> JExpr
- math_tanh :: [JExpr] -> JExpr
- math_expm1 :: [JExpr] -> JExpr
- math_log1p :: [JExpr] -> JExpr
- math_fround :: [JExpr] -> JExpr
- decl :: Ident -> JStat

# 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 -> JExpr #

toJExprFromList :: [a] -> JExpr #

#### Instances

Instances details

ToJExpr FastString # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: FastString -> JExpr # toJExprFromList :: [FastString] -> JExpr #
ToJExpr Ident # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Ident -> JExpr # toJExprFromList :: [Ident] -> JExpr #
ToJExpr JExpr # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: JExpr -> JExpr # toJExprFromList :: [JExpr] -> JExpr #
ToJExpr JVal # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: JVal -> JExpr # toJExprFromList :: [JVal] -> JExpr #
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 -> JExpr # toJExprFromList :: [CIStatic] -> JExpr #
ToJExpr ClosureType # |
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: ClosureType -> JExpr # toJExprFromList :: [ClosureType] -> JExpr #
ToJExpr StaticLit # |
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: StaticLit -> JExpr # toJExprFromList :: [StaticLit] -> JExpr #
ToJExpr VarType # |
Instance details Defined in GHC.StgToJS.Types Methods toJExpr :: VarType -> JExpr # toJExprFromList :: [VarType] -> JExpr #
ToJExpr Integer # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Integer -> JExpr # toJExprFromList :: [Integer] -> JExpr #
ToJExpr () # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: () -> JExpr # toJExprFromList :: [()] -> JExpr #
ToJExpr Bool # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Bool -> JExpr # toJExprFromList :: [Bool] -> JExpr #
ToJExpr Char # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Char -> JExpr # toJExprFromList :: [Char] -> JExpr #
ToJExpr Double # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Double -> JExpr # toJExprFromList :: [Double] -> JExpr #
ToJExpr Int # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Int -> JExpr # toJExprFromList :: [Int] -> JExpr #
ToJExpr a => ToJExpr [a] # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: [a] -> JExpr # toJExprFromList :: [[a]] -> JExpr #
ToJExpr a => ToJExpr (Map String a) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: Map String a -> JExpr # toJExprFromList :: [Map String a] -> JExpr #
ToJExpr a => ToJExpr (UniqMap FastString a) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: UniqMap FastString a -> JExpr # toJExprFromList :: [UniqMap FastString a] -> JExpr #
(ToJExpr a, ToJExpr b) => ToJExpr (a, b) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b) -> JExpr # toJExprFromList :: [(a, b)] -> JExpr #
(ToJExpr a, ToJExpr b, ToJExpr c) => ToJExpr (a, b, c) # |
Instance details Defined in GHC.JS.Make Methods toJExpr :: (a, b, c) -> JExpr # toJExprFromList :: [(a, b, c)] -> JExpr #
(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) -> JExpr # toJExprFromList :: [(a, b, c, d)] -> JExpr #
(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) -> JExpr # toJExprFromList :: [(a, b, c, d, e)] -> JExpr #
(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) -> JExpr # toJExprFromList :: [(a, b, c, d, e, f)] -> JExpr #

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 -> JStat #

#### Instances

Instances details

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

# Introduction functions

var :: FastString -> JExpr #

construct a JS variable reference

jString :: FastString -> JExpr #

Convert a ShortText to a Javascript String

jLam :: ToSat a => a -> JExpr #

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)))

jFun :: ToSat a => Ident -> a -> JStat #

Create a new function. The result is a `JStat`. Usage:

    jFun fun_name $ \x -> ...

jFunction :: Ident -> [Ident] -> JStat -> JStat #

jVar :: ToSat a => a -> JStat #

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

    jVar $ x y -> mconcat [x ||= one_, y ||= two_, x + y]

jFor :: (JExpr -> JStat) -> (JExpr -> JExpr) -> (JExpr -> JStat) -> (JExpr -> JStat) -> JStat #

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...)

jForNoDecl :: Ident -> JExpr -> JExpr -> JStat -> JStat -> JStat #

jForIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat #

Create a 'for in' statement. Usage:

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

jForEachIn :: ToSat a => JExpr -> (JExpr -> a) -> JStat #

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

jTryCatchFinally :: ToSat a => JStat -> a -> JStat -> JStat #

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 -> JExpr -> JStat infixl 2 #

Declare a variable and then Assign the variable to an expression

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

(|=) :: JExpr -> JExpr -> JStat infixl 2 #

Assign a variable to an expression

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

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

JS infix Equality operators

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

JS infix Equality operators

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

JS infix Equality operators

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

JS infix Equality operators

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

return the expression at idx of obj

    obj .! idx ==> obj[idx]

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

JS infix Ord operators

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

JS infix Ord operators

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

JS infix Ord operators

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

JS infix Ord operators

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

JS infix bit shift operators

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

JS infix bit shift operators

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

JS infix bit shift operators

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

JS infix bit operators

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

JS infix bit operators

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

JS infix bit operators

if_ :: JExpr -> JExpr -> JExpr -> JExpr #

JS if-expression

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

if10 :: JExpr -> JExpr #

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

    if10 e ==> e ? 1 : 0

if01 :: JExpr -> JExpr #

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

    if01 e ==> e ? 0 : 1

ifS :: JExpr -> JStat -> JStat -> JStat #

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

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

ifBlockS :: JExpr -> [JStat] -> [JStat] -> JStat #

If-expression which returns blocks

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

jwhenS :: JExpr -> JStat -> JStat #

A when-statement as syntactic sugar via `ifS`

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

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

an expression application, see related `appS`

    app f xs ==> f(xs)

appS :: FastString -> [JExpr] -> JStat #

A statement application, see the expression form `app`

returnS :: JExpr -> JStat #

Return a `JExpr`

loop :: JExpr -> (JExpr -> JExpr) -> (JExpr -> JStat) -> JStat #

"for" loop with increment at end of body

loopBlockS :: JExpr -> (JExpr -> JExpr) -> (JExpr -> [JStat]) -> JStat #

"for" loop with increment at end of body

preIncrS :: JExpr -> JStat #

Prefix-increment a `JExpr`

postIncrS :: JExpr -> JStat #

Postfix-increment a `JExpr`

preDecrS :: JExpr -> JStat #

Prefix-decrement a `JExpr`

postDecrS :: JExpr -> JStat #

Postfix-decrement a `JExpr`

off8 :: JExpr -> JExpr -> JExpr #

Byte indexing of o with a 8-bit offset

off16 :: JExpr -> JExpr -> JExpr #

Byte indexing of o with a 16-bit offset

off32 :: JExpr -> JExpr -> JExpr #

Byte indexing of o with a 32-bit offset

off64 :: JExpr -> JExpr -> JExpr #

Byte indexing of o with a 64-bit offset

mask8 :: JExpr -> JExpr #

a bit mask to retrieve the lower 8-bits

mask16 :: JExpr -> JExpr #

a bit mask to retrieve the lower 16-bits

signExtend8 :: JExpr -> JExpr #

Sign-extend/narrow a 8-bit value

signExtend16 :: JExpr -> JExpr #

Sign-extend/narrow a 16-bit value

typeof :: JExpr -> JExpr #

Given a `JExpr`, return the its type.

returnStack :: JStat #

assignAllEqual :: HasDebugCallStack => [JExpr] -> [JExpr] -> JStat #

assignAll :: [JExpr] -> [JExpr] -> JStat #

assignAllReverseOrder :: [JExpr] -> [JExpr] -> JStat #

declAssignAll :: [Ident] -> [JExpr] -> JStat #

nullStat :: JStat #

The empty JS statement

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

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

    obj .^ prop ==> obj.prop

trace :: ToJExpr a => a -> JStat #

## Hash combinators

jhEmpty :: Map k JExpr #

The empty JS HashMap

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

A singleton JS HashMap

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

insert a key-value pair into a JS HashMap

jhFromList :: [(FastString, JExpr)] -> 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_ :: JExpr #

The JS literal `null`

undefined_ :: JExpr #

The JS literal `undefined`

false_ :: JExpr #

The JS literal `false`

true_ :: JExpr #

The JS literal `true`

zero_ :: JExpr #

The JS literal 0

one_ :: JExpr #

The JS literal 1

two_ :: JExpr #

The JS literal 2

three_ :: JExpr #

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 :: [JExpr] -> JExpr #

math_sin :: [JExpr] -> JExpr #

math_cos :: [JExpr] -> JExpr #

math_tan :: [JExpr] -> JExpr #

math_exp :: [JExpr] -> JExpr #

math_acos :: [JExpr] -> JExpr #

math_asin :: [JExpr] -> JExpr #

math_atan :: [JExpr] -> JExpr #

math_abs :: [JExpr] -> JExpr #

math_pow :: [JExpr] -> JExpr #

math_sqrt :: [JExpr] -> JExpr #

math_asinh :: [JExpr] -> JExpr #

math_acosh :: [JExpr] -> JExpr #

math_atanh :: [JExpr] -> JExpr #

math_cosh :: [JExpr] -> JExpr #

math_sinh :: [JExpr] -> JExpr #

math_tanh :: [JExpr] -> JExpr #

math_expm1 :: [JExpr] -> JExpr #

math_log1p :: [JExpr] -> JExpr #

math_fround :: [JExpr] -> JExpr #

# Statement helpers

decl :: Ident -> JStat #

construct a js declaration with the given identifier

# Orphan instances

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