Merge branch 'test' into shell

Conflicts:
	include/v/vere.h
	urb/urbit.pill
	urb/zod/arvo/clay.hoon
	urb/zod/arvo/eyre.hoon
	urb/zod/arvo/hoon.hoon
	urb/zod/main/mar/hook/door.hook
	urb/zod/main/mar/psal/door.hook
	urb/zod/main/mar/txt/door.hook
	urb/zod/main/pub/src/doc/ref/vol/1.md
	v/loop.c
	v/raft.c
	v/reck.c
	v/unix.c
This commit is contained in:
Philip C Monk 2014-11-04 15:22:33 -05:00
commit 5242925469
20 changed files with 2555 additions and 3130 deletions

View File

@ -1,4 +1,4 @@
:: ames (4a), networking
!: :: ames (4a), networking
::
|= pit=vase
=> =~
@ -1433,7 +1433,7 @@
=+ bou=bust:puz
=. bin
?. &(bou !oub) bin
:_(bin [%wine [our her] " not responding still trying"])
:_(bin [%wine [our her] " not responding still crying"])
=. diz ?:((boom:puz now) (pode:diz now) diz)
(busk xong:diz yem)
::

View File

@ -1,6 +1,6 @@
!:
:: batz (4b), shell
::
::
|= pit=vase
=> =~
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

View File

@ -1,3 +1,4 @@
!:
:: clay (4c), revision control
::
|= pit=vase
@ -78,7 +79,7 @@
== ::
++ room :: fs per ship
$: hun=duct :: terminal duct
hez=(unit duct) :: sync duch
hez=(unit duct) :: sync duct
dos=(map desk dojo) :: native desk
== ::
++ rove (each mood moot) :: stored request
@ -137,9 +138,9 @@
?~(nao ~ [~ (~(read-at-aeon ze lim dom ran) u.nao mun)])
::
++ balk :: read and send
|= [hen=duct oan=@ud mun=mood]
|= [hen=duct yon=@ud mun=mood]
^+ +>
=+ vid=(~(read-at-aeon ze lim dom ran) oan mun)
=+ vid=(~(read-at-aeon ze lim dom ran) yon mun)
?~ vid (blub hen) (blab hen mun u.vid)
::
++ bait

View File

@ -1,4 +1,4 @@
::
!:
:: dill (4d), terminal handling
::
|= pit=vase

View File

@ -1,4 +1,3 @@
::
:: :: %eyre, http servant
!? 164
::::
@ -811,69 +810,11 @@
==
::
^= fac
0w89.wgGV4.jAl90.00003.sV4OG.IJjfa.1vYpi.gRxB9.3m6kA.dopig.
RxB93.m6kAd.opigR.xB93m.6kAdo.pigRx.B93m6.kAdop.igRxB.93m6k.
Adopi.gRxBf.vGSfy.m8hQj.T-DiD.7kqvH.vEpA3.3vH-C.in~Tq.l8U0n.
1FVhj.w9E1A.NIF6w.4j9v~.VZ0~B.9flkB.IY90B.-ieSV.Ky8Q~.4~07s.
JcXFC.DtI-1.GGz-1.V-olV.g3wsv.ZCQM1.BJbVj.Vwiv0.uo7Gh.4qsxA.
92ZYU.tJ5uH.yiIzV.FwvJR.UUq6z.cpKIG.Hck9v.qGDm1.PY2rM.itxLB.
fn0Bo.5DO8x.oO7KE.kYh-P.NiKp1.HT88j.Mu3ZK.ciKsU.TnlkV.0Zo77.
12ciy.nY3dM.7nDnY.GVgGh.ZllpO.SFHFb.p1Ae0.uUpXV.eqFvS.pkBRl.
jv0MP.ilRHP.1HwtK.GFptt.2KdpP.RsYqI.wRHEG.j~LZQ.I06qJ.fP0Pp.
77qjo.s0PU0.rGGg6.lgNvc.~CZE~.bSp9j.EGHF~.UqYB6.l4Y~Z.P~GGE.
LwrJs.ZvYV-.U4Wh4.04dws.6HeuZ.2ZF7A.y4MN5.3vsCj.QHzjW.4lflk.
WU6X0.AmMws.vbMfB.3e1s~.aeE7W.0hQPH.ODvMf.cvgzb.Y15Ah.01384.
YwVPT.KzILB.PlaqN.pNlvw.fdQ79.~mPpo.YaHqw.fnWGB.QYM4F.w3E0b.
0o~n-.faydD.zlllI.0nU3D.w5rlI.4nrSG.VkhPM.NTkpa.eoXzw.9AEYN.
auZGt.99gxL.8RlsI.aXMXX.tFVhX.V4kj8.yczjh.faRI3.JTg1H.-0uZM.
JA6rR.z0~pO.uXiSg.rvU27.A58MU.TBijQ.23F1J.CCIYE.IO8w-.cMlMA.
hvKh4.zY16M.gjRlk.v--9h.TNNRR.HhIGo.8kZXk.Wb74j.faHlk.6V-Vw.
jMan8.yb37R.Q2h42.Or3Nw.Pp39w.jZ--3.-jwZH.U~3Za.Uu0u6.bNAOP.
U2jux.Jqo2R.O8x1~.ecZvL.30ug~.qpoFw.vwtqD.Vb6EI.cZQyO.EN-xl.
nlsLC.dT099.apOh5.SEeDz.07-GE.xFzZk.KcmCl.SJWF5.v3u1x.Uq1Cj.
tV~hG.YuGGb.SgpdR.xHaBh.S3eEv.q0mSg.RZh8s.wxhnk.EcNvW.GccZQ.
yO0Jb.n18hs.BLFx2.iigqf.AhsKS.LWqby.TUEmv.gmmhR.6DW3w.uLR0Y.
QQBC8.YoQ63.g8m8i.iq3B-.SxwLn.jLbh3.l7cq3.eVQmV.5O2df.SXBkv.
Y3LLb.denQq.GvR0R.P3Gh4.2iiq2.h-srW.o0ZZ-.HIrdj.npm5n.pnv07.
vyT77.43WGP.Bciiq.zt1cI.7A4xB.zK9xm.-tV6x.ZdA6P.pheXQ.aSz4X.
Zj2bS.C1UPx.~c1dS.xwF3b.6jZ-M.WI2eQ.e69Qw.DGFly.tTze-.GGbZU.
qJ-m-.fD8yI.Adktz.oqTsF.F7ltA.6no6T.~fWJU.0gRsp.-P88x.a9I9b.
Adkvz.ory8J.Ouhfu.H8c-U.2HLgE.Wi4xH.3AEGK.VjkS-.Z5hMx.UN5o~.
Y~EWp.7LGox.IQxpt.cgONH.CEyKJ.jjTdM.GJ9HL.RloJZ.xuRtL.JZ7jg.
ZZj6w.2AOoM.CENdS.xxegZ.RzTdh.i-1hZ.N1HPF.EqHU0.XzN6K.mBedG.
uvBiL.HqpmY.Bl9z2.qzqA8.WzKqz.h~S1J.K2QHQ.Dy-CM.7RO0l.QksW3.
mpFnx.fy-Pa.p7xhW.SboOd.fOBon.mCgSX.Z38Qe.dMHUC.79wje.wziG5.
6Xtn7.ksEHO.xkBrO.e7yFe.vNaYx.FgDsI.BS9y8.AELs-.C9-DB.FAZI-.
wKt2N.8qQhA.Apxm7.O5yIB.X51l9.Kduxm.SRA5N.UYi6I.MrySX.RZXrT.
8UcY2.zUAfu.SOcUK.vZrDL.vBAHb.eOo~N.7J3sR.eJhSo.4~YE1.5k0h5.
51RqS.b0jyR.RfhON.4Dt07.idahL.5isLK.eeBv3.znQxC.9LXkE.xKghP.
Ia-R0.AgmB5.pGGIA.slCGu.CtR5q.NrzHh.1bscz.8CsWC.KH4it.LLrWm.
UlRdr.lUGji.W76xr.kVAmO.6oAYS.7nXX~.kfeM2.TSS2m.JOCAb.sFFWg.
4xH3C.MDKh4.FZso1.tXwUJ.Taq5K.8yS24.xHr4M.Kvu~E.HTpka.-Zg3f.
KEXFS.qCKwh.l1KRN.c9H8A.HFcSw.rePCF.Iy93m.njkMZ.IEyiq.lFq3y.
gRFzg.uL9tz.zP8du.Y1ZWP.PtQ6G.gzIt5.K8hNz.UAdpM.Q43L6.IMHx5.
N8qPh.EfX8G.UC~68.S93ms.d18Vh.adkOx.GLkTI.khFcL.ZWG5G.Adoeh.
hx~As.hci6I.Uq2pG.ykqHO.yUAdq.gQ7FD.4sOjn.IwGGw.UAdqo.Q4jVN.
eJP8c.xQlm~.8nJ1y.gRF3g.oSPAM.fuqE0.M~23y.gRHyo.gngjF.ceM3n.
V~uQy.93m-9.xa-3N.T80~v.GzR-g.HqBGA.mi4xH.3AMOL.mCjT5.Blqab.
60ruw.HDV~k.Tj~fX.Swx8u.ZFOoi.m1GUF.Gs4-q.0kfxh.H8yjt.OCXGL.
PYGTY.23LgI.Wl4x6.8bI3e.MXeVb.h6rL9.DXWyt.8wJ8W.HalWR.itqp3.
pkrSC.8bQSM.HLV2J.G7sCj.QtGEi.AkSwI.A4P0J.gJ85j.MuMUY.nkT45.
-rkqv.BFBFU.KGd98.qRs~A.iblOv.mVKWx.Z19cs.AxHc6.UIKJc.NIHW8.
EnOEy.fygRG.29bbR.FBDVL.Ter6T.SBKat.MFBPE.AfuO9.kBHV~.QstE-.
VaYNV.qpfhL.sFHj0.eFphG.U6Hw6.EsVox.7kpks.N6bRk.GMLY~.HWBVj.
Snx6X.0GY2b.GhzmW.udfRF.jTgLC.uPWGL.fIwM6.16Ah4.NFZjz.Ftln7.
KQ-k-.0SO8H.xrqcw.MXZG9.6BZsJ.zULJU.NPDy3.aewMa.3auiA.Ysei3.
YQJGB.PlCAQ.S5YPU.uGEtI.wQrw1.cy8Sd.bFYuX.GGWZS.DSq1Y.O8ELq.
cR6kA.dopig.RxB93.m6kAd.opigR.xB93m.6kAdo.pigRx.B93m6.kAdop.
igRxB.93m6k.Adopi.gRxB9.3m6kA.doSsI.1Tves.7Fb5l.hneus.VDLsZ.
~P3DD.D~CpI.BALPA.rxSTT.fuXa4.gP3Yv.sPKOY.KSMKP.balqk.xjbEH.
idkbq.Elo0N.dHjkM.vEBiq.BC-Rb.IKMiB.JiaoS.x3mLy.Jr6P5.ToiS2.
gAz4y.qNHiI.k7WIl.9EJGb.iJ2Tp.NQ5H5.VpSni.By-OX.TfvYs.plRic.
rpPJD.7xkgk.h9BMw.001EY.XFJDs.CYKpn.1xoTd.HrCAK.tTtT0.6lOon.
tQpCZ.jt5x5.t1A00.01UCO.x20ts.d003n.3g00s.RB8s0.A0002.8p0xY.
20w82.5h9gD.c4000.0l9ny.s0000.0o8p0.0006g.0001i.h4x93.g0000.
Eq2wR.7jB29
0w89wg.GV4jA.l9000.00dPb.YzBT6.giO00.o100d.wZcqc.a9tg-.VTG0b.
AUIvE.HBM3g.cK4SE.0aagi.l090p.I1P5g.Y-80r.y1YS9.1xE~Y.qgpFY.
vKN1V.905y0.2UwvL.43TUw.uL406.0-31h.xwoJF.Ul454.ilk00.00Yps.
BNumh.xpl9B.pS5Ji.i1BoC.ZAgg1.BsC5T.t6pLk.Thohn.gp000.0ov~P.
7M000.0o840.00010.0001i.h4x93.g0000.Eq2wR.7jB29
==
::
++ huff :: request by ship

