From 9c5a4389556f9b7969451945b0086d33ad95facf Mon Sep 17 00:00:00 2001 From: vere Date: Mon, 8 Sep 2014 21:06:21 +0000 Subject: [PATCH 1/5] bump protocol number --- arvo/ames.hoon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arvo/ames.hoon b/arvo/ames.hoon index 2a6b74458..646e01d6a 100644 --- a/arvo/ames.hoon +++ b/arvo/ames.hoon @@ -439,7 +439,7 @@ vix=(bex +((cut 0 [25 2] mag))) :: width of sender tay=(cut 0 [27 5] mag) :: message type == - ?> =(7 vez) + ?> =(0 vez) ?> =(chk (end 0 20 (mug bod))) :+ [(end 3 wix bod) (cut 3 [wix vix] bod)] (kins tay) @@ -459,7 +459,7 @@ =+ tay=(ksin q.kec) %+ mix %+ can 0 - :~ [3 7] + :~ [3 0] [20 (mug bod)] [2 yax] [2 qax] @@ -1047,7 +1047,7 @@ ++ gnaw :: gnaw:am |= [kay=cape ryn=lane pac=rock] :: process packet ^- [p=(list boon) q=fort] - ?. =(7 (end 0 3 pac)) [~ fox] + ?. =(0 (end 0 3 pac)) [~ fox] =+ kec=(bite pac) ?: (goop p.p.kec) [~ fox] ?. (~(has by urb.ton.fox) q.p.kec) From 41a1eb9cc16ab3b3a4ca3cc64b4264764c11eb50 Mon Sep 17 00:00:00 2001 From: vere Date: Tue, 9 Sep 2014 23:12:09 +0000 Subject: [PATCH 2/5] bump protocol number --- arvo/ames.hoon | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arvo/ames.hoon b/arvo/ames.hoon index 646e01d6a..0d5f096ba 100644 --- a/arvo/ames.hoon +++ b/arvo/ames.hoon @@ -439,7 +439,7 @@ vix=(bex +((cut 0 [25 2] mag))) :: width of sender tay=(cut 0 [27 5] mag) :: message type == - ?> =(0 vez) + ?> =(1 vez) ?> =(chk (end 0 20 (mug bod))) :+ [(end 3 wix bod) (cut 3 [wix vix] bod)] (kins tay) @@ -459,7 +459,7 @@ =+ tay=(ksin q.kec) %+ mix %+ can 0 - :~ [3 0] + :~ [3 1] [20 (mug bod)] [2 yax] [2 qax] @@ -1047,7 +1047,7 @@ ++ gnaw :: gnaw:am |= [kay=cape ryn=lane pac=rock] :: process packet ^- [p=(list boon) q=fort] - ?. =(0 (end 0 3 pac)) [~ fox] + ?. =(1 (end 0 3 pac)) [~ fox] =+ kec=(bite pac) ?: (goop p.p.kec) [~ fox] ?. (~(has by urb.ton.fox) q.p.kec) From 8732d6e097cd719e96fc70e37fa1de44233f9915 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 10 Sep 2014 00:31:17 +0000 Subject: [PATCH 3/5] clay local subscription doc done --- arvo/zuse.hoon | 1 + main/pub/src/doc/ref/vol/4c.md | 69 ++++++++++++++++++++++++++++++++-- 2 files changed, 66 insertions(+), 4 deletions(-) diff --git a/arvo/zuse.hoon b/arvo/zuse.hoon index e2f7d871b..96413dfd6 100644 --- a/arvo/zuse.hoon +++ b/arvo/zuse.hoon @@ -1184,6 +1184,7 @@ %delta (~(put in $(lob q.gar)) lob) %indirect (~(put in $(lob s.gar)) lob) == + :: ++ new-lobes-takos :: garg & repack |= [b=(set lobe) a=(set tako)] ^- [(set tako) (set lobe)] diff --git a/main/pub/src/doc/ref/vol/4c.md b/main/pub/src/doc/ref/vol/4c.md index 1e6f7bdaa..a711a3aac 100644 --- a/main/pub/src/doc/ref/vol/4c.md +++ b/main/pub/src/doc/ref/vol/4c.md @@ -1007,6 +1007,18 @@ scan backwards until we find the first revision committed before that date, and we produce that. If we requested a date before any revisions were committed, we produce `0`. +The definitions of `++aeon-to-tako` and `++tako-to-yaki` are trivial. + +``` + ++ aeon-to-tako ~(got by hit) +``` + +``` + ++ tako-to-yaki ~(got by hut) :: grab yaki +``` + +We simply look up the aeon or tako in their respective maps (`hit` and `hut`). + Assuming we got a valid version number, `++aver` calls `++read-at-aeon:ze`, which reads the requested data at the given revision. @@ -1567,10 +1579,6 @@ We let `sar` be the set of commits reachable from `a`. If `a` is null, then obviously no commits are reachable. Otherwise, we call `++reachable-takos` to calculate this. -The type signature says everything you need to know about this. We take a set -of hashes of commits and data and convert them into the actual commits and data -in the most straightforward way possible. - ``` ++ reachable-takos :: reachable |= p=tako :: XX slow @@ -1584,3 +1592,56 @@ in the most straightforward way possible. (~(uni in s) ^$(p q)) :: otherwise traverse ``` +We very simply produce the set of the given tako plus its parents, recursively. + +Back in `++reachable-between-takos`, we let `yak` be the yaki of `b`, the +ending commit. With this, we create a set that is the union of `sar` and all +takos reachable from `b`. + +We pass `sar` into `++new-lobes` to get all the lobes referenced by any tako +referenced by `a`. The result is passed into `++new-lobes-takos` to do the +same, but not recomputing those in already calculated last sentence. This +produces the sets of takos and lobes we need. + +``` + ++ new-lobes :: object hash set + |= [b=(set lobe) a=(set tako)] :: that aren't in b + ^- (set lobe) + %+ roll (~(tap in a) ~) + |= [tak=tako bar=(set lobe)] + ^- (set lobe) + =+ yak=(tako-to-yaki tak) + %+ roll (~(tap by q.yak) ~) + |= [[path lob=lobe] far=_bar] + ^- (set lobe) + ?~ (~(has in b) lob) :: don't need + far + =+ gar=(lobe-to-blob lob) + ?- -.gar + %direct (~(put in far) lob) + %delta (~(put in $(lob q.gar)) lob) + %indirect (~(put in $(lob s.gar)) lob) + == +``` + +Here, we're creating a set of lobes referenced in a commit in `a`. We start +out with `b` as the initial set of lobes, so we don't need to recompute any of +the lobes referenced in there. + +The algorithm is pretty simple, so we won't bore you with the details. We +simply traverse every commit in `a`, looking at every blob referenced there, +and, if it's not already in `b`, we add it to `b`. In the case of a direct +blob, we're done. For a delta or an indirect blob, we recursively add every +blob referenced within the blob. + +``` + ++ new-lobes-takos :: garg & repack + |= [b=(set lobe) a=(set tako)] + ^- [(set tako) (set lobe)] + [a (new-lobes b a)] +``` + +Here, we just update the set of lobes we're given with the commits we're given +and produce both sets. + +This concludes our discussion of a local subscription. From d0d80f6ce220a8419b442246059b2cabb7cbafdf Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Wed, 10 Sep 2014 19:52:06 +0000 Subject: [PATCH 4/5] clay foreign request doc done --- arvo/clay.hoon | 7 +- main/pub/src/doc/ref/vol/4c.md | 390 +++++++++++++++++++++++++++++++++ 2 files changed, 394 insertions(+), 3 deletions(-) diff --git a/arvo/clay.hoon b/arvo/clay.hoon index 256bb0ab3..dfa068872 100644 --- a/arvo/clay.hoon +++ b/arvo/clay.hoon @@ -338,8 +338,9 @@ =+ nex=(~(get by haw.u.ref) nez) ?~ nex +>+.^$ ?~ u.nex +>+.^$ :: should never happen - =. +>+.^$ =+ roo=(edis ((hard nako) u.u.nex)) - ?>(?=(^ ref.roo) roo) + =. +>+.^$ + =+ roo=(edis ((hard nako) u.u.nex)) + ?>(?=(^ ref.roo) roo) %= $ haw.u.ref (~(del by haw.u.ref) nez) == @@ -397,7 +398,7 @@ ..wake =- (blub:- p.i.xiq) =+ ^= ear (~(lobes-at-path ze lim dom ran) u.huy r.p.q.i.xiq) - ?: =(s.p.q.i.xiq ear) ..wake + ?: =(s.p.q.i.xiq ear) (blub p.i.xiq) =+ fud=(~(make-nako ze lim dom ran) u.nab u.huy) (bleb p.i.xiq +(u.nab) fud) == diff --git a/main/pub/src/doc/ref/vol/4c.md b/main/pub/src/doc/ref/vol/4c.md index a711a3aac..1e780b5d0 100644 --- a/main/pub/src/doc/ref/vol/4c.md +++ b/main/pub/src/doc/ref/vol/4c.md @@ -1645,3 +1645,393 @@ Here, we just update the set of lobes we're given with the commits we're given and produce both sets. This concludes our discussion of a local subscription. + +Lifecycle of a Foreign Read or Subscription +------------------------------------------- + +Foreign reads and subscriptions are handled in much the same way as local ones. +The interface is the same -- a vane or app sends a `%warp` kiss with the +request. The difference is simply that the `sock` refers to the foreign ship. + +Thus, we start in the same place -- in `++call`, handling `%warp`. However, +since the two side of the `sock` are different, we follow a different path. + +``` + =+ wex=(do now p.q.hic p.q.q.hic ruf) + =+ ^= woo + ?~ q.q.q.hic + abet:(ease:wex hen) + abet:(eave:wex hen u.q.q.q.hic) + [-.woo (posh q.p.q.hic p.q.q.hic +.woo ruf)] +``` + +If we compare this to how the local case was handled, we see that it's not all +that different. We use `++do` rather than `++un` and `++de` to set up the core +for the foreign ship. This gives us a `++de` core, so we either cancel or +begin the request by calling `++ease` or `++eave`, exactly as in the local +case. In either case, we call `++abet:de` to resolve our various types of +output into actual moves, as described in the local case. Finally, we call +`++posh` to update our raft, putting the modified rung into the raft. + +We'll first trace through `++do`. + +``` + ++ do + |= [now=@da [who=ship him=ship] syd=@tas ruf=raft] + =+ ^= rug ^- rung + =+ rug=(~(get by hoy.ruf) him) + ?^(rug u.rug *rung) + =+ ^= red ^- rede + =+ yit=(~(get by rus.rug) syd) + ?^(yit u.yit `rede`[~2000.1.1 ~ [~ *rind] *dome]) + ((de now ~ ~) [who him] syd red ran.ruf) +``` + +If we already have a rung for this foreign ship, then we use that. Otherwise, +we create a new blank one. If we already have a rede in this rung, then we use +that, otherwise we create a blank one. An important point to note here is that +we let `ref` in the rede be `[~ *rind]`. Recall, for domestic desks `ref` is +null. We use this to distinguish between foreign and domestic desks in `++de`. + +With this information, we create a `++de` core as usual. + +Although we've already covered `++ease` and `++eave`, we'll go through them +quickly again, highlighting the case of foreign request. + +``` + ++ ease :: release request + |= hen=duct + ^+ +> + =. qyx (~(del by qyx) hen) + ?~ ref +> + |- ^+ +>+.$ + =+ nux=(~(get by fod.u.ref) hen) + ?~ nux +>+.$ + %= +>+.$ + say [[hen [(scot %ud u.nux) ~] for [u.nux syd ~]] say] + fod.u.ref (~(del by fod.u.ref) hen) + bom.u.ref (~(del by bom.u.ref) u.nux) + == +``` + +Here, we still remove the duct from our cult (we maintain a cult even for +foreign desks), but we also need to tell the foreign desk to cancel our +subscription. We do this by sending a request (by appending to `say`, which +gets resolved in `++abet:de` to a `%want` kiss to ames) to the foreign ship to +cancel the subscription. Since we don't anymore expect a response on this +duct, we remove it from `fod` and `bom`, which are the maps between ducts, +raves, and request sequence numbers. Basically, we remove every trace of the +subscription from our request manager. + +In the case of `++eave`, where we're creating a new request, everything is +exactly identical to the case of the local request except `++duce`. We said +that `++duce` simply puts the request into our cult. This is true for a +domestic request, but distinctly untrue for foreign requests. + +``` + ++ duce :: produce request + |= [hen=duct rov=rove] + ^+ +> + =. qyx (~(put by qyx) hen rov) + ?~ ref +>.$ + |- ^+ +>+.$ :: XX why? + =+ rav=(reve rov) + =+ ^= vaw ^- rave + ?. ?=([%& %v *] rav) rav + [%| [%ud let.dom] `case`q.p.rav r.p.rav] + =+ inx=nix.u.ref + %= +>+.$ + say [[hen [(scot %ud inx) ~] for [inx syd ~ vaw]] say] + nix.u.ref +(nix.u.ref) + bom.u.ref (~(put by bom.u.ref) inx [hen vaw]) + fod.u.ref (~(put by fod.u.ref) hen inx) + == +``` + +If we have a request manager (i.e. this is a foreign desk), then we do the +approximate inverse of `++ease`. We create a rave out of the given request and +send it off to the foreign desk by putting it in `say`. Note that the rave is +created to request the information starting at the next revision number. Since +this is a new request, we put it into `fod` and `bom` to associate the request +with its duct and its sequence number. Since we're using another sequence +number, we must increment `nix`, which represents the next available sequence +number. + +And that's really it for this side of the request. Requesting foreign +information isn't that hard. Let's see what it looks like on the other side. +When we get a request from another ship for information on our ship, that comes +to us in the form of a `%wart` from ames. + +We handle a `%wart` in `++call`, right next to where we handle the `%warp` case. + +``` + %wart + ?> ?=(%re q.q.hic) + =+ ryf=((hard riff) s.q.hic) + :_ ..^$ + :~ :- hen + :^ %pass [(scot %p p.p.q.hic) (scot %p q.p.q.hic) r.q.hic] + %c + [%warp [p.p.q.hic p.p.q.hic] ryf] + == +``` + +Every request we receive should be of type `riff`, so we coerce it into that +type. We just convert this into a new `%warp` kiss that we pass to ourself. +This gets handled like normal, as a local request. When the request produces +a value, it does so like normal as a `%writ`, which is returned to `++take` +along the path we just sent it on. + +``` + %writ + ?> ?=([@ @ *] tea) + =+ our=(need (slaw %p i.tea)) + =+ him=(need (slaw %p i.t.tea)) + :_ ..^$ + :~ :- hen + [%pass ~ %a [%want [our him] [%r %re %c t.t.tea] p.+.q.hin]] + == +``` + +Since we encoded the ship we need to respond to in the path, we can just pass +our `%want` back to ames, so that we tell the requesting ship about the new +data. + +This comes back to the original ship as a `%waft` from ames, which comes into +`++take`, right next to where we handled `%writ`. + +``` + %waft + ?> ?=([@ @ ~] tea) + =+ syd=(need (slaw %tas i.tea)) + =+ inx=(need (slaw %ud i.t.tea)) + =+ ^= zat + =< wake + (knit:(do now p.+.q.hin syd ruf) [inx ((hard riot) q.+.q.hin)]) + =^ mos ruf + =+ zot=abet.zat + [-.zot (posh q.p.+.q.hin syd +.zot ruf)] + [mos ..^$(ran.ruf ran.zat)] :: merge in new obj +``` + +This gets the desk and sequence number from the path the request was sent over. +This determines exactly which request is being responded to. We call +`++knit:de` to apply the changes to our local desk, and we call `++wake` to +update our subscribers. Then we call `++abet:de` and `++posh` as normal (like +in `++eave`). + +We'll examine `++knit` and `++wake`, in that order. + +``` + ++ knit :: external change + |= [inx=@ud rot=riot] + ^+ +> + ?> ?=(^ ref) + |- ^+ +>+.$ + =+ ruv=(~(get by bom.u.ref) inx) + ?~ ruv +>+.$ + => ?. |(?=(~ rot) ?=(& -.q.u.ruv)) . + %_ . + bom.u.ref (~(del by bom.u.ref) inx) + fod.u.ref (~(del by fod.u.ref) p.u.ruv) + == + ?~ rot + =+ rav=`rave`q.u.ruv + %= +>+.$ + lim + ?.(&(?=(| -.rav) ?=(%da -.q.p.rav)) lim `@da`p.q.p.rav) + :: + haw.u.ref + ?. ?=(& -.rav) haw.u.ref + (~(put by haw.u.ref) p.rav ~) + == + ?< ?=(%v p.p.u.rot) + =. haw.u.ref + (~(put by haw.u.ref) [p.p.u.rot q.p.u.rot q.u.rot] ~ r.u.rot) + ?. ?=(%w p.p.u.rot) +>+.$ + |- ^+ +>+.^$ + =+ nez=[%w [%ud let.dom] ~] + =+ nex=(~(get by haw.u.ref) nez) + ?~ nex +>+.^$ + ?~ u.nex +>+.^$ :: should never happen + =. +>+.^$ =+ roo=(edis ((hard nako) u.u.nex)) + ?>(?=(^ ref.roo) roo) + %= $ + haw.u.ref (~(del by haw.u.ref) nez) + == +``` + +This is kind of a long gate, but don't worry, it's not bad at all. + +First, we assert that we're not a domestic desk. That wouldn't make any sense +at all. + +Since we have the sequence number of the request, we can get the duct and rave +from `bom` in our request manager. If we didn't actually request this data (or +the request was canceled before we got it), then we do nothing. + +Else, we remove the request from `bom` and `fod` unless this was a subscription +request and we didn't receive a null riot (which would indicate the last +message on the subscription). + +Now, if we received a null riot, then if this was a subscription request by +date, then we update `lim` in our request manager (representing the latest time +at which we have complete information for this desk) to the date that was +requested. If this was a single read request, then we put the result in our +simple cache `haw` to make future requests faster. Then we're done. + +If we received actual data, then we put it into our cache `haw`. Unless it's a +`%w` request, we're done. + +If it is a `%w` request, then we try to get the `%w` at our current head from +the cache. In general, that should be the thing we just put in a moment ago, +but that is not guaranteed. The most common case where this is different is +when we receive desk updates out of order. At any rate, since we now have new +information, we need to apply it to our local copy of the desk. We do so in +`++edis`, and then we remove the stuff we just applied from the cache, since +it's not really a true "single read", like what should really be in the cache. + +``` + ++ edis :: apply subscription + |= nak=nako + ^+ +> + %= +> + hit.dom (~(uni by hit.dom) gar.nak) + let.dom let.nak + lat.ran %+ roll (~(tap in bar.nak) ~) + =< .(yeb lat.ran) + |= [sar=blob yeb=(map lobe blob)] + =+ zax=(blob-to-lobe sar) + %+ ~(put by yeb) zax sar + hut.ran %+ roll (~(tap in lar.nak) ~) + =< .(yeb hut.ran) + |= [sar=yaki yeb=(map tako yaki)] + %+ ~(put by yeb) r.sar sar + == +``` + +This shows, of course, exactly why nako is defined the way it is. To become +completely up to date with the foreign desk, we need to merge `hit` with the +foreign one so that we have all the revision numbers. We update `let` so that +we know which revision is the head. + +We merge the new blobs in `lat`, keying them by their hash, which we get from a +call to `++blob-to-lobe`. Recall that the hash is stored in the actual blob +itself. We do the same thing to the new yakis, putting them in `hut`, keyed by +their hash. + +Now, our local dome should be exactly the same as the foreign one. + +This concludes our discussion of `++knit`. Now the changes have been applied to +our local copy of the desk, and we just need to update our subscribers. We do +so in `++wake:de`. + +``` + ++ wake :: update subscribers + ^+ . + =+ xiq=(~(tap by qyx) ~) + =| xaq=(list ,[p=duct q=rove]) + |- ^+ ..wake + ?~ xiq + ..wake(qyx (~(gas by *cult) xaq)) + ?- -.q.i.xiq + & + =+ cas=?~(ref ~ (~(get by haw.u.ref) `mood`p.q.i.xiq)) + ?^ cas + %= $ + xiq t.xiq + ..wake ?~ u.cas (blub p.i.xiq) + (blab p.i.xiq p.q.i.xiq u.u.cas) + == + =+ nao=(~(case-to-aeon ze lim dom ran) q.p.q.i.xiq) + ?~ nao $(xiq t.xiq, xaq [i.xiq xaq]) + $(xiq t.xiq, ..wake (balk p.i.xiq u.nao p.q.i.xiq)) + :: + | + =+ mot=`moot`p.q.i.xiq + =+ nab=(~(case-to-aeon ze lim dom ran) p.mot) + ?~ nab + $(xiq t.xiq, xaq [i.xiq xaq]) + =+ huy=(~(case-to-aeon ze lim dom ran) q.mot) + ?~ huy + =+ ptr=[%ud +(let.dom)] + %= $ + xiq t.xiq + xaq [[p.i.xiq [%| ptr q.mot r.mot s.mot]] xaq] + ..wake =+ ^= ear + (~(lobes-at-path ze lim dom ran) let.dom r.p.q.i.xiq) + ?: =(s.p.q.i.xiq ear) ..wake + =+ fud=(~(make-nako ze lim dom ran) u.nab let.dom) + (bleb p.i.xiq let.dom fud) + == + %= $ + xiq t.xiq + ..wake =- (blub:- p.i.xiq) + =+ ^= ear + (~(lobes-at-path ze lim dom ran) u.huy r.p.q.i.xiq) + ?: =(s.p.q.i.xiq ear) (blub p.i.xiq) + =+ fud=(~(make-nako ze lim dom ran) u.nab u.huy) + (bleb p.i.xiq +(u.nab) fud) + == + == + -- +``` + +This is even longer than `++knit`, but it's pretty similar to `++eave`. We loop +through each of our subscribers `xiq`, processing each in turn. When we're done, +we just put the remaining subscribers back in our subscriber list. + +If the subscriber is a single read, then, if this is a foreign desk (note that +`++wake` is called from other arms, and not only on foreign desks). Obviously, +if we find an identical request there, then we can produce the result +immediately. Referential transparency for the win. We produce the result with +a call to `++blab`. If this is a foreign desk but the result is not in the +cache, then we produce `++blub` (canceled subscription with no data) for +reasons entirely opaque to me. Seriously, it seems like we should wait until +we get an actual response to the request. If someone figures out why this is, +let me know. At any rate, it seems to work. + +If this is a domestic desk, then we check to see if the case exists yet. If +it doesn't, then we simply move on to the next subscriber, consing this one +onto `xaq` so that we can check again the next time around. If it does exist, +then we call `++balk` to fulfill the request and produce it. + +`++balk` is very simple, so we'll describe it here before we get to the +subscription case. + +``` + ++ balk :: read and send + |= [hen=duct oan=@ud mun=mood] + ^+ +> + =+ vid=(~(read-at-aeon ze lim dom ran) oan mun) + ?~ vid (blub hen) (blab hen mun u.vid) +``` + +We call `++read-at-aeon` on the given request and aeon. If you recall, this +processes a `mood` at a particular aeon and produces the result, if there is +one. If there is data at the requested location, then we produce it with +`++blab`. Else, we call `++blub` to notify the subscriber that no data can +ever come over this subscriptioin since it is now impossible for there to ever +be data for the given request. Because referential transparency. + +At any rate, back to `++wake`. If the given rave is a subscription request, +then we proceed similarly to how we do in `++eave`. We first try to get the +aeon referred to by the starting case. If it doesn't exist yet, then we can't +do anything interesting with this subscription, so we move on to the next one. + +Otherwise, we try to get the aeon referrred to by the ending case. If it +doesn't exist yet, then we produce all the information we can. We call +`++lobes-at-path` at the given aeon and path to see if the requested path has +actually changed. If it hasn't, then we don't produce anything; else, we +produce the correct nako by calling `++bleb` on the result of `++make-nako`, as +in `++eave`. At any rate, we move on to the next subscription, putting back +into our cult the current subscription with a new start case of the next aeon +after the present. + +If the aeon referred to by the ending case does exist, then we drop this +subscriber from our cult and satisfy its request immediately. This is the same +as before -- we check to see if the data at the path has actually changed, +producing it if it has; else, we call `++blub` since no more data can be +produced over this subscription. + +This concludes our discussion of foreign requests. From fccc933066c7f07a72ef455284f195dfdaf4d1c6 Mon Sep 17 00:00:00 2001 From: Anton Dyudin Date: Wed, 10 Sep 2014 13:00:23 -0700 Subject: [PATCH 5/5] (sear plex rood):vast now usable as a parser --- arvo/ford.hoon | 2 +- arvo/hoon.hoon | 34 +++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/arvo/ford.hoon b/arvo/ford.hoon index 98fe28311..40aaa5cf4 100644 --- a/arvo/ford.hoon +++ b/arvo/ford.hoon @@ -438,7 +438,7 @@ ?. ?=([%$ ?(%da %ud %tas) *] a) ~ [~ u=(^case a)] :: - ++ hath (cook plex:voz (stag %clsg poor:voz)) :: hood path + ++ hath (sear plex:voz (stag %clsg poor:voz)) :: hood path ++ have (sear tome ;~(pfix fas hath)) :: hood beam ++ hood %+ ifix [gay gay] diff --git a/arvo/hoon.hoon b/arvo/hoon.hoon index d11da6940..b8c7e5290 100644 --- a/arvo/hoon.hoon +++ b/arvo/hoon.hoon @@ -8467,28 +8467,36 @@ ;~(plug (star low) (star hig)) :: ++ plex - |= gen=twig ~| [%plex gen] ^- path + |= gen=twig ^- (unit path) ?: ?=([%zpcb *] gen) $(gen q.gen) - ?> ?=([%clsg *] gen) - (turn p.gen |=(a=twig ?>(?=(%dtzy -.a) q.a))) + ?. ?=([%clsg *] gen) ~ + %+ reel p.gen + |= [a=twig b=_`(unit path)`[~ u=/]] + ?~ b ~ + ?. ?=(%dtzy -.a) ~ + `[q.a u.b] :: ++ pray - |= gen=twig ~| %pray ^- twig + |= gen=twig ~| %pray ^- (unit twig) =+ rev=(plex gen) - ?: (~(has in was) rev) + ?~ rev ~ + :- ~ + ?: (~(has in was) u.rev) ~|(%pray-loop !!) - =+ ruv=`path`(weld rev `path`[%hoon ~]) + =+ ruv=`path`(weld u.rev `path`[%hoon ~]) =+ txt=(,@ta .^(%cx ruv)) ~| ruv %+ rash txt - (ifix [gay gay] tall(was (~(put in was) rev), wer rev)) + (ifix [gay gay] tall(was (~(put in was) u.rev), wer u.rev)) :: ++ prey - |= gun=(list twig) ^- twig - ?~ gun [~ 1] - ?~ t.gun (pray i.gun) - [%tsgr (pray i.gun) $(gun t.gun)] + |= gun=(list twig) ^- (unit twig) + ?~ gun `[~ 1] + =+ gup=(pray i.gun) + ?~ gup ~ + ?~ t.gun gup + (bind $(gun t.gun) |=(a=twig [%tsgr u.gup a])) :: ++ phax |= ruw=(list (list beer)) @@ -8910,7 +8918,7 @@ [%dtkt %dtzz %$ %cx rev] ;~(plug hill rood) == - (cook prey (most ket rood)) + (sear prey (most ket rood)) == == (stag %cnzz rope) @@ -9202,7 +9210,7 @@ :~ [':' ;~(pfix col (toad expz))] [',' (rune com %zpcm expb)] [';' (rune sem %zpsm expb)] - ['^' ;~(pfix ket (cook prey (toad exps)))] + ['^' ;~(pfix ket (sear prey (toad exps)))] ['>' (rune gar %zpgr expa)] ['=' (rune tis %zpts expa)] ['?' (rune wut %zpwt hinh)]