Skip to content

Commit 3b03bdb

Browse files
Update GenRustJets to generate Bitcoin Jets
1 parent 73be556 commit 3b03bdb

File tree

1 file changed

+74
-54
lines changed

1 file changed

+74
-54
lines changed

Haskell-Generate/GenRustJets.hs

Lines changed: 74 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import Data.Char (toLower)
55
import Data.Foldable (toList)
66
import Data.Function (on)
77
import Data.Functor.Fixedpoint (Fix(..))
8-
import Data.List (sortBy)
8+
import Data.List (nubBy, sortBy)
99
import Data.List.Split (chunksOf)
1010
import Data.Maybe (fromMaybe)
1111
import qualified Data.Map as Map
@@ -47,7 +47,14 @@ sortJetName = sortBy (compare `on` name)
4747
where
4848
name (SomeArrow j) = jetName j
4949

50-
cJetName = lowerSnakeCase . jetName
50+
rustJetName :: JetData x y -> String
51+
rustJetName jd = lowerSnakeCase (jetName jd)
52+
53+
cJetName :: JetData x y -> String
54+
cJetName jd = prefix (jetModule jd) ++ lowerSnakeCase (jetName jd)
55+
where
56+
prefix BitcoinModule = "bitcoin_"
57+
prefix _ = ""
5158