View File

@ -1,4 +1,4 @@
::::::
!:::::
:: :: %ford, new execution control
!? 164
::::

View File

@ -1,4 +1,4 @@
:: :: %gall, user-level applications
!: :: %gall, user-level applications
!? 164
::::
|= pit=vase
@ -583,7 +583,7 @@
^- lens
?~ huv.sat *lens
=+ gat=(slap u.huv.sat [%cnzy %peek])
=+ cor=(slam gat !>(pax))
=+ cor=(slam gat !>([our pax]))
=+ ^= dek
|* fun=$+(vase *)
|= nam=@tas

View File

@ -31,11 +31,11 @@
++ bean ,? :: 0=&=yes, 1=|=no
++ beer $|(@ [~ p=twig]) :: simple embed
++ beet $| @ :: advanced embed
$% [%a p=twig] ::
[%b p=twig] ::
[%c p=twig] ::
[%d p=twig] ::
[%e p=twig q=(list tuna)] ::
$% [%a p=twig] :: take tape
[%b p=twig] :: take manx
[%c p=twig] :: take marl
[%d p=twig] :: take $+(marl marl)
[%e p=twig q=(list tuna)] :: element literal
== ::
++ bloq ,@ :: blockclass
++ calf ,[p=(map ,@ud wine) q=wine] ::
@ -49,8 +49,8 @@
[std=term kel=@] :: kelvin version
[ven=term pro=term kel=@] :: vendor and product
[ven=term pro=term ver=@ kel=@] :: all of the above
== ::
++ clue ,[p=axis q=chum r=tyre] :: battery definition
==
++ clue ,[p=chum q=nock r=(list (pair term nock))] :: battery definition
++ coil $: p=?(%gold %iron %lead %zinc) :: core type
q=type ::
r=[p=?(~ ^) q=(map term foot)] ::
@ -154,8 +154,8 @@
p=[p=tape q=tape r=tape s=tape] ::
q=(list tank) ::
== ::
$: %rose ::
p=[p=tape q=tape r=tape] ::
$: %rose :: delimeted list
p=[p=tape q=tape r=tape] :: mid open close
q=(list tank) ::
== ::
==
@ -341,19 +341,19 @@
[%10 p=?(@ [p=@ q=nock]) q=nock] :: hint
[%11 p=nock] :: grab data from sky
== ::
++ tone $% [%0 p=*] ::
[%1 p=(list)] ::
[%2 p=(list ,[@ta *])] ::
++ tone $% [%0 p=*] :: success
[%1 p=(list)] :: blocks
[%2 p=(list ,[@ta *])] :: error ~_s
== ::
++ toon $% [%0 p=*] ::
[%1 p=(list)] ::
[%2 p=(list tank)] ::
++ toon $% [%0 p=*] :: success
[%1 p=(list)] :: blocks
[%2 p=(list tank)] :: stack trace
== ::
++ tune $% [%0 p=vase] ::
[%1 p=(list)] ::
[%2 p=(list ,[@ta *])] ::
== ::
++ twin ,[p=term q=wing r=axis s=type] ::
++ twin ,[p=term q=wing r=axis s=type] :: alias info
++ type $| ?(%noun %void) :: set all or set none
$% [%atom p=term] :: number and format
[%bull p=twin q=type] :: wing synonym
@ -418,7 +418,7 @@
++ wonk |*(veq=edge ?~(q.veq !! p.u.q.veq)) ::
:: ::
:: ::
++ map |* [a=_,* b=_,*] :: associative array
++ map |* [a=_,* b=_,*] :: associative tree
$|(~ [n=[p=a q=b] l=(map a b) r=(map a b)]) ::
++ qeu |* a=_,* :: queue
$|(~ [n=a l=(qeu a) r=(qeu a)]) ::
@ -812,13 +812,6 @@
+<-(+ $(+<- +<->))
--
::
++ wild :: concatenate
|* [a=(list) b=(list)]
=> .(a ^.(homo a), b ^.(homo b))
|-
?~ a b
[i=i.a $(a t.a)]
::
++ zing :: promote
=| *
|%
@ -1141,23 +1134,25 @@
/remlysfynwerrycsugnysnyllyndyndemluxfedsedbecmun\
/lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes'
|%
++ ind ~/ %ind
++ ind ~/ %ind :: parse prefix
|= a=@tas
=+ b=0
|- ^- (unit ,@)
?:(=(256 b) ~ ?:(=(a (tod b)) [~ b] $(b +(b))))
++ ins ~/ %ins
++ ins ~/ %ins :: parse suffix
|= a=@tas
=+ b=0
|- ^- (unit ,@)
?:(=(256 b) ~ ?:(=(a (tos b)) [~ b] $(b +(b))))
++ tod ~/(%tod |=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] dex))))
++ tos ~/(%tos |=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] sis))))
++ tod ~/ %tod :: fetch prefix
|=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] dex)))
++ tos ~/ %tos :: fetch suffix
|=(a=@ ?>((lth a 256) (cut 3 [(mul 3 a) 3] sis)))
--
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 2cF, signed and modular ints ::
::
++ si :: signed integer
++ si !: :: signed integer
|%
++ abs |=(a=@s (add (end 0 1 a) (rsh 0 1 a))) :: absolute value
++ dif |= [a=@s b=@s] :: subtraction
@ -1206,9 +1201,9 @@
--
++ fe :: modulo bloq
|_ a=bloq
++ dif |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c))))
++ inv |=(b=@ (sub (dec out) (sit b)))
++ net |= b=@ ^- @
++ dif |=([b=@ c=@] (sit (sub (add out (sit b)) (sit c)))) :: difference
++ inv |=(b=@ (sub (dec out) (sit b))) :: inverse
++ net |= b=@ ^- @ :: flip byte endianness
=> .(b (sit b))
?: (lte a 3)
b
@ -1216,19 +1211,19 @@
%+ con
(lsh c 1 $(a c, b (cut c [0 1] b)))
$(a c, b (cut c [1 1] b))
++ out (bex (bex a))
++ rol |= [b=bloq c=@ d=@] ^- @
++ out (bex (bex a)) :: mod value
++ rol |= [b=bloq c=@ d=@] ^- @ :: roll left
=+ e=(sit d)
=+ f=(bex (sub a b))
=+ g=(mod c f)
(sit (con (lsh b g e) (rsh b (sub f g) e)))
++ ror |= [b=bloq c=@ d=@] ^- @
++ ror |= [b=bloq c=@ d=@] ^- @ :: roll right
=+ e=(sit d)
=+ f=(bex (sub a b))
=+ g=(mod c f)
(sit (con (rsh b g e) (lsh b (sub f g) e)))
++ sum |=([b=@ c=@] (sit (add b c)))
++ sit |=(b=@ (end a 1 b))
++ sum |=([b=@ c=@] (sit (add b c))) :: wrapping add
++ sit |=(b=@ (end a 1 b)) :: enforce modulo
--
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 2cG, floating point ::
@ -1770,31 +1765,32 @@
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 2cI, almost macros ::
::
++ cury
++ cury :: curry left
|* [a=_|=(^ **) b=*]
|* c=_+<+.a
(a b c)
::
++ curr
++ curr :: curry right
|* [a=_|=(^ **) c=*]
|* b=_+<+.a
(a b c)
::
++ cork |*([a=_,* b=gate] (corl b a))
++ cork |*([a=_,* b=gate] (corl b a)) :: compose forward
::
++ corl
++ corl :: compose backwards
|* [a=gate b=_,*]
|= c=_+<.b
=< +:|.((a (b))) :: type check
|* c=_+<.b
(a (b c))
::
++ hard
++ hard :: force coerce to type
|* han=$+(* *)
|= fud=* ^- han
~| %hard
=+ gol=(han fud)
?>(=(gol fud) gol)
::
++ soft
++ soft :: maybe coerce to type
|* han=$+(* *)
|= fud=* ^- (unit han)
=+ gol=(han fud)
@ -2484,9 +2480,7 @@
[zac [~ i.q.tub [zac t.q.tub]]]
::
++ sear :: conditional cook
~/ %sear
|* [pyq=_|=(* *(unit)) sef=_rule]
~/ %fun
|= tub=nail
=+ vex=(sef tub)
?~ q.vex
@ -2583,9 +2577,7 @@
[(last p.vex p.wag) [~ (raq p.u.q.vex p.u.q.wag) q.u.q.wag]]
::
++ stun :: parse several times
~/ %stun
|* [[les=@ mos=@] fel=_rule]
~/ %fun
|= tub=nail
^- (like (list ,_(wonk (fel))))
?: =(0 mos)
@ -3432,7 +3424,6 @@
rex
:- '.'
=>(.(rex $(esc t.esc)) ((x-co 4) i.esc))
::
++ v-co |=(min=@ (em-co [32 min] |=([? b=@ c=tape] [~(v ne b) c])))
++ w-co |=(min=@ (em-co [64 min] |=([? b=@ c=tape] [~(w ne b) c])))
@ -3440,10 +3431,8 @@
++ y-co |=(dat=@ ((d-co 2) dat))
++ z-co |=(dat=@ `tape`['0' 'x' ((x-co 1) dat)])
--
~% %co +> ~
|%
++ em-co
~/ %emco
|= [[bas=@ min=@] [par=$+([? @ tape] tape)]]
|= hol=@
^- tape
@ -3457,7 +3446,6 @@
==
::
++ ox-co
~/ %oxco
|= [[bas=@ gop=@] dug=$+(@ @)]
%+ em-co
[|-(?:(=(0 gop) 1 (mul bas $(gop (dec gop))))) 0]
@ -3470,7 +3458,6 @@
|=([? b=@ c=tape] [(dug b) c])
::
++ ro-co
~/ %roco
|= [[buz=@ bas=@ dop=@] dug=$+(@ @)]
|= hol=@
^- tape
@ -4657,7 +4644,7 @@
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 2eW, lite number theory ::
::
++ egcd :: schneier's egcd
++ egcd !: :: schneier's egcd
|= [a=@ b=@]
=+ si
=+ [c=(sun a) d=(sun b)]
@ -5266,7 +5253,7 @@
|= [who=@p wud=@]
(shas (mix %shak who) wud)
::
++ sham :: noun hash
++ sham :: 128bit noun hash
|= yux=* ^- @uvH ^- @
?@ yux
(shaf %mash yux)
@ -9478,6 +9465,86 @@
|= txt=@ta
^- twig
(rash txt wide:vast)
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::: :::::: profiling support; move me ::::::
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
++ doss
$: sap=@ud :: sample count
hit=(map term ,@ud) :: hit points
cut=(map span hump) :: cut points
==
::
++ hump
$: sap=@ud :: sample count
inn=(map span ,@ud) :: calls into
out=(map span ,@ud) :: calls out of
==
::
++ pi-heck
|= [nam=@tas day=doss]
^- doss
=+ lam=(~(get by hit.day) nam)
day(hit (~(put by hit.day) nam ?~(lam 1 +(u.lam))))
::
++ pi-noon :: sample trace
|= [pax=path day=doss]
=| lax=(unit span)
|- ^- doss
?~ pax day(sap +(sap.day))
%= $
pax t.pax
lax `i.pax
cut.day
%+ ~(put by cut.day) i.pax
^- hump
=+ nax=`(unit span)`?~(t.pax ~ `i.t.pax)
=+ hup=`hump`=+(hup=(~(get by cut.day) i.pax) ?^(hup u.hup [0 ~ ~]))
:+ +(sap.hup)
?~ lax inn.hup
=+ hag=(~(get by inn.hup) u.lax)
(~(put by inn.hup) u.lax ?~(hag 1 +(u.hag)))
?~ nax out.hup
=+ hag=(~(get by out.hup) u.nax)
(~(put by out.hup) u.nax ?~(hag 1 +(u.hag)))
==
::
++ pi-tell :: produce dump
|= day=doss
^- (list tape)
;: welp
[(welp "events: " (scow %ud sap.day)) ~]
::
%+ turn
(~(tap by hit.day) ~)
|= [nam=term num=@ud]
:(welp (trip nam) ": " (scow %ud num))
["" ~]
::
%- zing
^- (list (list tape))
%+ turn
(~(tap by cut.day) ~)
|= [nam=term hup=hump]
;: welp
[(welp "sector: " (trip nam)) ~]
[(welp "weight: " (scow %ud (div (mul 1.000 sap.hup) sap.day))) ~]
["inn:" ~]
::
%+ turn
(~(tap by inn.hup) ~)
|= [nam=term num=@ud]
^- tape
:(welp " " (trip nam) ": " (scow %ud num))
::
["out:" ~]
::
%+ turn
(~(tap by out.hup) ~)
|= [nam=term num=@ud]
^- tape
:(welp " " (trip nam) ": " (scow %ud num))
==
==
--
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::: :::::: volume 3, Arvo models and skeleton ::::::
@ -9524,7 +9591,7 @@
a ::
== ::
++ kirk (unit (set monk)) :: audience
++ khan ,[p=@tas q=path] :: foreign identity
++ khan ,[p=@tas q=@ta] :: foreign identity
++ lens :: observation core
$_ ^? ::
|% ++ u *(unit (unit ,~)) :: existence
@ -9725,6 +9792,7 @@
bed=beam
==
^- (unit (unit cage))
:: ~& [%arvo-scry ren bed]
=+ ^= old
:* fur
ren
@ -9906,6 +9974,7 @@
:::::: :::::: Postface ::::::
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
!:
~& %post-start
=+ pit=`vase`!>(.) ::
=+ bud=pit :: becomes tang
=+ vil=(viol p.bud) :: cached reflexives

