Skip to content

Commit 710da8d

Browse files
Update GenRustJets to generate Bitcoin Jets
1 parent e36063f commit 710da8d

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
@@ -88,6 +95,7 @@ moduleJets = sortJetName . toList . moduleCodes
8895

8996
rustModuleName = fromMaybe "Core" . moduleName
9097
lowerRustModuleName = map toLower . rustModuleName
98+
moduleEnvType mod = lowerRustModuleName mod ++ "::CTxEnv, "
9199

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

112+
allJets :: [SomeArrow JetData]
113+
allJets = nubBy eqJet . sortJetName $ moduleJets =<< [bitcoinModule, elementsModule]
114+
where
115+
eqJet (SomeArrow jt1) (SomeArrow jt2) = jetName jt1 == jetName jt2 && jetModule jt1 == jetModule jt2
116+
104117
data CompactTy = CTyOne
105118
| CTyWord Int
106119
| CTyMaybe CompactTy
@@ -191,16 +204,14 @@ rustJetTargetTy = rustJetTy "target_ty" (\(SomeArrow jet) -> unreflect (snd (rei
191204
rustJetPtr :: Module -> Doc a
192205
rustJetPtr mod = vsep $
193206
[ nest 4 (vsep ("fn c_jet_ptr(&self) -> &dyn Fn(&mut CFrameItem, CFrameItem, &Self::CJetEnvironment) -> bool {" :
194-
if modname == "Bitcoin"
195-
then ["unimplemented!(\"Bitcoin jets have not yet been implemented.\")"]
196-
else [ nest 4 (vsep ("match self {" :
197-
map (<>comma)
198-
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=>" <+>
199-
pretty ("&simplicity_sys::c_jets::jets_wrapper::"++cJetName jet)
200-
| SomeArrow jet <- moduleJets mod
201-
]))
202-
, "}"
203-
]))
207+
[ nest 4 (vsep ("match self {" :
208+
map (<>comma)
209+
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=>" <+>
210+
pretty ("&simplicity_sys::c_jets::jets_wrapper::"++cJetName jet)
211+
| SomeArrow jet <- moduleJets mod
212+
]))
213+
, "}"
214+
]))
204215
, "}"
205216
]
206217
where
@@ -265,23 +276,26 @@ rustJetImpl mod = vsep $
265276
where
266277
modname = rustModuleName mod
267278
env = vsep
268-
[ pretty $ "type Environment = "++env++";"
279+
[ pretty $ "type Transaction = "++transaction++";"
280+
, pretty $ "type Environment<T> = "++env++"<T> where T: Borrow<Self::Transaction>;"
269281
, pretty $ "type CJetEnvironment = "++cEnv++";"
270282
, ""
271-
, pretty $ "fn c_jet_env("++envArg++": &Self::Environment) -> &Self::CJetEnvironment {"
283+
, pretty $ "fn c_jet_env<T>("++envArg++": &Self::Environment<T>) -> &Self::CJetEnvironment"
284+
, " where T: Borrow<Self::Transaction>"
285+
, "{"
272286
, pretty $ " "++envBody
273287
, "}"
274288
]
275289
where
276-
env | Nothing <- moduleName mod = "()"
277-
| Just "Elements" == moduleName mod = "ElementsEnv<std::sync::Arc<elements::Transaction>>"
290+
transaction | Nothing <- moduleName mod = "core::convert::Infallible"
291+
| Just name <- moduleName mod = map toLower name ++"::Transaction"
292+
env | Nothing <- moduleName mod = "CoreEnv"
278293
| Just name <- moduleName mod = name ++ "Env"
279-
cEnv | Just "Elements" == moduleName mod = "CElementsTxEnv"
280-
| otherwise = "()"
281-
envArg | Just "Bitcoin" == moduleName mod = "_env"
294+
cEnv | Nothing <- moduleName mod = "CoreEnv<Self::Transaction>"
295+
| otherwise = "CTxEnv"
296+
envArg | Nothing <- moduleName mod = "_"
282297
| otherwise = "env"
283-
envBody | Nothing == moduleName mod = "env"
284-
| Just "Bitcoin" == moduleName mod = "unimplemented!(\"Unspecified CJetEnvironment for Bitcoin jets\")"
298+
envBody | Nothing <- moduleName mod = "&CoreEnv::EMPTY"
285299
| otherwise = "env.c_tx_env()"
286300

287301
rustJetEnum :: Module -> Doc a
@@ -311,7 +325,7 @@ rustJetDisplay mod =
311325
nestBraces ("match self" <+>
312326
nestBraces (vsep (
313327
map (<>comma)
314-
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=> f.write_str" <> (parens . dquotes . pretty $ cJetName jet)
328+
[ pretty modname <> "::" <> pretty (jetName jet) <+> "=> f.write_str" <> (parens . dquotes . pretty $ rustJetName jet)
315329
| SomeArrow jet <- moduleJets mod
316330
]))
317331
)
@@ -329,7 +343,7 @@ rustJetFromStr mod =
329343
nestBraces ("match s" <+>
330344
nestBraces (vsep (
331345
map (<> comma)
332-
([ dquotes (pretty (cJetName jet)) <+> "=> Ok" <> parens (pretty modname <> "::" <> pretty (jetName jet))
346+
([ dquotes (pretty (rustJetName jet)) <+> "=> Ok" <> parens (pretty modname <> "::" <> pretty (jetName jet))
333347
| SomeArrow jet <- moduleJets mod
334348
] ++ [ "x => Err(crate::Error::InvalidJetName(x.to_owned()))" ]
335349
)))
@@ -352,14 +366,13 @@ rustImports mod = vsep (map (<> semi)
352366
, "use hashes::sha256::Midstate"
353367
, "use simplicity_sys::CFrameItem"
354368
, "use std::io::Write"
355-
, "use std::{fmt, str}"
369+
, "use std::{borrow::Borrow, fmt, str}"
356370
] ++ envImports))
357371
where
358-
envImports | Nothing == moduleName mod = []
359-
| Just "Bitcoin" == moduleName mod = ["use crate::jet::bitcoin::BitcoinEnv"]
372+
envImports | Nothing == moduleName mod = ["use crate::jet::core::CoreEnv"]
360373
| Just name <- moduleName mod =
361374
[ pretty $ "use crate::jet::"++map toLower name++"::"++name++"Env"
362-
, pretty $ "use simplicity_sys::C"++name++"TxEnv"
375+
, pretty $ "use simplicity_sys::"++map toLower name++"::CTxEnv"
363376
]
364377

365378
rustJetDoc :: Module -> SimpleDocStream a
@@ -375,14 +388,16 @@ rustJetDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
375388
rustFFIImports :: Doc a
376389
rustFFIImports = vsep (map (<> semi)
377390
[ "use crate::ffi::c_void"
378-
, "use crate::{CElementsTxEnv, CFrameItem}"
391+
, "use crate::bitcoin"
392+
, "use crate::elements"
393+
, "use crate::CFrameItem"
379394
])
380395

381-
rustFFISigs :: Module -> Doc a
382-
rustFFISigs mod = vsep
396+
rustFFISigs :: Doc a
397+
rustFFISigs = vsep
383398
[ nest 4 $ vsep $
384399
"extern \"C\" {" :
385-
(declaration <$> moduleJets mod)
400+
(declaration <$> allJets)
386401
, "}"
387402
]
388403
where
@@ -394,63 +409,68 @@ rustFFISigs mod = vsep
394409
linkName = "#[link_name = \"c_"++cJetName jet++"\"]"
395410
signature = "pub fn "++cJetName jet++"(dst: *mut CFrameItem, src: *const CFrameItem, env: *const "++envType++") -> bool"
396411
envType | CoreModule <- jetModule jet = "c_void"
397-
| ElementsModule <- jetModule jet = "CElementsTxEnv"
412+
| ElementsModule <- jetModule jet = "elements::CTxEnv"
413+
| BitcoinModule <- jetModule jet = "bitcoin::CTxEnv"
398414

399-
rustFFIDoc :: Module -> SimpleDocStream a
400-
rustFFIDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
415+
rustFFIDoc :: SimpleDocStream a
416+
rustFFIDoc = layoutPretty layoutOptions $ vsep (map (<> line)
401417
[ rustHeader
402418
, rustFFIImports
403-
, rustFFISigs mod
419+
, rustFFISigs
404420
])
405421

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

412-
rustWrappers :: Module -> Doc a
413-
rustWrappers mod = vsep ((<> line) . wrapper <$> moduleJets mod)
430+
rustWrappers :: Doc a
431+
rustWrappers = vsep ((<> line) . wrapper <$> allJets)
414432
where
415433
wrapper (SomeArrow jet) = vsep
416434
[ nest 4 $ vsep
417435
[ pretty $ "pub fn "++cJetName jet++templateParam++"(dst: &mut CFrameItem, src: CFrameItem, "++envParam++") -> bool {"
418-
, pretty $ "unsafe { "++lowerRustModuleName mod++"_ffi::"++cJetName jet++"(dst, &src, "++envArg++") }"
436+
, pretty $ "unsafe { jets_ffi::"++cJetName jet++"(dst, &src, "++envArg++") }"
419437
]
420438
, "}"
421439
]
422440
where
423441
templateParam | CoreModule <- jetModule jet = "<T>"
424442
| otherwise = ""
425443
envParam | CoreModule <- jetModule jet = "_env: &T"
426-
| ElementsModule <- jetModule jet = "env: &CElementsTxEnv"
444+
| ElementsModule <- jetModule jet = "env: &elements::CTxEnv"
445+
| BitcoinModule <- jetModule jet = "env: &bitcoin::CTxEnv"
427446
envArg | CoreModule <- jetModule jet = "std::ptr::null()"
428-
| ElementsModule <- jetModule jet = "env"
447+
| otherwise = "env"
429448

430-
rustWrapperDoc :: Module -> SimpleDocStream a
431-
rustWrapperDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
449+
rustWrapperDoc :: SimpleDocStream a
450+
rustWrapperDoc = layoutPretty layoutOptions $ vsep (map (<> line)
432451
[ rustHeader
433452
, rustWrapperImports
434-
, rustWrappers mod
453+
, rustWrappers
435454
])
436455

437456
cWrapperImports :: Doc a
438457
cWrapperImports = vsep
439-
[ "#include \"simplicity/elements/elementsJets.h\""
458+
[ "#include \"simplicity/bitcoin/bitcoinJets.h\""
459+
, "#include \"simplicity/elements/elementsJets.h\""
440460
, "#include \"simplicity/simplicity_assert.h\""
441461
, "#include \"wrapper.h\""
442462
]
443463

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

449-
cWrapperDoc :: Module -> SimpleDocStream a
450-
cWrapperDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
469+
cWrapperDoc :: SimpleDocStream a
470+
cWrapperDoc = layoutPretty layoutOptions $ vsep (map (<> line)
451471
[ rustHeader -- also works for C
452472
, cWrapperImports
453-
, cWrappers mod
473+
, cWrappers
454474
])
455475

456476
renderFile name doc = withFile name WriteMode (\h -> renderIO h doc)
@@ -459,8 +479,8 @@ main = do
459479
renderFile "core.rs" (rustJetDoc coreModule)
460480
renderFile "elements.rs" (rustJetDoc elementsModule)
461481
renderFile "bitcoin.rs" (rustJetDoc bitcoinModule)
462-
renderFile "jets_ffi.rs" (rustFFIDoc elementsModule)
463-
renderFile "jets_wrapper.rs" (rustWrapperDoc elementsModule)
464-
renderFile "jets_wrapper.c" (cWrapperDoc elementsModule)
482+
renderFile "jets_ffi.rs" rustFFIDoc
483+
renderFile "jets_wrapper.rs" rustWrapperDoc
484+
renderFile "jets_wrapper.c" cWrapperDoc
465485

466486
layoutOptions = LayoutOptions { layoutPageWidth = AvailablePerLine 100 1 }

0 commit comments

Comments
 (0)