Safe Haskell | Safe-Inferred |
---|---|
Language | GHC2021 |
Synopsis
- prettyTerm :: Config -> ClosedTerm a -> Doc ()
- prettyTermAndCost :: forall a. Config -> ClosedTerm a -> Doc ()
- prettyTerm' :: Config -> ClosedTerm p -> Either Text (Doc ())
- prettyScript :: Script -> Doc ()
Documentation
prettyTerm :: Config -> ClosedTerm a -> Doc () Source #
Prettify a Plutarch term.
This will call error
if there's a compilation failure. Use prettyTerm'
for a non-partial version.
Example ==
import Plutarch.Prelude
import Plutarch.Api.V1
checkSignatory :: Term s (PPubKeyHash :--> PScriptContext :--> PUnit)
checkSignatory = plam $ ph ctx' -> unTermCont $ do
ctx <- pletFieldsC ["txInfo", "purpose"] ctx'
purph <- pmatchC ctx.purpose
pure $ case purph of
PSpending _ ->
let signatories = pfield
"signatories" # ctx.txInfo
in pif
(pelem # pdata ph # pfromData signatories)
-- Success!
(pconstant ())
-- Signature not present.
perror
_ -> ptraceError "checkSignatoryCont: not a spending tx"
Prettification result:
let frSndPair = !!sndPair unDataSum = (xF -> frSndPair (unConstrData xF)) frTailList = !tailList frHeadList = !headList frIfThenElse = !ifThenElse in (oP4ECBT qsrxlF0Y7 -> let cjlB6yrGk = unDataSum qsrxlF0Y7 cRFO = unConstrData (frHeadList (frTailList cjlB6yrGk)) cs9iR = !!fstPair cRFO w4 = frSndPair cRFO in if equalsInteger 1 cs9iR then if (vModHwqYB -> let blM6d67 = (x5sad ePDSInSEC -> !(!!chooseList ePDSInSEC ~False ~(if equalsData (frHeadList ePDSInSEC) vModHwqYB then True else x5sad (frTailList ePDSInSEC)))) mC = (jfZs -> blM6d67 (itzT -> jfZs jfZs itzT)) in blM6d67 (ispwp_oeT -> mC mC ispwp_oeT)) (bData oP4ECBT) (unListData let q6X3 = frHeadList cjlB6yrGk in frHeadList let olbZ = unDataSum q6X3 in frTailList (frTailList (frTailList (frTailList (frTailList (frTailList (frTailList olbZ))))))) then () else ERROR else !(!trace "checkSignatoryCont: not a spending tx" ~ERROR))
Semantics ==
Constants ===
- Builtin integers are printed as regular integers. [0-9]+
- Builtin bytestrings are printed in hex notation, prefixed by `0x`. 0x[0-9a-f]+/i
- Builtin strings are printed as is.
- Builtin unit is printed as the unit literal. ()
- Builtin booleans are printed as the literal
True
orFalse
. - Builtin lists are prettified as list literals, i.e delimited with `[` and `]`.
- Builtin pairs are prettified as 2-ary tuple literals, e.g. `(a, b)`.
I
data (i.e data encoded integers) are prettified like builtin integers with a#
prefix. #[0-9]+B
data (i.e data encoded bytestrings) are prettified like builtin bytestrings with a#
prefix. #0x[0-9a-f]+/iList
data (i.e data encoded lists) are prettified like builtin lists with a#
prefix.Map
data is printed like record literals. Delimited by `{` and `}`.
Each key value pair is prettified like key = value and multiple pairs are joined with `,`.
For example, `Map [(I 42, I 0), (I 100, I 1)]` is prettified as `{ #42 = #0, #100 = #1 }` - Constr data has two core elements in its prettified form:
- The constructor index, prettified as an integer prefixed with
Σ
(sigma). - Its fields, prettified as a list.
These two elements are then joined with a .
(period).
For example, `Constr 1 [I 42]` is prettified as "Σ1.[#42]".
Builtin functions ===
Builtin functions are prettified into their name, in title case.
Forced term ===
Forced terms are prefixed with a !
. The unary operator !
has higher fixity than function application.
Delayed term ===
Delayed terms are prefixed with a ~
. The unary operator ~
has higher fixity than function application.
Var ===
Random names are generated for all variable bindings, and these names are used to refer to them.
Names are always unique, between 1 and 8 characters in length, and begin with a lowercase letter.
Names may consist of alphanumeric characters, underscore, or single quotes.
LamAbs ===
Lambdas are prettified similar to haskell lambdas, i.e `x -> ...`.
Lambdas with multiple arguments are detected and simplified: `x y z -> ...`.
Apply ===
Application is, simply, a space - just like haskell. `f x`.
Multi arg applications to the same function are detected and simplified: `f x y`.
Error term ===
perror
is represented by the literal ERROR
.
Special handling ===
To achieve better prettification, certain AST structures are given special handling logic.
- The AST structure produced by
plet
(SingleApply
+LamAbs
pair) is prettified into Haskell-like let bindings. - Lazy ifthenelse (
pif
in particular, notpif'
) is detected and prettified into Haskell-like syntax: `if cond then expr1 else expr2`.
Chains of ifthenelse are nested:
if cond then expr1 else if cond then expr2 else expr3
- When generating names for bindings, well known structures are identified and given special names.
This machinery is made to be extensible in the future.
For example, the structure of the pfix
function is well known and constant - so it is simply called fix
in the output.
Bindings to forced builtin functions inherit the builtin function name, prefixed with a fr
.
prettyTermAndCost :: forall a. Config -> ClosedTerm a -> Doc () Source #
Same as prettyTerm
but also includes the execution budget and script size
@since WIP
prettyTerm' :: Config -> ClosedTerm p -> Either Text (Doc ()) Source #
Non-partial prettyTerm
.
prettyScript :: Script -> Doc () Source #
prettyTerm
for pre-compiled Script
s.