hexresearch / hschain-utxo

UTXO-based contracts for hschain
0 stars 0 forks source link

Quasi quotes for high level language #194

Closed anton-k closed 3 years ago

anton-k commented 3 years ago

Implements quasi quoter for high level language. How to use:

-- | QuasiQuoter for high level language.
 --
 -- With quasi quoter we can create scripts quote easily. We use prefix utxo:
 --
 -- > box'script = [utxo|main = (2 + 2) == 4|]
 --
 --  QuasiQuote is trasformed to value of type Script.
 --  It accepts two types of code. First type is code for expressions.
 --  It is treated as if it's module with single main function defined with given expression.
 --
 -- > script = [utxo|lengthText "Hello"|]
 --
 -- It would be converted to script with single main function:
 --
 -- > main = lengthText "Hello"
 --
 --  Also it accepts full modules with set of definitions.
 --
 --  Dependencies: for quasi quoter to work we should import module @Hschain.Utxo.Lang@
 --  and enable extension @OverloadedStrings@.
 --
 -- For interpolation of external haskell values we use single parens around variable:
 --
 -- > [utxo|main = pk (alicePubKey)|]
 --
 -- Value is inlined to code over class @ToLang@. It invokes the method @toLangExpr@ on the value.
 -- Note that in this form inside the code value can have any type. For typechecker
 -- it's treated just like haskell value @undefined@. So if type in the external code is erroneous
 -- program is going to fail at runtime.
 --
 -- It can be usefull to restrict the types of inlined haskell values
 -- to be able to check them at compile-time.
 --
 -- We can do it with special form by supplying the type with operator @#@:
 --
 -- > [utxo|main = pk (alicePubKey # PublicKey) |]
 --
 --  This expression is going to fail at compile time if @alicePubKey@ has inproper type.
 --
 -- We can inline:
 --
 --    * primitives: Int, Int64, Bool, Text, ByteString, Sigma ByteString, Script (inlined as ByteString),
 --                  PublicKey (inlined as ByteString),
 --
 --    * composites: lists and tuples of inlineable values.
 --
 -- Useful examples:
 --
 --  Simple spends:
 --
 -- > spendScript = [utxo|pk (alicePubKey)|]
 --
 --  Spend with delay time:
 --
 -- > spendDelayed delay alicePk bobPk = [|utxo
 -- >
 -- >    main =   (pk (alicePk) &&* toSigma (getHeight < (delay)))
 -- >         ||* (pk (bobPk)   &&* toSigma (getHeight >= (delay)))
 -- > |]

I wrote several tests with it. Unfortunately now XorGame test brakes with QQ. And I don't know how to quickly fix it. I have deactivated it for now. I'm going to fix it later.