@@ -5,7 +5,7 @@ import Data.Char (toLower)
55import Data.Foldable (toList )
66import Data.Function (on )
77import Data.Functor.Fixedpoint (Fix (.. ))
8- import Data.List (sortBy )
8+ import Data.List (nubBy , sortBy )
99import Data.List.Split (chunksOf )
1010import Data.Maybe (fromMaybe )
1111import 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
5259coreJetData :: (TyC x , TyC y ) => CoreJet x y -> JetData x y
5360coreJetData jet = JetData { jetName = mkName jet
@@ -87,6 +94,7 @@ moduleJets = sortJetName . toList . moduleCodes
8794
8895rustModuleName = fromMaybe " Core" . moduleName
8996lowerRustModuleName = map toLower . rustModuleName
97+ moduleEnvType mod = lowerRustModuleName mod ++ " ::CTxEnv, "
9098
9199coreModule :: Module
92100coreModule = Module Nothing (someArrowMap coreJetData <$> (treeEvalBitStream Core. getJetBit))
@@ -100,6 +108,11 @@ elementsModule = Module (Just "Elements") (someArrowMap elementsJetData <$> take
100108bitcoinModule :: Module
101109bitcoinModule = 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+
103116data CompactTy = CTyOne
104117 | CTyWord Int
105118 | CTyMaybe CompactTy
@@ -190,16 +203,14 @@ rustJetTargetTy = rustJetTy "target_ty" (\(SomeArrow jet) -> unreflect (snd (rei
190203rustJetPtr :: Module -> Doc a
191204rustJetPtr 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
286300rustJetEnum :: 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
364377rustJetDoc :: Module -> SimpleDocStream a
@@ -374,14 +387,16 @@ rustJetDoc mod = layoutPretty layoutOptions $ vsep (map (<> line)
374387rustFFIImports :: Doc a
375388rustFFIImports = 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
405421rustWrapperImports :: Doc a
406422rustWrapperImports = 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
436455cWrapperImports :: Doc a
437456cWrapperImports = 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
455475renderFile 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
465485layoutOptions = LayoutOptions { layoutPageWidth = AvailablePerLine 100 1 }
0 commit comments