5259
coreJetData :: (TyC x, TyC y) => CoreJet x y -> JetData x y
5360
coreJetData jet = JetData { jetName = mkName jet
@@ -87,6 +94,7 @@ moduleJets = sortJetName . toList . moduleCodes
8794

8895
rustModuleName = fromMaybe "Core" . moduleName
8996
lowerRustModuleName = map toLower . rustModuleName
97+
moduleEnvType mod = lowerRustModuleName mod ++ "::CTxEnv, "
9098

9199
coreModule :: Module
92100
coreModule = Module Nothing (someArrowMap coreJetData <$> (treeEvalBitStream Core.getJetBit))
@@ -100,6 +108,11 @@ elementsModule = Module (Just "Elements") (someArrowMap elementsJetData <$> take
100108
bitcoinModule :: Module
101109
bitcoinModule = Module (Just "Bitcoin") (someArrowMap bitcoinJetData <$> takeRight (treeEvalBitStream Bitcoin.getJetBit))
102110

111+
allJets :: [SomeArrow JetData]
112+
allJets = nubBy eqJet . sortJetName $ moduleJets =<< [bitcoinModule, elementsModule]
113+
where
114+
eqJet (SomeArrow jt1) (SomeArrow jt2) = jetName jt1 == jetName jt2 && jetModule jt1 == jetModule jt2
115+
103116
data CompactTy = CTyOne
104117
| CTyWord Int
105118
| CTyMaybe CompactTy
@@ -190,16 +203,14 @@ rustJetTargetTy = rustJetTy "target_ty" (\(SomeArrow jet) -> unreflect (snd (rei
190203
rustJetPtr :: Module -> Doc a
191204
rustJetPtr mod = vsep $
192205
[ nest 4 (vsep ("fn c_jet_ptr(&self) -> &dyn Fn(&mut CFrameItem, CFrameItem, &Self::CJetEnvironment) -> bool {" :
193-
if modname == "Bitcoin"
194-
then ["unimplemented!(\"Bitcoin jets have not yet been implemented.\")"]
195-
else [ nest 4 (vsep ("match self {" :
196-
map (<>comma)
197-
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=>" <+>
198-
pretty ("&simplicity_sys::c_jets::jets_wrapper::"++cJetName jet)
199-
| SomeArrow jet <- moduleJets mod
200-
]))
201-
, "}"
202-
]))
206+
[ nest 4 (vsep ("match self {" :
207+
map (<>comma)
208+
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=>" <+>
209+
pretty ("&simplicity_sys::c_jets::jets_wrapper::"++cJetName jet)
210+
| SomeArrow jet <- moduleJets mod
211+
]))
212+
, "}"
213+
]))
203214
, "}"
204215
]
205216
where
@@ -264,23 +275,26 @@ rustJetImpl mod = vsep $
264275
where
265276
modname = rustModuleName mod
266277
env = vsep
267-
[ pretty $ "type Environment = "++env++";"
278+
[ pretty $ "type Transaction = "++transaction++";"
279+
, pretty $ "type Environment<T> = "++env++"<T> where T: Borrow<Self::Transaction>;"
268280
, pretty $ "type CJetEnvironment = "++cEnv++";"
269281
, ""
270-
, pretty $ "fn c_jet_env("++envArg++": &Self::Environment) -> &Self::CJetEnvironment {"
282+
, pretty $ "fn c_jet_env<T>("++envArg++": &Self::Environment<T>) -> &Self::CJetEnvironment"
283+
, " where T: Borrow<Self::Transaction>"
284+
, "{"
271285
, pretty $ " "++envBody
272286
, "}"
273287
]
274288
where
275-
env | Nothing <- moduleName mod = "()"
276-
| Just "Elements" == moduleName mod = "ElementsEnv<std::sync::Arc<elements::Transaction>>"
289+
transaction | Nothing <- moduleName mod = "core::convert::Infallible"
290+
| Just name <- moduleName mod = map toLower name ++"::Transaction"
291+
env | Nothing <- moduleName mod = "CoreEnv"
277292
| Just name <- moduleName mod = name ++ "Env"
278-
cEnv | Just "Elements" == moduleName mod = "CElementsTxEnv"
279-
| otherwise = "()"
280-
envArg | Just "Bitcoin" == moduleName mod = "_env"
293+
cEnv | Nothing <- moduleName mod = "CoreEnv<Self::Transaction>"
294+
| otherwise = "CTxEnv"
295+
envArg | Nothing <- moduleName mod = "_"
281296
| otherwise = "env"
282-
envBody | Nothing == moduleName mod = "env"
283-
| Just "Bitcoin" == moduleName mod = "unimplemented!(\"Unspecified CJetEnvironment for Bitcoin jets\")"
297+
envBody | Nothing <- moduleName mod = "&CoreEnv::EMPTY"
284298
| otherwise = "env.c_tx_env()"
285299

286300
rustJetEnum :: Module -> Doc a
@@ -310,7 +324,7 @@ rustJetDisplay mod =
310324
nestBraces ("match self" <+>
311325
nestBraces (vsep (
312326
map (<>comma)
313-
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=> f.write_str" <> (parens . dquotes . pretty $ cJetName jet)
327+
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=> f.write_str" <> (parens . dquotes . pretty $ rustJetName jet)
314328
| SomeArrow jet <- moduleJets mod
315329
]))
316330
)
@@ -328,7 +342,7 @@ rustJetFromStr mod =
328342
nestBraces ("match s" <+>
329343
nestBraces (vsep (
330344
map (<> comma)
331-
([ dquotes (pretty (cJetName jet)) <+> "=> Ok" <> parens (pretty modname <> "::" <> pretty (jetName jet))
345+
([ dquotes (pretty (rustJetName jet)) <+> "=> Ok" <> parens (pretty modname <> "::" <> pretty (jetName jet))
332346
| SomeArrow jet <- moduleJets mod
333347
] ++ [ "x => Err(crate::Error::InvalidJetName(x.to_owned()))" ]
334348
)))
@@ -351,14 +365,13 @@ rustImports mod = vsep (map (<> semi)
351365
, "use hashes::sha256::Midstate"
352366
, "use simplicity_sys::CFrameItem"
353367
, "use std::io::Write"
354-
, "use std::{fmt, str}"
368+
, "use std::{borrow::Borrow, fmt, str}"
355369
] ++ envImports))
356370
where
357-
envImports | Nothing == moduleName mod = []
358-
| Just "Bitcoin" == moduleName mod = ["use crate::jet::bitcoin::BitcoinEnv"]
371+
envImports | Nothing == moduleName mod = ["use crate::jet::core::CoreEnv"]
359372
| Just name <- moduleName mod =
360373
[ pretty $ "use crate::jet::"++map toLower name++"::"++name++"Env"
361-
, pretty $ "use simplicity_sys::C"++name++"TxEnv"
374+
, pretty $ "use simplicity_sys::"++map toLower name++"::CTxEnv"
362375
]
363376

364377
rustJetDoc :: Module -> SimpleDocStream a
@@ -374,14 +387,16 @@ rustJetDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
374387
rustFFIImports :: Doc a
375388
rustFFIImports = vsep (map (<> semi)
376389
[ "use crate::ffi::c_void"
377-
, "use crate::{CElementsTxEnv, CFrameItem}"
390+
, "use crate::bitcoin"
391+
, "use crate::elements"
392+
, "use crate::CFrameItem"
378393
])
379394

380-
rustFFISigs :: Module -> Doc a
381-
rustFFISigs mod = vsep
395+
rustFFISigs :: Doc a
396+
rustFFISigs = vsep
382397
[ nest 4 $ vsep $
383398
"extern \"C\" {" :
384-
(declaration <$> moduleJets mod)
399+
(declaration <$> allJets)
385400
, "}"
386401
]
387402
where
@@ -393,63 +408,68 @@ rustFFISigs mod = vsep
393408
linkName = "#[link_name = \"c_"++cJetName jet++"\"]"
394409
signature = "pub fn "++cJetName jet++"(dst: *mut CFrameItem, src: *const CFrameItem, env: *const "++envType++") -> bool"
395410
envType | CoreModule <- jetModule jet = "c_void"
396-
| ElementsModule <- jetModule jet = "CElementsTxEnv"
411+
| ElementsModule <- jetModule jet = "elements::CTxEnv"
412+
| BitcoinModule <- jetModule jet = "bitcoin::CTxEnv"
397413

398-
rustFFIDoc :: Module -> SimpleDocStream a
399-
rustFFIDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
414+
rustFFIDoc :: SimpleDocStream a
415+
rustFFIDoc = layoutPretty layoutOptions $ vsep (map (<> line)
400416
[ rustHeader
401417
, rustFFIImports
402-
, rustFFISigs mod
418+
, rustFFISigs
403419
])
404420

405421
rustWrapperImports :: Doc a
406422
rustWrapperImports = vsep (map (<> semi)
407-
[ "use crate::{CElementsTxEnv, CFrameItem}"
408-
, "use super::elements_ffi"
423+
[ "use crate::bitcoin"
424+
, "use crate::elements"
425+
, "use crate::CFrameItem"
426+
, "use super::jets_ffi"
409427
])
410428

411-
rustWrappers :: Module -> Doc a
412-
rustWrappers mod = vsep ((<> line) . wrapper <$> moduleJets mod)
429+
rustWrappers :: Doc a
430+
rustWrappers = vsep ((<> line) . wrapper <$> allJets)
413431
where
414432
wrapper (SomeArrow jet) = vsep
415433
[ nest 4 $ vsep
416434
[ pretty $ "pub fn "++cJetName jet++templateParam++"(dst: &mut CFrameItem, src: CFrameItem, "++envParam++") -> bool {"
417-
, pretty $ "unsafe { "++lowerRustModuleName mod++"_ffi::"++cJetName jet++"(dst, &src, "++envArg++") }"
435+
, pretty $ "unsafe { jets_ffi::"++cJetName jet++"(dst, &src, "++envArg++") }"
418436
]
419437
, "}"
420438
]
421439
where
422440
templateParam | CoreModule <- jetModule jet = "<T>"
423441
| otherwise = ""
424442
envParam | CoreModule <- jetModule jet = "_env: &T"
425-
| ElementsModule <- jetModule jet = "env: &CElementsTxEnv"
443+
| ElementsModule <- jetModule jet = "env: &elements::CTxEnv"
444+
| BitcoinModule <- jetModule jet = "env: &bitcoin::CTxEnv"
426445
envArg | CoreModule <- jetModule jet = "std::ptr::null()"
427-
| ElementsModule <- jetModule jet = "env"
446+
| otherwise = "env"
428447

429-
rustWrapperDoc :: Module -> SimpleDocStream a
430-
rustWrapperDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
448+
rustWrapperDoc :: SimpleDocStream a
449+
rustWrapperDoc = layoutPretty layoutOptions $ vsep (map (<> line)
431450
[ rustHeader
432451
, rustWrapperImports
433-
, rustWrappers mod
452+
, rustWrappers
434453
])
435454

436455
cWrapperImports :: Doc a
437456
cWrapperImports = vsep
438-
[ "#include \"simplicity/elements/elementsJets.h\""
457+
[ "#include \"simplicity/bitcoin/bitcoinJets.h\""
458+
, "#include \"simplicity/elements/elementsJets.h\""
439459
, "#include \"simplicity/simplicity_assert.h\""
440460
, "#include \"wrapper.h\""
441461
]
442462

443-
cWrappers :: Module -> Doc a
444-
cWrappers mod = vsep (map wrapper $ moduleJets mod)
463+
cWrappers :: Doc a
464+
cWrappers = vsep (map wrapper $ allJets)
445465
where
446466
wrapper (SomeArrow jet) = pretty $ "WRAP_("++cJetName jet++")"
447467

448-
cWrapperDoc :: Module -> SimpleDocStream a
449-
cWrapperDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
468+
cWrapperDoc :: SimpleDocStream a
469+
cWrapperDoc = layoutPretty layoutOptions $ vsep (map (<> line)
450470
[ rustHeader -- also works for C
451471
, cWrapperImports
452-
, cWrappers mod
472+
, cWrappers
453473
])
454474

455475
renderFile name doc = withFile name WriteMode (\h -> renderIO h doc)
@@ -458,8 +478,8 @@ main = do
458478
renderFile "core.rs" (rustJetDoc coreModule)
459479
renderFile "elements.rs" (rustJetDoc elementsModule)
460480
renderFile "bitcoin.rs" (rustJetDoc bitcoinModule)
461-
renderFile "jets_ffi.rs" (rustFFIDoc elementsModule)
462-
renderFile "jets_wrapper.rs" (rustWrapperDoc elementsModule)
463-
renderFile "jets_wrapper.c" (cWrapperDoc elementsModule)
481+
renderFile "jets_ffi.rs" rustFFIDoc
482+
renderFile "jets_wrapper.rs" rustWrapperDoc
483+
renderFile "jets_wrapper.c" cWrapperDoc
464484

465485
layoutOptions = LayoutOptions { layoutPageWidth = AvailablePerLine 100 1 }

0 commit comments

Comments
 (0)