86
arvo/jael.hoon Normal file
View File

@ -0,0 +1,86 @@
:: %jael, secret storage
::
:::: /hoon/jael
::
!? 164
::::
:: %jael is logically homogeneous, but please follow these conventions:
::
:: /cap :: foreign app keys
:: /service :: service name, eg %face
:: /appid :: your ship's app-id
:: /@uvH :: by hash
:: /@ud :: by number
:: /@tas :: by name
::
:: /key :: foreign user secrets
:: /service :: service name, eg %face
:: /userid :: user identity
::
:: /urb :: urbit secrets
:: /tok/hash
|= pit=vase
=> =~
:: structures
|%
++ axle :: %jael state
$: %0 ::
ent=@uwH :: entropy
all=(map ship ,[p=@ q=safe]) :: entropy, secrets
== ::
++ mast $: ent=@
++ mort ,[p=@da q=duct r=@] :: a mortal secret
++ gift :: out result <-$
$% [%done p=path q=@] :: key expired
== ::
++ kiss :: in request ->$
$% [%kill p=
[%drop p=@p q=path r=@] :: discard key
[%junk p=@] :: add entropy
[%show p=@p q=path] :: read subtree
[%tell p=@ q=path r=@da s=@] :: save key
== ::
++ safe ,[p=(unit ,@) q=(map ,@ta safe)] :: secret tree
++ move ,[p=duct q=[%give p=gift]] :: local move
-- ::
. ==
=| axle
=* lex -
|= [now=@da eny=@ ski=sled] :: activate
^? :: opaque core
|% ::
++ call :: request
|= [hen=duct hic=(hypo (hobo kiss))]
^- [p=(list move) q=_..^$]
=> .(q.hic ?.(?=(%soft -.q.hic) q.hic ((hard kiss) p.q.hic)))
!!
::
++ doze
|= [now=@da hen=duct]
^- (unit ,@da)
~
::
++ load :: highly forgiving
|= old=*
=+ lox=((soft axle) old)
^+ ..^$
?~ lox
~& %jael-reset
..^$
..^$(+>- u.lox)
::
++ scry
|= [fur=(unit (set monk)) ren=@tas who=ship syd=desk lot=coin tyl=path]
^- (unit (unit (pair mark ,*)))
:: actually scry
~
::
++ stay :: save w/o cache
`axle`+>-.$(pol (~(run by pol) |=(a=baby [tad.a dym.a ~])))
::
++ take :: response
|= [tea=wire hen=duct hin=(hypo noun)]
!!
--

100
arvo/kahn.hoon Normal file
View File

@ -0,0 +1,100 @@
:: %kahn, social state
::
:::: /hoon/kahn
::
!? 164
::::
|= pit=vase
=> =~
:: structures
|%
++ axle :: %kahn state
$: %0 ::
big=(unit ship) :: main ship, freeze
soc=(map monk node) :: state once big
== ::
++ cert (each will ,*) :: urbit and others
++ gift :: out result <-$
$: [%then p=node] :: propagate change
== ::
++ node :: social identity
$: ven=@ud :: iteration number
tin=(map monk link) :: inbound links
oud=(map monk link) :: outbound links
cet=cert :: certificate
== ::
++ kiss :: change
$: [%that p=note] :: social update
== ::
++ link (pair rank ,@da) :: graph link
++ note (qual ,@ud monk (map monk link) cert) ::
++ rank :: privilege ring
$? %0 :: owner / admin
%1 :: guardian / employer
%2 :: partner / employee
%3 :: friend / customer
%4 :: neighbor/ contact
%5 :: zombie
== ::
-- ::
. ==
=| axle
=* lex -
|= [now=@da eny=@ ski=sled] :: activate
^? :: opaque core
|% ::
++ call :: request
|= [hen=duct hic=(hypo (hobo kiss))]
^- [p=(list move) q=_..^$]
=> .(q.hic ?.(?=(%soft -.q.hic) q.hic ((hard kiss) p.q.hic)))
!!
::
++ doze
|= [now=@da hen=duct]
^- (unit ,@da)
~
::
++ load :: highly forgiving
|= old=*
=+ lox=((soft axle) old)
^+ ..^$
?~ lox
~& %lunt-reset
..^$
..^$(+>- u.lox)
::
++ scry
|= [fur=(unit (set monk)) ren=@tas who=ship syd=desk lot=coin tyl=path]
^- (unit (unit (pair mark ,*)))
?. =(big [~ who]) ~
=+ ^= yub ^- [(unit monk)
?: =(%urb syd)
?. ?=([* ~] tyl) ~
=+ goy=(slaw %p
?+ ?=([%$ %da @]
?+ lot ~
[%$ %ud @]
%+ bind
(perm who u.hun q.p.lot [syd t.tyl])
|=(a=* [%noun a])
::
?. =(now q.p.lot) ~
%+ bind
(temp who u.hun [syd t.tyl])
|=(a=* [%noun a])
==
?. ?=([%da
=+ mok ^- (unit monk)
?: =(%urb face)
(
::
++ stay :: save w/o cache
`axle`+>-.$
::
++ take :: response
|= [tea=wire hen=duct hin=(hypo noun)]
!!
--

103
arvo/lunt.hoon Normal file
View File

@ -0,0 +1,103 @@
:: %lunt, fleet job control
::
:::: /hoon/lunt
::
!? 164
::::
|= pit=vase
=> =~
:: structures
|%
++ axle :: %lunt state
$: %0 ::
all=(map ship axil) :: state by owner
== ::
++ born ,[p=brat q=(unit ship)] :: task identity
++ brat ,@ud :: task number
++ bulb ::
$: p=@p :: ship identity
q=home :: server data
== ::
++ home :: storage access
$: pad=@uvH :: passcode
huc=husk :: log server
sog=hulk :: storage server
== ::
++ hulk :: checkpoint service
$% [%astr p=@ud q=@ud] :: S3
== ::
++ husk :: log server
$: pro=@tas :: protocol
cap=@uvH :: access code
srv=(list (pair ,@ud clip)) :: server cluster
== ::
++ gift :: result
$: [%die p=brat] :: kill
[%int p=brat] :: interrupt
[%run p=brat q=@p r=home] :: load
[%say p=brat q=(list ovum)] :: send events
[%new p=brat q=@p r=home s=(list ovum)] :: create
== ::
++ kiss :: request
$: [%com p=@p] :: toggle compute svr
[%end p=brat] :: local end
[%fan p=@ud] :: set local fanout
[%kil ~] :: terminate ship
[%int ~] :: interrupt ship
[%new p=@p q=(set ,@p) q=home r=@uvI] :: create ship
[%run p=@p q=home] :: run existing ship
[%say p=(list ovum)] :: remote events
[%sto p=husk] :: toggle logger
== ::
++ axil ::
$: bus=(unit ,@p) :: master
loc=@ud :: local resources
hen=(unit duct) :: effect duct
ent=@ :: entropy
seq=@ :: brat sequence
why=(map duct born) :: hosted ships
how=(map born duct) :: reverse why
hut=(map born home) :: storage control
sto=(set husk) :: storage resources
com=(set ship) :: compute resources
== ::
-- ::
. ==
=| axle
=* lex -
|= [now=@da eny=@ ski=sled] :: activate
^? :: opaque core
|% ::
++ call :: request
|= [hen=duct hic=(hypo (hobo kiss))]
^- [p=(list move) q=_..^$]
=> .(q.hic ?.(?=(%soft -.q.hic) q.hic ((hard kiss) p.q.hic)))
!!
::
++ doze
|= [now=@da hen=duct]
^- (unit ,@da)
~
::
++ load :: highly forgiving
|= old=*
=+ lox=((soft axle) old)
^+ ..^$
?~ lox
~& %lunt-reset
..^$
..^$(+>- u.lox)
::
++ scry
|= [fur=(unit (set monk)) ren=@tas who=ship syd=desk lot=coin tyl=path]
^- (unit (unit (pair mark ,*)))
~
::
++ stay :: save w/o cache
`axle`+>-.$
::
++ take :: response
|= [tea=wire hen=duct hin=(hypo noun)]
!!
--

94
arvo/musk.hoon Normal file
View File

@ -0,0 +1,94 @@
:: %musk, realm management
::
:::: /hoon/musk
::
!? 164
::::
|= pit=vase
=> =~
:: structures
|%
++ axle :: %musk state
$: %0 ::
all=(map ship axil) :: state by owner
== ::
++ axil ::
$: kid=(map ship girl) :: daughters
deq=(map narc ship) :: reverse address
siq=(map ship (list clan)) :: ship to clans
kes=(map clan (list ship)) :: clan to ships
== ::
++ clan ,@tas :: group identity
++ narc :: contact address
$: [%$ p=ship] :: urbit
[%m p=@t q=@t] :: email p@q
[%f p=@t] :: facebook
[%g p=@t] :: google
[%p p=@t] :: phone message
[%t p=@t] :: twitter
== ::
++ pony :: daughter status
$% [%cold ~] :: virginal
[%dead ~] :: written off
[%fake ~] :: virtual
[%free ~] :: downloaded
[%here ~] :: hosted
[%left p=(unit ship)] :: run away to
== ::
++ rank :: relative privilege
$? %0 :: enemy
%1 :: neighbor
%2 :: guest/customer
%3 :: friend/employee
%4 :: officer/family
%5 :: self/admin
== ::
++ girl ::
$: hop=pony :: status
tag=(unit ,@tas) :: petname
tip=rank :: rank
fig=(set narc) :: identities
loc=(unit ,[p=@da q=@ud r=clip]) :: last position
sym=(set ,[p=@ q=@uvH]) :: symmetric keys?
wyl=will :: crypto will
== ::
-- ::
. ==
=| axle
=* lex -
|= [now=@da eny=@ ski=sled] :: activate
^? :: opaque core
|% ::
++ call :: request
|= [hen=duct hic=(hypo (hobo kiss))]
^- [p=(list move) q=_..^$]
=> .(q.hic ?.(?=(%soft -.q.hic) q.hic ((hard kiss) p.q.hic)))
!!
::
++ doze
|= [now=@da hen=duct]
^- (unit ,@da)
~
::
++ load :: highly forgiving
|= old=*
=+ lox=((soft axle) old)
^+ ..^$
?~ lox
~& %lunt-reset
..^$
..^$(+>- u.lox)
::
++ scry
|= [fur=(unit (set monk)) ren=@tas who=ship syd=desk lot=coin tyl=path]
^- (unit (unit (pair mark ,*)))
~
::
++ stay :: save w/o cache
`axle`+>-.$
::
++ take :: response
|= [tea=wire hen=duct hin=(hypo noun)]
!!
--

View File

@ -1,24 +0,0 @@
?> ?=([@ @] .)
%. .
|= [x=@ y=@]
=- (add:all x y)
^= all
=> %164
~% %k164 ~ ~
|%
++ add
~/ %add
|= [a=@ b=@]
^- @
?: =(0 a) b
$(a (dec a), b +(b))
::
++ dec
~/ %dec
|= a=@
?< =(0 a)
=+ b=0
|- ^- @
?: =(a +(b)) b
$(b +(b))
--

View File

@ -41,7 +41,7 @@
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 3bB, cryptosuites ::
::
++ crua :: cryptosuite A (RSA)
++ crua !: :: cryptosuite A (RSA)
^- acru
=| [mos=@ pon=(unit ,[p=@ q=@ r=[p=@ q=@] s=_*fu])]
=> |%
@ -1009,9 +1009,10 @@
%indirect p.p
==
::
++ ze
++ ze !:
|_ [lim=@da dome rang]
++ aeon-to-tako ~(got by hit)
++ aeon-to-yaki (cork aeon-to-tako tako-to-yaki)
++ make-yaki :: make yaki
|= [p=(list tako) q=(map path lobe) t=@da]
^- yaki
@ -1082,17 +1083,16 @@
((diff (blob-to-umph (lobe-to-blob u.leb))) zeq zoq)
::
++ lobes-at-path :: lobes-at-path:ze
|= [oan=aeon pax=path] :: data at path
|= [yon=aeon pax=path] :: data at path
^- (map path lobe)
?: =(0 oan) ~
?: =(0 yon) ~
%- mo
%+ skim
%. ~
%~ tap by
=< q
%- tako-to-yaki
%- aeon-to-tako
oan
%- aeon-to-yaki
yon
|= [p=path q=lobe]
?| ?=(~ pax)
?& !?=(~ p)
@ -1110,8 +1110,7 @@
?: =(0 let) [~ 0] :: avoid underflow
?: %+ gte p.lok
=< t
%- tako-to-yaki
%- aeon-to-tako
%- aeon-to-yaki
let
[~ let]
$(let (dec let))
@ -1221,11 +1220,11 @@
==
::
++ rewind :: rewind:ze
|= oan=aeon :: rewind to aeon
|= yon=aeon :: rewind to aeon
^+ +>
?: =(let oan) +>
?: (gth oan let) !! :: don't have version
+>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako oan))), let oan)
?: =(let yon) +>
?: (gth yon let) !! :: don't have version
+>(ank (checkout-ankh q:(aeon-to-yaki yon)), let yon)
::
::::
++ update-lat :: update-lat:ze
@ -1245,16 +1244,15 @@
?: =(let 0) :: initial commit
~ :: has nothing
=< q
%- tako-to-yaki
%- aeon-to-tako
%- aeon-to-yaki
let
%- |= bar=(map path blob) :: find unchanged
=+ sar=(sa (turn lar |=([p=path *] p))) :: changed paths
%+ roll (~(tap by hat) ~)
=- =+ sar=(sa (turn lar |=([p=path *] p))) :: changed paths
%+ roll (~(tap by hat) ~) :: find unchanged
|= [[pat=path gar=lobe] bat=_bar]
?: (~(has in sar) pat) :: has update
bat
(~(put by bat) pat (lobe-to-blob gar)) :: use original
^= bar ^- (map path blob)
%+ roll lar
|= [[pat=path mys=miso] bar=(map path blob)]
^+ bar
@ -1757,34 +1755,29 @@
?^(r.mun ~ [~ let])
?: ?=(%w p.mun)
=+ ^= yak
%- tako-to-yaki
%- aeon-to-tako
%- aeon-to-yaki
let
?^(r.mun ~ [~ [t.yak (forge-nori yak)]])
::?> ?=(^ hit) ?^(r.mun ~ [~ i.hit]) :: what do?? need [@da nori]
(query(ank ank:(descend-path:(zu ank) r.mun)) p.mun)
::
++ read-at-aeon :: read-at-aeon:ze
|= [oan=aeon mun=mood] :: seek and read
|= [yon=aeon mun=mood] :: seek and read
^- (unit)
?: &(?=(%w p.mun) !?=(%ud -.q.mun)) :: NB only for speed
?^(r.mun ~ [~ oan])
(read:(rewind oan) mun)
?^(r.mun ~ [~ yon])
(read:(rewind yon) mun)
::
++ equiv :: test paths
|= [p=(map path lobe) q=(map path lobe)]
^- ?
%- |= qat=?
?. qat %.n
%+ roll (~(tap by q) ~)
|= [[pat=path lob=lobe] eq=?]
^- ?
?. eq %.n
=- ?. qat %.n
%+ levy (~(tap by q) ~)
|= [pat=path lob=lobe]
(~(has by p) pat)
%+ roll (~(tap by p) ~)
|= [[pat=path lob=lobe] eq=?]
^- ?
?. eq %.n
^= qat
%+ levy (~(tap by p) ~)
|= [pat=path lob=lobe]
=+ zat=(~(get by q) pat)
?~ zat %.n
=((lobe-to-noun u.zat) (lobe-to-noun lob))
@ -1793,16 +1786,14 @@
|= [wen=@da lem=nori] :: edit
^+ +>
?- -.lem
& =+ ^= yet
& =^ yak lat :: merge objects
%+ forge-yaki wen
?: =(let 0) :: initial import
[~ q.lem]
[(some r:(tako-to-yaki (aeon-to-tako let))) q.lem]
=+ yak=-.yet
=. lat +.yet :: merge objects
[(some r:(aeon-to-yaki let)) q.lem]
?. ?| =(0 let)
!=((lent p.yak) 1)
!(equiv q.yak q:(tako-to-yaki (aeon-to-tako let)))
!(equiv q.yak q:(aeon-to-yaki let))
==
+>.$ :: silently ignore
=: let +(let)
@ -1814,7 +1805,7 @@
==
--
::
++ zu :: filesystem
++ zu !: :: filesystem
|= ank=ankh :: filesystem state
=| myz=(list ,[p=path q=miso]) :: changes in reverse
=| ram=path :: reverse path into

20
main/bin/liquid.hoon Normal file
View File

@ -0,0 +1,20 @@
!:
:: /=main=/bin/liquid/hoon
::
=> .(- `[who=@p how=path]`-)
|= [est=time eny=@uw]
|= arg=*
=+ ^= lok ^- case
?: =(~ arg) [%da est]
?> =(~ +.arg)
((hard case) -.arg)
=+ cav=(scot (dime lok))
=+ top=`path`[(scot %p who) %arvo cav ~]
=+ pax=`path`(weld top `path`[%hoon ~])
~& %liquid-start
=+ gen=(reck pax)
~& %liquid-parsed
=+ ken=q:(~(mint ut %noun) %noun gen)
~& %liquid-compiled
:_ ~ :_ ~
[%xx %sage [%dummy %pill ~] [ken 0]]

View File

@ -17,7 +17,9 @@
=+ ken=q:(~(mint ut %noun) %noun gen)
~& %solid-compiled
=+ ^= all
~& [%solid-ken `@ux`(mug ken)]
=+ all=.*(0 ken)
~& %solid-loaded
=+ ^= vay ^- (list ,[p=@tas q=@tas])
:~ [%$ %zuse]
[%f %ford]

View File

@ -6,8 +6,9 @@
::
++ grow :: convert to
|%
++ mime [/text/html (taco own)] :: convert to %mime
++ hymn ;div:(pre:"{(trip own)}") :: convert to %html
++ mime [/text/hoon (taco own)] :: convert to %mime
++ psal ;div:(pre:"{(trip own)}") :: convert to %html
++ hymn ;html:(head:title:"Source" "+{psal}")
--
++ grab |% :: convert from
++ noun ,@t :: clam from %noun

File diff suppressed because it is too large Load Diff

View File

@ -685,8 +685,8 @@ each in detail.
These two kisses are nearly identical. At a high level, they apply changes to
the filesystem. Whenever we add, remove, or edit a file, one of these cards is
sent. The `p` is the ship whose filesystem we're trying to change, the `q` is
the desk we're changing, and the `r` is the request change. For the format of
the requested change, see the documentation for `++nori` above.
the desk we're changing, and the `r` is the requested change. For the format
of the requested change, see the documentation for `++nori` above.
When a file is changed in the unix filesystem, vere will send a `%into` kiss.
This tells clay that the duct over which the kiss was sent is the duct that
@ -1024,11 +1024,11 @@ which reads the requested data at the given revision.
```
++ read-at-aeon :: read-at-aeon:ze
|= [oan=aeon mun=mood] :: seek and read
|= [yon=aeon mun=mood] :: seek and read
^- (unit)
?: &(?=(%w p.mun) !?=(%ud -.q.mun)) :: NB only for speed
?^(r.mun ~ [~ oan])
(read:(rewind oan) mun)
?^(r.mun ~ [~ yon])
(read:(rewind yon) mun)
```
If we're requesting the revision number with a case other than by number, then
@ -1038,11 +1038,11 @@ to get the requested information.
```
++ rewind :: rewind:ze
|= oan=aeon :: rewind to aeon
|= yon=aeon :: rewind to aeon
^+ +>
?: =(let oan) +>
?: (gth oan let) !! :: don't have version
+>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako oan))), let oan)
?: =(let yon) +>
?: (gth yon let) !! :: don't have version
+>(ank (checkout-ankh q:(tako-to-yaki (aeon-to-tako yon))), let yon)
```
If we're already at the requested version, we do nothing. If we're requesting
@ -1490,9 +1490,9 @@ We call `++lobes-at-path:ze` to get the data at the particular path.
```
++ lobes-at-path :: lobes-at-path:ze
|= [oan=aeon pax=path] :: data at path
|= [yon=aeon pax=path] :: data at path
^- (map path lobe)
?: =(0 oan) ~
?: =(0 yon) ~
%- mo
%+ skim
%. ~
@ -1500,7 +1500,7 @@ We call `++lobes-at-path:ze` to get the data at the particular path.
=< q
%- tako-to-yaki
%- aeon-to-tako
oan
yon
|= [p=path q=lobe]
?| ?=(~ pax)
?& !?=(~ p)
@ -2001,9 +2001,9 @@ subscription case.
```
++ balk :: read and send
|= [hen=duct oan=@ud mun=mood]
|= [hen=duct yon=@ud mun=mood]
^+ +>
=+ vid=(~(read-at-aeon ze lim dom ran) oan mun)
=+ vid=(~(read-at-aeon ze lim dom ran) yon mun)
?~ vid (blub hen) (blab hen mun u.vid)
```
@ -2035,3 +2035,397 @@ 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.
Lifecycle of a Local Write
--------------------------
There are two kisses that cause a local write: `%info` and `%into`. These are
exactly identical except that `%into` resets the the sync duct in clay, so it
ought only to be called from unix. Within arvo, we call `%info`.
Both are handled in `++call`.
```
?(%info %into)
?: =(%$ q.q.hic)
?. ?=(%into -.q.hic) [~ ..^$]
=+ yar=(need (~(get by fat.ruf) p.q.hic))
[~ ..^$(fat.ruf (~(put by fat.ruf) p.q.hic yar(hez [~ hen])))]
=^ mos ruf
=+ une=(un p.q.hic now ruf)
=+ ^= zat
(exec:(di:wake:une q.q.hic) hen now r.q.hic)
=+ zot=abet.zat
:- -.zot
=. une (pish:une q.q.hic +.zot ran.zat)
abet:une(hez.yar ?.(=(%into -.q.hic) hez.yar.une [~ hen]))
[mos ..^$]
```
Recall that in the kiss (`q.hic`) the `p` is the ship whose filesystem we're
trying to change, the `q` is the desk we're changing, and the `r` is the
requested change.
If `q`, the desk name, is empty, then we don't make any actual changes to the
filesystem. In the case of `%info`, we do nothing at all. For the `%into`
kiss, we simply set the sync duct to the duct we received this kiss on. This
allows us to set the sync duct without making a change to our filesystem.
Otherwise, we construct the core for a local ship with `++un` and for the local
desk with `++di`, as described above. We then apply the change with
`++exec:de`, which contains the meat of the write functionality. Afterward, we
call `++abet:de` to resolve our changes to the desk and `++pish:un` and
`++abet:un` to resolve our changes to the ship, as described above. Again, if
this is a `%info` kiss, then we don't change the sync duct; else, we set it to
the calling duct.
The interesting call here was, of course, `++exec:de`.
```
++ exec :: change and update
|= [hen=duct wen=@da lem=nori]
^+ +>
(echo:wake:(edit wen lem) hen wen lem)
```
First, we call `++edit` to apply our changes, then we call `++wake` to push out
any new updates to our subscribers. Finally, we call `++echo` to announce our
changes to both unix and the terminal.
We have described `++wake` above, so we'll discuss `++edit` and `++echo` here.
Since `++echo` is significantly simpler, we'll start with it.
```
++ echo :: announce changes
|= [hen=duct wen=@da lem=nori]
^+ +>
%= +>
vag ?~(hez vag :_(vag [u.hez [%ergo who syd let.dom]]))
yel
=+ pre=`path`~[(scot %p for) syd (scot %ud let.dom)]
?- -.lem
| :_ yel
[hen %note '=' %leaf :(weld (trip p.lem) " " (spud pre))]
& |- ^+ yel
?~ q.q.lem yel
:_ $(q.q.lem t.q.q.lem)
:- hen
:+ %note
?-(-.q.i.q.q.lem %del '-', %ins '+', %mut ':')
[%leaf (spud (weld pre p.i.q.q.lem))]
==
==
```
If we have a sync duct, then we push out a `%ergo` gift along it so that unix
knows there has been a change to the filesystem and can update the copy on the
unix filesystem.
Additionally, we push out a `%note` gift to the terminal duct to display the
new changes to the user. This is responsible for the printed lines we see when
a file is added, removed, or modified.
It remains to discuss `++edit:de`.
```
++ edit :: apply changes
|= [wen=@da lem=nori]
^+ +>
=+ axe=(~(edit ze lim dom ran) wen lem)
=+ `[l=@da d=dome r=rang]`+<.axe
+>.$(dom d, ran r)
```
We very simply call `++edit:ze` and apply the resultant dome and rang back into
ourself. As we should expect, the actual handling of the changes themselves
is delegated to `++ze` in `arvo/zuse.hoon`.
```
++ edit :: edit:ze
|= [wen=@da lem=nori] :: edit
^+ +>
?- -.lem
& =^ yak lat :: merge objects
%+ forge-yaki wen
?: =(let 0) :: initial import
[~ q.lem]
[(some r:(aeon-to-yaki let)) q.lem]
?. ?| =(0 let)
!=((lent p.yak) 1)
!(equiv q.yak q:(aeon-to-yaki let))
==
+>.$ :: silently ignore
=: let +(let)
hit (~(put by hit) +(let) r.yak)
hut (~(put by hut) r.yak yak)
==
+>.$(ank (checkout-ankh q.yak))
| +>.$(lab ?<((~(has by lab) p.lem) (~(put by lab) p.lem let)))
==
```
Two kinds of changes may be made to a filesystem: we can modify the contents
or we can label a revision.
Labeling a revision (the `|` case) is much simpler. We first assert that the
label doesn't already exist. Then, we put in `lab` in our dome the label
associated with the current revision number.
In the `&` case, we're actually modifying the contents of the filesystem.
First, we create the commit in `++forge-yaki` by applying the given changes to
our current revision. This also updates `lat` in our rang with the new data
objects.
Unless either this is the initial import, the generated yaki doesn't have
exactly one parent, or the data in the generated yaki is the same as that in
our current revision, we silently ignore the request. Note that this only
allows changes that don't affect the contents of the filesystem if this is a
merge.
If one of the conditions does hold, then we apply the generated commit. We
increment `let`, the revision number of our head; associate the new revision
number with the hash of the new commit; and put the new commit in `hut`.
Finally, we update our current ankh by checking out the new commit.
We discussed `++checkout-ankh` above, so it remains only to discuss
`++forge-yaki` and `++equiv`. We begin with the simpler, `++equiv:ze`.
```
++ equiv :: test paths
|= [p=(map path lobe) q=(map path lobe)]
^- ?
=- ?. qat %.n
%+ levy (~(tap by q) ~)
|= [pat=path lob=lobe]
(~(has by p) pat)
^= qat
%+ levy (~(tap by p) ~)
|= [pat=path lob=lobe]
=+ zat=(~(get by q) pat)
?~ zat %.n
=((lobe-to-noun u.zat) (lobe-to-noun lob))
```
We're checking to see if the data in both filesystem trees is identical. We
start by going through `p` and checking to see if (1) the path exists in `q`
and (2) the data is the same as in `q`.
This shows that `q` is a superset of `p`. To show that `p` and `q` are
equivalent, we have to make sure there is nothing in `q` that is not also in
`p`. Once we've done that, we know `p` and `q` are equivalent.
```
++ forge-yaki :: forge-yaki:ze
|= [wen=@da par=(unit tako) lem=soba] :: forge yaki
=+ ^= per
?~ par ~
~[u.par]
=+ gar=(update-lat (apply-changes q.lem) lat)
:- %^ make-yaki per +.gar wen :: from existing diff
-.gar :: fix lat
```
Here, we first make `per`, our list of parents. If we have a parent, we put it
in the list, else the list is empty. Simple.
We then apply the changes and update `lat`, our object store. Finally, we make
a yaki out of the generated change information and produce both it and the new
object store.
In increasing order of complexity, the new arms here are `++make-yaki`,
`++update-lat`, and `++apply-changes`.
```
++ make-yaki :: make yaki
|= [p=(list tako) q=(map path lobe) t=@da]
^- yaki
=+ ^= has
%^ cat 7 (sham [%yaki (roll p add) q t])
(sham [%tako (roll p add) q t])
[p q has t]
```
We're given almost everything we need to make a yaki, so we just need to
generate the hash of the new yaki. We take a noun hash of a noun that depends
on the hashes of the parents, the data at this commit, and the date of the
commit. Note that this means two identical changes made on the same parents at
different times will have different hashes.
```
++ update-lat :: update-lat:ze
|= [lag=(map path blob) sta=(map lobe blob)] :: fix lat
^- [(map lobe blob) (map path lobe)]
%+ roll (~(tap by lag) ~)
|= [[pat=path bar=blob] [lut=_sta gar=(map path lobe)]]
?~ (~(has by lut) p.bar)
[lut (~(put by gar) pat p.bar)]
:- (~(put by lut) p.bar bar)
(~(put by gar) pat p.bar)
```
We're given a map of paths directly to their contents, but we wish to have both
a map from paths to hashes of their contents and a map from hashes to the
content itself. We're given an initial map of the second kind, but when
applying the changes, we may add new content which is not yet stored here.
We roll over the given map from paths to data and, if the data is already in
our store, then we simply add a reference to the hash in the map from paths to
hashes. Otherwise, we also have to add the entry in the map from hashes to
data.
```
++ apply-changes :: apply-changes:ze
|= lar=(list ,[p=path q=miso]) :: store changes
^- (map path blob)
=+ ^= hat :: current state
?: =(let 0) :: initial commit
~ :: has nothing
=< q
%- aeon-to-yaki
let
=- =+ sar=(sa (turn lar |=([p=path *] p))) :: changed paths
%+ roll (~(tap by hat) ~) :: find unchanged
|= [[pat=path gar=lobe] bat=_bar]
?: (~(has in sar) pat) :: has update
bat
(~(put by bat) pat (lobe-to-blob gar)) :: use original
^= bar ^- (map path blob)
%+ roll lar
|= [[pat=path mys=miso] bar=(map path blob)]
^+ bar
?- -.mys
%ins :: insert if not exist
?: (~(has by bar) pat) !! ::
?: (~(has by hat) pat) !! ::
(~(put by bar) pat (make-direct p.mys %c)) :: TODO content type?
%del :: delete if exists
?. |((~(has by hat) pat) (~(has by bar) pat)) !!
(~(del by bar) pat)
%mut :: mutate, must exist
=+ ber=(~(get by bar) pat)
?~ ber
=+ har=(~(get by hat) pat)
?~ har !!
%+ ~(put by bar) pat
(make-delta u.har p.mys)
%+ ~(put by bar) pat
(make-delta p.u.ber p.mys)
==
```
We let `hat` be the state of our head. We let `bar` be the new state of
the files we touch in our changes, and then we add in the unchanged files.
To compute `bar`, we go through each change, handling each one individually.
If the change is an insert, then we first assert that the file doesn't already
exist and that we haven't already added it in this changeset. Note that this
means it is impossible to delete a file and then insert it again in the same
changeset. If this is indeed a new file, then put the path into `bar`,
associated with its data blob, as calculated by `++make-direct`.
```
++ make-direct :: make blob
|= [p=* q=umph]
^- blob
[%direct (mug p) p q]
```
We're given everything we need to create a `%direct` blob except the hash,
which we calculate as the simple mug of the file contents.
In the case of a delete, we first assert that the file exists in either the
current head or our new changes. Note that it is possible to insert a file and
then delete it in the same changeset. If the file does exist, then we remove
it from `bar`.
Finally, in the case of a mutation, we try to get the current state of the file
from our new changes in `bar`. If it's not there, then we assert that the file
exists in our current head (it must, after all, if we're changing it), and we
make a `%delta` blob out of the difference between the old contents and the new
contents. If the file is in `bar`, then make the `%delta` blob as a change
from from the contents already in `bar` to the new contents. This means it is
possible to have multiple mutations to a file in the same changeset.
After we've computed the contents of modified files, we must add all the
unmodified files. We might naively suppose that `(~(uni by hat) bar)` would do
this, but this would add back all the deleted files. To get around this, we
let `sar` be the changed files, and then we simply roll over the files at our
current head, adding everything that isn't in `sar`.
This concludes our discussion of a local write.
Lifecycle of a Local Merge
--------------------------
Merges are pretty simple from the perspective of clay. A `%merg` kiss is sent
with already-generated merge state, and we simply apply the new state. The
question of how the merge is generated is much more complicated, but it is also
out of the scope of this section. If you're interested, take a look at
`++construct-merge:ze`.
We've seen most of the arms involved, so we'll go through most of it pretty
quickly. In `++call` we handle the `%merg` kiss.
```
%merg :: direct state up
=^ mos ruf
=+ une=(un p.q.hic now ruf)
=+ ^= zat
(exem:(di:wake:une q.q.hic) hen now r.q.hic)
=+ zot=abet.zat
:- -.zot
=. une (pish:une q.q.hic +.zot ran.zat)
abet:une(hez.yar ?.(=(%into -.q.hic) hez.yar.une [~ hen]))
[mos ..^$]
```
As we've seen several times before, we set up a core for the local ship with
`++un`. We set up a core for the local desk with `++di` and updating our
subscribers with `++wake`. We call `++exem` to execute the merge. `++abet:de`,
`++pish:un` and `++abet:un` resolve all our changes.
The only new arm here is `++exem:de`.
```
++ exem :: execute merge
|= [hen=duct wen=@da mer=mizu] :: aka direct change
?. (gte p.mer let.dom) !! :: no
=. +>.$ %= +>.$
hut.ran (~(uni by hut.r.mer) hut.ran)
lat.ran (~(uni by lat.r.mer) lat.ran)
let.dom p.mer
hit.dom (~(uni by q.mer) hit.dom)
==
=+ ^= hed :: head commit
=< q
%- ~(got by hut.ran)
%- ~(got by hit.dom)
let.dom
=. ank.dom :: real checkout
(~(checkout-ankh ze lim dom ran) hed)
(echa:wake hen wen mer) :: notify or w/e
```
We first do a quick sanity check that the head of the merge data is greater
than the head of the old data. Merges must add at least one revision.
We merge the new data in the obvious way. We do map merges for `hut` and `lat`
in rang to get all the new data and commits, we do a map merge in`hit` in our
dome to get all the new revision numbers, and we update our head to the most
recent revision.
Then, we checkout the commit at our head and announce the results to unix.
`++echa` is the only new arm here.
```
++ echa :: announce raw
|= [hen=duct wen=@da mer=mizu]
^+ +>
%= +>
vag ?~(hez vag :_(vag [u.hez [%ergo who syd let.dom]]))
==
```
If we have a sync duct, we tell unix that a new revision is available.
This concludes our discussion of a local merge.

84
try/bin/profile.hoon Normal file
View File

@ -0,0 +1,84 @@
|%
++ doss
$: sap=,@ud :: sample count
hit=(map term ,@ud) :: hit points
cut=(map span hump) :: cut points
==
::
++ hump
$: sap=,@ud :: sample count
inn=(map span ,@ud) :: calls into
out=(map span ,@ud) :: calls out of
==
::
++ pi
|_ day=doss
++ heck :: report event
|= [nam=@tas day=doss]
^- day
=+ lam=(~(get by hit.day) nam)
day(hit (~(put by hit.day) ?~(lam 1 +(u.lam))))
::
++ noon :: sample trace
|= pax=path
=| lax=(unit span)
|- ^- day
?~ pax day(sap +(sap.day))
%= $
pax t.pax
lax `i.pax
cut.day
%+ ~(put by cut.day) i.pax
^- hump
=+ nax=`(unit span)`?~(t.pax ~ `i.t.pax)
=+ hup=`hump`=+(hup=(~(get by cut) i.pax) ?^(hup u.hup [0 ~ ~]))
:+ +(sap.hup)
?~ lax inn.hup
=+(hag=(~(get by inn.hup) u.lax) ?~(hag 1 +(u.hag)))
?~ nax out.hup
=+(hag=(~(get by out.hup) u.nax) ?~(hag 1 +(u.hag)))
==
::
++ tell :: produce dump
^- (list tape)
;: welp
^- (list tape)
[(welp "events: " (scow %ud sap.day)) ~]
::
^- (list tape)
%+ turn
(~(tap by hit.day) ~)
|= [nam=term num=@ud]
:(welp (trip nam) ": " (scow %ud num))
["" ~]
::
^- (list tape)
%- welp
%+ turn
(~(tap by cut.day) ~)
|= [nam=term hup=hump]
^- (list tape)
;: welp
[(welp "sector: " (trip nam)) ~]
::
[(welp "weight: " (div (mul 1.000 sap.hup) sap.day)) ~]
::
["inn:" ~]
::
%+ turn
(~(tap by inn.hup) ~)
|= [nam=term num=@ud]
^- tape
:(welp " " (trip nam) ": " (scow %ud num))
::
["out:" ~]
::
%+ turn
(~(tap by out.hup) ~)
|= [nam=term num=@ud]
^- tape
:(welp " " (trip nam) ": " (scow %ud num))
==
==
--
--