Merge remote-tracking branch 'origin/master' into typedclay

Conflicts:
	urb/urbit.pill
	urb/zod/arvo/eyre.hoon
	urb/zod/arvo/hoon.hoon
	urb/zod/arvo/zuse.hoon
	urb/zod/main/app/poke/core.hook
	urb/zod/main/app/reboot/core.hook
	urb/zod/main/app/shell/core.hook
	urb/zod/main/app/tree/core.hook
This commit is contained in:
Philip C Monk 2015-03-05 18:27:07 -05:00
commit 31d3788115
303 changed files with 73931 additions and 597 deletions

View File

@ -440,7 +440,7 @@
vix=(bex +((cut 0 [25 2] mag))) :: width of sender
tay=(cut 0 [27 5] mag) :: message type
==
?> =(0 vez)
?> =(2 vez)
?> =(chk (end 0 20 (mug bod)))
:+ [(end 3 wix bod) (cut 3 [wix vix] bod)]
(kins tay)
@ -460,7 +460,7 @@
=+ tay=(ksin q.kec)
%+ mix
%+ can 0
:~ [3 0]
:~ [3 2]
[20 (mug bod)]
[2 yax]
[2 qax]
@ -1043,7 +1043,7 @@
++ gnaw :: gnaw:am
|= [kay=cape ryn=lane pac=rock] :: process packet
^- [p=(list boon) q=fort]
?. =(0 (end 0 3 pac)) [~ fox]
?. =(2 (end 0 3 pac)) [~ fox]
=+ kec=(bite pac)
?: (goop p.p.kec) [~ fox]
?. (~(has by urb.ton.fox) q.p.kec)
@ -1704,9 +1704,12 @@
=+ neh=(claw p.p.bon)
?> ?=(^ neh)
?: ?=(%e ven)
?> |(=(%pr cak) =(%pc cak))
:_ [%sick %wart p.bon cak `path`t.t.t.q.q.bon r.bon]
[[%e `path`t.t.t.q.q.bon] hen]
?+ cak !! :: XX fix eyre
%pr :_ [%sick %waft p.bon r.bon]
[[`path`t.t.t.q.q.bon] hen]
%pc :_ [%sick %wart p.bon cak `path`t.t.t.q.q.bon r.bon]
[[%e `path`t.t.t.q.q.bon] hen]
==
=+ ton=[%waft p.bon r.bon]
:: ~& [%milk-waft [[ven `path`t.t.t.q.q.bon] t.neh]]
:_ [%sick ton]
@ -1768,6 +1771,7 @@
:~ :- (claw p.p.bon)
[%sick %wart p.bon i.t.q.q.bon t.t.q.q.bon r.bon]
==
::
%ge :: %gall request
=* imp t.t.q.q.bon
?> (levy imp (sane %ta))
@ -1776,6 +1780,7 @@
(scot %p q.p.bon)
q.q.bon
:_ fox [hen %pass pax %g %rote p.bon imp r.bon]~
::
%gh :: %gall response
=* imp t.t.q.q.bon
?> (levy imp (sane %ta))

View File

@ -2144,6 +2144,12 @@
[-.zot (posh her syd +.zot ruf)]
[mos ..^$]
==
::
%mere
~& ?: ?=(%& -.p.+.q.hin)
['merge succeeded' p.p.+.q.hin]
['merge failed' p.p.p.+.q.hin]
[~ ..^$]
::
%waft
?> ?=([@ @ ~] tea)

View File

@ -51,6 +51,7 @@
$% [%mess p=[p=ship q=path] q=ship r=mess] ::
[%nuke p=[p=ship q=path] q=ship] ::
[%show p=[p=ship q=path] q=ship r=path] ::
[%took p=[p=ship q=path] q=ship] ::
== == ::
$: %t ::
$% [%wait p=@da] ::
@ -65,15 +66,9 @@
$% [%logo p=@] ::
[%mean p=ares] ::
[%nice ~] ::
$: %rush :: XX
$: %rush ::
$% [%term-line q=term-line] ::
[%hymn q=manx] ::
[%json q=json] ::
== == ::
$: %rust ::
$% [%term-line q=term-line] ::
[%hymn q=manx] ::
[%json q=json] ::
== == ::
[%verb ~] ::
[%sage p=path q=*] ::
@ -322,9 +317,10 @@
%nice +>.$
%note ?.(p.yar +>.$ (fume p.+.sih q.+.sih)) :: debug message
?(%rush %rust) :: XX reset prompt
=. mos :_(mos [hen %pass tea %g %took [our /terminal] our])
?> ?=(%term-line +>-.sih)
=. +>.$
=+ lis=?-(-.+.sih %rust (scag 1.000 r.q.sih), %rush r.q.sih)
=+ lis=(scag 1.000 r.q.sih)
=- (furl (zing (turn (flop lis) -)))
|= a=tark
^- wall
@ -333,16 +329,19 @@
?: =(q.s.yar p.a) ~
~[(welp ~(ram re q.a) ~(ram re r.a))]
==
?. (levy r.q.sih |=(a=tark ?=(%stem -.a)))
+>.$ :: XX separate prompt/history messages
%- edit
=| bed=bein
=+ ^= hyt ^- hist
=+ hyt=(~(get by r.yar) /)
?~(hyt *hist u.hyt)
?: &(?=(^ q.q.yar) =(/ hux.u.q.q.yar))
=+ bun=(rip 5 (turf r.p.q.sih))
%= u.q.q.yar
bul ?~ r.p.q.sih bul.u.q.q.yar (met 3 r.p.q.sih)
bus ?~ r.p.q.sih bus.u.q.q.yar (met 3 r.p.q.sih)
but ?~ r.p.q.sih but.u.q.q.yar (rip 3 r.p.q.sih)
bul ?~ r.p.q.sih bul.u.q.q.yar (lent bun)
bus ?~ r.p.q.sih bus.u.q.q.yar (lent bun)
but ?~ r.p.q.sih but.u.q.q.yar bun
hyt [+(p.hyt) [%$ q.hyt]]
pot (trip p.p.q.sih)
pol (met 3 p.p.q.sih)

View File

@ -46,6 +46,7 @@
$% [%mess p=hapt q=ship r=cage] ::
[%nuke p=hapt q=ship] ::
[%show p=hapt q=ship r=path] ::
[%took p=hapt q=ship] ::
== == ::
$: %t :: to %temp
$% [%wait p=@da] ::
@ -400,13 +401,17 @@
?: ?=(%mess i.mab)
(hear:woy ~ %& %json !>(jon))
=+ can=(slav %ud i.t.mab)
=+ sem=(need (~(get by can.sub.siq:beat:u.ouy) can))
(soon %& sem u.ouy can %show ?.(?=(%show i.mab) jon (wrap sem jon)))
=+ sem=(~(get by can.sub.siq:beat:u.ouy) can)
?~ sem :: XX shouldn't occur
u.ouy
(soon %& u.sem u.ouy can %show ?.(?=(%show i.mab) jon (wrap u.sem jon)))
::
?(%rust %rush)
?> ?=(%show i.mab)
=+ can=(slav %ud i.t.mab)
=+ sem=(need (~(get by can.sub.siq:beat:u.ouy) can))
=. mow.u.ouy
:_(mow.u.ouy [hen %pass tea [%g %took [- + ~]:hap.sem you.u.ouy]])
?: =(0 can)
=< abet =< work =< abet
?~ num.sem
@ -537,6 +542,7 @@
q.ask (~(del by q.ask) sud)
kes (~(del by kes) hen)
==
:: ~& eyre-them/(earn p.u.p.kyz)
%= +>.$
mow :_(mow [ged [%give %thus p.ask p.kyz]])
p.ask +(p.ask)
@ -546,6 +552,7 @@
::
%they :: inbound response
=+ kas=(need (~(get by q.ask) p.kyz))
:: ~& > eyre-they/[p.q.kyz (earn p.q.kas)]
%= +>.$
mow :_(mow [p.kas [%give %thou q.kyz]])
q.ask (~(del by q.ask) p.kas)
@ -867,7 +874,7 @@
[~ u=~(. ya [our ses] u.suf u.cuz)]
::
++ noon :: login page
|= [our=ship ses=hole whu=(unit ship) rul=tape ruf=tape]
|= [our=ship ses=hole whu=(unit ship) rul=tape]
^- manx
=+ ^= sic ^- manx
;script:'''
@ -913,9 +920,9 @@
delete all.pas;
console.log('redirect')
window.location= // "http://"+seal.who+".urbit.org/gul?"
"http://0:8445/gul?"
+ $.param(all);
window.location=
"http://"+seal.who+".urbit.org/gul?"
+ $.param(all);
return false;
}
@ -938,7 +945,7 @@
$output.html(output.replace(
'sorry. please try again.<br>',''))
$.post(form, seal, function(data,xhr,status) {
$.post("/pul", seal, function(data,xhr,status) {
console.log(data);
if(data.ok == true) {
document.location = data.next;
@ -990,7 +997,6 @@
; var host = '{(trip (rsh 3 1 (scot %p our)))}';
; var goal = '{?~(whu ~ (trip (rsh 3 1 (scot %p u.whu))))}';
; var burl = '{rul}';
; var form = '{ruf}';
; var sesh = '{(trip ses)}';
==
=> .(+.sic (weld `marl`cof `marl`+.sic))
@ -1592,8 +1598,8 @@
:+ ~
%red
:: :+ [p.p.pul q.p.pul r.p.pul]
:+ [| q.p.pul r.p.pul] :: XX https
[~ /gul]
:+ [| q.p.pul r.p.pul] :: XX https
[p.q.pul /gul] :: XX js discrimination
:- [%url (crip (earn pul(p.p |)))]
?~ whu ~
[%who (rsh 3 1 (scot %p u.whu))]~
@ -1792,6 +1798,12 @@
++ lash :: user is authorized
|=(a=ship (~(has ju aut.ced) %$ (scot %p a)))
::
++ redi :: js login redirect
|= pul=purl ^- tape
"window.location = '{(earn pul)}".
"{?~(r.pul "?" "&")}url=' +".
"encodeURIComponent(window.location)"
::
++ step :: step in work
|- ^+ +
=^ zib +.$
@ -1888,10 +1900,9 @@
?: wit.p.som.pip
[~ pip(pez [%who %$ (scot %p (need whu.p.som.pip))])]
=+ rul=(earn pul.p.som.pip)
=+ ruf=(earn (erle our pul.p.som.pip(q.q /pul, r ~)))
=+ sus=?~(foy.p.som.pip ses q.u.foy.p.som.pip)
~& auth-request/secret=`cord`lass
=+ ham=(noon our sus whu.p.som.pip rul ruf)
=+ ham=(noon our sus whu.p.som.pip rul)
[~ pip(pez [%fin %ham ham])]
?. =(lass u.pus.p.som.pip)
:_ +>.$
@ -1928,9 +1939,13 @@
%= pip
pez
:- %fin
=+ pul=p.som.pip
?: ?=([~ %js] p.q.pul) :: XX js discrimination
[%mid /application/javascript (tact (redi pul(p.q ~)))]
=. p.q.pul ~
:- %raw
:+ 307
[%location (crip (earn p.som.pip))]~
[%location (crip (earn pul))]~
~
==
::
@ -2053,7 +2068,7 @@
|= nap=@ud
=+ suy=(~(get by sok) nap)
?~ suy ~
(some ~(. yo nap u.suy))
(some ~(. yo nap=nap you=p.u.suy siq=q.u.suy))
::
++ yo :: app instance
|_ $: nap=@ud :: instance number
@ -2160,7 +2175,7 @@
^- [(unit pimp) _+>]
=. +>.$
%- ~(rep by can.sub.siq)
|= [p=[p=@ud q=stem] q=_+>.$]
=+ [*p=[p=@ud q=stem] q=+>.$] |.
?. =([hap pax] [hap.q.p pax.q.p]) q
=. q q(can.sub.siq (~(del by can.sub.siq:q) p.p))
([-(hen +)]:[pass:q hen.q.p] `p.p %g %nuke [- + ~]:hap you)

View File

@ -37,7 +37,7 @@
[%dub p=term q=horn] :: /= apply face
[%fan p=(list horn)] :: /. list
[%for p=path q=horn] :: /, descend
[%hel p=horn] :: /% propogate heel
[%hel p=@ud q=horn] :: /% propogate heel
[%hub p=horn] :: /@ list by @ud
[%man p=(map span horn)] :: /* hetero map
[%nap p=horn] :: /_ homo map
@ -569,7 +569,7 @@
(stag %dub ;~(pfix tis dub:read))
(stag %fan ;~(pfix dot fan:read))
(stag %for ;~(pfix com for:read))
(stag %hel ;~(pfix cen day:read))
(stag %hel ;~(pfix cen hel:read))
(stag %hub ;~(pfix pat day:read))
(stag %man ;~(pfix tar man:read))
(stag %nap ;~(pfix cab day:read))
@ -609,6 +609,11 @@
%+ rail
;~(plug (ifix [sel ser] hath) apex(tol |))
;~(pfix gap ;~(plug hath ;~(pfix gap apex)))
::
++ hel
%+ rail
;~(plug ;~(pose ;~(sfix dem:ag cen) (easy 0)) apex(tol |))
;~(pfix gap ;~(plug ;~(pose ;~(sfix dem:ag gap) (easy 0)) apex))
::
++ man
%+ rail fail
@ -966,7 +971,7 @@
(fine cof `gage`[p.kas vax])
::
%call
%+ cool |.(leaf/"ford: call {<`@p`(mug kas)>}")
:: %+ cool |.(leaf/"ford: call {<`@p`(mug kas)>}")
%. [cof p.kas q.kas]
;~ cope
;~ coax
@ -1176,7 +1181,7 @@
|- ^- vase
?~ doy [[%cube 0 [%atom %n]] 0]
%+ slop
(slop [[%atom %a] p.n.doy] q.n.doy)
(slop [[%atom %ta] p.n.doy] q.n.doy)
(slop $(doy l.doy) $(doy r.doy))
::
++ chap :: produce resources
@ -1211,7 +1216,12 @@
(slop i.tev $(tev t.tev))
::
%for $(hon q.hon, s.how (weld (flop p.hon) s.how))
%hel $(hon p.hon, arg /, s.how (weld arg s.how))
%hel
%= $
hon q.hon
arg (scag p.hon arg)
s.how (weld (slag p.hon arg) s.how)
==
%hub (chad cof bax %ud p.hon)
%man
|- ^- (bolt vase)

View File

@ -31,6 +31,7 @@
[%nuke p=hapt q=ship] :: clear duct
[%rote p=sack q=path r=*] :: remote request
[%roth p=sack q=path r=*] :: remote response
[%took p=hapt q=ship] :: remote acknowledge
[%wipe p=hapt] :: forget app
== ::
++ knob :: pending action
@ -45,6 +46,8 @@
[%sire p=term q=span] :: spawn subprocess
[%nuke p=ship] :: clear duct
[%take p=path q=vase] :: user result
[%took p=ship] :: rush queue drained
[%told p=ship] :: rush queue filled
== ::
++ mast :: apps by ship
$: hun=duct :: control duct
@ -67,6 +70,7 @@
[%sire p=term q=hapt] ::
[%mess p=hapt q=ship r=cage] ::
[%nuke p=hapt q=ship] ::
[%took p=hapt q=ship] ::
== == ::
$: @tas :: to any
$% [%meta p=vase] ::
@ -87,9 +91,9 @@
r=(map bone duct) :: by bone
== ::
++ roon :: foreign response
$% [%d p=mark q=*] :: diff
$% [%d p=mark q=*] :: diff (rush)
[%e p=ares] :: error
[%f p=mark q=*] :: full refresh
[%f p=mark q=*] :: full refresh (rust)
[%k ~] :: message response
== ::
++ rook :: foreign request
@ -99,20 +103,24 @@
== ::
++ seat :: the living app
$: app=term :: app name
huv=(unit vase) :: application vase
qic=(unit toil) :: current project
onz=(unit (pair duct path)) :: live fords
vey=(qeu toil) :: pending projects
$: huv=(unit vase) :: application vase
qic=(unit toil) :: current project
onz=(unit (pair duct path)) :: live fords
vey=(qeu toil) :: pending projects
== ::
nuc=(set duct) :: nuked ducts
tik=@ud :: build number
act=@ud :: action number
lat=@da :: last change
orm=(unit ,@da) :: build date
$: tik=@ud :: build number
act=@ud :: action number
lat=@da :: last change
orm=(unit ,@da) :: build date
== ::
mom=(unit duct) :: parent duct
cub=(map span term) :: offspring
sup=(map bone (pair ship path)) :: subscribers
pus=(jug path bone) :: srebircsbus
peq=(map bone ,@uvI) :: peekers
$: sup=(map bone (pair ship path)) :: subscribers
pus=(jug path bone) :: srebircsbus
peq=(map bone ,@uvI) :: peekers
qel=(map bone ,@ud) :: rush queue length
== ::
ped=(set (pair ship desk)) :: active depends
zam=scar :: opaque ducts
== ::
@ -194,7 +202,9 @@
++ lump :: position
|= pax=path
^- [p=hapt q=path]
?> ?=([@ @ *] pax)
?. ?=([@ @ *] pax)
~& [%lump-path-bad pax]
!!
:- :- (slav %p i.pax)
(need (pick i.t.pax))
t.t.pax
@ -213,17 +223,21 @@
?- -.q.hic
%init
[p=~ q=..^$(pol.all (~(put by pol.all) p.q.hic hen ~ ~))]
::
%rote
(gawk hen p.q.hic q.q.hic ((hard ,[@ud rook]) r.q.hic))
::
%roth
(gawd hen p.q.hic q.q.hic ((hard ,[@ud roon]) r.q.hic))
::
%wipe
=+ mat=(~(got by pol.all) p.p.q.hic)
~? !(~(has by bum.mat) q.p.q.hic) [%wipe-lost q.p.q.hic]
=. bum.mat (~(del by bum.mat) q.p.q.hic)
=. pol.all (~(put by pol.all) p.p.q.hic mat)
[p=~ q=..^$]
?(%mess %show %nuke %sire)
::
?(%mess %show %nuke %took %sire)
|- ^- [p=(list move) q=_..^^$]
=+ =| law=(unit cuff)
|- ^- $: law=(unit cuff)
@ -236,6 +250,7 @@
%mess [p %mess q r]:q.hic
%show [p %show q r]:q.hic
%nuke [p %nuke q]:q.hic
%took [p %took q]:q.hic
%sire [[p.q +.q.q] %sire p -.q.q]:q.hic
==
((goad hen law) p.hap q.hap kon)
@ -246,6 +261,7 @@
^- [p=(list move) q=_..^$]
?: ?=(%crud +<.q.hin)
~& [%gall-crud-error pax hen]
~& [%gall-crud-data (,[@tas (list tank)] +>.q.hin)]
?> ?=(%g -.q.hin)
?~ pax ~& %strange-path [~ ..^$]
=+ lum=(lump t.pax)
@ -341,7 +357,10 @@
|= [hen=duct law=(unit cuff)]
|= [our=@p imp=path kon=knob]
^- [(list move) _..^^$]
?> ?=(?(%mess %show %nuke) -.kon)
?> ?=(?(%mess %show %nuke %took) -.kon)
?: ?=(%took -.kon)
:: ~& [%gape-took our imp hen]
[~ ..^^$]
=+ you=`ship`?-(-.kon %mess p.kon, %nuke p.kon, %show p.kon)
=+ mat=(~(got by pol.all) you)
=+ sad==+(sad=(~(get by sap.mat) our) ?^(sad u.sad [.(p 1)]:*scad))
@ -383,6 +402,7 @@
?~ q.sih
[hen %give %nice ~]
[hen %give %mean u.q.sih]
::
%f
:_ ..^$
:_ ~
@ -409,6 +429,7 @@
num=(slav %ud i.t.t.t.pax)
imp=`path`t.t.t.t.pax
==
:: ~& [%gall-gave hen -.pax [our you num imp]]
:_ ..^$
=+ rod=|=(ron=roon `note`[%a %wont [our you] [%q %gh imp] num ron])
?+ -.pax !!
@ -441,7 +462,8 @@
==
==
%s ?+ -.sih !!
%a ~
%a :_ ~ :- hen
[%pass [%r pax] %g %took [our imp] you]
%g
:_ ~ :- hen
?- -.+.sih
@ -453,7 +475,8 @@
%mean [%pass [%r pax] (rod %e p.+.sih)]
%nice [%give %nice ~]
%rush [%pass [%r pax] (rod %d p.+.sih q.+.sih)]
%rust [%pass [%r pax] (rod %f p.+.sih q.+.sih)]
%rust :: ~& [%gave-rust [our you num imp] hen]
[%pass [%r pax] (rod %f p.+.sih q.+.sih)]
%sage !!
%verb !!
%veer !!
@ -523,6 +546,8 @@
^- [(list move) _..^^$]
=+ mut=(~(get by pol.all) our)
?^ mut
?: &(?=([@ @ *] imp) !(~(has by bum.u.mut) imp)) :: %took for dead imps
[~ ..^^$]
abet:work:(quem:(boar:(gent our imp u.mut) hen law) kon)
((gape hen law) our imp kon)
::
@ -649,7 +674,8 @@
::
++ blow
^+ .
=> (give %nice ~)
:: ~& [%gall-blow ost]
=> (give %mean ~)
=+ pax=+:(fall (~(get by sup.sat) ost) *[ship path])
%= +
qic.sat ~
@ -669,6 +695,7 @@
:_ ~
:- [%$ 12]~
(cave !>([[our app.sat imp] cub.sat sup.sat pus.sat [act.sat eny now]]))
::
++ core |=(vax=vase (cove %core vax)) :: core as silk
++ cove :: cage as silk
|= cay=cage
@ -676,20 +703,7 @@
[%done ~ cay]
::
++ deal :: reboot
^+ .
=. tik.sat +(tik.sat)
=+ pys=(~(tap by sup.sat) ~)
:: ~& [%gall-deal tik.sat pys]
|- ^+ +>.$
?~ pys +>.$
=. +>.$ $(pys t.pys)
%_ +>.$
mow
:_ mow
:+ (able p.i.pys)
%slip
[%g %show [our imp] q.i.pys]
==
.(tik.sat +(tik.sat))
::
++ deff
|= [wir=wire hon=duct caq=vase]
@ -700,8 +714,8 @@
::
++ drug :: set dependencies
|= pen=(set (pair ship desk))
:: ~& [%drug %pen pen]
:: ~& [%drug %ped ped.sat]
:: ~& [%drug ped=ped.sat]
:: ~& [%drug pen=pen]
^+ +>
=+ ^= new ^- (list move)
%+ turn
@ -710,7 +724,7 @@
|= a=(pair ship desk)
:- hun.mat
:^ %pass (away %w %drug (scot %p p.a) q.a ~) %c
::~& [%sync-subscribe our p.a q.a]
:: ~& [%sync-subscribe our p.a q.a]
[%warp [our p.a] q.a ~ %| [%da +(now)] [%da (add now ~d1000)] /]
=+ ^= old ^- (list move)
%+ turn
@ -947,6 +961,10 @@
|= vax=vase
^+ +>
=+ new=?~(huv.sat & !=(+<+.q.vax +<+.q.u.huv.sat))
:: ?. ?=(%core -.p.vax)
:: ~| [%morn-not-core -.p.vax app.sat imp]
:: ~> %mean.|.((skol p.vax))
:: !!
=. huv.sat `vax
?. new +>.$
=: act.sat +(act.sat)
@ -989,14 +1007,32 @@
=+ yov=(~(tap by vey.sat) ~) :: XX ++pun
+>.$(vey.sat (~(gas to *(qeu toil)) `_yov`[[hen kon] yov]))
::
++ said
++ said :: sayz, done wrong
|= vud=vase
|- ^- [(list toil) (list move)]
?: =(~ q.vud) [~ mow]
=- [p.fob (weld (flop q.fob) mow)]
^= fob
|- ^- (pair (list toil) (list move))
?: =(~ q.vud) [~ ~]
=+ sud=(sump (slot 2 vud))
=+ res=$(vud (slot 3 vud))
:- ?~(-.sud -.res [u.-.sud -.res])
?~(+.sud +.res [u.+.sud +.res])
:- ?~ -.sud
-.res
[u.-.sud -.res]
?~ +.sud
+.res
[u.+.sud +.res]
::
++ sayz :: dissect app moves
|= vud=vase
=| toy=(list toil)
|- ^- [(list toil) (list move)]
?: =(~ q.vud) [toy mow]
=+ sud=(sump (slot 2 vud))
%= $
vud (slot 3 vud)
toy ?~(-.sud toy [u.-.sud toy])
mow ?~(+.sud mow [u.+.sud mow])
==
::
++ show :: subscribe
|= [you=ship pax=path] :: subscription
@ -1028,7 +1064,13 @@
?: ?=(%mean p.p.q.caq)
:- `[hon %nuke our]
`[hon %give %mean (ares q.p.q.caq)]
:^ ~ ~ hon
:- ?. ?| ?=(?(%rush %rust) p.p.q.caq)
?& ?=(%meta p.p.q.caq)
?=([* ?(%rush %rust) *] q.p.q.caq)
== ==
~
`[hon %told our]
:+ ~ hon
:- %give
?: ?=(%nice p.p.q.caq) [%nice ~]
(sumo (spec (slot 3 caq)))
@ -1105,6 +1147,31 @@
::
%feel
+>.$(qic.sat ~)
::
%took
=+ qol=(~(get by qel.sat) ost)
:: ~& [%yawn-took-has ost qol [our hen]]
%= +>.$
qic.sat ~
qel.sat
?~ qol
:: ~& [%took-underflow our hen]
qel.sat
?: =(`1 qol)
(~(del by qel.sat) ost)
(~(put by qel.sat) ost (dec u.qol))
==
::
%told
=+ qol=(~(get by qel.sat) ost)
:: ~& [%yawn-told-has ost qol [our hen]]
=+ qul=?~(qol 1 +(u.qol))
=. qel.sat (~(put by qel.sat) ost qul)
:: XX turn me back on!
:: ?: =(10 qul)
:: ~& [%yawn-told-full ost our hen]
:: +>.$(qic.sat ~, vey.sat (~(put to vey.sat) hen %nuke p.kon))
+>.$(qic.sat ~)
::
%load
=+ [hom=(slot 2 q.p.kon) old=(slot 3 q.p.kon)]
@ -1130,7 +1197,7 @@
::
%mess
=+ ^- cog=term
=- |- ?~ goz %poke
=- |- ?~ goz ?:((warm %pock) %pock %poke)
?: (warm i.goz) i.goz
$(goz t.goz)
^- goz=(list term)
@ -1161,6 +1228,7 @@
[%call (harm cog (conf (core u.huv.sat))) (cove %$ sam)]
::
%show
:: ~& showing/[app.sat imp q.kon]
?: (warm %peer)
=+ sam=!>([ost p.kon q.kon])
?> ?=(^ huv.sat)
@ -1193,6 +1261,17 @@
(xeno [q.kon imp] %feel ~)
::
%take
?: ?& ?=([%g %rush @ *] q.q.kon)
|((warm %posh) (warm (cat 3 'posh-' &3.q.q.kon)))
==
?> ?=(^ huv.sat)
=+ [goc gil]=[(cat 3 'posh-' &3.q.q.kon) (spec (slot 7 q.kon))]
=. - ?:((warm goc) [goc (slot 3 gil)] [%posh gil])
=+ sam=:(slop [[%atom %ud] ost] !>(p.kon) gil)
%+ ford /s/pour
:+ %dude leaf/"pouring"
:+ %dude (skol p.gil)
[%call (harm goc (conf (core u.huv.sat))) (cove %$ sam)]
?: (warm %purr)
?> ?=(^ huv.sat)
=+ sam=:(slop [[%atom %ud] ost] !>(p.kon) !>(p.q.kon) q.kon)

View File

@ -9,13 +9,13 @@
(make:all cud) :: else simple compile
^= all :: assemble engine
=~ :: volume stack
%164 :: version constant
%163 :: version constant
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::: :::::: volume 0, version stub ::::::
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
~% %k.164 ~ ~ ::
~% %k.163 ~ ~ ::
|% ::
++ hoon %164 :: version stub
++ hoon %163 :: version stub
-- ::
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
:::::: :::::: volume 1, Hoon models ::::::
@ -272,7 +272,7 @@
[%smdt p=twig q=tusk] ::
[%smdq p=(list beer)] :: assemble string
[%smsg p=twig q=tusk] :: gonads
[%smsm p=twig q=twig] :: make sure q is a p
[%smsm p=tile q=twig] :: make sure q is a p
:: :::::: compositions
[%tsbr p=tile q=twig] :: push bunt: =+(_p q)
[%tscl p=tram q=twig] :: p changes, then q
@ -401,7 +401,7 @@
++ wall (list tape) :: text lines (no \n)
++ wain (list cord) :: text lines (no \n)
++ wing (list limb) ::
++ wine $| ?(%noun %path %tank %void %wall %wool %yarn)
++ wine $| ?(%noun %path %type %void %wall %wool %yarn)
$% [%atom p=term] ::
[%core p=(list ,@ta) q=wine] ::
[%face p=term q=wine] ::
@ -1927,6 +1927,7 @@
+- uni :: union
~/ %uni
|* b=_a
?: =(a b) a
|- ^+ a
?~ b
a
@ -3326,7 +3327,7 @@
::
%f
?: =(& q.p.lot)
['.' 'm' 'o' 's' 't' 'a' 's' 's' 'u' 'r' 'r' 'e' 'd' 'l' 'y' rex]
['.' 'y' rex]
?:(=(| q.p.lot) ['.' 'n' rex] (z-co q.p.lot))
::
%n ['~' rex]
@ -3652,9 +3653,9 @@
|= pax=path ^- tape
=- ~(ram re %rose ["/" "/" ~] -)
(turn pax |=(a=span [%leaf (trip a)]))
++ stab :: parse span to path
|= zep=@ta ^- path
(rash zep ;~(pfix fas (more fas urs:ab)))
++ stab :: parse cord to path
=+ fel=;~(pfix fas (more fas urs:ab))
|=(zep=@t `path`(rash zep fel))
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:: section 2eM, regular-expressions ::
::
@ -6662,7 +6663,8 @@
::
[%smsm *] :: ;;
:+ %tsgr [%ktts %v ~ 1] :: => v=.
:+ %tsls [%ktts %a [%tsgr [%cnzy %v] p.gen]] :: =+ a==>(v {p.gen})
:+ %tsls :+ %ktts %a :: =+ ^= a
[%tsgr [%cnzy %v] [%bccm p.gen]] :: =>(v ,{p.gen})
:+ %tsls [%ktts %b [%tsgr [%cnzy %v] q.gen]] :: =+ b==>(v {q.gen})
:+ %tsls :: =+ c=(a b)
[%ktts %c [%cnhp [%cnzy %a] [%cnzy %b] ~]] ::
@ -7011,7 +7013,7 @@
?- q.ham
%noun [%leaf '*' ~]
%path [%leaf '/' ~]
%tank [%leaf '*' 't' ~]
%type [%leaf '#' 't' ~]
%void [%leaf '#' ~]
%wool [%leaf '*' '"' '"' ~]
%wall [%leaf '*' '\'' '\'' ~]
@ -7089,9 +7091,13 @@
?> ?=(@ -.lum)
[[%leaf (rip 3 -.lum)] $(lum +.lum)]
::
%tank
=+ cis=(tank lum)
?.(=(lum cis) ~ [~ cis])
%type
=+ reb=(slap [p:!>(.) .(sut lum)] %cnzy %duck)
=+ cis=(tank q.reb)
?. =(cis q.reb) ~
:^ ~ %palm
[~ ~ ~ ~]
[[%leaf '#' 't' '/' ~] cis ~]
::
%wall
:- ~
@ -7358,6 +7364,8 @@
[p.yad [%face p.sut q.yad]]
::
[%fork *]
?: =(p.sut fork/[cube/[%noun atom/%tas]]^[cube/[%void atom/%tas]])
[dex %type] :: XX proper print
=+ hin=$(sut p.sut)
=+ yon=$(dex p.hin, sut q.sut)
:- p.yon
@ -8946,7 +8954,7 @@
=+ rev=(plex b)
?~ rev ~
%- some
:+ %smsm ~(clam al a)
:+ %smsm a
[%dtkt %dtzz %$ %cx u.rev]
;~(plug hill rood)
==
@ -9194,7 +9202,7 @@
:~ [':' (rune col %smcl expi)]
['.' (rune dot %smdt expi)]
['~' (rune sig %smsg expi)]
[';' (rune sem %smsm expb)]
[';' (rune sem %smsm expo)]
==
==
:- '='
@ -9846,6 +9854,7 @@
=+ rig=(slym q.sew arg)
=+ rev=(slym (slap bud (rain pax txt)) bud)
=+ syg=(slym rev arg)
~| %load-lost
+>.$(q.sew (slam (slap syg [%cnzy %load]) (slap rig [%cnzy %stay])))
::
++ wink :: deploy
@ -10142,7 +10151,7 @@
++ jack :: dispatch card
|= [lac=? gum=muse]
^- [[p=(list ovum) q=(list muse)] _niz]
=. lac |(lac ?=(?(%g %f) p.gum))
:: =. lac |(lac ?=(?(%g %f) p.gum))
%+ fire
p.gum
?- -.r.gum

View File

@ -525,7 +525,7 @@
==
::
++ poja :: parse JSON
=< |=(a=cord (rush a apex))
=< |=(a=cord `(unit json)`(rush a apex))
|%
++ apex :: JSON value
%+ knee *json |. ~+
@ -2005,7 +2005,8 @@
^- miso
=+ dir=((hard arch) .^(%cy pax))
?~ q.dir [%ins val]
[%mut ((hard cage) .^(%cx pax)) val]
=+ for=((hard mark) -:(flop pax))
[%mut [for [%atom %$] .^(%cx pax)] val]
::
++ file :: simple file load
|= pax=path
@ -2083,12 +2084,13 @@
[~ ~]
?^ t.rax
[p.pok [i.rax q.pok]]:[pok=$(rax t.rax) .]
=+ ^- raf=(unit ,[p=term q=(unit term)])
%+ rush i.rax
;~(plug sym ;~((bend) (easy ~) ;~(pfix dot sym)))
?~ raf
=+ ^- raf=(like tape)
%. [1^1 (flop (trip i.rax))]
;~(sfix (plus ;~(less dot next)) dot)
?~ q.raf
[~ [i.rax ~]]
[q.u.raf [p.u.raf ~]]
=+ `[ext=tape [@ @] fyl=tape]`u.q.raf
[[~ (crip (flop ext))] [(crip (flop fyl)) ~]]
::
++ fuel :: parse fcgi
|= [bem=beam but=path]
@ -2223,7 +2225,7 @@
--
::
++ epur :: url/header parser
=< |=(a=cord (rush a auri))
=< |=(a=cord `(unit purl)`(rush a auri))
|%
++ apat :: 2396 abs_path
%+ cook deft
@ -2672,8 +2674,8 @@
(turn b |=(c=span (cat 3 '_' (wack c))))
::
++ pick :: light path decoding
|= a=span ^- (unit ,[p=term q=path])
(rush a (most cab (sear wick urt:ab)))
=+ fel=(most cab (sear wick urt:ab))
|=(a=span `(unit ,[p=term q=path])`(rush a fel))
::
++ saxo :: autocanon
|= who=ship
@ -3209,5 +3211,5 @@
[%chan (list $|(@ud [p=@ud q=@ud]))] ::
++ wund (list ,[p=life q=ring r=acru]) :: mace in action
++ will (list deed) :: certificate
++ zuse %314 :: hoon/zuse kelvin
++ zuse %310 :: hoon/zuse kelvin
--

1
docs/psal.hook Normal file
View File

@ -0,0 +1 @@
;list;

16
docs/pub/doc.md Normal file
View File

@ -0,0 +1,16 @@
urbit
=====
is a general-purpose computing stack designed to live in the cloud.
<list dataPreview="true"></list>
`arvo` is event driven and modular. `arvo` modules are called 'vanes'.
<list dataPath="/doc/arvo" dataPreview="true"></list>
------------------------------------------------------------------------
If you're new to the system, take a look at some of the
[guides](doc/guides) to get oriented. Come join us on `:chat` to ask
questions and get help.

146
docs/pub/doc/arvo.md Normal file
View File

@ -0,0 +1,146 @@
arvo
====
arvo is our operating system.
arvo is composed of modules called vanes:
<list dataPreview="true"></list>
<hr></hr>
At a high level `%arvo` takes a mess of unix io events and turns them
into something clean and structured for the programmer.
`%arvo` is designed to avoid the usual state of complex event networks:
event spaghetti. We keep track of every event's cause so that we have a
clear causal chain for every computation. At the bottom of every chain
is a unix io event, such as a network request, terminal input, file
sync, or timer event. We push every step in the path the request takes
onto the chain until we get to the terminal cause of the computation.
Then we use this causal stack to route results back to the caller.
`++ducts`
---------
The `%arvo` causal stack is called a `++duct`. This is represented
simply as a list of paths, where each path represents a step in the
causal chain. The first element in the path is the first letter of
whichever vane handled that step in the computation, or the empty span
for unix.
Here's a duct that was recently observed in the wild:
~[
/g/a/~zod/4_shell_terminal/u/time
/g/a/~zod/shell_terminal/u/child/4/main
/g/a/~zod/terminal/u/txt
/d/term-mess
//term/1
]
This is the duct the timer vane receives when "timer" sample app asks
the timer vane to set a timer. This is also the duct over which the
response is produced at the specified time. Unix sent a terminal
keystroke event (enter), and arvo routed it to %dill(our terminal),
which passed it on to the %gall app terminal, which sent it to shell,
its child, which created a new child (with process id 4), which on
startup asked the timer vane to set a timer.
The timer vane saves this duct, so that when the specified time arrives
and unix sends a wakeup event to the timer vane, it can produce the
response on the same duct. This response is routed to the place we
popped off the top of the duct, i.e. the time app. This app produces the
text "ding", which falls down to the shell, which drops it through to
the terminal. Terminal drops this down to dill, which converts it into
an effect that unix will recognize as a request to print "ding" to the
screen. When dill produces this, the last path in the duct has an
initial element of the empty span, so this is routed to unix, which
applies the effects.
This is a call stack, with a crucial feature: the stack is a first-class
citizen. You can respond over a duct zero, one, or many times. You can
save ducts for later use. There are definitely parallels to Scheme-style
continuations, but simpler and with more structure.
Making Moves
------------
If ducts are a call stack, then how do we make calls and produce
results? Arvo processes "moves" which are a combination of message data
and metadata. There are two types of moves. A `%pass` move is analogous
to a call:
[duct %pass return-path=path vane-name=@tD data=card]
Arvo pushes the return path (preceded by the first letter of the vane
name) onto the duct and sends the given data, a card, to the vane we
specified. Any response will come along the same duct with the path
`return-path`.
A `%give` move is analogous to a return:
[duct %give data=card]
Arvo pops the top path off the duct and sends the given card back to the
caller.
Vanes
-----
As shown above, we use arvo proper to route and control the flow of
moves. However, arvo proper is rarely directly responsible for
processing the event data that directly causes the desired outcome of a
move. This event data is contained within a card, which is simply a
`(pair term noun)`. Instead, arvo proper passes the card off to one of
its vanes, which each present an interface to clients for a particular
well-defined, stable, and general-purpose piece of functionality.
As of this writing, we have seven vanes, which each provide the
following services:
- `%ames` name of both our network and the vane that communicates over
it
- `%clay` version-controlled, referentially- transparent, and global
filesystem
- `%dill` terminal driver. Unix sends keyboard events to `%dill` from
either the console or telnet, and `%dill` produces terminal output.
- `%eyre` http server. Unix sends http messages to `%eyre`, and
`%eyre` produces http messages in response
- `%ford` handles resources and publishing
- `%gall` manages our userspace applications.. `%gall` keeps state and
manages subscribers
- `%time` a simple timer
Cards
-----
Cards are the vane-specific portion of a move. Each vane defines a
protocol for interacting with other vanes (via arvo) by defining four
types of cards: kisses, gifts, notes, and signs.
When one vane is `%pass`ed a card in its `++kiss`, arvo activates the
`++call` gate with the card as its argument. To produce a result, the
vane `%give`s one of the cards defined in its `++gift`. If the vane
needs to request something of another vane, it `%pass`es it a `++note`
card. When that other vane returns a result, arvo activates the `++take`
gate of the initial vane with one of the cards defined in its `++sign`.
In other words, there are only four ways of seeing a move: (1) as a
request seen by the caller, which is a ++note. (2) that same request as
seen by the callee, a `++kiss`. (3) the response to that first request
as seen by the callee, a `++gift`. (4) the response to the first request
as seen by the caller, a `++sign`.
When a `++kiss` card is passed to a vane, arvo calls its `++call` gate,
passing it both the card and its duct. This gate must be defined in
every vane. It produces two things in the following order: a list of
moves and a possibly-modified copy of its context. The moves are used to
interact with other vanes, while the new context allows the vane to save
its state. The next time arvo activates the vane it will have this
context as its subject.
This overview has detailed how to pass a card to a particular vane. To
see the cards each vane can be `%pass`ed as a `++kiss` or return as a
`++gift` (as well as the semantics tied to them), each vane's public
interface is explained in detail in its respective overview.

29
docs/pub/doc/arvo/ames.md Normal file
View File

@ -0,0 +1,29 @@
<div class="short">
`%ames`
=======
`%ames` is our networking protocol.
`%ames` is the name of both our network and the vane that communicates
over it. When Unix receives a packet over the correct UDP port, it pipes
it straight into `%ames` for handling. Also, all packets sent over the
`%ames` network are sent by the `%ames` vane. Apps and vanes may use
`%ames` to directly send messages to other ships. In general, apps use
gall and clay to communicate with other ships rather than using `%ames`
directly, but this isn't a requirement. Of course, gall and clay use
`%ames` behind the scenes to communicate across the network. These are
the only two vanes that use `%ames`.
`%ames` includes several significant components. Although the actual
crypto algorithms are defined in zuse, they're used extensively in
`%ames` for encrypting and decrypting packets. Congestion control and
routing is handled entirely in `%ames`. Finally, the actual `%ames`
protocol itself, including how to route incoming packets to the correct
vane or app, is defined in `%ames`.
</div>
<hr>
</hr>
<list></list>

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,8 @@
<div class="short">
`%arvo`
=======
`%arvo` is our operating system.
</div>

View File

@ -0,0 +1,4 @@
`%arvo` commentary
==================
`%arvo` is our operating system.

27
docs/pub/doc/arvo/clay.md Normal file
View File

@ -0,0 +1,27 @@
<div class="short">
`%clay`
=======
`%clay` is our filesystem.
`%clay` is version-controlled, referentially-transparent, and global.
While this filesystem is stored in `%clay`, it is mirrored to Unix for
convenience. Unix tells `%clay`s whenever a file changes in the Unix
copy of the filesystem so that the change may be applied. `%clay` tells
unix whenever an app or vane changes the filesystem so that the change
can be effected in Unix. Apps and vanes may use `%clay` to write to the
filesystem, query it, and subscribe to changes in it. Ford and gall use
`%clay` to serve up apps and web pages.
`%clay` includes three components. First is the filesystem/version
control algorithms, which are mostly defined in `++ze` and `++zu` in
zuse. Second is the write, query, and subscription logic. Finally, there
is the logic for communicating requests to, and receiving requests from,
foreign ships.
</div>
------------------------------------------------------------------------
<list></list>

File diff suppressed because it is too large Load Diff

27
docs/pub/doc/arvo/dill.md Normal file
View File

@ -0,0 +1,27 @@
<div class="short">
`%dill`
=======
`%dill` is our terminal driver.
Unix sends keyboard events to `%dill` from either the console or telnet,
and `%dill` produces terminal output. The only app that should directly
talk to `%dill` is the terminal app. Command-line apps are run by,
receive input from, and produce output to, the `%shell` app, which is
controlled by `%terminal`, which talks to `%dill`, which talks to unix.
Clay also uses `%dill` directly to print out the filesystem change
events, but this is questionable behavior.
`%dill` has two main components. First, it controls the terminal on a
very basic, event-by-event level. This includes keeping track of things
like the dimensions of the terminal, the prompt type (plain text or
password), which duct to produce effects on, and so forth. Second, it
handles terminal events, keystroke by keystroke. Most characters are
simply pushed onto the buffer and blitted to the screen, but some
characters, including control-modified keys, arrow keys, etc. require
special handling. Most of the readline functionality is in `%dill`.
</div>
------------------------------------------------------------------------

View File

@ -0,0 +1,5 @@
Dill: Reference
===============
Dill: Commentary
================

58
docs/pub/doc/arvo/eyre.md Normal file
View File

@ -0,0 +1,58 @@
<div class="short">
`%eyre`
=======
`%eyre` is our http server.
Unix sends http messages to `%eyre`, and `%eyre` produces http messages
in response. In general, apps and vanes do not call `%eyre`; rather,
`%eyre` calls apps and vanes. `%eyre` uses `%ford` and `%gall` to
functionally publish pages and facilitate communication with apps.
`%eyre` primarily parses web requests and handles them in a variety of
ways, depending on the control string. Nearly all of these are
essentially stateless, like functional publishing with `%ford`.
Additionally, there's a fairly significant component that handles
`%gall` messaging and subscriptions, which must be stateful.
</div>
------------------------------------------------------------------------
HTTP Methods
============
`GET` `gog` `https://[ship-name].urbit.org/gog/[service]` Owner
requesting a page on her own Urbit. `gig`
`https://[ship-name].urbit.org/gig/[user-name]/[service]` Another user
requesting a page on a foreign Urbit.
`goe`
`https://[ship-name].urbit.org/goe/[service]/[port]/[stream]/[sequence]`
`https://[ship-name].urbit.org/goe/[service]/[port]/[stream]/[sequence].json`
Pulls a specific response to her subscription on her own Urbit. `gie`
`https://[ship-name].urbit.org/gie/[user-name]/[service]/[port]/[stream]/[sequence]`
`https://[ship-name].urbit.org/gie/[user-name]/[service]/[port]/[stream]/[sequence].json`
Pulls a specific response to her subscription on a foreign Urbit.
`PUT` `tos`
`https://[ship-name].urbit.org/tos/[service]/[port]/[stream]/[path]`
`{oryx: [string]}` Initiate a subscription on her own Urbit. `tis`
`https://[ship-name].urbit.org/tis/[user-name]/[service]/[port]/[stream]/[path]`
`{oryx: [string]}` Initiate a subscription on a foreign Urbit.
`tom` `https://[ship-name].urbit.org/tom/[service]/[port]/[sequence]`
`{oryx: [string], xyro: [json]}` Send a message to her Urbit with
sequence number `[sequence]`. `tim`
`https://[ship-name].urbit.org/tim/[user-name]/[service]/[port]/[sequence]`
`{oryx: [string], xyro: [json]}` Send a message to a foreign Urbit with
sequence number `[sequence]`.
`tou` `https://[ship-name].urbit.org/tou/[service]/[port]/[stream]`
Unsubscribe from stream `[stream]` on her Urbit. `tiu`
`https://[ship-name].urbit.org/tiu/[user-name]/[service]/[port]/[stream]`
Unsubscribe from stream `[stream]` on a foreign Urbit.
urb.js
======

View File

@ -0,0 +1,5 @@
Eyre: Reference
===============
Eyre: Commentary
================

128
docs/pub/doc/arvo/ford.md Normal file
View File

@ -0,0 +1,128 @@
<div class="short">
`%ford`
=======
`%ford` is our typed and marked computation engine.
A variety of different services are provided by `%ford`, but they mostly
involve compiling hook files, slapping/slammming code with marked data,
and converting data between marks, including validating data to a mark.
Throughout every computation, `%ford` keeps track of which resources are
dependencies so that the client may be aware when one or more
dependencies are updated.
`%ford` neither accepts unix events nor produces effects. It exists
entirely for the benefit of applications and other vanes, in particular
`%gall`. `%eyre` exposes the functional publishing aspects of `%ford`
while `%gall` uses `%ford` to control the execution of applications.
`%clay` is intended to use `%ford` to managed marked data, but this is
not yet reality.
</div>
------------------------------------------------------------------------
<list></list>
------------------------------------------------------------------------
Cards
=====
`%ford` accepts just one card, `%exec`. This is misleading, however,
since there are fourteen different `silk`s that may be used with it. In
every case, the expected response to a `%exec` card is a `%made` gift
with either an error or the produced result along with its set of
dependencies.
Silks may autocons, so that the product of a cell of silks is a cell of
the product of the two silks.
[`%bake`](#bake)
================
Tries to functionally produce the file at a given beam with the given
mark and heel. It fails if there is no way to translate at this level.
[`%boil`](#boil)
================
Functionally produces the file at a given beam with the given mark and
heel. If there is no way to translate at this beam, we pop levels off
the stack and attempt to bake there until we find a level we can bake.
This should almost always be called instead of `%bake`.
[`%call`](#call)
================
Slams the result of one silk against the result of another.
[`%cast`](#cast)
================
Translates the given silk to the given mark, if possible. This is one of
the critical and fundamental operations of ford.
[`%diff`](#diff)
================
Diffs the two given silks (which must be of the same mark), producing a
cage of the mark specified in `++mark` in `++grad` for the mark of the
two silks.
[`%done`](#done)
================
Produces exactly its input. This is rarely used on its own, but many
silks are recursively defined in terms of other silks, so we often need
a silk that simply produces its input. A monadic return, if you will.
[`%dude`](#dude)
================
Computes the given silk with the given tank as part of the stack trace
if there is an error.
[`%dune`](#dune)
================
Produces an error if the cage is empty. Otherwise, it produces the value
in the unit.
[`%mute`](#mute)
================
Takes a silk and a list of changes to make to the silk. At each wing in
the list we put the value of the associated silk.
[`%pact`](#pact)
================
Applies the second silk as a patch to the first silk. The second silk
must be of the mark specified in `++mark` in `++grad` for the mark of
the first silk.
[`%plan`](#plan)
================
Performs a structured assembly directly. This is not generally directly
useful because several other silks perform supersets of this
functionality. We don't usually have naked hoods outside ford.
[`%reef`](#reef)
================
Produces a core containing the entirety of zuse and hoon, suitable for
running arbitrary code against. The mark is `%noun`.
[`%ride`](#ride)
================
Slaps a twig against a subject silk. The mark of the result is `%noun`.
[`%vale`](#vale)
================
Validates untyped data from a ship against a given mark. This is an
extremely useful function.

File diff suppressed because it is too large Load Diff

161
docs/pub/doc/arvo/gall.md Normal file
View File

@ -0,0 +1,161 @@
<div class="short">
`%gall`
=======
`%gall` manages our userspace applications.
It allows applications and vanes to send messages to applications and
subscribe to data streams. This requires `%gall` to be a sort of a
hypervisor. Messages coming into `%gall` are routed to the intended
application, and the response comes back along the same route. If the
intended target is on another ship, `%gall` will behind-the-scenes route
it through ames to the other ship to run. This provides an abstraction
where all apps on all ships are communicated with over the same
interface.
`%gall` neither accepts events from unix nor produces effects. It exists
entirely for the benefit of other vanes and, in particular,
applications. Eyre exposes `%gall`'s interface over http, and ames does
the same over the ames network. `%gall` uses ford to compile and run the
applications.
</div>
------------------------------------------------------------------------
Cards
=====
`%gall` accepts the following cards. The first three are the most
commonly used, while the others are primarily used internally.
[`%mess`](#mess)
================
Sends a message to an app. This will result in a call to the app's
`++poke` arm. The response is exactly one of a `%nice` if the action
succeeded or a `%mean` if not.
------------------------------------------------------------------------
[`%show`](#show)
================
Subscribes to a stream from an app. This will result in a call to the
app's either `++peek` or `++peer` arm. The first response will always be
either a `%nice` or a `%mean`, indicating whether or not the
subscription was successful. After the first response, there will be
zero or more responses of either `%rush` or `%rust`, which communicate
either a differntial or full update to the data stream. There may be a
`%mean`, which indicates that the subscription has been canceled and no
more responses will be received along this stream.
------------------------------------------------------------------------
[`%nuke`](#nuke)
================
Unsubscribes the current duct from its stream. This receives a response
of either a `%nice` or a `%mean`. Note that a response of `%nice` does
not imply that the current duct was in fact subscribed to any stream.
------------------------------------------------------------------------
[`%init`](#init)
================
Initializes a ship's apps. This should be called exactly once for each
ship on the pier. This produces no moves in response.
------------------------------------------------------------------------
[`%sire`](#sire)
================
Instantiates a child app. The app will be at path `[p parent-path]`, and
it will be an instance of the `q` app. The only response will be `%gone`
when the child dies.
------------------------------------------------------------------------
[`%rote`](#rote)
================
Signifies a remote request from ames. `r` should be of type `rook`. This
how an app on a foreign ship may send a `%mess`, `%show`, or `%nuke`
card. Note that `%gall` automatically converts `%mess`, `%show`, and
`%nuke` into ames messages behind the scenes, so the only entity that
should use `%rote` and `%roth` is ames. Formally, the response is either
a `%nice` or a `%mean`, which ames uses to give a positive or negative
ack. A logical response comes by passing a `%roth` card.
------------------------------------------------------------------------
[`%roth`](#roth)
================
Gives the response received from a remote request. `r` should be of type
`roon`. This is how an app responds to a foreign request with a `%rush`,
`%rust`, `%nice`, or `%mean`. The response is either a `%nice` or a
`%mean`. Even though we, as the proverb goes, "never ack an ack", we do
need to acknowledge these responses since they're really independent
one-way messages.
------------------------------------------------------------------------
[`%wipe`](#wipe)
================
Wipes the given app from memory. This is generally considered a hack,
but it is sometimes useful during development to wipe the state of an
app. We don't guarantee that this actually completely wipes the app.
Generally, you want to use a `%cide` card if you actually want to kill
an app. This gives no response.
------------------------------------------------------------------------
[`%cide`](#cide)
================
Kills an app and all its children. Even though it's not technically a
part of `%gall`'s interface since it's not in `++kiss` and can't be
called from the outside, it's worth mentioning `%cide`, which may be
called from within `%gall` apps. It should call `++part` to allow the
app any last words. This gives no response.
------------------------------------------------------------------------
Service Gates
=============
[`++poke`]()
============
Handles incoming messages. Most commonly with an associated `%logo`. For
example `++poke-json` handles an incoming JSON request from `%eyre`.
[`++peer`]()
============
Handles incoming subscriptions.
[`++pull`]()
============
Handles dropping subscribers.
[`++pour`]()
============
Handles responses to `%pass` moves.
[`++park`]()
============
Save state on update.
[`++prep`]()
============
Load state on update.

View File

@ -0,0 +1,5 @@
Gall: Reference
===============
Gall: Commentary
================

View File

@ -0,0 +1,8 @@
<div class="short">
`%ives`
=======
`%ives` isn't finished yet.
</div>

View File

@ -0,0 +1,5 @@
Ives: Reference
===============
Ives: Commentary
================

View File

@ -0,0 +1,8 @@
<div class="short">
`%jael`
=======
`%jael` isn't finished yet.
</div>

View File

@ -0,0 +1,5 @@
Jael: Reference
===============
Jael: Commentary
================

View File

@ -0,0 +1,8 @@
<div class="short">
`%kahn`
=======
`%kahn` isn't finished yet.
</div>

View File

@ -0,0 +1,5 @@
Kahn: Reference
===============
Kahn: Commentary
================

View File

@ -0,0 +1,8 @@
<div class="short">
`%lunt`
=======
`%lunt` isn't finished yet.
</div>

View File

@ -0,0 +1,5 @@
Lunt: Reference
===============
Lunt: Commentary
================

21
docs/pub/doc/arvo/time.md Normal file
View File

@ -0,0 +1,21 @@
<div class="short">
`%time`
=======
`%time` is a simple timer.
It allows vanes and applications to set and timer events, which are
managed in a simple priority queue. `%time` produces effects to start
the unix timer, and when the requested `%time` passes, unix sends wake
events to `%time`, which time routes back to original sender. We don't
guarantee that a timer event will happen at exactly the `%time` it was
set for, or even that it'll be particularly close. A timer event is a
request to not be woken until after the given time.
`%eyre` uses `%time` for timing out sessions, and `%clay` uses `%time`
for keeping track of time-specified file requests. `%ames` should
probably use `%time` to keep track of things like network timeouts and
retry timing, but it currently uses its own alarm system.
</div>

229
docs/pub/doc/arvo/util.md Normal file
View File

@ -0,0 +1,229 @@
<div class="short">
CLI Apps
========
These are our simple command-line applications.
You can find them in `/main/app`.
</div>
------------------------------------------------------------------------
### [`:begin`](#begin)
`~zod/try=> :begin [~ship-name [~valid-ticket-for-ship]]`
Start a ship. `:begin` collects all of the necesarry information to
start an Urbit ship. Takes an option `[~ship-name]` or
`[~ship-name [~valid-ticket-for-ship]]` pair.
------------------------------------------------------------------------
### [`:cat`](#cat)
`~zod/try=> :cat path-to-file [...]`
"cat" a file. `:cat` either prints a file, or concatenates and then
prints multiple files to the terminal.
------------------------------------------------------------------------
### [`:cp`](#cp)
`~zod/try=> :cp /path/to/source /path/to/destination`
Copy a file to a given location.
------------------------------------------------------------------------
### [`:grep`](#grep)
`~zod/try=> :grep 'literal'`
"grep" a file or standard input. Currently only supports literals, but
will eventuall support regular expressions.
------------------------------------------------------------------------
### [`:hi`](#hi)
`~zod/try=> :hi ~ship ["message"]`
Send a ship a message which is empty by default, becoming their neighbor
in the process. Often used to ping ships to check connectivity.
------------------------------------------------------------------------
### [`:into`](#into)
`~zod/try=> :into /path/to/file 'contents'`
Write text to a file. If the specified file does not exist, create a
file by that name.
------------------------------------------------------------------------
### [`:label`](#label)
`~zod/try=> :label %path %label`
"label". Add a label to a change number.
~zod/try=> :label %try %zebra
= new /~zod/try/3
~zod/try=> :ls /=try/zebra
readme
Note that adding a label is part of the delta stream and creates a new
change number, `3`.
------------------------------------------------------------------------
### [`:ls`](#ls)
`~zod/try=> :ls path/to/directory`
"ls". List files at a path. Unlike "ls" in Unix, the current path `%`
must be explicitly given (you cannot call `:ls` with no arguments to
display the files at the current path).
------------------------------------------------------------------------
### [`:mv`](#mv)
`~zod/try=> :mv /path/to/source /path/to/destination`
Move a file to a given location, creating a new revision of the source
that omits the moved file.
------------------------------------------------------------------------
### [`:reload`](#reload)
`~zod/try=> :reload %vane-name [...]`
Reload the standard library (zuse) and/or arvo vanes. If zuse is
reloaded, vanes depending on the changes must be reloaded as well. For
example `:reload %zuse %ford` is necessary to make use of changes in
application code or the REPL.
Possible values for %vane-name see [Overview](overview.md "overview"):
------------------------------------------------------------------------
### [`:reset`](#reset)
`~zod/try=> :reset`
Reloads all vanes. See [`:reset`] for reloading only or a specific vane.
------------------------------------------------------------------------
### [`:rm`](#rm)
`~zod/try=> :rm /path/to/source`
Remove a file.
------------------------------------------------------------------------
### [`:solid`](#solid)
`~zod/try=> :solid`
compiles a kernel into a new full urbit.pill
------------------------------------------------------------------------
### [`:sync`](#sync)
`:sync %source-desk ~hidduc-posmeg %target-desk`
Sets up a subscription to the source desk on the target ship name to the
target desk on your ship.
------------------------------------------------------------------------
### [`:ticket`](#ticket)
`~zod/try=> :ticket ~ship-name`
Creates a will for a ship. `:ticket` outputs the ticket for a Urbit
ship. Takes an option `[~ship-name]`. On destroyes this command creates
a yacht and takes the option \`[\~yacht-name-destroyer-name]
------------------------------------------------------------------------
### [`:thumb`](#thumb)
`~zod/try=> :thumb ~ship-name`
Show the ships information. Only works if you issued a [`:hi`]
[\`\~ship-name] beforehand.
This command is not avaible since the switch from batz to `%gall`!
Use this for the time beeing: - will:
`~zod/try=> ((hard (unit gcos)) .^(%a /=gcos=/~ship-name))` - raw will:
`~zod/try=> ((hard will) .^(%a /=will=/~ship-name))`
------------------------------------------------------------------------
### [`:unsync`](#unsync)
`:unsync %source-desk ~hidduc-posmeg %target-desk`
Cancels the subscription to the source desk on the target ship name to
the target desk on your ship.
------------------------------------------------------------------------
### [`:verb`](#verb)
`~zod/try=> :verb`
Turn verbose arvo mode on/off.
You'll see events, internal cards, and effects.
[%unix p=%wake //temp]
[ %give
%t
%wake
~[
/c/tyme
/g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod/main
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
/d/term-mess
//term/1
]
]
[ %give
%c
%writ
~[
/g/a/~zod/._~~.58_~~.shell_~~.terminal__/w/drug/~zod
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/began/u
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.2_~~.shell_~~.terminal__/u/to-gan
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/._~~.shell_~~.terminal__/u/child/2/main
/g/a/~harnyr-darlux-bitrux-litnum--falbec-tacsev-magdus-tobsyn/terminal/u/txt
/d/term-mess
//term/1
]
]
...
------------------------------------------------------------------------
### [`:ye`](#ye)
`~zod/try=> :ye ["message"]`
Send a message to all ships. Often used to announce a continuity breach.
------------------------------------------------------------------------

15
docs/pub/doc/guide.md Normal file
View File

@ -0,0 +1,15 @@
<div class="short">
Guides
======
These guides are designed to get you oriented in urbit.
Each one covers a specific topic. Although it's not necesarry to follow
them in order, they do get increasingly complex.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -0,0 +1,812 @@
`%ford` Guide
=============
#### basic `hoon` and talking to the web
<div class="short">
`%ford` is the arvo vane that handles asset management and publishing.
We use `%ford` to compose our files when programming, and also to bundle
files together for the web.
This guide assumes that you have installed and started your urbit.
Assuming you cloned the repo into `/$URB_DIR` you should be able to find
the unix mirror of your ship's filesystem in
`/$URB_DIR/$PIER/$SHIP-NAME`. All of the filesystem paths in this guide
are relative to that Unix directory.
Also, we refer to `http://ship-name.urbit.org/` in our URLs, but you can
also use `http://localhost:8080/` if you prefer to just talk to your
machine directly.
</div>
<hr>
</hr>
1. Let's publish a webpage
--------------------------
#### In
/main/pub/fab/guide/exercise/1/hymn.hook
#### Put
;html
;head
;meta(charset "utf-8");
;title: Exercise 1
==
;body
;div
;h1: Exercise 1 — Simple HTML
;p: As you may notice, urbit has no problem talking to the web.
==
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/1/
#### What did you just do?
The code you just wrote is urbit's native programming langauge, hoon.
Generating HTML with hoon is similar to writing [jade](link) or other
similar HTML shorthand. In hoon, this shorthand is called [`++sail`]()
and it's a native part of the hoon language.
In `++sail` node-names are prefixed with a `;` and closed with a `==`.
Nodes that have text content and are only on one line use a `:`, such as
our `;h1:` above, and are closed implicitly with a new line. Nodes with
no content are closed with another `;`, such as `;br;`.
You can find more information about `++sail` in our [rune library
documentation](link).
<hr>
</hr>
2. Let's do some programming on the page.
-----------------------------------------
#### In
/pub/fab/guide/exercise/2/hymn.hook
#### Put
;html
;head
;meta(charset "utf-8");
;title: Exercise 2
==
;body
;div
;h1: Exercise 2 — Call a function
;p: Although it may be obvious, 2+2={<(add 2 2)>}
==
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/2/
### What's going on there?
Clearly, the code `(add 2 2)` is generating `4`, and it's not too hard
to see why. `add` is one of the library functions that are a part of
`hoon.hoon`. Try replacing `(add 2 2)` with `(sub 2 (add 2 2))`. You can
find documentation for the full hoon library in the [library
reference](link).
Since the product of `(add 2 2)` is a number, we need a few extra things
to have it print properly. In `++sail` we use `{` and `}` to do string
interpolation. Everything after the `:` is expected to be a string, so
we need to tell the parser when we start writing code. The `<` and `>`
inside our `{` `}` are converting our result `4`, a number, to the
string `"4"`. hoon is a strongly typed language kind of like haskell, so
we need to explicitly convert our types.
<hr>
</hr>
3. Let's assign some variables.
-------------------------------
#### In
/pub/fab/guide/exercise/3/hymn.hook
#### Put
=+ ^= a 1
=+ b=2
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 3
==
;body
;div
;h1: Exercise 3 — Assignment
;p: a={<a>}
;p: b={<b>}
;p: a+b={<(add a b)>}
==
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/3/
#### How does that work?
The first thing you should notice in this example is the `=+` at the top
of our file. `=+` is a rune. hoon is a programming with no reserved
words. We don't use `if` `this` or `function` at all. Instead, runes
have their own pronunciation. `=+` is pronounced 'tislus'. You can find
the table of pronunciation [here](link). In hoon you construct your
programs using runes, which are two character ascii pairs. You can see
the whole set of runes in the [rune index](link).
`=+` pushes an expression on to our subject. The subject in hoon is
similar to `this` in other languages. hoon being a functional language
if we want something to be available further on in our computation we
need to attach it to the subject first.
The second thing you should notice is the `^- manx`. Here the rune
`[^-]()` is used to cast our product to a [++manx](), which you can
think of like the hoon MIME type for XML. Using a `^-` is not required,
but helps us produce more informative error messages when we generate a
type error or mismatch.
Looking at the rendered page it's clear that we're assigning `a` to be
`1` and `b` to be `2`. Looking at the code, however, you can see that
we're doing this in two different ways. Runes in hoon can have irregular
forms, and `^=` is one of them. The first two lines of our example are
doing the same thing, where `a=2` is simply the irregular form of
`^= a 2`. You can see the full list of irregular forms [here](link).
Looking at the simple computation on the page, you can try changing the
values of `a` and `b` to any integers to produce similar results.
<hr>
</hr>
4. Let's build our own computation
----------------------------------
#### In
/pub/fab/guide/exercise/4/hymn.hook
#### Put
|%
++ start 1
++ end 10
++ length
|= [s=@ud e=@ud]
(sub e s)
--
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 4
==
;body
;div
;h1: Exercise 4 — Cores
;p: We'll be starting at {<start>}
;p: And ending at {<end>}
;p: Looks like a length of {<(length start end)>}
==
==
==
#### Try it
(and be sure to put two spaces between `++` and arm names)
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/4/
### What's happening?
As you can see from the output, we have written a little function that
takes two numbers, `s` and `e` and returns their difference. The first
thing to notice about our code is the first rune. `|%` is a `core` rune.
You can think of cores like functions or objects in other languages.
`|%` runes contain an arbitrary number of arms, denoted with either `++`
or `+-` and closed with `--`.
Each arm has a value, either static data (in the case of `++start` and
`++end`) or a gate (in the case of `++length`). A gate is a kind of
core. Gates only have one arm and are quite similar to a function in
other languages. We use `|=` to construct our gate. Runes in hoon are
generally categorized by their first character. `|` indicates a rune
having to do with cores. You can find all of the `|` runes in the [rune
library](link).
Our `++length` [gate]() takes two arguments, `s` and `e`. In hoon we
call the data passed in to a gate the 'sample'. Every `|=` has two
parts: the sample type and the computation, also known as a `tile` and a
`twig`. Casually, `[s=@ud e=@ud]` means that the gate takes two
arguments, labelled going forward as `s` and `e`, and required to both
be `@ud` or unsigned decimal. Our computation, `(sub e s)` simply
computes the difference between `e` and `s`.
`@ud` is an odor. Odors aren't quite types, but they're similar. You'll
learn the difference by example as we progress, and you can always refer
to the [odor index](link).
You probably also noticed our indentation. In general hoon has both tall
and wide forms. In tall form, hoon uses two spaces for indentation and
is back-stepped so nested code doesn't drift away toward the right
margin. In wide form we use parenthesis just like almost everyone else.
<hr>
</hr>
5.
--
#### In
/pub/fab/guide/exercise/5/hymn.hook
#### Put
|%
++ dist ,[start=@ud end=@ud]
++ length
|= [d=dist]
(sub end.d start.d)
--
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 5
==
;body
;div
;h1: Exercise 5 — Cores
;p: How long does it take to get from 2 to 20? {<(length 2 20)>}
==
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/5/
#### What's the difference?
Clearly we're producing the same result as before, but we're doing it in
a different way.
The first line in our gate, `++length` always specifies the sample tile.
As you can see here, our sample tile is actually a `++dist`, the body of
which, `,[start=@ud end=@ud]` looks very similar to our previous example
in that it accepts two `@ud`. The important difference is that `++dist`
is now defined in a way that can be re-used. hoon is a strongly typed
language, but it encourages the creation of your own types using what we
call tiles.
At a high level you can think of hoon as being composed of two things,
tiles and twigs. Twigs are the actual AST structures that get consumed
by the compiler. Tiles reduce to twigs and provide major affordances for
the programmer. If you're interested in learning about tiles more deeply
you can find an in-depth explanation in the [tile overview](link).
It should suffice, for now, to say that we create tiles in the same way
that you would think of creating type definitions in another language.
The primary way we do this is with `$` runes you can find more about
them in the [`$` section]() of the rune library.
In this specific example we are using the `$,` tile rune in its
irregular form, `,`. `,` generates a validator from the given
expression. In effect, `++dist` uses the type system to only produce
cells that appear in the form `[start=@ud end=@ud]`. When we use it in
our `++length` gate we assert that our input must be validated by
`++dist`. To test that out, you can try passing something that isn't an
unsigned decimal (or `@ud`) to `++length`. Try replacing `(length 2 20)`
with `(length 2 'a')`. As we continue you'll see how this pattern can be
quite useful.
One other thing to point out which may be immediately confusing coming
from other languages is the order of addressing `start` and `end`. We
call these labels faces, and we address them in the opposite order than
you're usually familiar with. We still separate our addressing with `.`,
but do it from the inside out. Given a tuple such as
`[a=1 b=[c=[d=2 e=3]]]` we can address the value of `e` with `e.c.b`.
You can read more about how faces work in the commentary on `++type`
[here](link).
<hr>
</hr>
6.
--
#### In
/pub/fab/guide/exercise/6/hymn.hook
#### Put
|%
++ fib
|= x=@
?: (lte x 2)
1
(add $(x (dec x)) $(x (sub x 2)))
--
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: Exercise 6
==
;body
;div
;h1: Exercise 6 — Loops
;p: {<(fib 1)>}, {<(fib 2)>}, {<(fib 3)>}, {<(fib 4)>}
==
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/6/
#### What is that doing?
We're printing a few members of the [fibonacci sequence](link) by
calling our arm `++fib` with a few values. The fibonacci sequence is a
fairly straight forward algorithm: `F(n-1) + F(n-2)` where `F(1) = 1`
and `F(2) = 1`. As is obvious from the formula, generating the fibonacci
value at any number requires us to recurse, or loop. Let's walk through
the code.
Our example here should look similar to the previous one. We build a
core with `|%` and add the arm `++fib`. `++fib` is a gate which takes
one argument `x`, an atom. Using [`?:`](link) we test if `x` is less
than `2` with the library function [`lte`](link) to handle our seed
values of `F(1) = 1` and `F(2) = 1`. `?:` is a member of the [`?`
runes](link), related to true / false values, or loobeans. In hoon true
and false are `0` and `1` respectively and take the odor `@f`. We tend
to say 'yes' and 'no' instead of 'true' and 'false' to keep track of the
switch. Our built-in function `lte` produces a loobean, so we evaluate
our first line if true, and second if false.
If `x` is not less than `2` we compute `F(n-1) + F(n-2)` by using `$`.
We mentioned previously that a gate is a special kind of core with only
one arm, called `$`. Here we're using `$` to mimic the behavior of a
loop. You can read the expression `$(x (dec x))` as 'call the gate again
with `x` replaced by `(dec x)`. For more on how this works, check out
the documentation of [`%=`](link) and [`%-`](link). With that in mind it
should be clear how the last line of `++fib` produces the member of the
sequence at a given value `x`.
<hr>
</hr>
7.
--
#### In
/pub/fab/guide/exercise/7/hymn.hook
#### Put
::
::
:::: /hook/hymn/7/exercise/guide/fab/pub/
::
/? 314
/= gas /$ fuel
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: %ford Example 1
==
;body
;div
;h1: %ford Example 1 — Page Variables
;div.who: {<(~(get ju aut.ced.gas) 0)>}
;div.where: {(spud s.bem.gas)} rev {(scow %ud p.r.bem.gas)}
;code
;pre: {<gas>}
==
==
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/7/
http://ship-name.urbit.org/gin/del/main/pub/fab/guide/exercise/7/
Here we're putting our publishing framework, `%ford` to work a little
bit. We're printing out some of the parameters our page is passed: who
is looking at it, where it is and what revision our desk is on. We have
also thrown in all our FCGI parameters in a codeblock for reference.
To do this we have introduced some new runes, `/?`, `/=` and `/$`. We
tend to call runes with a leading `/` "`%ford` runes" since they are
used by the `%ford` vane for resource loading and composition. By
convention, we indent four spaces after them to make them more obvious.
They belong at the top of the file.
`/?` simply checks for compatibility. In this case the line means 'need
urbit 314 or below', or in hoon: `(lte zuse 314)`. `314` is the number
in the kelvin versioning system, which you can read about [here](link).
`/=` is similar to the combination of `=+ =^`, or assignment. `/$`
calls a parsing function, which we specify as [`++fuel`](link) with the
[`++beam`](link) and [`++path`](link) of our current file.
`/= gas /$ fuel` is a common way to open your page, since the
product of `++fuel` is useful when writing pages to the web. The use of
`++fuel` is not enforced — you can also write your own parser.
Our page is made up of two generated parts: who requested the page, the
location of the page and its revision. Both are parsed out of the `gas`
variable using some straightforward library functions, [`++ju`](link),
[`++spud`](link) and [`++scow`](link). You can follow those links to the
library reference to learn more about them. You'll also notice our
addressing moving in the opposite direction as you may be used to.
`aut.ced.gas` pulls `aut` from inside `ced` from inside `gas`.
Inside of the `;code` tag we also print (for our own reference) the
entire `gas`, so you can take a look at the contents. This can be a
helpful trick when debugging. To fully understand what gets put in
`gas`, we can take a look at `++fuel` and note that it produces a
[`++epic`](link), which also contains a [`++cred`](link). You can follow
those links to learn more about them.
When we try changing the url from `gen/main` to `gin/del/main` we're
using some of the access methods from `%eyre` (the urbit webserver) to
pretend to be the urbit `~del`. You can find documentation on those
access methods in the `%eyre` commentary, [here](link).
Path and identity are useful, but there are some other parameters worth
checking out as well.
<hr>
</hr>
8.
--
#### In
/pub/fab/guide/exercise/8/hymn.hook
#### Put
::
::
:::: /hook/hymn/8/exercise/guide/fab/pub/
::
/? 314
/= gas /$ fuel
::
^- manx
;html
;head
;title: %ford Example 2
==
;body
;div: Do you have a code?
;div: ?code={<(fall (~(get by qix.gas) %code) '')>}
==
==
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/8/
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/8/?code=yes-i-do
This is a simple example, showing off another use of
`/= gas /$ fuel`. In this case we're just pulling out the value of
the `code` query string parameter. You should be able to change that
value to any url-safe string and see it appear on the page.
We're using a few simple library functions to actually pull the value
out, [`++fall`](link) and [`get:by`](link). Query string parameters are
stored in `qix.gas` as a `++map`, one of the main container constructs
used in hoon. We'll encounter a lot of maps along the way, and you can
learn more about them in the [map section](link) of the library doc.
<hr>
</hr>
9.
--
#### In
/pub/fab/guide/exercise/9/hymn.hook
#### Put
::
::
:::: /hook/hymn/exercise/9/guide/fab/pub/
::
/? 314
::
// /%%/lib
^- manx
;html
;head
;title: %ford Example 3
==
;body
;h1: %ford Example 3
;p: {<(fib 1)>}, {<(fib 2)>}, {<(fib 3)>}, {<(fib 4)>}
==
==
#### And in
/pub/fab/guide/exercise/9/lib.hoon
#### Put
|%
++ fib
|= x=@
?: (lte x 2)
1
(add $(x (dec x)) $(x (sub x 2)))
--
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/9/
#### How are they getting combined?
Clearly this looks a lot like our previous example using `++fib`, only
now we're using two separate files. The majority of this code should be
familiar to you from example 6, so let's focus on a single line,
`// /%%/lib`.
`//` is a `%ford` rune that loads a resource from a given path. `//` is
used as a way to organize project code into separate files, not for
loading libraries and structures. We'll show some examples of how urbit
handles those things shortly. You can think of `//` as a kind of
`include` or `require`. `//` takes a `beam`, an absolute global path in
`%clay` — the global urbit filesystem.
In `%clay` we use `%` to navigate relative paths. `%` is sort of like
`.` when moving around the unix file system. Although we put our code in
the unix path `/pub/fab/guide/exercise/9/hymn.hook` the file extension
is just a hint to the system. `/%/` (the equivalent of a unix `./`)
actually resolves to `/pub/fab/guide/exercise/9/hymn`.
We commonly use two kinds of extensions, `.hoon` for source files and
`.hook` for files that generate something else. Since our hymn file is
generating html, it's a `.hook`, and our source file is just a `.hoon`.
In order to find our file one level up we need two `%%` to get to
`/pub/fab/guide/exercise/9/`. Adding `lib` resolve to our neighboring
file. You can read more about how `%clay` paths are parsed in the
[`%clay` overview](link). It's also pretty easy to try them out using
`:cd` and `:ls` in your `%arvo` terminal.
<hr>
</hr>
10.
---
#### In
/pub/fab/guide/exercise/10/hymn.hook
#### Put
::
::
:::: /hook/hymn/10/exercise/guide/fab/pub/
::
/? 314
/= gas /$ fuel
// /%%/lib
::
=+ ^= arg
%+ slav
%ud
%+ fall
%- ~(get by qix.gas) %number
'0'
::
^- manx
;html
;head
;title: %ford Example 4
==
;body
;div: {<(fib arg)>}
==
==
#### And in
/pub/fab/guide/exercise/10/lib.hoon
#### Put
|%
++ fib
|= x=@
?: (lte x 2)
1
(add $(x (dec x)) $(x (sub x 2)))
--
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/10/
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/10/?number=7
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/10/?number=12
As you can see by changing the URL, we're now passing our query string
parameter to our `++fib` script and printing the output. It's common to
pull some data out of the URL and do something with it, but we don't
have any type information about our query string parameters and hoon is
a strongly typed languge. As you can see, we're calling `++fib` with a
parameter `arg`. Let's look closely at how we generate `arg`.
The first part of our assignment should look familiar from previous
example, `=+ ^= arg` puts the face `arg` on the product of our
remaining computation. In short, you can read the code that produces
`arg` as `(slav %ud (fall (~(get by qix.gas) %number) '0'))`. We use `%`
runes to write this in tall form. `%` runes are used for calling gates
or evaluating changes. `%+` 'slams' or calls a gate with two arguments,
and `%-` 'slams' or calls a gate with one argument. As usual, you can
find more about the `%` runes in the [`%` section](link) of the rune
library.
To get a value out of our map of query string parameters `qix.gas` we
use a method from the [maps library](link) that produces a `++unit`.
`++unit`s are a common type in hoon used for optional values. A
[`++unit`](link) is either `~` or `[~ p=value]`. Since we need to
specify a value for `(fib arg)` even when someone doesn't enter the
query string we use [`++fall`](link), which produces either the value of
the unit, or the second argument if the `++unit` is null. Since our
`qix.gas` has string values in it we specify a string in our second
argument, `'0'`. As an aside, `'0'` is different from `"0"` in hoon. You
can read about the difference in [`++cord`](link) and [`++tape`](link).
Our outermost call, to [`++slav`](link), casts our string to a `@ud`
which is the type expected by `++fib`. `++slav` takes the name of an
odor and a value, and tries to cast the value to that odor.
<hr>
</hr>
11.
---
#### In
/pub/fab/guide/exercise/11/hymn.hook
#### Put
/= posts /: /%%/lib
/; |= a=(list (pair ,@ ,manx))
%+ turn
a
|= [* b=manx]
b
/@
/psal/
::
^- manx
;html
;head
;meta(charset "utf-8");
;title: %ford Example 11
==
;body
;h1: Ford example — Loading Resources by Number
;* posts
==
==
#### In
/pub/fab/guide/exercise/11/lib/1.md
#### Put
#1
This is my first post.
#### In
/pub/fab/guide/exercise/11/lib/2.md
#### Put
#2
This is my second post.
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/11/
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/11/lib/1/
http://ship-name.urbit.org/gen/main/pub/fab/guide/exercise/11/lib/2/
#### Experiment with it
Try adding other `.md` files with numeric file names (such as `3.md`) to
the `11/lib/` directory to get a feel for what's going on.
What's happening?
As you can see, we're loading the markdown files in `11/lib` and putting
them in to our page. Let's dive into the code.
We're using `/=` to assign the `posts` face. `/:` sets the `++beam` for
the computation below it. You can think of it sort of like setting an
environment variable. Everything below uses our `++beam` `/%%/lib`.
If we take the next few lines and write them as pseudo code in wide form
they might look something like this, `(/; [gate] (/@ /psal/))`. That
being the case, let's start at the bottom and move upwards since that's
how our data flows. In depth documentation on individual `++horn` runes
can be found in the [horn section of the rune library](link).
`/psal/` loads our `psal` mark. Marks are like content types, and we
keep them in `/main/mar/`. You can open `/main/mar/psal/door.hook` to
see that we specify the ways in which a particular mark can be converted
to produced well typed output. The general form of this is [`/mark/`]()
where `mark` exists in the `/main/mar/` directory. A `psal` is a partial
`hymn`, where `hymn` is the hoon structure for `html`.
`/@` loads a list of files in numerical order from the previously
specified `++beam` using our mark, `psal`. `/@` has a few close
relatives. `/&`, for example, reads files by `@da` or absolute date. You
can see the rest in the [horn section of the library](link).
`/;` takes the output from `/@` and `/psal/` and passes it to a twig. In
this case, a gate. Our `/@` actually produces a [`++list`](link) of
pairs of `[@ manx]` where the `@` is the filename, and the `manx` is the
converted contents. We use [`++turn`](link), one of our `++list`
operator functions, to iterate through the list and produce only a list
of `++manx`. This is the output assigned to `posts`.
Then, further down, we use [`;*`](link) to write the list to the page.
<hr>
</hr>
12.
---
#### Look in
/pub/fab/guide/hymn.hook
/pub/fab/guide/main.css
/pub/fab/guide/main.js
#### Try it
http://ship-name.urbit.org/gen/main/pub/fab/guide/
#### Bring it all together
It turns out it's pretty easy to pull our examples together into a
single blog-like page using what we just covered. We include some css to
make things a bit prettier, and this should give you a good jumping off
point for experimenting with your own publishing code.
#### Have fun!

251
docs/pub/doc/guide/b-cli.md Normal file
View File

@ -0,0 +1,251 @@
This guide is intended to get you oriented in the Arvo command prompt
and give you a tour of some basic utilities. The command prompt comes in
two flavors, in a web browser and in a terminal. For the most part
they're the same, except that in a browser you can evaluate tall-form
Hoon expressions but you can't run readline apps, such as `:chat`.
Every Arvo command prompt is also a Hoon REPL. The command line is a
great place to test out your hoon knowledge. In this guide we're just
going to talk about some basic system utilities and get comfortable
moving around in `%clay`. If you'd just like to see a list of
command-line utilities, you can find the Arvo man pages [here]().
This rudimentary tour should work well in both places.
1
Move around `%clay`
After finishing the [setup instructions]() you should have an Arvo
prompt that looks like this:
~talsur-todres/try=>
The path at the beginning of your prompt is actually a path in the
global filesystem of Urbit, called `%clay`. Since `%clay` is universal
across all of Urbit, each full path starts with a ship name. `%clay` is
also versioned on a per-desk basis. Desks are the top-level directories
in your pier.
Moving around `%clay` is simple. There is no equivalent of `cd`.
Instead, just type a valid path name at the prompt to move to that
directory. Here we'll move to our starting root path in the try desk,
`/try=` to the `main` desk:
~talsur-todres/try=> /=main=
=% /~talsur-todres/main/0
~talsur-todres/main=>
We have two shortcuts in `%clay` that are worth noting, `=` and `%`.
`=` copies in some corresponding part of our current path. In the second
line above you can see how the `=` in `/=main=` pull in the
`~talsur-todres` and `0` in from our starting directory,
`/~talsur-todres/try/0`. It's important to note that our full prompt to
start is `/~talsur-todres/try=`, where the trailing `=` indicates the
current revision. In the shell, revision `0` never exists — it's used as
a pointer to the head.
`%` is similar to `.` in unix:
~talsur-todres/main=> %
=% /~talsur-todres/main/0
~talsur-todres/main=> %%
[~.~talsur-todres ~.main ~]
~talsur-todres/main=> %%%
[~.~talsur-todres ~]
~talsur-todres/main=> %%%%
~
When using `%` to move around in `%clay` you need to make sure to use
leading and trailing `/` to ensure your path is interpolted correctly:
~talsur-todres/main=> /%%%/try=
=% /~talsur-todres/try/0
~talsur-todres/try=>
2
Create some revisions
Let's use `:into`, our simple utility for writing text to a file, to
create a new file:
~talsur-todres/try=> :into %/helo/txt 'helo mars'
written
~talsur-todres/try=>
To confirm that our file was written, we can use `:ls`. `:ls` prints a
list of directory contents, but requires that you specify a path. `%`
will suffice for the current path:
~talsur-todres/try=> :ls %
readme helo
~talsur-todres/try=>
Let's quickly switch back to a unix command prompt to see a few things
about both how files are synced between `%clay` and unix, and where your
apps live.
my-pier/talsur-todres/$ ls try
helo.txt readme.md
my-pier/talsur-todres/$ cat try/helo.txt
helo mars
Here you can see that our files are synced back to unix as they are
changed in urbit, and vice-versa. As you change files in unix you'll see
those changes appear in `%clay`.
my-pier/talsur-todres/$ ls main/app/
bang grep poke solid unsync
began hi radio sync verb
begin into reload talk ye
cat label reset terminal
chat ls rm test
cp mv shell ticket
my-pier/talsur-todres/$ cat main/app/ls/core.hook
!:
|_ [hid=hide ~]
++ poke-ls-args
|= [ost=bone you=ship arg=path ~]
=+ lon=((hard arch) .^(%cy arg))
:_ +>.$
:* [ost %pass / %g %cide %$]
[ost %give %nice ~]
%+ turn (~(tap by sup.hid))
|= [ost=bone *]
:^ ost %give %rush
:- %tang
:_ ~
:+ %rose [" " ~ ~]
(turn (~(tap by r.lon) ~) |=([a=@ta b=*] leaf/(trip a)))
==
++ peer
|=
*
`+>
--
Here you can see that `/main/app` is the main location where our apps
are stored, and the contents of the `:ls` app. urbit applications are of
course written in hoon, our naitive programming language. Don't worry
about the contents of the file for now. Since changes in unix are synced
back in to urbit, we can develop urbit programs by simply editing them
in our favorite editor and saving them.
For the time being let's switch back to urbit and update our file with
some new content, so we can see how `%clay` stores revisions.
~talsur-todres/try=> :into %/helo/txt 'gbye mars'
written
~talsur-todres/try=> :ls /=try/1
readme helo
~talsur-todres/try=> :cat /=try/1/helo/txt
/~talsur-todres/try/9/helo/txt
helo mars
~talsur-todres/try=> :cat /=try/2/helo/txt
/~talsur-todres/try/10/helo/txt
gbye mars
~talsur-todres/try=> :cat /=try=/helo/txt
/~talsur-todres/try/~2014.11.26..01.06.33..c93a/helo/txt
gbye mars
~talsur-todres/try=>
Here we use `:ls` to investigate the filesystem across versions. You can
see that our `helo` file exists in our first revision. Using the simple
`:cat` command we can print the contents of `/=try/helo/txt` in its two
separate, versioned states.
We can even move to a different version of our desk and look around:
~talsur-todres/try=> /=try/1
=% /~talsur-todres/try/1
~talsur-todres/try/1> :ls %
readme helo
~talsur-todres/try/1>
This is sort of like being in a detached HEAD in git.
3
Start a yacht
Each Urbit destroyer can delegate around four billion yachts. Yachts are
also urbit ships, but are pegged to their parent identity, and are set
up to mirror their filesystem. We can generate a `[ship: ticket]` pair
for a yacht by using the `:ticket` utility:
~talsur-todres/try=> :ticket ~talsur-todres-talsur-todres
~talsur-todres-talsur-todres: ~figpem-fapmyl-wacsud-racwyd
Every yacht for a particular destroyer ends in the same `ship-name`, and
has every possible destroyer prefix. For example,
`~tasfyn-partyv-talsur-todres` is also a valid yacht from
`~talsur-todres`.
Start up a new `vere` process with something like `bin/vere -c yacht`.
Then run `:begin` and enter the `[ship: ticket]` pair you just generated
when prompted. When the process is complete you should get a
`; ~talsur-todres-talsur-todres :y1: is your neighbor` message on your
destroyer. To confirm that everything is working properly, you can use
`:hi` to send a message:
~talsur-todres/try=> :hi ~talsur-todres-talsur-todres "whats up"
hi ~talsur-todres-talsur-todres successful
~talsur-todres/try=>
Which will appear on your new yacht:
< ~talsur-todres: whats up
~talsur-todres-talsur-todres/try=>
You should also see the contents of your `/try` desk mirrored on your
yacht:
~talsur-todres-talsur-todres/try=> :ls %
readme helo
~talsur-todres-talsur-todres/try=>
Making another change on your destroyer should automatically propagate
down to your yacht:
~talsur-todres/try=> :into %/helo/txt 'back to mars'
written
~talsur-todres/try=>
[%merge-fine ~talsur-todres %try]
~talsur-todres-talsur-todres/try=> :cat %/helo/txt
back to mars
~talsur-todres-talsur-todres/try=>
4
Move files around
Another familiar command line utility is `:mv`:
~talsur-todres/try=> :mv %/helo/txt %/test/helo/txt
moved
~talsur-todres/try=>
[%merge-fine ~talsur-todres %try]
~talsur-todres-talsur-todres/try=> :cat %/test/helo/txt
back to mars
~talsur-todres-talsur-todres/try=>
In `%clay` we don't use file extensions or folders. A path either does
or does not have anything in it. There's no need to do the equivalent of
`mkdir` before moving something.
We also implement the familiar `:rm`:
~talsur-todres/try=> :rm %/test/helo/txt
removed
~talsur-todres/try=> :cat %/test/helo/txt
file /~talsur-todres/try/~2014.11.26..16.49.52..3f5e/test/helo/txt not available
~talsur-todres/try=>
[%merge-fine ~talsur-todres %try]
~talsur-todres-talsur-todres/try=> :cat %/test/helo/txt
file /~tasfyn-partyv-talsur-todres/try/~2014.11.26..16.50.15..556b/test/helo/txt not available
~talsur-todres-talsur-todres/try=>

View File

@ -0,0 +1,284 @@
This guide is focussed on storing application state using the `%gall`
vane. To show off how we store and distribute data in Urbit we're going
to examine a simple webapp. Some of the material here expects that you
have looked over the [`%ford` guide](). If you haven't, it's a good idea
to start there. There's also more information in the [`%gall`
overview]() and [`%gall` commentary]() but it's not necesarry that you
read those before going forward.
One important thing to keep in mind is that `%gall` services aren't
'started' or 'stopped' as in a unix system. When your files are copied
in they are compiled and begin running immediately and permanently.
`%gall` services simply wake up when certain events happen.
If you need to make updates to the structure of your stored data, you
write connector functions or (when developing) just throw your existing
data away. We'll see examples of how this works, just keep in mind that
when we talk about a `%gall` 'service' it has no concept of 'running'.
Going forward we'll refer to the directory you cloned the repo in as
`/$URB_DIR` and assume that your pier is listening for HTTP connections
on port `8080`.
1.
Get the code.
Clone the GitHub repository and move the files into your `/main` desk,
under the corresponding paths. You will need four files:
- /main/app/lead/core.hook
- /main/pub/lead/hymn.hook
- /main/pub/lead/src/main.css
- /main/pub/lead/src/main.js
When everything is in place, try it:
http://localhost:8080/gen/main/pub/lead/
That URL should render a page and be self explanatory. Try adding names
to the leaderboard and incrementing their scores. It's also fun to open
a few tabs and watch how the state gets updated simultaneously.
2.
How is the code structured?
In our `%ford` guide we generated pages by defining all of their
possible states, but we didn't exactly store any data. When building
applications on top of Urbit we think of them as existing in two natural
parts: page resources and state services. Effectively, we think of any
Urbit app talking to the web as a single page app whose resources are
generated by `%ford` which talks to a `%gall` service if it needs to
persist any state. Let's look more closely at the specifics in this
simple app.
When we load our page, we render the contents of our
`/main/pub/lead/hymn.hook`. This file should look familiar as
[`++sail`](). Our `hymn.hook` file writes the basic HTML elements to the
page, and pulls in our supporting CSS and JavaScript resources.
Our application-specific resources are stored in `/main/pub/lead/src/`.
`/main/pub/lead/src/main.css` simply produces the page layout, while
`/main/pub/lead/src/main.js` updates the page and sends data.
We also use two utility scripts: `/gop/hart.js` and
`/gen/main/lib/urb.js`. These are the standard libraries for handling
data transfer from a browser to Urbit, and are very frequently used.
`hart.js` handles the page heartbeat, making regular AJAX requests so we
can keep track of subscribers, and `urb.js` offers a more complete set
of helper functions. `urb.js` depends on `hart.js`, so that's why
`hart.js` always goes in the `<head>`. For complete documentation, check
out the [`urb.js` reference]().
Our application state is stored and distributed to connected clients by
`/main/app/lead/core.hook`. Let's take a closer look at how that works.
At the top of our `core.hook` we have:
/? 314 :: need urbit 314
This should be familiar from the `%ford` guide. Here we're requiring
that this code run on an Urbit ship where `(lte zuse 314)` is `yes`. In
this `core.hook` we only use one `%ford` rune, but this is where we
would also pull in any dependencies we might have or use other [`/`
runes]().
Below our `/?` you can see that our code is divided into two sections: a
[`|%`]() where we define our models, and a [`|_`]() where we define the
body of our program. We'll look at these more closely one at a time.
3.
How is our state stored?
In `/main/app/lead/core.hook`:
++ axle
$% [%0 p=(map ,@t ,@ud)]
==
is the first arm inside our leading `|%` that's important to notice.
`++axle` defines the tile for our state. By convention we store our
state as a [`$%`](), or labelled cases. We assume that our state can be
versioned, so we want its model to be one of many tagged cases. This
makes it possible to migrate our state to a new version of the service.
Since this is the first version of our app, we tag our state with `%0`.
In this simple application we're keeping track of pairs of names to
scores, and we define that here as `(map ,@t ,@ud)`. You can think of
this kind of like an associative array of strings to numbers, or an
object with string keys and numeric values.
When we use `++axle` to define the type of our state it's kind of like
declaring a schema definition. There's no secondary data storage layer.
Since `%gall` services run permanently your data persists as normal
application state. We use tiles the way we normally would to declare the
type of data that we're passing around.
Looking ahead, you can see that our main `|_` takes a `++axle` as part
of its sample. Let's look at how that core actually works, to get a
sense of what our application is doing.
4.
Where do requests go?
In `/main/app/lead/core.hook`:
++ peer
|= [ost=bone you=ship pax=path]
^- [(list move) _+>]
?~ pax
[[ost %give %rust %json vat-json]~ +>.$]
:_ +>.$
:_ ~
?+ -.pax
=- [ost %give %mean -]
`[%not-found [%leaf "you need to specify a path"]~]
%data
=- [ost %give %rush %json -]
(joba %conn %b &)
==
is the most important arm to look at first. `++peer` is one of the
predefined arms that `%gall` calls when certain events happen. You can
find them all in the [`%gall` overview]().
We 'get a `++peer`' when we get either a HTTP request, or a subscription
request. Each time this happens our main `|_` is populated with a
`++hide` and our current `++axle` in its sample and `++peer` gets passed
three things: `[ost=bone you=ship pax=path]`. The sample in the `|_`
that contains `++peer` is our application state and all of the contained
arms have access to that sample as part of their context. To change the
state we simply produce a new context with changed values.
Let's look at each of these parts of our context and the sample in
`++peer`.
`++hide`, labelled `hid` in peer's context, gives us some information
about the `++request` being passed in. You can look at the specifics in
the [`%arvo` `++models`](), but for our purposes we can think of it
simply as request metadata.
`++axle`, labelled as `vat` in peer's context, should be familiar from
the discussion in the previous step.
`ost` is a `++bone`, or an identifier for an `%arvo` duct. 'Duct' is
actually a pretty good word for what a ++duct does. Informally, when an
event is processed in `%arvo` we patch together our requisite
computations with `++ducts`. For example, when we get a network packet,
parse it, pass it to the webserver, and then pass it to the application
framework we use a `++duct` to make all those connections. In `++peer`
our ost just identifies the incoming request by number. We don't have
access to the connecting `++duct`, but we use `ost` in the effects we
produce so our responses are correctly coupled to the incoming request.
`you` is a `++ship`, which is just a [`@p`]() or a phonemic string like
`~tasfyn- partyv`. `%eyre` does some work to figure out who this is, or
uses a submarine name if it can't be determined. You can read more about
how we parse identities in `%eyre` in the [`%eyre` reference]().
`pax` is a `++path`, or a list of `@ta`. In Hoon we most often write
paths as you would expect, `/something/like/this`. In `%gall` services
requests come in on a specific path, like `/data` or `/`.
`++peer`, as with any arm that handles events, must produce a pair of a
`(list ++move)` and our context, with any intended changes. In this peer
we handle two cases, when `pax` is empty, or `~`, when our `pax` is
`/data`. We throw an error if `pax` is anything else.
5.
What exactly is a list of moves?
Try pointing your browser at:
http://localhost:8082/lead/
to see our response when `pax` in `++peer` is `~`. In our case we use
this URL to load the initial state of the application as JSON. This is
produced by the line `[[ost %give %rust %json vat-json]~ +>.$]` which
produces a single `++move`, and our local context. Let's look more
closely at our `++move`.
++ move ,[p=bone q=[%give gift]] :: output operation
From our prior discussion we're familiar with a `++bone`, and `++gift`
is defined right above in `core.hook`:
++ gift :: output action
$% [%rust gilt] :: total update
[%rush gilt] :: partial update
[%mean (unit (pair term (list tank)))] :: Error, maybe w/ msg
[%nice ~] :: Response message
==
::
Which clearly depends on `++gilt`:
++ gilt :: subscription frame
$% [%hymn p=manx] :: html tree
[%json p=json] :: json
==
::
`++gift` defines the possible actions we can take in the moves that we
produce. We can send either partial or total updates with `%rush` or
`%rust` respectively. We can also send either an error, `%mean` or
default acknowledgement, `%nice`.
Returning to our original `++move`, `[ost %give %rust %json vat-json]`
we can now read it as 'send a total update with `++vat-json` as
`++json`'. `++vat-json` simply takes our `(map @t @ud)` and turns it in
to JSON.
Looking at the remainer of `++peer` we can see that it is mostly
control-flow that produces a `%mean` if our `pax` is not matched, and a
`%rush` if our `pax` is `%data`. We'll revisit this `%data` path later
on.
5.
How do we change our state?
All of our state changes happen in `++poke-json`. Incoming messages are
handled by `++poke` arms in `%gall` services. If an incoming message has
a `%logo` it is appeneded after a `-`. Messages from the web are often
sent as JSON, so `++poke- json` is common for services that face the
web.
Let's walk through this part:
=. p.vat
(~(put by p.vat) newl)
:_ +>.$
:* [ost %give %nice ~]
(deliver %upd-lead (joba -.newl [%n (scot %ud +.newl)]))
==
Using [`=.`]() we update the value of `p.vat` in our context using
[`put:by`](), one of our map container functions. Then, we produce
`+>.$` as our context. Since we have changed the value of `p.vat` within
our immediate context, `$`, this is equivalient to updating the state of
our service. Changing a value in your context and producing it is all
you need to do to update your permanent state. That's one of the main
goals of `%gall`, to be a single-level store.
So, how did we get to this point in `++poke-json`?
=+ ^= jop
^- kiss
%- need %. jon
=> jo %- of
:~ [%new-lead so]
[%add-lead so]
==
6.
`++deliver`
7.
main.js

View File

@ -0,0 +1 @@
A fully featured app using %ford and %gall

100
docs/pub/doc/guide/e-dev.md Normal file
View File

@ -0,0 +1,100 @@
Doing development can be a messy process. Since Urbit ships are meant to
last forever it can be convenient to development on a disposable ship as
to not permanently destroy any of your own part of the urbit network. In
this short guide we're going to go over how to set up a fake network for
development on a single physical machine.
This guide assumes that you have already followed the [setup
instructions](). Going forward we'll refer to the directory you cloned
the repo in as `/$URB_DIR`.
1.
Start a fake `vere` for the carrier `~zod`.
In `/$URB_DIR`, run
$ bin/vere -F -I ~zod -c zod
This will boot `vere` into the carrier `~zod`. Because we're using the
flag `-F` `vere` doesn't check any of the keys to confirm that we are in
fact the owner of `~zod`. We use `-I` here to signal to `vere` that we
want to start an 'imperial' ship, or carrier. `-I` takes a ship name.
You can enter any one of the 256 Urbit carriers. More information on
`vere` and its command line options can be found [here]().
You should see `vere` start as usual, although instead of copying its
files from a parent ship the files are copied from `urb/zod` inside your
Urbit directory.
For most development tasks, using a fake carrier works really well. You
get a very short name, and a safe testing environment. If you need to
test out a collection of ships talking to each other, let's keep going.
2.
Start a second fake `vere`.
In a new terminal, cd to `/$URB_DIR` and run:
$ bin/vere -F -c doznec
Since we don't specify a carrier with `-I` here, this should boot into a
submarine, as if you had started vere normally. In your running fake
`~zod` you should see a [`~&`]() alerting you that the sub you just
started is your neighbor. This means that a key exchange has happened,
and your packets are being transmitted directly. Now, let's get a ticket
for a cruiser.
In your fake `~zod`, ticket a cruiser:
~zod/try=> :ticket ~doznec
This line should return a `[ship: ticket]` pair of [`@p`](). You can Now
you can return to your submarine and run:
~sipmyl-wolmeb-haswel-losmyl--dibten-holdyn-dacdyn-natsep/try=> :begin
Use the `[ship: ticket]` pair you got from your fake `~zod` to complete
the `:begin` process for `~doznec`. When finished you should see
something like `; ~doznec _doz_ is your neighbor` on your fake `~zod`.
You can repeat this process on `~doznec`, ticketing destroyers that are
children of `~doznec` by running `:ticket` with a valid destroyer.
`:ticket` actually takes two arguments, a ship name and a number
indicating how many tickets to generate. `~tasfyn-partyv` is the first
destroyer under `~doznec`, so you can run `:ticket ~tasfyn-partyv 5` to
get five `[ship: ticket]` pairs.
3.
Add some files, make sure the network if functioning.
You should now have a directory `/$URB_DIR/zod`.
In
/$URB_DIR/zod/zod/try/test.txt
Put
hello from mars
You should see a sync event on `~zod` indicated by a `+` with the file
path, and at least one `%merge-fine` messages on `~doznec`. On your
filesystem, you should see the file mirrored in
`/$URB_DIR/doznec/doznec/try/test.txt`.
You can also send a few `:hi` messages over the network. On `~doznec`
try:
~doznec/try=> :hi ~zod "just checking in from urth"
You should see the message appear on your `~zod` and get a
`hi ~zod successful` on your `~doznec`.
This is a good way to set up a test environment where you can try
anything out and break anything you want. When working in these test
environments it is usually safest to keep your working files outside of
your pier and copy them in. This way you can quickly
`rm -rf zod/ && bin/vere -F -I ~zod -c zod` to start again.

24
docs/pub/doc/hoon.md Normal file
View File

@ -0,0 +1,24 @@
<div class="short">
hoon
====
hoon is our programming language.
hoon is a strict, typed, functional language that compiles itself to
nock. The hoon compiler is 4000 lines of hoon. Adding standard
libraries, the self-compiling kernel is 8000 lines. The hoon compiler is
located towards the bottom of `/=main=/arvo/hoon.hoon`. The standard
library is split between `/=main=/arvo/hoon.hoon` and
`/=main=/arvo/zuse.hoon`.
hoon has no particular familial relationship to other languages you may
know. It uses its own type inference algorithm and is as different from
Haskell as from Lisp. hoon syntax is also completely unfamiliar. hoon
uses ascii digraphs, which we call 'runes', instead of reserved words.
</div>
------------------------------------------------------------------------
<list></list>

View File

@ -0,0 +1,4 @@
Library
=======
<list dataPreview="true"></list>

View File

@ -0,0 +1,37 @@
volume 0, Kelvin Versioning
===========================
### ++hoon
++ hoon %164 :: version stub
Declares the current Hoon version number in degrees Kelvin.
When normal people release normal software, they count by fractions, and
they count up. Thus, they can keep extending and revising their systems
incrementally. This is generally considered a good thing. It generally
is.
In some cases, however, specifications needs to be permanently frozen.
This requirement is generally found in the context of standards. Some
standards are extensible or versionable, but some are not. ASCII, for
instance, is perma-frozen. So is IPv4 (its relationship to IPv6 is
little more than nominal - if they were really the same protocol, they'd
have the same ethertype). Moreover, many standards render themselves
incompatible in practice through excessive enthusiasm for extensibility.
They may not be perma-frozen, but they probably should be.
The true, Martian way to perma-freeze a system is what I call Kelvin
versioning. In Kelvin versioning, releases count down by integer degrees
Kelvin. At absolute zero, the system can no longer be changed. At 1K,
one more modification is possible. And so on. For instance, Nock is at
5K. It might change, though it probably won't. Nouns themselves are at
0K - it is impossible to imagine changing anything about their three
sentence definition.
------------------------------------------------------------------------
~zod/try=> stub
164
------------------------------------------------------------------------

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,450 @@
chapter 2a, basic unsigned math
===============================
### ++add
Add
++ add :: add
~/ %add
|= [a=@ b=@]
^- @
?: =(0 a) b
$(a (dec a), b +(b))
::
Produces the sum of `a` and `b` as an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (add 2 2)
4
~zod/try=> (add 1 1.000.000)
1.000.001
~zod/try=> (add 1.333 (mul 2 2))
1.337
------------------------------------------------------------------------
### ++cap
Tree head
++ cap :: tree head
~/ %cap
|= a=@
^- ?(%2 %3)
?- a
%2 %2
%3 %3
?(%0 %1) !!
* $(a (div a 2))
==
::
Tests whether an `a` is in the head or tail of a noun. Produces the
[cube]() `%2` if it is within the head, or the [cube]() `%3` if is is
within the tail.
`a` is an [atom]().
~zod/try=> (cap 4)
%2
~zod/try=> (cap 6)
%3
~zod/try=> (cap (add 10 9))
%2
------------------------------------------------------------------------
### ++dec
Decrement
++ dec :: decrement
~/ %dec
|= a=@
~| %decrement-underflow
?< =(0 a)
=+ b=0
|- ^- @
?: =(a +(b)) b
$(b +(b))
::
Produces `a-1` as an atom.
`a` is an [atom]().
~zod/try=> (dec 7)
6
~zod/try=> (dec 0)
! decrement-underflow
! exit
------------------------------------------------------------------------
### ++div
Divide
++ div :: divide
~/ %div
|= [a=@ b=@]
^- @
~| 'div'
?< =(0 b)
=+ c=0
|-
?: (lth a b) c
$(a (sub a b), c +(c))
::
Computes `a` divided by `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (div 4 2)
2
~zod/try=> (div 17 8)
2
~zod/try=> (div 20 30)
0
------------------------------------------------------------------------
### ++fac
Factorial
++ fac :: factorial
~/ %fac
|= a=@
^- @
?: =(0 a) 1
(mul a $(a (dec a)))
::
Computes the factorial of `a`, producing an atom.
`a` is an [atom]().
~zod/try=> (fac 3)
6
~zod/try=> (fac 0)
1
~zod/try=> (fac 11)
39.916.800
------------------------------------------------------------------------
### ++gte
Greater-than/equal
++ gte :: greater-equal
~/ %gte
|= [a=@ b=@]
^- ?
!(lth a b)
::
Tests whether `a` is greater than a number `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (gte 100 10)
%.y
~zod/try=> (gte 4 4)
%.y
~zod/try=> (gte 3 4)
%.n
------------------------------------------------------------------------
### ++gth
Greater-than
++ gth :: greater-than
~/ %gth
|= [a=@ b=@]
^- ?
!(lte a b)
::
Tests whether `a` is greater than `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (gth 'd' 'c')
%.y
~zod/try=> (gth ~h1 ~m61)
%.n
------------------------------------------------------------------------
### ++lte
Less-than/equal
++ lte :: less-equal
~/ %lte
|= [a=@ b=@]
|(=(a b) (lth a b))
::
Tests whether `a` is less than or equal to `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (lte 4 5)
%.y
~zod/try=> (lte 5 4)
%.n
~zod/try=> (lte 5 5)
%.y
~zod/try=> (lte 0 0)
%.y
------------------------------------------------------------------------
### ++lth
Less-than
++ lth :: less-than
~/ %lth
|= [a=@ b=@]
^- ?
?& !=(a b)
|-
?| =(0 a)
?& !=(0 b)
$(a (dec a), b (dec b))
== == ==
::
Tests whether `a` is less than `b`, producing a loobean.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (lth 4 5)
%.y
~zod/try=> (lth 5 4)
%.n
~zod/try=> (lth 5 5)
%.n
~zod/try=> (lth 5 0)
%.n
------------------------------------------------------------------------
### ++mas
Axis within head/tail
++ mas :: tree body
~/ %mas
|= a=@
^- @
?- a
1 !!
2 1
3 1
* (add (mod a 2) (mul $(a (div a 2)) 2))
==
::
------------------------------------------------------------------------
Computes the axis of `a` within the head or the tail, producing an atom.
`a` is an [atom]().
~zod/try=> (mas 3)
1
~zod/try=> (mas 4)
2
~zod/try=> (mas 5)
3
~zod/try=> (mas 6)
2
~zod/try=> (mas 0)
! exit
~zod/try=> (mas 1)
! exit
### ++max
Maximum
++ max :: maximum
~/ %max
|= [a=@ b=@]
^- @
?: (gth a b) a
b
::
Computes the maximum of `a` and `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (max 10 100)
100
~zod/try=> (max 10.443 9)
10.443
~zod/try=> (max 0 1)
1
------------------------------------------------------------------------
### ++min
Minimum
++ min :: minimum
~/ %min
|= [a=@ b=@]
^- @
?: (lth a b) a
b
::
Computes the minimum of `a` and `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (min 10 100)
10
~zod/try=> (min 10.443 9)
9
~zod/try=> (min 0 1)
0
------------------------------------------------------------------------
### ++mod
Modulus
++ mod :: remainder
~/ %mod
|= [a=@ b=@]
^- @
?< =(0 b)
(sub a (mul b (div a b)))
::
Computes the remainder of dividing `a` by `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
------------------------------------------------------------------------
### ++mul
Multiply
++ mul :: multiply
~/ %mul
|= [a=@ b=@]
^- @
=+ c=0
|-
?: =(0 a) c
$(a (dec a), c (add b c))
::
Multiplies `a` by `b`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (mul 3 4)
12
~zod/try=> (mul 0 1)
0
------------------------------------------------------------------------
### ++peg
Axis within axis
++ peg :: tree connect
~/ %peg
|= [a=@ b=@]
^- @
?- b
1 a
2 (mul a 2)
3 +((mul a 2))
* (add (mod b 2) (mul $(b (div b 2)) 2))
==
::
Computes the axis of `b` within axis `a`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (peg 4 1)
4
~zod/try=> (peg 4 2)
8
~zod/try=> (peg 8 45)
269
------------------------------------------------------------------------
### ++sub
Subtract
++ sub :: subtract
~/ %sub
|= [a=@ b=@]
~| %subtract-underflow
^- @
?: =(0 b) a
$(a (dec a), b (dec b))
Subtracts `b` from `a`, producing an atom.
`a` is an [atom]().
`b` is an [atom]().
~zod/try=> (sub 10 5)
5
~zod/try=> (sub 243 44)
199
~zod/try=> (sub 5 0)
5
~zod/try=> (sub 0 5)
! subtract-underflow
! exit
------------------------------------------------------------------------

View File

@ -0,0 +1,897 @@
chapter 2b, basic containers
============================
Section 2bA, units
------------------
### ++biff
Unit as argument
++ biff :: apply
|* [a=(unit) b=$+(* (unit))]
?~ a ~
(b u.a)
Applies a gate that produces a unit, `b`, to the value (`u.a`) of a unit
`a`. If `a` is empty, `~` is produced.
`a` is a [unit]().
`b` is a [gate]() that accepts a noun and produces a unit.
~zod/try=> (biff (some 5) |=(a=@ (some (add a 2))))
[~ u=7]
~zod/try=> (biff ~ |=(a=@ (some (add a 2))))
~
------------------------------------------------------------------------
### ++bind
Bind
++ bind :: argue
|* [a=(unit) b=gate]
?~ a ~
[~ u=(b u.a)]
Applies a function `b` to the value (`u.a`) of a unit `a`, producing a
unit.
`a` is a [unit]()
`b` is a [gate]().
~zod/try=> (bind ((unit ,@) [~ 97]) ,@t)
[~ `a`]
~zod/try=> =a |=(a=@ (add a 1))
~zod/try=> (bind ((unit ,@) [~ 2]) a)
[~ 3]
------------------------------------------------------------------------
### ++bond
Replace null
++ bond :: replace
|* a=trap
|* b=(unit)
?~ b $:a
u.b
Replaces an empty unit `b` with the product of a kicked trap `a`. If the
unit is not empty, then the original unit is produced.
`a` is a [trap]().
`b` is a [unit]().
~zod/try=> (bex 10)
1.024
~zod/try=> ((bond |.((bex 10))) ~)
1.024
~zod/try=> ((bond |.((bex 10))) (slaw %ud '123'))
123
------------------------------------------------------------------------
### ++both
Group unit values
++ both :: all the above
|* [a=(unit) b=(unit)]
?~ a ~
?~ b ~
[~ u=[u.a u.b]]
Produces a unit whose value is a cell of the values of two input units
`a` and `b`. If either of the two units are empty, `~` is produced.
`a` is a [unit]().
`b` is a [unit]().
~zod/try=> (both (some 1) (some %b))
[~ u=[1 %b]]
~zod/try=> (both ~ (some %b))
~
------------------------------------------------------------------------
### ++clap
Apply gate to two units
++ clap :: combine
|* [a=(unit) b=(unit) c=_|=(^ +<-)]
?~ a b
?~ b a
[~ u=(c u.a u.b)]
Applies a binary operation `c` which produces a unit to the values of
two units `a` and `b`.
`a` is a [unit]().
`b` is a [unit]().
`c` is a [gate]() that performs a binary operation.
~zod/try=> =u ((unit ,@t) [~ 'a'])
~zod/try=> =v ((unit ,@t) [~ 'b'])
~zod/try=> (clap u v |=([a=@t b=@t] (welp (trip a) (trip b))))
[~ u="ab"]
~zod/try=> =a ((unit ,@u) [~ 1])
~zod/try=> =b ((unit ,@u) [~ 2])
~zod/try=> =c |=([a=@ b=@] (add a b))
~zod/try=> (clap a b c)
[~ 3]
------------------------------------------------------------------------
### ++drop
Unit list
++ drop :: enlist
|* a=(unit)
?~ a ~
[i=u.a t=~]
Produces a [list]() of the value from a unit `a`.
`a` is a [unit]().
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> (drop a)
[i=97 t=~]
~zod/try=> =a ((unit ,@) [~])
~zod/try=> (drop a)
~
------------------------------------------------------------------------
### ++fall
Default unit
++ fall :: default
|* [a=(unit) b=*]
?~(a b u.a)
Produces a default value `b` for a unit `a` in cases where the unit is
null.
`a` is a [unit]().
`b` is a [noun]() used as the default value.
~zod/try=> (fall ~ `a`)
`a`
~zod/try=> (fall [~ u=0] `a`)
0
------------------------------------------------------------------------
### ++lift
Fmap
++ lift :: lift gate (fmap)
|* a=gate :: flipped
|* b=(unit) :: curried
(bind b a) :: bind
Similar to `fmap` in Haskell: accepts a gate `a` that accepts and
produces an unwrapped value, passes it the value of a unit `b`, and then
produces a unit value.
`a` is a [gate]().
`b` is a [unit]().
~zod/try=> ((lift dec) `(unit ,@)`~)
~
~zod/try=> ((lift dec) `(unit ,@)`[~ 20])
[~ 19]
------------------------------------------------------------------------
### ++mate
Choose
++ mate :: choose
|* [a=(unit) b=(unit)]
?~ b a
?~ a b
?.(=(u.a u.b) ~|('mate' !!) a)
Accepts two units `a` and `b` whose values are expected to be
equivalent. If either is empty, then the value of the other is produced.
If neither are empty, it asserts that both values are the same and
produces that value. If the assertion fails, `++mate` crashes with
`'mate'` in the stack trace.
`a` is a [unit]().
`b` is a [unit]().
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> =b ((unit ,@) [~ 97])
~zod/try=> (mate a b)
[~ 97]
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> =b ((unit ,@) [~])
~zod/try=> (mate a b)
[~ 97]
~zod/try=> =a ((unit ,@) [~ 97])
~zod/try=> =b ((unit ,@) [~ 98])
~zod/try=> (mate a b)
! 'mate'
! exit
------------------------------------------------------------------------
### ++need
Unwrap
++ need :: demand
|* a=(unit)
?~ a !!
u.a
Retrieve the value from a unit and crash if the unit is null.
`a` is a [unit]().
~zod/try=> =a ((unit ,[@t @t]) [~ ['a' 'b']])
~zod/try=> (need a)
['a' 'b']
~zod/try=> =a ((unit ,@ud) [~ 17])
~zod/try=> (need a)
17
~zod/try=> =a ((unit ,@) [~])
~zod/try=> (need a)
! exit
------------------------------------------------------------------------
### ++some
Unify
++ some :: lift (pure)
|* a=*
[~ u=a]
Takes any atom `a` and produces a unit with the value set to `a`.
`a` is a [noun]().
~zod/try=> (some [`a` `b`])
[~ u=[`a` `b`]]
~zod/try=> (some &)
[~ u=%.y]
------------------------------------------------------------------------
section 2bB, lists
------------------
Reverse
### ++flop
++ flop :: reverse
~/ %flop
|* a=(list)
=> .(a (homo a))
^+ a
=+ b=`_a`~
|-
?~ a b
$(a t.a, b [i.a b])
Produces the list `a` in reverse order.
`a` is a [list]().
~zod/try=> =a (limo [1 2 3 ~])
~zod/try=> (flop a)
~[3 2 1]
### ++homo
Homogenize
++ homo :: homogenize
|* a=(list)
^+ =< $
|% +- $ ?:(_? ~ [i=(snag 0 a) t=$])
--
a
Produces a list whose type is a fork of all the contained types in the
list `a`.
`a` is a [list]().
~zod/try=> lyst
[i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
~zod/try=> (homo lyst)
~[1 97 2 98 [~ u=10]]
~zod/try=> =a (limo [1 2 3 ~])
~zod/try=> a
[i=1 t=[i=2 t=[i=3 t=~]]]
~zod/try=> (homo a)
~[1 2 3]
### ++limo
List Constructor
++ limo :: listify
|* a=*
^+ =< $
|% +- $ ?~(a ~ ?:(_? i=-.a t=$ $(a +.a)))
--
a
Turns a null-terminated tuple into a list.
`a` is a null-terminated tuple.
~zod/try=> (limo [1 2 3 ~])
[i=1 t=[i=2 t=[i=3 t=~]]]
### ++lent
List length
++ lent :: length
~/ %lent
|= a=(list)
^- @
=+ b=0
|-
?~ a b
$(a t.a, b +(b))
Produces the length of any list `a` as an atom.
`a` is a [list]().
~zod/try=> (lent (limo [1 2 3 4 ~]))
4
~zod/try=> (lent (limo [1 'a' 2 'b' (some 10) ~]))
5
------------------------------------------------------------------------
### ++levy
"and" to list
++ levy
~/ %levy :: all of
|* [a=(list) b=_|=(p=* .?(p))]
|- ^- ?
?~ a &
?. (b i.a) |
$(a t.a)
Produces the Boolean "and" of the result of every element in list `a`
passed to gate `b`.
`a` is a [list]().
`b` is a [gate]().
~zod/try=> =a |=(a=@ (lte a 1))
~zod/try=> (levy (limo [0 1 2 1 ~]) a)
%.n
~zod/try=> =a |=(a=@ (lte a 3))
~zod/try=> (levy (limo [0 1 2 1 ~]) a)
%.y
------------------------------------------------------------------------
### ++lien
"or" to list
++ lien :: some of
~/ %lien
|* [a=(list) b=$+(* ?)]
|- ^- ?
?~ a |
?: (b i.a) &
$(a t.a)
Produces the Boolean "or" of the result of every element in list `a`
passed to gate `b`.
`a` is a [list]().
`b` is a [gate]().
~zod/try=> =a |=(a=@ (gte a 1))
~zod/try=> (lien (limo [0 1 2 1 ~]) a)
%.y
~zod/try=> =a |=(a=@ (gte a 3))
~zod/try=> (lien (limo [0 1 2 1 ~]) a)
%.n
------------------------------------------------------------------------
### ++murn
Maybe transform
++ murn :: maybe transform
|* [a=(list) b=$+(* (unit))]
|-
?~ a ~
=+ c=(b i.a)
?~ c
$(a t.a)
[i=u.c t=$(a t.a)]
Passes each member of list `a` to gate `b`, which must produce a unit.
Produces a new list with all the results that do not produce `~`.
`a` is a [list]().
`b` is a [gate]() that produces a [unit]().
~zod/try=> =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
~zod/try=> (murn (limo [0 1 2 3 ~]) a)
[i=12 t=[i=13 t=~]]
### ++reap
Replicate
++ reap :: replicate
|* [a=@ b=*]
|- ^- (list ,_b)
?~ a ~
[b $(a (dec a))]
Replicate: produces a list containing `a` copies of `b`.
`a` is an [atom]()
`b` is a [noun]()
~zod/try=> (reap 20 %a)
~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
~zod/try=> (reap 5 ~s1)
~[~s1 ~s1 ~s1 ~s1 ~s1]
~zod/try=> `@dr`(roll (reap 5 ~s1) add)
~s5
------------------------------------------------------------------------
### ++reel
Right fold
++ reel :: right fold
~/ %reel
|* [a=(list) b=_|=([* *] +<+)]
|- ^+ +<+.b
?~ a
+<+.b
(b i.a $(a t.a))
Right fold: moves right to left across a list `a`, recursively slamming
a binary gate `b` with an element from `a` and an accumulator, producing
the final value of the accumulator.
`a` is a [list]().
`b` is a binary [gate]().
~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
~zod/try=> (reel (limo [1 2 3 4 5 ~]) sum)
15
~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
~zod/try=> (reel (limo [6 3 1 ~]) a)
4
~zod/try=> (reel (limo [3 6 1 ~]) a)
! subtract-underflow
! exit
------------------------------------------------------------------------
### ++roll
Left fold
++ roll :: left fold
~/ %roll
|* [a=(list) b=_|=([* *] +<+)]
|- ^+ +<+.b
?~ a
+<+.b
$(a t.a, b b(+<+ (b i.a +<+.b)))
Left fold: moves left to right across a list `a`, recursively slamming a
binary gate `b` with an element from the list and an accumulator,
producing the final value of the accumulator.
`a` is a [list]().
`b` is a binary [gate]().
~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
~zod/try=> (roll (limo [1 2 3 4 5 ~]) sum)
q=15
~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
~zod/try=> (roll (limo [6 3 1 ~]) a)
! subtract-underflow
! exit
~zod/try=> (roll (limo [1 3 6 ~]) a)
q=4
------------------------------------------------------------------------
### ++skid
Separate
++ skid :: separate
|* [a=(list) b=$+(* ?)]
|- ^+ [p=a q=a]
?~ a [~ ~]
=+ c=$(a t.a)
?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
Seperates a list `a` into two lists - Those elements of `a` who produce
true when slammed to gate `b` and those who produce `%.n`.
`a` is a [list]().
`b` is a [gate]() that accepts one argument and produces a loobean.
~zod/try=> =a |=(a=@ (gth a 1))
~zod/try=> (skid (limo [0 1 2 3 ~]) a)
[p=[i=2 t=[i=3 t=~]] q=[i=0 t=[i=1 t=~]]]
------------------------------------------------------------------------
### ++skim
Suffix
++ skim :: only
~/ %skim
|* [a=(list) b=_|=(p=* .?(p))]
|-
^+ a
?~ a ~
?:((b i.a) [i.a $(a t.a)] $(a t.a))
Cycles through the members of a list `a`, passing them to a gate `b` and
producing a list of all of the members that produce `%.y`. Inverse of
`++skip`.
`a` is a [list]().
`b` is a [gate]() that accepts one argument and produces a loobean.
~zod/try=> =a |=(a=@ (gth a 1))
~zod/try=> (skim (limo [0 1 2 3 ~]) a)
[i=2 t=[i=3 t=~]]
------------------------------------------------------------------------
### ++skip
Except
++ skip :: except
~/ %skip
|* [a=(list) b=_|=(p=* .?(p))]
|-
^+ a
?~ a ~
?:((b i.a) $(a t.a) [i.a $(a t.a)])
Cycles through the members of a list `a`, passing them to a gate `b` and
producing a list of all of the members that produce `%.n`. Inverse of
`++skim`.
`a` is a [list]().
`b` is a [gate]() that accepts one argument and produces a loobean.
~zod/try=> =a |=(a=@ (gth a 1))
~zod/try=> (skip (limo [0 1 2 3 ~]) a)
[i=0 t=[i=1 t=~]]
------------------------------------------------------------------------
### ++scag
Prefix
++ scag :: prefix
~/ %scag
|* [a=@ b=(list)]
|- ^+ b
?: |(?=(~ b) =(0 a)) ~
[i.b $(b t.b, a (dec a))]
Accepts an atom `a` and list `b`, producing the first `a` elements of
the front of the list.
`a` is an [atom]().
`b` is a [list]().
~zod/try=> (scag 2 (limo [0 1 2 3 ~]))
[i=0 t=[i=1 t=~]]
~zod/try=> (scag 10 (limo [1 2 3 4 ~]))
[i=1 t=[i=2 t=[i=3 t=[i=4 t=~]]]]
------------------------------------------------------------------------
### ++slag
Suffix
++ slag :: suffix
~/ %slag
|* [a=@ b=(list)]
|- ^+ b
?: =(0 a) b
?~ b ~
$(b t.b, a (dec a))
Accepts an atom `a` and list `b`, producing the remaining elements from
`b` starting at `a`.
`a` is an [atom]().
`b` is a [list]().
~zod/try=> (slag 2 (limo [1 2 3 4 ~]))
[i=3 t=[i=4 t=~]]
~zod/try=> (slag 1 (limo [1 2 3 4 ~]))
[i=2 t=[i=3 t=[i=4 t=~]]]
------------------------------------------------------------------------
### ++snag
Index
++ snag :: index
~/ %snag
|* [a=@ b=(list)]
|-
?~ b
~|('snag-fail' !!)
?: =(0 a) i.b
$(b t.b, a (dec a))
Accepts an atom `a` and a list `b`, producing the element at the index
of `a`and failing if the list is null. Lists are 0-indexed.
`a` is an [atom]().
`b` is a [list]().
~zod/try=> (snag 2 "asdf")
~~d
~zod/try=> (snag 0 `(list ,@ud)`~[1 2 3 4])
1
------------------------------------------------------------------------
### ++sort
Quicksort
++ sort :: quicksort
~/ %sort
|* [a=(list) b=$+([* *] ?)]
=> .(a ^.(homo a))
|- ^+ a
?~ a ~
%+ weld
$(a (skim t.a |=(c=_i.a (b c i.a))))
^+ t.a
[i.a $(a (skim t.a |=(c=_i.a !(b c i.a))))]
Quicksort: accepts a list `a` and a gate `b` which accepts two nouns and
produces a loobean. `++sort` then produces a list of the elements of `a`
sorted according to `b`.
`a` is an [atom]().
`b` is a [gate]() which accepts two nouns and produces a loobean.
~zod/try=> =a =|([p=@ q=@] |.((gth p q)))
~zod/try=> (sort (limo [0 1 2 3 ~]) a)
~[3 2 1 0]
------------------------------------------------------------------------
### ++swag
Infix
++ swag :: infix
|* [[a=@ b=@] c=(list)]
(scag b (slag a c))
Similar to `substr` in Javascript: extracts a string infix, beginning at
inclusive index `a`, producing `b` number of characters.
`a` and `b` are [atom]()s.
`c` is a [list]().
~zod/try=> (swag [2 5] "roly poly")
"ly po"
~zod/try=> (swag [2 2] (limo [1 2 3 4 ~]))
[i=3 t=[i=4 t=~]]
------------------------------------------------------------------------
### ++turn
Gate to list
++ turn :: transform
~/ %turn
|* [a=(list) b=_,*]
|-
?~ a ~
[i=(b i.a) t=$(a t.a)]
Accepts a list `a` and a gate `b`. Produces a list with the gate applied
to each element of the original list.
`a` is a [list]().
`b` is a [gate]().
~zod/try=> (turn (limo [104 111 111 110 ~]) ,@t)
<|h o o n|>
~zod/try=> =a |=(a=@ (add a 4))
~zod/try=> (turn (limo [1 2 3 4 ~]) a)
~[5 6 7 8]
------------------------------------------------------------------------
### ++weld
Concatenate
++ weld :: concatenate
~/ %weld
|* [a=(list) b=(list)]
=> .(a ^.(homo a), b ^.(homo b))
|- ^+ b
?~ a b
[i.a $(a t.a)]
Concatenate two lists `a` and `b`.
`a` and `b` are [list]()s.
~zod/try=> (weld "urb" "it")
~[~~u ~~r ~~b ~~i ~~t]
~zod/try=> (weld (limo [1 2 ~]) (limo [3 4 ~]))
~[1 2 3 4]
------------------------------------------------------------------------
### ++welp
Perfect weld
++ welp :: perfect weld
=| [* *]
|%
+- $
?~ +<-
+<-(. +<+)
+<-(+ $(+<- +<->))
--
Concatenate two lists `a` and `b` without losing their type information
to homogenization.
`a` and `b` are [list]()s.
~zod/try=> (welp "foo" "bar")
"foobar"
~zod/arvo=/hoon/hoon> (welp ~[60 61 62] ~[%a %b %c])
[60 61 62 %a %b %c ~]
~zod/arvo=/hoon/hoon> :type; (welp ~[60 61 62] ~[%a %b %c])
[60 61 62 %a %b %c ~]
[@ud @ud @ud %a %b %c %~]
~zod/arvo=/hoon/hoon> (welp [sa/1 so/2 ~] si/3)
[[%sa 1] [%so 2] %si 3]
------------------------------------------------------------------------
### ++wild
XXDELETE
++ wild :: concatenate
|* [a=(list) b=(list)]
=> .(a ^.(homo a), b ^.(homo b))
|-
?~ a b
[i=i.a $(a t.a)]
Concatenates two lists `a` and `b`, homogenizing their types
individually.
`a` and `b` are [list]()s.
~zod/try=> (wild (limo ~[1 2 3]) (limo [4]~))
~[1 2 3 4]
~zod/try=> (wild (limo 60 61 62 ~) (limo %a %b %c ~))
[i=60 [i=61 [i=62 ~[%a %b %c]]]]
~zod/try=> (weld (limo 60 61 62 ~) (limo %a %b %c ~))
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.000 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.001 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.002 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.004 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 15].[10.016 57]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 29].[10.006 44]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.056 3].[10.061 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.058 3].[10.061 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.059 3].[10.061 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.060 5].[10.060 47]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.826 7].[9.844 35]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 7].[9.844 35]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 11].[9.838 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.828 11].[9.838 13]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.829 13].[9.831 47]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.830 13].[9.831 47]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.706 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.707 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.708 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 7].[9.712 25]>
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 8].[9.712 25]>
! exit
------------------------------------------------------------------------
### ++zing
Cons
++ zing :: promote
=| *
|%
+- $
?~ +<
+<
(welp +<- $(+< +<+))
--
Turns a list of lists into a single list by promoting the elements of
each sublist into the higher.
Accepts a [list]() of lists.
~zod/try=> (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
~zod/try=> (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
~[1 97 2 98 3 99 4 100]

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,437 @@
section 2dA, sets
=================
### ++apt
Set verification
++ apt :: set invariant
|= a=(tree)
?~ a
&
?& ?~(l.a & ?&((vor n.a n.l.a) (hor n.l.a n.a)))
?~(r.a & ?&((vor n.a n.r.a) (hor n.a n.r.a)))
==
::
Produces a loobean indicating whether `a` is a set or not.
`a` is a [tree]().
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (apt b)
%.y
~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ['c' 4] ['d' 5] ~])
~zod/try=> m
{[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
~zod/try=> (apt m)
%.y
------------------------------------------------------------------------
### ++in
Set operations
++ in :: set engine
~/ %in
|/ a=(set)
Input arm.
~zod/try=> ~(. in (sa "asd"))
<13.evb [nlr(^$1{@tD $1}) <414.fvk 101.jzo 1.ypj %164>]>
`a` is a [set]()
### +-all:in
Logical AND
+- all :: logical AND
~/ %all
|* b=$+(* ?)
|- ^- ?
?~ a
&
?&((b n.a) $(a l.a) $(a r.a))
::
Computes the logical AND on every element in `a` slammed with `b`,
producing a loobean.
`a` is a [set]().
`b` is a [wet gate]() that accepts a noun and produces a loobean.
~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(all in b) |=(a=* ?@(+.a & |)))
%.n
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (~(all in b) |=(a=@t (gte a 100)))
%.y
------------------------------------------------------------------------
### +-any:in
Logical OR
+- any :: logical OR
~/ %any
|* b=$+(* ?)
|- ^- ?
?~ a
|
?|((b n.a) $(a l.a) $(a r.a))
::
Computes the logical OR on every element of `a` slammed with `b`.
`a` is a [set]().
`b` is a [gate]() that accepts a noun and produces a loobean.
~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(any in b) |=(a=* ?@(+.a & |)))
%.y
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (~(any in b) |=(a=@t (lte a 100)))
%.n
------------------------------------------------------------------------
### +-del:in
Remove noun
+- del :: b without any a
~/ %del
|* b=*
|- ^+ a
?~ a
~
?. =(b n.a)
?: (hor b n.a)
[n.a $(a l.a) r.a]
[n.a l.a $(a r.a)]
|- ^- ?(~ _a)
?~ l.a r.a
?~ r.a l.a
?: (vor n.l.a n.r.a)
[n.l.a l.l.a $(l.a r.l.a)]
[n.r.a $(r.a l.r.a) r.r.a]
::
Removes `b` from the set `a`.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =b (sa `(list ,@t)`['a' 'b' 'c' ~])
~zod/try=> (~(del in b) 'a')
{'c' 'b'}
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
~zod/try=> (~(del in b) 'john')
{'bonita' 'madeleine' 'daniel'}
~zod/try=> (~(del in b) 'susan')
{'bonita' 'madeleine' 'daniel' 'john'}
------------------------------------------------------------------------
### +-dig:in
Axis a in b
+- dig :: axis of a in b
|= b=*
=+ c=1
|- ^- (unit ,@)
?~ a ~
?: =(b n.a) [~ u=(peg c 2)]
?: (gor b n.a)
$(a l.a, c (peg c 6))
$(a r.a, c (peg c 7))
::
Produce the axis of `b` within `a`.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =a (sa `(list ,@)`[1 2 3 4 5 6 7 ~])
~zod/try=> a
{5 4 7 6 1 3 2}
~zod/try=> -.a
n=6
~zod/try=> (~(dig in a) 7)
[~ 12]
~zod/try=> (~(dig in a) 2)
[~ 14]
~zod/try=> (~(dig in a) 6)
[~ 2]
------------------------------------------------------------------------
### +-gas:in
Concatenate
+- gas :: concatenate
~/ %gas
|= b=(list ,_?>(?=(^ a) n.a))
|- ^+ a
?~ b
a
$(b t.b, a (put(+< a) i.b))
::
Insert the elements of a list `b` into a set `a`.
`a` is a [set]().
`b` is a [list]().
~zod/try=> b
{'bonita' 'madeleine' 'rudolf' 'john'}
~zod/try=> (~(gas in b) `(list ,@t)`['14' 'things' 'number' '1.337' ~])
{'1.337' '14' 'number' 'things' 'bonita' 'madeleine' 'rudolf' 'john'}
~zod/try=> (~(gas in s) `(list ,@t)`['1' '2' '3' ~])
{'1' '3' '2' 'e' 'd' 'a' 'c' 'b'}
------------------------------------------------------------------------
### +-has:in
b in a?
+- has :: b exists in a check
~/ %has
|* b=*
|- ^- ?
?~ a
|
?: =(b n.a)
&
?: (hor b n.a)
$(a l.a)
$(a r.a)
::
Checks if `b` is an element of `a`, producing a loobean.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
~zod/try=> (~(has in a) `a`)
%.y
~zod/try=> (~(has in a) 'z')
%.n
------------------------------------------------------------------------
### +-int:in
Intersection
+- int :: intersection
~/ %int
|* b=_a
|- ^+ a
?~ b
~
?~ a
~
?. (vor n.a n.b)
$(a b, b a)
?: =(n.b n.a)
[n.a $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor n.b n.a)
%- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
%- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
Produces a set of the intersection between two sets of the same type,
`a` and `b`.
`a` is a [set]().
`b` is a [set]().
~zod/try=> (~(int in (sa "ac")) (sa "ha"))
{~~a}
~zod/try=> (~(int in (sa "acmo")) ~)
{}
~zod/try=> (~(int in (sa "acmo")) (sa "ham"))
{~~a ~~m}
~zod/try=> (~(int in (sa "acmo")) (sa "lep"))
{}
------------------------------------------------------------------------
### +-put:in
Put b in a
+- put :: puts b in a
~/ %put
|* b=*
|- ^+ a
?~ a
[b ~ ~]
?: =(b n.a)
a
?: (hor b n.a)
=+ c=$(a l.a)
?> ?=(^ c)
?: (vor n.a n.c)
[n.a c r.a]
[n.c l.c [n.a r.c r.a]]
=+ c=$(a r.a)
?> ?=(^ c)
?: (vor n.a n.c)
[n.a l.a c]
[n.c [n.a l.a l.c] r.c]
::
Add an element `b` to the set `a`.
`a` is a [set]().
`b` is a [noun]().
~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
~zod/try=> =b (~(put in a) `d`)
~zod/try=> b
{`d` `a` `c` `b`}
~zod/try=> -.l.+.b
n=`d`
------------------------------------------------------------------------
### +-rep:in
Accumulate
+- rep :: replace by tile
|* [b=* c=_,*]
|-
?~ a b
$(a r.a, b $(a l.a, b (c n.a b)))
::
Accumulate the elements of `a` using a gate `c` and an accumulator `b`.
`a` is a [set]().
`b` is a [noun]() that accepts a noun and produces a loobean.
`c` is a [gate]().
~zod/try=> =a (~(gas in *(set ,@)) [1 2 3 ~])
~zod/try=> a
{1 3 2}
~zod/try=> (~(rep in a) 0 |=([a=@ b=@] (add a b)))
6
------------------------------------------------------------------------
### +-tap:in
Set to list
+- tap :: list tiles a set
~/ %tap
|= b=(list ,_?>(?=(^ a) n.a))
^+ b
?~ a
b
$(a r.a, b [n.a $(a l.a)])
::
Flatten the set `a` into a list.
`a` is an [set]().
`a` is a [set]().
`b` is a [list]().
~zod/try=> =s (sa `(list ,@t)`['a' 'b' 'c' 'd' 'e' ~])
~zod/try=> s
{'e' 'd' 'a' 'c' 'b'}
~zod/try=> (~(tap in s) `(list ,@t)`['1' '2' '3' ~])
~['b' 'c' 'a' 'd' 'e' '1' '2' '3']
~zod/try=> b
{'bonita' 'madeleine' 'daniel' 'john'}
~zod/try=> (~(tap in b) `(list ,@t)`['david' 'people' ~])
~['john' 'daniel' 'madeleine' 'bonita' 'david' 'people']
------------------------------------------------------------------------
### +-uni:in
Union
+- uni :: union
~/ %uni
|* b=_a
|- ^+ a
?~ b
a
?~ a
b
?: (vor n.a n.b)
?: =(n.b n.a)
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor n.b n.a)
$(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
$(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
?: =(n.a n.b)
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
?: (hor n.a n.b)
$(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
$(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
Produces a set of the union between two sets of the same type, `a` and
`b`.
`a` is a [set]().
`b` is a [set]().
~zod/try=> (~(uni in (sa "ac")) (sa "ha"))
{~~a ~~c ~~h}
~zod/try=> (~(uni in (sa "acmo")) ~)
{~~a ~~c ~~m ~~o}
~zod/try=> (~(uni in (sa "acmo")) (sa "ham"))
{~~a ~~c ~~m ~~o ~~h}
~zod/try=> (~(uni in (sa "acmo")) (sa "lep"))
{~~e ~~a ~~c ~~m ~~l ~~o ~~p}
------------------------------------------------------------------------
### +-wyt:in
Set size
+- wyt :: size of set
|- ^- @
?~(a 0 +((add $(a l.a) $(a r.a))))
Produce the number of elements in set `a` as an atom.
`a` is an [set]().
~zod/try=> =a (~(put in (~(put in (sa)) 'a')) 'b')
~zod/try=> ~(wyt in a)
2
~zod/try=> b
{'bonita' 'madeleine' 'daniel' 'john'}
~zod/try=> ~(wyt in b)
4
------------------------------------------------------------------------

View File

@ -0,0 +1,813 @@
section 2dB, maps
=================
### ++ept
Map invariant.
++ ept :: map invariant
|= a=(tree ,[p=* q=*])
?~ a
&
?& ?~(l.a & ?&((vor p.n.a p.n.l.a) (hor p.n.l.a p.n.a)))
?~(r.a & ?&((vor p.n.a p.n.r.a) (hor p.n.a p.n.r.a)))
==
Computes whether `a` is a [map](), producing a loobean.
`a` is a [tree]().
~zod/try=> m
{[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
~zod/try=> (ept m)
%.y
~zod/try=> b
{'bonita' 'madeleine' 'daniel' 'john'}
~zod/try=> (ept b)
! type-fail
! exit
------------------------------------------------------------------------
### ++ja
Jar engine
++ ja :: jar engine
|/ a=(jar)
A container arm for `++jar` operation arms. A `++jar` is a `++map` of
`++list`s. The contained arms inherit the [sample]() jar.
`a` is a [jar]().
~zod/try=> ~(. ja (mo (limo a/"ho" b/"he" ~)))
<2.dgz [nlr([p={%a %b} q=""]) <414.fvk 101.jzo 1.ypj %164>]>
------------------------------------------------------------------------
### +-get:ja
Grab value by key
+- get :: grab value by key
|* b=*
=+ c=(~(get by a) b)
?~(c ~ u.c)
Produces a list retrieved from jar `a` using the key `b`.
`a` is a [`++jar`]().
`b` is a key of the same type as the keys in `a`.
~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
~zod/try=> l
{[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(get ja l) 'a')
~[1 2 3]
~zod/try=> (~(get ja l) 'b')
~[4 5 6]
~zod/try=> (~(get ja l) 'c')
~
------------------------------------------------------------------------
### +-add:ja
Prepend to list
+- add :: adds key-list pair
|* [b=* c=*]
=+ d=(get(+< a) b)
(~(put by a) b [c d])
Produces jar `a` with value `c` prepended to the list located at key
`b`.
`a` is a [jar]().
`b` is a key of the same type as the keys in `a`.
`c` is a value of the same type as the values in `a`.
~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
~zod/try=> l
{[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(add ja l) 'b' 7)
{[p='a' q=~[1 2 3]] [p='b' q=~[7 4 5 6]]}
~zod/try=> (~(add ja l) 'a' 100)
{[p='a' q=~[100 1 2 3]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(add ja l) 'c' 7)
{[p='a' q=~[1 2 3]] [p='c' q=~[7]] [p='b' q=~[4 5 6]]}
~zod/try=> (~(add ja l) 'c' `(list ,@)`[7 8 9 ~])
! type-fail
! exit
------------------------------------------------------------------------
### ++ju
Jug operations
++ ju :: jug engine
|/ a=(jug)
Container arm for jug operation arms. A `++jug` is a `++map` of
`++sets`. The contained arms inherit its [sample]() jug, `a`.
`a` is a [jug]().
~zod/try=> ~(. ju (mo (limo a/(sa "ho") b/(sa "he") ~)))
<2.dgz [nlr([p={%a %b} q={nlr(^$1{@tD $1}) nlr(^$3{@tD $3})}]) <414.fvk 101.jzo 1.ypj %164>]>
### +-del:ju
Remove
+- del :: delete at key b
|* [b=* c=*]
^+ a
=+ d=(get(+< a) b)
=+ e=(~(del in d) c)
?~ e
(~(del by a) b)
(~(put by a) b e)
Produces jug `a` with value `c` removed from set located at key `b`.
`a` is a [jug]().
`b` is a key of the same type as the keys in `a`.
`c` is the value of the same type of the keys in `a` that is to be
removed.
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(del ju s) 'a' 1)
{[p='a' q={3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(del ju s) 'c' 7)
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
------------------------------------------------------------------------
### +-get:ju
Retrieve set
+- get :: gets set by key
|* b=*
=+ c=(~(get by a) b)
?~(c ~ u.c)
Produces a set retrieved from jar `a` using key `b`.
`a` is a [jar]().
`b` is a key of the same type as the keys in `a`.
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(get ju s) 'a')
{1 3 2}
~zod/try=> (~(get ju s) 'b')
{5 4 6}
~zod/try=> (~(get ju s) 'c')
~
------------------------------------------------------------------------
### +-has:ju
Check contents
+- has :: existence check
|* [b=* c=*]
^- ?
(~(has in (get(+< a) b)) c)
Computes whether a value `c` exists within the set located at key `b`
with jar `a`. Produces a loobean.
`a` is a [set]().
`b` is a key as a [noun]().
`c` is a value as a [noun]().
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(has ju s) 'a' 3)
%.y
~zod/try=> (~(has ju s) 'b' 6)
%.y
~zod/try=> (~(has ju s) 'a' 7)
%.n
~zod/try=> (~(has jus s) 'c' 7)
! -find-limb.jus
! find-none
! exit
~zod/try=> (~(has ju s) 'c' 7)
%.n
------------------------------------------------------------------------
### +-put:ju
Add key-set pair
+- put :: adds key-element pair
|* [b=* c=*]
^+ a
=+ d=(get(+< a) b)
(~(put by a) b (~(put in d) c))
Produces jar `a` with `c` added to the set value located at key `b`.
`a` is a [set]().
`b` is a key as a [noun]().
`c` is a [value]().
~zod/try=> s
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(put ju s) 'a' 7)
{[p='a' q={7 1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(put ju s) 'a' 1)
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
~zod/try=> (~(put ju s) 'c' 7)
{[p='a' q={1 3 2}] [p='c' q={7}] [p='b' q={5 4 6}]}
------------------------------------------------------------------------
### ++by
Map operations
++ by :: map engine
~/ %by
|/ a=(map)
Container arm for map operation arms. A map is a set of key, value
pairs. The contained arms inherit it's [sample]() [map](), `a`.
`a` is a [map]().
~zod/try=> ~(. by (mo (limo [%a 1] [%b 2] ~)))
<19.irb [nlr([p={%a %b} q=@ud]) <414.rvm 101.jzo 1.ypj %164>]>
------------------------------------------------------------------------
### +-all:by
Logical AND
+- all :: logical AND
~/ %all
|* b=$+(* ?)
|- ^- ?
?~ a
&
?&((b q.n.a) $(a l.a) $(a r.a))
Computes the logical AND on the results of slamming every element in map
`a` with gate `b`. Produces a loobean.
`a` is a [map]().
`b` is a [wet gate]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
%.n
~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
~zod/try=> (~(all by a) |=(a=@ (lte a 6)))
%.y
~zod/try=> (~(all by a) |=(a=@ (lte a 4)))
%.n
------------------------------------------------------------------------
### +-any:by
Logical OR
+- any :: logical OR
~/ %any
|* b=$+(* ?)
|- ^- ?
?~ a
|
?|((b q.n.a) $(a l.a) $(a r.a))
Computes the logical OR on the results of slamming every element with
gate `b`. Produces a loobean.
`a` is a [map]().
`b` is a [wet gate]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
%.y
~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
~zod/try=> (~(any by a) |=(a=@ (lte a 4)))
%.y
------------------------------------------------------------------------
### +-del:by
Delete
+- del :: delete at key b
~/ %del
|* b=*
|- ^+ a
?~ a
~
?. =(b p.n.a)
?: (gor b p.n.a)
[n.a $(a l.a) r.a]
[n.a l.a $(a r.a)]
|- ^- ?(~ _a)
?~ l.a r.a
?~ r.a l.a
?: (vor p.n.l.a p.n.r.a)
[n.l.a l.l.a $(l.a r.l.a)]
[n.r.a $(r.a l.r.a) r.r.a]
Produces map `a` with the element located at key `b` removed.
`a` is a [map]().
`b` is a key as a [noun]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(del by b) `a`)
{[p=`b` q=[2 3]]}
------------------------------------------------------------------------
### +-dig:by
Axis of key
+- dig :: axis of key
|= b=*
=+ c=1
|- ^- (unit ,@)
?~ a ~
?: =(b p.n.a) [~ u=(peg c 2)]
?: (gor b p.n.a)
$(a l.a, c (peg c 6))
$(a r.a, c (peg c 7))
Produce the axis of key `b` within map `a`.
`a` is a [map]().
`b` is a key as a [noun]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(dig by b) `b`)
[~ 2]
------------------------------------------------------------------------
### +-gas:by
Concatenate
+- gas :: concatenate
~/ %gas
|* b=(list ,[p=* q=*])
=> .(b `(list ,_?>(?=(^ a) n.a))`b)
|- ^+ a
?~ b
a
$(b t.b, a (put(+< a) p.i.b q.i.b))
Insert a list of key-value pairs `b` into map `a`.
`a` is a [map]().
`b` is a [list]() of [cells]() of key-value nouns `p` and `q`.
~zod/try=> =a (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
~zod/try=> =b `(list ,[@t *])`[[`c` 3] [`d` 4] ~]
~zod/try=> (~(gas by a) b)
{[p=`d` q=4] [p=`a` q=1] [p=`c` q=3] [p=`b` q=2]}
------------------------------------------------------------------------
### +-get:by
Grab unit value
+- get :: unit value by key
~/ %get
|* b=*
|- ^- ?(~ [~ u=_?>(?=(^ a) q.n.a)])
?~ a
~
?: =(b p.n.a)
[~ u=q.n.a]
?: (gor b p.n.a)
$(a l.a)
$(a r.a)
Produce the unit value of the value located at key `b` within map `a`.
`a` is a [map]()
`b` is a [key]() as a [noun]()
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(get by b) `b`)
[~ [2 3]]
------------------------------------------------------------------------
### +-got:by
Assert
+- got
|* b=*
%- need
%- get(+< a) b
Produce the value located at key `b` within map `a`. Crash if key `b`
does not exist.
`a` is a [map]().
`b` is a [key]().
~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' 2] ~])
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(get by m) 'a')
[~ 1]
~zod/try=> (~(got by m) 'a')
1
~zod/try=> (~(got by m) 'c')
! exit
------------------------------------------------------------------------
### +-has:by
Key existence check
+- has :: key existence check
~/ %has
|* b=*
!=(~ (get(+< a) b))
Checks whether map `a` contains an element with key `b`, producing a
loobean.
`a` is a [map]().
`b` is a key as a [noun]().
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
~zod/try=> (~(has by b) `b`)
%.y
~zod/try=> (~(has by b) `c`)
%.n
------------------------------------------------------------------------
### +-int:by
Intersection
+- int :: intersection
~/ %int
|* b=_a
|- ^+ a
?~ b
~
?~ a
~
?: (vor p.n.a p.n.b)
?: =(p.n.b p.n.a)
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor p.n.b p.n.a)
%- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
%- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
?: =(p.n.a p.n.b)
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
?: (hor p.n.a p.n.b)
%- uni(+< $(b l.b, a [n.a l.a ~])) $(a r.a)
%- uni(+< $(b r.b, a [n.a ~ r.a])) $(a l.a)
Produces a map of the (key) intersection between two maps of the same
type, `a` and `b`. If both maps have an identical key that point to
different values, the element from map `b` is used.
`a` is a [map]().
`b` is a [map]().
~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 3] ~])
~zod/try=> n
{[p='a' q=1] [p='c' q=3]}
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(int by m) n)
{[p='a' q=1]}
~ravpel-holber/try=> =p (mo `(list ,[@t *])`[['a' 2] ['b' 2] ~])
~zod/try=> p
{[p='a' q=2] [p='b' q=2]}
~zod/try=> (~(int by p) n)
{[p='a' q=2]}
~zod/try=> =q (mo `(list ,[@t *])`[['a' 2] ['c' 2] ~])
~zod/try=> q
{[p='a' q=2] [p='b' q=2]}
~zod/try=> (~(int by p) q)
{[p='a' q=2] [p='b' q=2]}
~zod/try=> =o (mo `(list ,[@t *])`[['c' 3] ['d' 4] ~])
~zod/try=> (~(int by m) o)
{}
------------------------------------------------------------------------
### +-mar:by
Assert and Add
+- mar :: add with validation
|* [b=_?>(?=(^ a) p.n.a) c=(unit ,_?>(?=(^ a) q.n.a))]
?~ c
(del b)
(put b u.c)
Produces map `a` with the addition of a key-value pair, where the value
is a nonempty unit.
Accept a noun and a unit of a noun of the type of the map's keys and
values, respectively. Validate that the value is not null and put the
pair in the map. If the value is null, delete the key.
XX This arm is broken, asana task 15186618346453
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(mar by m) 'c' (some 3))
! -find-limb.n
! find-none
! exit
~zod/try=> (~(mar by m) 'c' ~)
! -find-limb.n
! find-none
! exit
~zod/try=> (~(mar by m) 'b' ~)
! -find-limb.n
! find-none
! exit
------------------------------------------------------------------------
### +-put:by
Add key-value pair
+- put :: adds key-value pair
~/ %put
|* [b=* c=*]
|- ^+ a
?~ a
[[b c] ~ ~]
?: =(b p.n.a)
?: =(c q.n.a)
a
[[b c] l.a r.a]
?: (gor b p.n.a)
=+ d=$(a l.a)
?> ?=(^ d)
?: (vor p.n.a p.n.d)
[n.a d r.a]
[n.d l.d [n.a r.d r.a]]
=+ d=$(a r.a)
?> ?=(^ d)
?: (vor p.n.a p.n.d)
[n.a l.a d]
[n.d [n.a l.a l.d] r.d]
Produces `a` with the addition of the key-value pair of `b` and `c`.
`a` is a [map]().
`b` is a key of the same type as the keys in `a`.
`c` is a value of the same type of the values in `a`.
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(put by m) 'c' 3)
{[p='a' q=1] [p='c' q=3] [p='b' q=2]}
~zod/try=> (~(put by m) "zod" 26)
! type-fail
! exit
~zod/try=> (~(put by m) 'a' 2)
{[p='a' q=2] [p='b' q=2]}
------------------------------------------------------------------------
### +-rep:by
+- rep :: replace by product
|* [b=* c=_,*]
|-
?~ a b
$(a r.a, b $(a l.a, b (c q.n.a b)))
Accumulate using gate from values in map
XX interface changing.
------------------------------------------------------------------------
### +-rib:by
+- rib :: transform + product
|* [b=* c=_,*]
|- ^+ [b a]
?~ a [b ~]
=+ d=(c n.a b)
=. n.a +.d
=+ e=$(a l.a, b -.d)
=+ f=$(a r.a, b -.e)
[-.f [n.a +.e +.f]]
Replace values with accumulator
XX interface changing, possibly disappearing
------------------------------------------------------------------------
### +-run:by
Transform values
+- run :: turns to tuples
|* b=_,*
|-
?~ a a
a(n (b q.n.a), l $(a l.a), r $(a r.a))
Iterates over every value in set `a` using gate `b`. Produces a map.
`a` is a [map]().
`b` is a [wet gate]().
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> ^+(m (~(run by m) dec))
{[p='a' q=0] [p='b' q=1]}
~zod/try=> `(map ,@tas ,@t)`(~(run by m) (cury scot %ux))
{[p=%a q='0x1'] [p=%b q='0x2']}
------------------------------------------------------------------------
### +-tap:by
Listify pairs
+- tap :: listify pairs
~/ %tap
|= b=(list ,_?>(?=(^ a) n.a))
^+ b
?~ a
b
$(a r.a, b [n.a $(a l.a)])
Produces the list of all elements in map `a` that is prepended to list
`b`, which is empty by default.
`a` is a [map]().
`b` is a [list]().
{[p='a' q=1] [p='b' q=2]}
~zod/try=> `*`m
[[98 2] [[97 1] 0 0] 0]
~zod/try=> (~(tap by m))
~[[p='b' q=2] [p='a' q=1]]
~zod/try=> `*`(~(tap by m))
[[98 2] [97 1] 0]
------------------------------------------------------------------------
### +-uni:by
Union
+- uni :: union, merge
~/ %uni
|* b=_a
|- ^+ a
?~ b
a
?~ a
b
?: (vor p.n.a p.n.b)
?: =(p.n.b p.n.a)
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
?: (hor p.n.b p.n.a)
$(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
$(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
?: =(p.n.a p.n.b)
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
?: (hor p.n.a p.n.b)
$(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
$(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
Produces a map of the union between the keys of `a` and `b`. If `b`
shares a key with `a`, the tuple from `a` is preserved.
`a` is a [map]().
`b` is a [map]().
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> o
{[p='d' q=4] [p='c' q=3]}
~zod/try=> (~(uni by m) o)
{[p='d' q=4] [p='a' q=1] [p='c' q=3] [p='b' q=2]}
~zod/try=> (~(uni by m) ~)
{[p='a' q=1] [p='b' q=2]}
~zod/try=> n
{[p='a' q=1] [p='c' q=9]}
~zod/try=> (~(uni by o) n)
{[p='d' q=4] [p='a' q=1] [p='c' q=3]}
~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 9] ~])
~zod/try=> n
{[p='a' q=1] [p='c' q=9]}
~zod/try=> (~(uni by o) n)
{[p='d' q=4] [p='a' q=1] [p='c' q=9]}
------------------------------------------------------------------------
### +-urn:by
Turn (with key)
+- urn :: turn
|* b=$+([* *] *)
|-
?~ a ~
[n=[p=p.n.a q=(b p.n.a q.n.a)] l=$(a l.a) r=$(a r.a)]
Iterates over every value in map `a` using gate `b`, which accepts both
the key and the value of each element as its sample.
`a` is a [map]().
`b` is a [wet gate]() that accepts two nouns (a key and a value) and
produces a noun (the new value).
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(urn by m) |=(a=[p=* q=*] q.a))
{[p='a' q=1] [p='b' q=2]}
~zod/try=> (~(urn by m) |=(a=[p=* q=*] 7))
{[p='a' q=7] [p='b' q=7]}
~zod/try=> (~(urn by m) |=(a=[p=* q=*] p.a))
{[p='a' q=97] [p='b' q=98]}
------------------------------------------------------------------------
### +-wyt:by
Depth
+- wyt :: depth of map
|- ^- @
?~(a 0 +((add $(a l.a) $(a r.a))))
Produce the depth of the tree map `a`.
`a` is a [map]().
~zod/try=> m
{[p='a' q=1] [p='b' q=2]}
~zod/try=> o
{[p='d' q=4] [p='c' q=3]}
~zod/try=> ~(wyt by m)
2
~zod/try=> ~(wyt by o)
2
~zod/try=> ~(wyt by (~(uni by m) o))
4
------------------------------------------------------------------------

View File

@ -0,0 +1,221 @@
section 2dC, queues
===================
### ++to
Queue engine
++ to :: queue engine
|/ a=(qeu)
Container arm for queue operation arms. The contained arms inherit its
[sample]() `++qeu` `a`.
`a` is a queue, [++qeu]().
### +-bal:to
Balance
+- bal
|- ^+ a
?~ a ~
?. |(?=(~ l.a) (vor n.a n.l.a))
$(a [n.l.a l.l.a $(a [n.a r.l.a r.a])])
?. |(?=(~ r.a) (vor n.a n.r.a))
$(a [n.r.a $(a [n.a l.a l.r.a]) r.r.a])
a
::
Vertically rebalances queue `a`.
`a` is a [queue]().
~zod/try=> `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
{"a" "b" "c" "d" "e" "f" "g"}
~zod/try=> `*`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
[[97 0] 0 [98 0] 0 [99 0] 0 [100 0] 0 [101 0] 0 [102 0] 0 [103 0] 0 0]
~zod/try=> ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
{"a" "b" "c" "d" "e" "f" "g"}
~zod/try=> `*`~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
[[100 0] [[99 0] [[98 0] [[97 0] 0 0] 0] 0] [101 0] 0 [102 0] 0 [103 0] 0 0]
------------------------------------------------------------------------
### +-dep:to
Maximum Depth
+- dep :: max depth of queue
|- ^- @
?~ a 0
+((max $(a l.a) $(a r.a)))
::
Produces the maximum depth of leaves (r.a and l.a) in queue `a`.
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 7 ~])
~zod/try=> ~(dep to a)
4
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 ~])
~zod/try=> ~(dep to a)
3
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 ~])
~zod/try=> ~(dep to a)
2
~zod/try=> ~(dep to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
7
~zod/try=> ~(dep to ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]))
4
------------------------------------------------------------------------
### +-gas
Push list
+- gas :: insert list to queue
|= b=(list ,_?>(?=(^ a) n.a))
|- ^+ a
?~(b a $(b t.b, a (put(+< a) i.b)))
::
Push all elements of list `b` into the queue.
`a` is a [queue]().
`b` is a list.
~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
{3 2 1}
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
~zod/try=> =b `(list ,@)`[4 5 6 ~]
~zod/try=> (~(gas to a) b)
{6 5 4 3 2 1}
------------------------------------------------------------------------
### +-get:to
Pop
+- get :: head-tail pair
|- ^+ [p=?>(?=(^ a) n.a) q=a]
?~ a
!!
?~ r.a
[n.a l.a]
=+ b=$(a r.a)
:- p.b
?: |(?=(~ q.b) (vor n.a n.q.b))
[n.a l.a q.b]
[n.q.b [n.a l.a l.q.b] r.q.b]
::
Produces the head and tail queue of `a`.
`a` is a [queue]().
~zod/try=> =s (~(gas to *(qeu ,@)) `(list ,@)`~[1 2 3])
~zod/try=> ~(get to s)
[p=1 q={3 2}]
~zod/try=> ~(get to ~)
! exit
------------------------------------------------------------------------
### +-nap:to
Remove last in
+- nap :: removes head
?> ?=(^ a)
?: =(~ l.a) r.a
=+ b=get(+< l.a)
bal(+< ^+(a [p.b q.b r.a]))
::
Removes the head of queue `a`, producing the resulting queue.
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
~zod/try=> -.a
n=6
~zod/try=> =b ~(nap to a)
~zod/try=> -.b
n=2
~zod/try=> b
{5 4 3 2 1}
~zod/try=> a
{6 5 4 3 2 1}
------------------------------------------------------------------------
### +-put:to
Insert
+- put :: insert new tail
|* b=*
|- ^+ a
?~ a
[b ~ ~]
bal(+< a(l $(a l.a)))
::
Accept any noun `b` and adds to queue `a` as the head, producing the
resulting queue.
`a` is a [queue]().
`b` is any noun.
~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
~zod/try=> (~(put to a) 7)
{7 6 5 4 2 1 3}
------------------------------------------------------------------------
### +-tap:to
Queue to list
+- tap :: queue to list
|= b=(list ,_?>(?=(^ a) n.a))
^+ b
?~ a
b
$(a r.a, b [n.a $(a l.a)])
::
Produces queue `a` as a list from front to back.
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
~zod/try=> `*`a
[6 0 2 [4 [5 0 0] 0] 1 0 3 0 0]
~zod/try=> (~(tap to a) `(list ,@)`[99 100 101 ~])
~[3 1 2 4 5 6 99 100 101]
------------------------------------------------------------------------
### +-top:to
+- top :: produces head
|- ^- (unit ,_?>(?=(^ a) n.a))
?~ a ~
?~(r.a [~ n.a] $(a r.a))
Produces the head of queue `a` as a unit (an empty queue has no head).
`a` is a [queue]().
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
~zod/try=> ~(top to a)
[~ 1]
------------------------------------------------------------------------

View File

@ -0,0 +1,69 @@
section 2dD, casual containers
==============================
### ++mo
Map from list
++ mo :: map from list
|* a=(list)
=> .(a `_(homo a)`a)
=> .(a `(list ,[p=_-<.a q=_->.a])`a)
=+ b=*(map ,_?>(?=(^ a) p.i.a) ,_?>(?=(^ a) q.i.a))
(~(gas by b) a)
::
Produces a map of key-value pairs from the left-right cell pairs of list
`a`.
`a` is a [list]().
~zod/try=> (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
{[p=`a` q=1] [p=`b` q=2]}
------------------------------------------------------------------------
### ++sa
Set from list
++ sa :: set from list
|* a=(list)
=> .(a `_(homo a)`a)
=+ b=*(set ,_?>(?=(^ a) i.a))
(~(gas in b) a)
::
Produces a set of the elements in list `a`.
`a` is a [list]().
~zod/try=> (sa `(list ,@)`[1 2 3 4 5 ~])
{5 4 1 3 2}
~zod/try=> (sa `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
{[`a` 1] [`b` 2]}
------------------------------------------------------------------------
### ++qu
Queue from list
++ qu :: queue from list
|* a=(list)
=> .(a `_(homo a)`a)
=+ b=*(qeu ,_?>(?=(^ a) i.a))
(~(gas to b) a)
Produces a queue from list `a`.
`a` is a [list]().
~zod/try=> (qu `(list ,@ud)`~[1 2 3 5])
{5 3 2 1}
~zod/try=> (qu "sada")
{'a' 'd' 'a' 's'}
~zod/try=> ~(top to (qu "sada"))
[~ 's']
------------------------------------------------------------------------

View File

@ -0,0 +1,162 @@
section 2eA, packing
====================
### ++cue
Unpack atom to noun
++ cue :: unpack atom to noun
~/ %cue
|= a=@
^- *
=+ b=0
=+ m=`(map ,@ ,*)`~
=< q
|- ^- [p=@ q=* r=_m]
?: =(0 (cut 0 [b 1] a))
=+ c=(rub +(b) a)
[+(p.c) q.c (~(put by m) b q.c)]
=+ c=(add 2 b)
?: =(0 (cut 0 [+(b) 1] a))
=+ u=$(b c)
=+ v=$(b (add p.u c), m r.u)
=+ w=[q.u q.v]
[(add 2 (add p.u p.v)) w (~(put by r.v) b w)]
=+ d=(rub c a)
[(add 2 p.d) (need (~(get by m) q.d)) m]
::
Produces a noun unpacked from atom `a`. The inverse of jam.
`a` is an [atom]().
~zod/try=> (cue 12)
1
~zod/try=> (cue 817)
[1 1]
~zod/try=> (cue 4.657)
[1 2]
~zod/try=> (cue 39.689)
[0 19]
------------------------------------------------------------------------
### ++jam
++ jam :: pack
~/ %jam
|= a=*
^- @
=+ b=0
=+ m=`(map ,* ,@)`~
=< q
|- ^- [p=@ q=@ r=_m]
=+ c=(~(get by m) a)
?~ c
=> .(m (~(put by m) a b))
?: ?=(@ a)
=+ d=(mat a)
[(add 1 p.d) (lsh 0 1 q.d) m]
=> .(b (add 2 b))
=+ d=$(a -.a)
=+ e=$(a +.a, b (add b p.d), m r.d)
[(add 2 (add p.d p.e)) (mix 1 (lsh 0 2 (cat 0 q.d q.e))) r.e]
?: ?&(?=(@ a) (lte (met 0 a) (met 0 u.c)))
=+ d=(mat a)
[(add 1 p.d) (lsh 0 1 q.d) m]
=+ d=(mat u.c)
[(add 2 p.d) (mix 3 (lsh 0 2 q.d)) m]
::
Produces an atom unpacked from noun `a`. The inverse of cue.
`a` is a [noun]().
~zod/try=> (jam 1)
12
~zod/try=> (jam [1 1])
817
~zod/try=> (jam [1 2])
4.657
~zod/try=> (jam [~ u=19])
39.689
------------------------------------------------------------------------
### ++mat
Length-encode
++ mat :: length-encode
~/ %mat
|= a=@
^- [p=@ q=@]
?: =(0 a)
[1 1]
=+ b=(met 0 a)
=+ c=(met 0 b)
:- (add (add c c) b)
(cat 0 (bex c) (mix (end 0 (dec c) b) (lsh 0 (dec c) a)))
Produces a cell whose tail `q` is atom `a` with a bit representation of
its length prepended to it (as the least significant bits). The head `p`
is the length of `q` in bits.
`a` is an atom.
~zod/try=> (mat 0xaaa)
[p=20 q=699.024]
~zod/try=> (met 0 q:(mat 0xaaa))
20
~zod/try=> `@ub`q:(mat 0xaaa)
0b1010.1010.1010.1001.0000
~zod/try=> =a =-(~&(- -) `@ub`0xaaa)
0b1010.1010.1010
~zod/try=> =b =-(~&(- -) `@ub`(xeb a))
0b1100
~zod/try=> =b =-(~&(- -) `@ub`(met 0 a))
0b1100
~zod/try=> =c =-(~&(- -) (xeb b))
4
~zod/try=> [`@ub`a `@ub`(end 0 (dec c) b) `@ub`(bex c)]
[0b1010.1010.1010 0b100 0b1.0000]
------------------------------------------------------------------------
### ++rub
Length-decode
++ rub :: length-decode
~/ %rub
|= [a=@ b=@]
^- [p=@ q=@]
=+ ^= c
=+ [c=0 m=(met 0 b)]
|- ?< (gth c m)
?. =(0 (cut 0 [(add a c) 1] b))
c
$(c +(c))
?: =(0 c)
[1 0]
=+ d=(add a +(c))
=+ e=(add (bex (dec c)) (cut 0 [d (dec c)] b))
[(add (add c c) e) (cut 0 [(add d (dec c)) e] b)]
The inverse of `++mat`. Accepts a cell of index `a` and a bitstring `b`
and produces the cell whose tail `q` is the decoded atom at index `a`
and whose head is the length of the encoded atom `q`, by which the
offset `a` is advanced. Only used internally as a helper cue.
`a` is an atom.
`b` is a bitstring as an atom.
~zod/try=> `@ub`(jam 0xaaa)
0b1.0101.0101.0101.0010.0000
~zod/try=> (rub 1 0b1.0101.0101.0101.0010.0000)
[p=20 q=2.730]
~zod/try=> `@ux`q:(rub 1 0b1.0101.0101.0101.0010.0000)
0xaaa
------------------------------------------------------------------------

View File

@ -0,0 +1,63 @@
section 2eB, parsing (tracing)
==============================
### ++last
Farther trace
++ last |= [zyc=hair naz=hair] :: farther trace
^- hair
?: =(p.zyc p.naz)
?:((gth q.zyc q.naz) zyc naz)
?:((gth p.zyc p.naz) zyc naz)
::
Compares two line-column pairs, `zyc` and `naz`, and produces whichever
[hair]() is farther along.
`zyc` is a [hair]().
`naz` is a [hair]().
~zod/try=> (last [1 1] [1 2])
[p=1 q=2]
~zod/try=> (last [2 1] [1 2])
[p=2 q=1]
~zod/try=> (last [0 0] [99 0])
[p=99 q=0]
~zod/try=> (last [7 7] [7 7])
[p=7 q=7]
------------------------------------------------------------------------
### ++lust
Detect newline
++ lust |= [weq=char naz=hair] :: detect newline
^- hair
?:(=(10 weq) [+(p.naz) 1] [p.naz +(q.naz)])
Advances the hair `naz` by a row if the char `weq` is a newline, or by a
column if `weq` is any other character.
`weq` is a [char]().
`naz` is a [hair]().
~zod/try=> (lust `a` [1 1])
[p=1 q=2]
~zod/try=> (lust `@t`10 [1 1])
[p=2 q=1]
~zod/try=> (lust '9' [10 10])
[p=10 q=11]
/~zod/try=> (roll "maze" [.(+<+ [1 1])]:lust)
[1 5]
/~zod/try=> %- roll :_ [.(+<+ [1 1])]:lust
"""
Sam
lokes
"""
[2 6]
------------------------------------------------------------------------

View File

@ -0,0 +1,652 @@
section 2eC, parsing (custom rules)
===================================
### ++cold
Replace with constant
++ cold :: replace w/ constant
~/ %cold
|* [cus=* sef=_rule]
~/ %fun
|= tub=nail
=+ vex=(sef tub)
?~ q.vex
vex
[p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
::
Parser modifier. Accepts a rule `sef` and produces a parser that
produces a constant `cus`, if `sef` is successful.
`cus` is a constant [noun]().
`sef` is a [`++rule`]().
~zod/try=> ((cold %foo (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((cold %foo (just 'a')) [[1 1] "bc"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++cook
Apply gate
++ cook :: apply gate
~/ %cook
|* [poq=_,* sef=_rule]
~/ %fun
|= tub=nail
=+ vex=(sef tub)
?~ q.vex
vex
[p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
::
Parser modifier. Produces a parser that takes a (successful) result of a
rule `sef` and slams it through `poq`.
`poq` is a [gate]().
`sef` is a [`++rule`]().
~zod/try=> ((cook ,@ud (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((cook ,@tas (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
------------------------------------------------------------------------
### ++easy
Always parse
++ easy :: always parse
~/ %easy
|* huf=*
~/ %fun
|= tub=nail
^- (like ,_huf)
[p=p.tub q=[~ u=[p=huf q=tub]]]
::
Parser generator. Produces a parser that succeeds with given noun `huf`
without consuming any text.
~zod/try=> ((easy %foo) [[1 1] "abc"])
[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
~zod/try=> ((easy %foo) [[1 1] "bc"])
[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
~zod/try=> ((easy 'a') [[1 1] "bc"])
[p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
------------------------------------------------------------------------
### ++fail
Never parse
++ fail |=(tub=nail [p=p.tub q=~]) :: never parse
Produces an [edge]() at the same text position ([hair]()) with a failing
result (`q=~`).
`tub` is a [`++nail`]().
~zod/try=> (fail [[1 1] "abc"])
[p=[p=1 q=1] q=~]
~zod/try=> (fail [[p=1.337 q=70] "Parse me, please?"])
[p=[p=1.337 q=70] q=~]
------------------------------------------------------------------------
### ++full
Parse to end
++ full :: parse to end
|* sef=_rule
|= tub=nail
=+ vex=(sef tub)
?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
::
Accepts a [`++nail`](), `tub`, and produces a parser that succeeds only
when a `tub` success consumes the remainder of the [tape]().
`sef` is a [`++rule`]().
~zod/try=> ((full (just 'a')) [[1 1] "ab"])
[p=[p=1 q=2] q=~]
~zod/try=> ((full (jest 'ab')) [[1 1] "ab"])
[p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
~zod/try=> ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
[p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
------------------------------------------------------------------------
### ++funk
Add to tape
++ funk :: add to tape first
|* [pre=tape sef=_rule]
|= tub=nail
(sef p.tub (weld pre q.tub))
::
Parser modifier: prepend text to tape before applying parser.
`pre` is a [`++tape`]()
`sef` is a [`++rule`]()
~zod/try=> ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
~zod/try=> ((funk "parse" (just 'a')) [[1 4] " me"])
[p=[p=1 q=4] q=~]
------------------------------------------------------------------------
### ++here
Place-based apply
++ here :: place-based apply
~/ %here
|* [hez=_|=([a=pint b=*] [a b]) sef=_rule]
~/ %fun
|= tub=nail
=+ vex=(sef tub)
?~ q.vex
vex
[p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
::
Parser modifier. Similar to [`++cook`](), produces a parser that takes a
(successful) result of `sef` and slams it through `hez`. `hez` accepts a
[`++pint`]() `a` and a noun `b`, which is what the parser parsed.
`hez` is a [gate]().
`sef` is a [`++rule`]()
~zod/try=> (scan "abc" (star alf))
"abc"
~zod/try=> (scan "abc" (here |*(^ +<) (star alf)))
[[[p=1 q=1] p=1 q=4] "abc"]
~zod/try=> (scan "abc" (star (here |*(^ +<) alf)))
~[[[[p=1 q=1] p=1 q=2] ~~a] [[[p=1 q=2] p=1 q=3] ~~b] [[[p=1 q=3] p=1 q=4] ~~c]]
------------------------------------------------------------------------
### ++inde
Indentation block
++ inde |* sef=_rule :: indentation block
|= nail ^+ (sef)
=+ [har tap]=[p q]:+<
=+ lev=(fil 3 (dec q.har) ' ')
=+ eol=(just `@t`10)
=+ =- roq=((star ;~(pose prn ;~(sfix eol (jest lev)) -)) har tap)
;~(simu ;~(plug eol eol) eol)
?~ q.roq roq
=+ vex=(sef har(q 1) p.u.q.roq)
=+ fur=p.vex(q (add (dec q.har) q.p.vex))
?~ q.vex vex(p fur)
=- vex(p fur, u.q -)
:+ &3.vex
&4.vex(q.p (add (dec q.har) q.p.&4.vex))
=+ res=|4.vex
|- ?~ res |4.roq
?. =(10 -.res) [-.res $(res +.res)]
(welp [`@t`10 (trip lev)] $(res +.res))
::
Apply rule to indented block starting at current column number, omitting
the leading whitespace.
`sef` is a [`++rule`]()
~zod/try=> (scan "abc" (inde (star ;~(pose prn (just `@`10)))))
"abc"
~zod/try=> (scan "abc" (star ;~(pose prn (just `@`10))))
"abc"
~zod/try=> (scan " abc\0ade" ;~(pfix ace ace (star ;~(pose prn (just `@`10)))))
"abc
de"
~zod/try=> (scan " abc\0ade" ;~(pfix ace ace (inde (star ;~(pose prn (just `@`10))))))
! {1 6}
! exit
~zod/try=> (scan " abc\0a de" ;~(pfix ace ace (inde (star ;~(pose prn (just `@`10))))))
"abc
de"
------------------------------------------------------------------------
### ++jest
Match a cord
++ jest :: match a cord
|= daf=@t
|= tub=nail
=+ fad=daf
|- ^- (like ,@t)
?: =(0 daf)
[p=p.tub q=[~ u=[p=fad q=tub]]]
?: |(?=(~ q.tub) !=((end 3 1 daf) i.q.tub))
(fail tub)
$(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
::
Match and consume a cord.
`daf` is a `@t`
~zod/try=> ((jest 'abc') [[1 1] "abc"])
[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
~zod/try=> (scan "abc" (jest 'abc'))
'abc'
~zod/try=> (scan "abc" (jest 'acb'))
! {1 2}
! 'syntax-error'
! exit
~zod/try=> ((jest 'john doe') [[1 1] "john smith"])
[p=[p=1 q=6] q=~]
~zod/try=> ((jest 'john doe') [[1 1] "john doe"])
[p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
------------------------------------------------------------------------
### ++just
Match a char
++ just :: XX redundant, jest
~/ %just :: match a char
|= daf=char
~/ %fun
|= tub=nail
^- (like char)
?~ q.tub
(fail tub)
?. =(daf i.q.tub)
(fail tub)
(next tub)
::
Match and consume a single character.
`daf` is a [`++char`]()
~zod/try=> ((just 'a') [[1 1] "abc"])
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> (scan "abc" (just 'a'))
! {1 2}
! 'syntax-error'
! exit
~zod/try=> (scan "a" (just 'a'))
~~a
~zod/try=> (scan "%" (just '%'))
~~~25.
------------------------------------------------------------------------
### ++knee
Recursive parsers
++ knee :: callbacks
|* [gar=* sef=_|.(rule)]
|= tub=nail
^- (like ,_gar)
((sef) tub)
::
Used for recursive parsers, which would otherwise be infinite when
compiled.
`gar` is a noun.
`sef` is a [gate]() that accepts a [`++rule`]()
~zod/try=> |-(;~(plug prn ;~(pose $ (easy ~))))
! rest-loop
! exit
~zod/try=> |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
< 1.obo
[ c=c=tub=[p=[p=@ud q=@ud] q=""]
b
< 1.bes
[ c=tub=[p=[p=@ud q=@ud] q=""]
b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
v=<414.fvk 101.jzo 1.ypj %164>
]
>
a
... 450 lines omitted ...
]
>
~zod/try=> (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
[~~a "bcd"]
------------------------------------------------------------------------
### ++mask
Match char
++ mask :: match char in set
~/ %mask
|= bud=(list char)
~/ %fun
|= tub=nail
^- (like char)
?~ q.tub
(fail tub)
?. (lien bud |=(a=char =(i.q.tub a)))
(fail tub)
(next tub)
::
Parser generator. Matches the next character if it is in a list of
characters.
`bud` is a list of [`++char`]()
~zod/try=> (scan "a" (mask "cba"))
~~a
~zod/try=> ((mask "abc") [[1 1] "abc"])
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((mask "abc") [[1 1] "bbc"])
[p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((mask "abc") [[1 1] "dbc"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++next
Consume char
++ next :: consume a char
|= tub=nail
^- (like char)
?~ q.tub
(fail tub)
=+ zac=(lust i.q.tub p.tub)
[zac [~ i.q.tub [zac t.q.tub]]]
::
Consume any character, producing it as a result.
`tub` is a [`++nail`]()
~zod/try=> (next [[1 1] "ebc"])
[p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> (next [[1 1] "john jumps jones"])
[p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
------------------------------------------------------------------------
### ++sear
Conditional `++cook`
++ sear :: conditional cook
|* [pyq=_|=(* *(unit)) sef=_rule]
|= tub=nail
=+ vex=(sef tub)
?~ q.vex
vex
=+ gey=(pyq p.u.q.vex)
?~ gey
[p=p.vex q=~]
[p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
::
Conditional [`++cook`](). Slams the result through a gate that produces
a unit; if that unit is empty, fail.
`tub` is a [`++nail`]()
~zod/try=> ((sear |=(a=* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=~]
------------------------------------------------------------------------
### ++shim
Char in range
++ shim :: match char in range
~/ %shim
|= [les=@ mos=@]
~/ %fun
|= tub=nail
^- (like char)
?~ q.tub
(fail tub)
?. ?&((gte i.q.tub les) (lte i.q.tub mos))
(fail tub)
(next tub)
::
Match characters within a range.
`les` and `mos` are atoms, `@`.
~zod/try=> ((shim 'a' 'z') [[1 1] "abc"])
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((shim 'a' 'Z') [[1 1] "abc"])
[p=[p=1 q=1] q=~]
~zod/try=> ((shim 'a' 'Z') [[1 1] "Abc"])
[p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
------------------------------------------------------------------------
### ++stag
Add label
++ stag :: add a label
~/ %stag
|* [gob=* sef=_rule]
~/ %fun
|= tub=nail
=+ vex=(sef tub)
?~ q.vex
vex
[p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
::
Add a label to an edge parsed by a rule.
`gob` is a noun.
`sef` is a rule.
~zod/try=> ((stag %foo (just 'a')) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
~zod/try=> ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
[p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
~zod/try=> ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
[p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
------------------------------------------------------------------------
### ++stet
Add faces
++ stet
|* leh=(list ,[?(@ [@ @]) _rule])
|-
?~ leh
~
[i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
::
Add `[p q]` faces to range-parser pairs in a list.
`leh` is a list of range-parsers.
~zod/try=> (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
[[1 10] (cold %foo (just 'a'))]~]))
~[
[p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
]
~zod/try=> [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
[ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
[[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
~
]
~zod/try=> (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
~[
[p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
[p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
]
------------------------------------------------------------------------
### ++stew
Switch by first
++ stew :: switch by first char
~/ %stew
|* leh=(list ,[p=?(@ [@ @]) q=_rule]) :: char/range keys
=+ ^= wor :: range complete lth
|= [ort=?(@ [@ @]) wan=?(@ [@ @])]
?@ ort
?@(wan (lth ort wan) (lth ort -.wan))
?@(wan (lth +.ort wan) (lth +.ort -.wan))
=+ ^= hel :: build parser map
=+ hel=`(tree $_(?>(?=(^ leh) i.leh)))`~
|- ^+ hel
?~ leh
~
=+ yal=$(leh t.leh)
|- ^+ hel
?~ yal
[i.leh ~ ~]
?: (wor p.i.leh p.n.yal)
=+ nuc=$(yal l.yal)
?> ?=(^ nuc)
?: (vor p.n.yal p.n.nuc)
[n.yal nuc r.yal]
[n.nuc l.nuc [n.yal r.nuc r.yal]]
=+ nuc=$(yal r.yal)
?> ?=(^ nuc)
?: (vor p.n.yal p.n.nuc)
[n.yal l.yal nuc]
[n.nuc [n.yal l.yal l.nuc] r.nuc]
~% %fun ..^$ ~
|= tub=nail
?~ q.tub
(fail tub)
|-
?~ hel
(fail tub)
?: ?@ p.n.hel
=(p.n.hel i.q.tub)
?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
:: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
(q.n.hel tub)
?: (wor i.q.tub p.n.hel)
$(hel l.hel)
$(hel r.hel)
::
Parser generator. From an associative list of characters or character
ranges to rules, construct a map, and parse tapes only with rules
associated with a range the tape's first character falls in.
------------------------------------------------------------------------
### ++stir
Parse repeatedly
++ stir :: parse repeatedly
~/ %stir
|* [rud=* raq=_|*([a=* b=*] [a b]) fel=_rule]
~/ %fun
|= tub=nail
^- (like ,_rud)
=+ vex=(fel tub)
?~ q.vex
[p.vex [~ rud tub]]
=+ wag=$(tub q.u.q.vex)
?> ?=(^ q.wag)
[(last p.vex p.wag) [~ (raq p.u.q.vex p.u.q.wag) q.u.q.wag]]
::
Parse with rule as many times as possible, and fold over results with a
binary gate.
`rud` is a noun.
`raq` is a gate that takes two nouns and produces a cell.
`fel` is a rule.
~zod/try=> (scan "abc" (stir *@ add prn))
294
~zod/try=> (roll "abc" add)
b=294
------------------------------------------------------------------------
### ++stun
Parse several times
++ stun :: parse several times
|* [[les=@ mos=@] fel=_rule]
|= tub=nail
^- (like (list ,_(wonk (fel))))
?: =(0 mos)
[p.tub [~ ~ tub]]
=+ vex=(fel tub)
?~ q.vex
?: =(0 les)
[p.vex [~ ~ tub]]
vex
=+ ^= wag %= $
les ?:(=(0 les) 0 (dec les))
mos ?:(=(0 mos) 0 (dec mos))
tub q.u.q.vex
==
?~ q.wag
wag
[p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
Parse bounded number of times.
`[les=@ mos=@]` is a cell of atoms indicating the bounds.
`fel` is a rule.
~zod/try=> ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
[p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
~zod/try=> ((stun [5 10] prn) [1 1] "aquickbro")
[p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
~zod/try=> ((stun [5 10] prn) [1 1] "aqui")
[p=[p=1 q=5] q=~]
------------------------------------------------------------------------

View File

@ -0,0 +1,289 @@
section 2eD
===========
### ++bend
Conditional composer
++ bend :: conditional comp
~/ %bend
|* raq=_|*([a=* b=*] [~ u=[a b]])
~/ %fun
|* [vex=edge sab=_rule]
?~ q.vex
vex
=+ yit=(sab q.u.q.vex)
=+ yur=(last p.vex p.yit)
?~ q.yit
[p=yur q=q.vex]
=+ vux=(raq p.u.q.vex p.u.q.yit)
?~ vux
[p=yur q=q.vex]
[p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
::
Parsing composer: connects the edge `vex` with the subsequent rule `sab`
as an optional suffix, using the gate `raq` to compose or reject its
result. If there is no suffix, or if the suffix fails to be composed
with the current result, the current result is produced. Used to map a
group of rules to a specified output.
`raq` is a [gate]().
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
[p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
~zod/try=> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
[p=[p=1 q=3] q=[~ u=[p=~~r q=[p=[p=1 q=3] q="q"]]]]
~zod/try=> (scan "aa" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
~~b
~zod/try=> (scan "ba" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
! {1 3}
! exit
~zod/try=> `(unit ,@tas)`(scan "" ;~((bend) (easy ~) sym))
~
~zod/try=> `(unit ,@tas)`(scan "sep" ;~((bend) (easy ~) sym))
[~ %sep]
------------------------------------------------------------------------
### ++comp
Arbitrary compose
++ comp
~/ %comp
|* raq=_|*([a=* b=*] [a b]) :: arbitrary compose
~/ %fun
|* [vex=edge sab=_rule]
?~ q.vex
vex
=+ yit=(sab q.u.q.vex)
=+ yur=(last p.vex p.yit)
?~ q.yit
[p=yur q=q.yit]
[p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
::
Parsing composer: connects the edge `vex` with a following rule `sab`,
combining the contents of `vex` with the result of `sab` using a binary
gate `raq`. Used to fold over the results of several rules.
`raq` is a [gate]() that accepts a cell of two nouns, `a` and `b`, and
produces a cell of two nouns.
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> (scan "123" ;~((comp |=([a=@u b=@u] (add a b))) dit dit dit))
6
~zod/try=> (scan "12" ;~((comp |=([a=@u b=@u] (add a b))) dit dit dit))
! {1 3}
! exit
------------------------------------------------------------------------
### ++glue
Skip delimiter
++ glue :: add rule
~/ %glue
|* bus=_rule
~/ %fun
|* [vex=edge sab=_rule]
(plug vex ;~(pfix bus sab))
::
Parsing composer: connects an edge `vex` with a following rule `sab` by
parsing the rule `bus` (the delimiting symbol) and throwing out the
result.
`bus` is a [rule]().
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> (scan "200|mal|bon" ;~((glue bar) dem sym sym))
[q=200 7.102.829 7.237.474]
~zod/try=> `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
[200 %mal %bon]
~zod/try=> (scan "200|;|bon" ;~((glue bar) dem sem sym))
[q=200 ~~~3b. 7.237.474]
~zod/try=> (scan "200.;.bon" ;~((glue dot) dem sem sym))
[q=200 ~~~3b. 7.237.474]
------------------------------------------------------------------------
### ++less
Parse unless
++ less :: no first and second
|* [vex=edge sab=_rule]
?~ q.vex
=+ roq=(sab)
[p=(last p.vex p.roq) q=q.roq]
vex(q ~)
::
Parsing composer: if an edge `vex` reflects a success, fail. Otherwise,
connect `vex` with the following rule.
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> (scan "sas-/lo" (star ;~(less lus bar prn)))
"sas-/lo"
~zod/try=> (scan "sas-/l+o" (star ;~(less lus bar prn)))
! {1 8}
! exit
~zod/try=> (scan "sas|-/lo" (star ;~(less lus bar prn)))
! {1 5}
! exit
------------------------------------------------------------------------
### ++pfix
Discard first rule
++ pfix :: discard first rule
~/ %pfix
(comp |*([a=* b=*] b))
::
Parsing composer: connects an [edge]() `vex` with two subsequent rules,
ignoring the result of the first and producing the result of the second.
`vex` is an [edge]().
~zod/try=> `@t`(scan "%him" ;~(pfix cen sym))
'him'
~zod/try=> (scan "+++10" ;~(pfix (star lus) dem))
q=10
------------------------------------------------------------------------
### ++plug
Parse to tuple
++ plug :: first then second
~/ %plug
|* [vex=edge sab=_rule]
?~ q.vex
vex
=+ yit=(sab q.u.q.vex)
=+ yur=(last p.vex p.yit)
?~ q.yit
[p=yur q=q.yit]
[p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
::
Parsing composer: connects `vex` with a following rule `sab`, producing
a cell of both the results. See also: the monad applicator [;\~]() for a
more detailed explanation.
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> (scan "1..20" ;~(plug dem dot dot dem))
[q=1 ~~~. ~~~. q=20]
~zod/try=> (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
[1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
~zod/try=> ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
[%moke '/' ~ %da ~2014.1.1]
------------------------------------------------------------------------
### ++pose
Parse options
++ pose :: first or second
~/ %pose
|* [vex=edge sab=_rule]
?~ q.vex
=+ roq=(sab)
[p=(last p.vex p.roq) q=q.roq]
vex
Parsing composer: if `vex` reflects a failure, connect it with the
following rule `sab`. See also: the monad applicator [;\~]()
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> `@t`(scan "+" ;~(pose lus tar cen))
'+'
~zod/try=> `@t`(scan "*" ;~(pose lus tar cen))
'*'
~zod/try=> `@t`(scan "%" ;~(pose lus tar cen))
'%'
~zod/try=> `@t`(scan "-" ;~(pose lus tar cen))
! {1 1}
! exit
------------------------------------------------------------------------
### ++simu
First and second
++ simu :: first and second
|* [vex=edge sab=_rule]
?~ q.vex
vex
=+ roq=(sab)
roq
::
Parsing composer: if an edge `vex` reflects a failure, fail. Otherwise,
connect `vex` with the following rule.
`sab` is a [rule]().
`vex` is an [edge]().
~zod/try=> (scan "~zod" scat:vast)
[%dtzy p=%p q=0]
~zod/try=> (scan "%zod" scat:vast)
[%dtzz p=%tas q=6.582.138]
~zod/try=> (scan "%zod" ;~(simu cen scat:vast))
[%dtzz p=%tas q=6.582.138]
~zod/try=> (scan "~zod" ;~(simu cen scat:vast))
! {1 1}
! exit
------------------------------------------------------------------------
### ++sfix
Discard second rule
++ sfix :: discard second rule
~/ %sfix
(comp |*([a=* b=*] a))
Parsing composer: connects `vex` with two subsequent rules returning the
result of the first and discarding the result of the second.
`a` is the result of parsing the first [rule]().
`b` is the result of of parsing the second [rule]().
~zod/try=> `@t`(scan "him%" ;~(sfix sym cen))
'him'
~zod/try=> (scan "10+++" ;~(sfix dem (star lus)))
q=10
------------------------------------------------------------------------

View File

@ -0,0 +1,195 @@
section 2eE, parsing (composers)
================================
### ++bass
++ bass
|* [wuc=@ tyd=_rule]
%+ cook
|= waq=(list ,@)
%+ roll
waq
=|([p=@ q=@] |.((add p (mul wuc q))))
tyd
::
Parser modifier:
[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) ordered list
as atom of a base.
`wuc` is an [atom]().
`tyd` is a [rule]().
~zod/try=> (scan "123" (bass 10 (star dit)))
q=123
~zod/try=> (scan "123" (bass 8 (star dit)))
q=83
~zod/try=> `@ub`(scan "123" (bass 8 (star dit)))
0b101.0011
------------------------------------------------------------------------
### ++boss
++ boss
|* [wuc=@ tyd=_rule]
%+ cook
|= waq=(list ,@)
%+ reel
waq
=|([p=@ q=@] |.((add p (mul wuc q))))
tyd
::
Parser modifier:
[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) ordered list
as atom of a base.
`wuc` is an [atom]().
`tyd` is a [rule]().
~zod/try=> (scan "123" (boss 10 (star dit)))
q=321
~zod/try=> `@t`(scan "bam" (boss 256 (star alp)))
'bam'
~zod/try=> `@ux`(scan "bam" (boss 256 (star alp)))
0x6d.6162
------------------------------------------------------------------------
### ++ifix
++ ifix
|* [fel=[p=_rule q=_rule] hof=_rule]
;~(pfix p.fel ;~(sfix hof q.fel))
::
Parser modifier: surround with pair of rules, output of which is
discarded.
`fel` is a pair of [rule]()s.
`hof` is a [rule]().
~zod/try=> (scan "-40-" (ifix [hep hep] dem))
q=40
~zod/try=> (scan "4my4" (ifix [dit dit] (star alf)))
"my"
------------------------------------------------------------------------
### ++more
++ more
|* [bus=_rule fel=_rule]
;~(pose (most bus fel) (easy ~))
::
Parser modifier: using a delimiter rule, parse a list of matches.
`bus` is a [rule]().
`fel` is a [rule]().
~zod/try=> (scan "" (more ace dem))
~
~zod/try=> (scan "40 20" (more ace dem))
[q=40 ~[q=20]]
~zod/try=> (scan "40 20 60 1 5" (more ace dem))
[q=40 ~[q=20 q=60 q=1 q=5]]
------------------------------------------------------------------------
### ++most
++ most
|* [bus=_rule fel=_rule]
;~(plug fel (star ;~(pfix bus fel)))
::
Parser modifier: using a delimiter rule, parse a list of at least one
match.
`bus` is a [rule]().
`fel` is a [rule]().
~zod/try=> (scan "40 20" (most ace dem))
[q=40 ~[q=20]]
~zod/try=> (scan "40 20 60 1 5" (most ace dem))
[q=40 ~[q=20 q=60 q=1 q=5]]
~zod/try=> (scan "" (most ace dem))
! {1 1}
! exit
------------------------------------------------------------------------
### ++plus
++ plus |*(fel=_rule ;~(plug fel (star fel)))
Parser modifier: parse list of at least one match
`fel` is a [rule]().
~zod/try=> (scan ">>>>" (cook lent (plus gar)))
4
~zod/try=> (scan "- - " (plus ;~(pose ace hep)))
[~~- " - "]
~zod/try=> `tape`(scan "- - " (plus ;~(pose ace hep)))
"- - "
~zod/try=> `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
['-' [' ' [' ' ['-' [' ' ~]]]]]
------------------------------------------------------------------------
### ++slug
++ slug
|* raq=_|*([a=* b=*] [a b])
|* [bus=_rule fel=_rule]
;~((comp raq) fel (stir rud raq ;~(pfix bus fel)))
::
Parser modifier: By composing with a gate, parse a delimited list of
matches.
`bus` is a [rule]().
`fel` is a [rule]().
~zod/try=> (scan "20+5+110" ((slug add) lus dem))
135
~zod/try=> `@t`(scan "a b c" ((slug |=(a=[@ @t] (cat 3 a))) ace alp))
'abc'
------------------------------------------------------------------------
### ++star
++ star :: 0 or more times
|* fel=_rule
(stir `(list ,_(wonk *fel))`~ |*([a=* b=*] [a b]) fel)
Parser modifier: parse list of matches.
`fel` is a [rule]().
~zod/try=> (scan "aaaaa" (just 'a'))
! {1 2}
! 'syntax-error'
! exit
~zod/try=> (scan "aaaaa" (star (just 'a')))
"aaaaa"
~zod/try=> (scan "abcdef" (star (just 'a')))
! {1 2}
! 'syntax-error'
! exit
~zod/try=> (scan "abcabc" (star (jest 'abc')))
<|abc abc|>
~zod/try=> (scan "john smith" (star (shim 0 200)))
"john smith"
------------------------------------------------------------------------

View File

@ -0,0 +1,648 @@
section 2eF, parsing (ascii)
============================
### ++ace
Parse space
++ ace (just ' ')
Parses ASCII character 32, space.
~zod/try=> (scan " " ace)
~~.
~zod/try=> `cord`(scan " " ace)
' '
~zod/try=> (ace [[1 1] " "])
[p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (ace [[1 1] " abc "])
[p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q="abc "]]]]
------------------------------------------------------------------------
### ++bar
Parse vertical bar
++ bar (just '|')
Parses ASCII character 124, the vertical bar.
~zod/try=> (scan "|" bar)
~~~7c.
~zod/try=> `cord`(scan "|" bar)
'|'
~zod/try=> (bar [[1 1] "|"])
[p=[p=1 q=2] q=[~ [p=~~~7c. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (bar [[1 1] "|="])
[p=[p=1 q=2] q=[~ [p=~~~7c. q=[p=[p=1 q=2] q="="]]]]
------------------------------------------------------------------------
### ++bas
Parse backslash
++ bas (just '\\')
Parses ASCII character 92, the backslash. Note the extra `\` in the slam
of `bas` with [`++just`]() is to escape the escape character, `\`.
~zod/try=> (scan "\\" bas)
~~~5c.
~zod/try=> `cord`(scan "\\" bas)
'\'
~zod/try=> (bas [[1 1] "\"])
~ <syntax error at [1 18]>
~zod/try=> (bas [[1 1] "\\"])
[p=[p=1 q=2] q=[~ [p=~~~5c. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (bas [[1 1] "\""])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++buc
Parse dollar sign
++ buc (just '$')
Parses ASCII character 36, the dollar sign.
~zod/try=> (scan "$" buc)
~~~24.
~zod/try=> `cord`(scan "$" buc)
'$'
~zod/try=> (buc [[1 1] "$"])
[p=[p=1 q=2] q=[~ [p=~~~24. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (buc [[1 1] "$%"])
[p=[p=1 q=2] q=[~ [p=~~~24. q=[p=[p=1 q=2] q="%"]]]]
------------------------------------------------------------------------
### ++cab
Parse underscore
++ cab (just '_')
Parses ASCII character 95, the underscore.
~zod/try=> (scan "_" cab)
~~~5f.
~zod/try=> `cord`(scan "_" cab)
'_'
~zod/try=> (cab [[1 1] "_"])
[p=[p=1 q=2] q=[~ [p=~~~5f. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (cab [[1 1] "|_"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++cen
Parses percent sign
++ cen (just '%')
Parses ASCII character 37, the percent sign.
~zod/try=> (scan "%" cen)
~~~25.
~zod/try=> `cord`(scan "%" cen)
'%'
~zod/try=> (cen [[1 1] "%"])
[p=[p=1 q=2] q=[~ [p=~~~25. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (cen [[1 1] "%^"])
[p=[p=1 q=2] q=[~ [p=~~~25. q=[p=[p=1 q=2] q="^"]]]]
------------------------------------------------------------------------
### ++col
Parse colon
++ col (just ':')
Parses ASCII character 58, the colon
~zod/try=> (scan ":" col)
~~~3a.
~zod/try=> `cord`(scan ":" col)
':'
~zod/try=> (col [[1 1] ":"])
[p=[p=1 q=2] q=[~ [p=~~~3a. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (col [[1 1] ":-"])
[p=[p=1 q=2] q=[~ [p=~~~3a. q=[p=[p=1 q=2] q="-"]]]]
------------------------------------------------------------------------
### ++com
Parse comma
++ com (just ',')
Parses ASCII character 44, the comma.
~zod/try=> (scan "," com)
~~~2c.
~zod/try=> `cord`(scan "," com)
','
~zod/try=> (com [[1 1] ","])
[p=[p=1 q=2] q=[~ [p=~~~2c. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (com [[1 1] "not com"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++doq
Parse double quote
++ doq (just '"')
Parses ASCII character 34, the double quote.
~tadbyl-hilbel/try=> (scan "\"" doq)
~~~22.
~tadbyl-hilbel/try=> `cord`(scan "\"" doq)
'"'
~tadbyl-hilbel/try=> (doq [[1 1] "\""])
[p=[p=1 q=2] q=[~ [p=~~~22. q=[p=[p=1 q=2] q=""]]]]
~tadbyl-hilbel/try=> (doq [[1 1] "not successfully parsed"])
[p=[p=1 q=1] q=~]
~tadbyl-hilbel/try=> (scan "see?" doq)
! {1 1}
! 'syntax-error'
! exit
------------------------------------------------------------------------
### ++dot
Parse period
++ dot (just '.')
Parses ASCII character 46, the period.
~zod/try=> (scan "." dot)
~~~.
~zod/try=> `cord`(scan "." dot)
'.'
~zod/try=> (dot [[1 1] "."])
[p=[p=1 q=2] q=[~ [p=~~~. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (dot [[1 1] ".^"])
[p=[p=1 q=2] q=[~ [p=~~~. q=[p=[p=1 q=2] q="^"]]]]
------------------------------------------------------------------------
### ++fas
Parse forward slash
++ fas (just '/')
Parses ASCII character 47, the forward slash.
~zod/try=> (scan "/" fas)
~~~2f.
~zod/try=> `cord`(scan "/" fas)
'/'
~zod/try=> (fas [[1 1] "/"])
[p=[p=1 q=2] q=[~ [p=~~~2f. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (fas [[1 1] "|/"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++gal
Parse less-than sign
++ gal (just '<')
Parses ASCII character 60, the less-than sign.
~zod/try=> (scan "<" gal)
~~~3c.
~zod/try=> `cord`(scan "<" gal)
'<'
~zod/try=> (gal [[1 1] "<"])
[p=[p=1 q=2] q=[~ [p=~~~3c. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (gal [[1 1] "<+"])
[p=[p=1 q=2] q=[~ [p=~~~3c. q=[p=[p=1 q=2] q="+"]]]]
~zod/try=> (gal [[1 1] "+<"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++gar
Parse greater-than sign
++ gar (just '>')
Parses ASCII character 62, the greater-than sign.
~zod/try=> (scan ">" gar)
~~~3e.
~zod/try=> `cord`(scan ">" gar)
'>'
~zod/try=> (gar [[1 1] ">"])
[p=[p=1 q=2] q=[~ [p=~~~3e. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (gar [[1 1] "=>"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++hax
Parse number sign
++ hax (just '#')
Parses ASCII character 35, the number sign.
~zod/try=> (scan "#" hax)
~~~23.
~zod/try=> `cord`(scan "#" hax)
'#'
~zod/try=> (hax [[1 1] "#"])
[p=[p=1 q=2] q=[~ [p=~~~23. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (hax [[1 1] "#!"])
[p=[p=1 q=2] q=[~ [p=~~~23. q=[p=[p=1 q=2] q="!"]]]]
------------------------------------------------------------------------
### ++kel
Parse left curley bracket
++ kel (just '{')
Parses ASCII character 123, the left curly bracket. Note that `{`
(`kel`) and `}` (`ker`) open and close a Hoon expression for Hoon string
interpolation. To parse either of them, they must be escaped.
~zod/try=> (scan "\{" kel)
~~~7b.
~zod/try=> `cord`(scan "\{" kel)
'{'
~zod/try=> (kel [[1 1] "\{"])
[p=[p=1 q=2] q=[~ [p=~~~7b. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (kel [[1 1] " \{"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++ker
Parse right curley bracket
++ ker (just '}')
Parses ASCII character 125, the right curly bracket. Note that `{`
(`kel`) and `}` (`ker`) open and close a Hoon expression for Hoon string
interpolation. To parse either of them, they must be escaped.
~zod/try=> (scan "}" ker)
~~~7d.
~zod/try=> `cord`(scan "}" ker)
'}'
~zod/try=> (ker [[1 1] "}"])
[p=[p=1 q=2] q=[~ [p=~~~7d. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (ker [[1 1] "\{}"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++ket
Parse caret
++ ket (just '^')
Parses ASCII character 94, the caret.
~zod/try=> (scan "^" ket)
~~~5e.
~zod/try=> `cord`(scan "^" ket)
'^'
~zod/try=> (ket [[1 1] "^"])
[p=[p=1 q=2] q=[~ [p=~~~5e. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (ket [[1 1] ".^"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++lus
Parse plus sign
++ lus (just '+')
Parses ASCII character 43, the plus sign.
~zod/try=> (scan "+" lus)
~~~2b.
~zod/try=> `cord`(scan "+" lus)
'+'
~zod/try=> (lus [[1 1] "+"])
[p=[p=1 q=2] q=[~ [p=~~~2b. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (lus [[1 1] ".+"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++hep
Parse hyphen
++ hep (just '-')
Parses ASCII character 45, the hyphen.
~zod/try=> (scan "-" hep)
~~-
~zod/try=> `cord`(scan "-" hep)
'-'
~zod/try=> (hep [[1 1] "-"])
[p=[p=1 q=2] q=[~ [p=~~- q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (hep [[1 1] ":-"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++pel
Parse left parenthesis
++ pel (just '(')
Parses ASCII character 40, the left parenthesis.
~zod/try=> (scan "(" pel)
~~~28.
~zod/try=> `cord`(scan "(" pel)
'('
~zod/try=> (pel [[1 1] "("])
[p=[p=1 q=2] q=[~ [p=~~~28. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (pel [[1 1] ";("])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++pam
Parse ampersand
++ pam (just '&')
Parses ASCII character 38, the ampersand.
~zod/try=> (scan "&" pam)
~~~26.
~zod/try=> `cord`(scan "&" pam)
'&'
~zod/try=> (pam [[1 1] "&"])
[p=[p=1 q=2] q=[~ [p=~~~26. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (pam [[1 1] "?&"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++per
Parse right parenthesis
++ per (just ')')
Parses ASCII character 41, the right parenthesis.
~zod/try=> (scan ")" per)
~~~29.
~zod/try=> `cord`(scan ")" per)
')'
~zod/try=> (per [[1 1] ")"])
[p=[p=1 q=2] q=[~ [p=~~~29. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (per [[1 1] " )"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++pat
Parse "at" sign
++ pat (just '@')
Parses ASCII character 64, the "at" sign.
~zod/try=> (scan "@" pat)
~~~4.
~zod/try=> `cord`(scan "@" pat)
'@'
~zod/try=> (pat [[1 1] "@"])
[p=[p=1 q=2] q=[~ [p=~~~4. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (pat [[1 1] "?@"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++sel
Parse left square bracket
Left square bracket
++ sel (just '[')
Parses ASCII character 91, the left square bracket.
~zod/try=> (scan "[" sel)
~~~5b.
~zod/try=> `cord`(scan "[" sel)
'['
~zod/try=> (sel [[1 1] "["])
[p=[p=1 q=2] q=[~ [p=~~~5b. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (sel [[1 1] "-["])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++sem
Parse semicolon
++ sem (just ';')
Parses ASCII character 59, the semicolon.
### Examples
~zod/try=> (scan ";" sem)
~~~3b.
~zod/try=> `cord`(scan ";" sem)
';'
~zod/try=> (sem [[1 1] ";"])
[p=[p=1 q=2] q=[~ [p=~~~3b. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (sem [[1 1] " ;"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++ser
Parse right square bracket
++ ser (just ']')
Parses ASCII character 93, the right square bracket.
~zod/try=> (scan "]" ser)
~~~5d.
~zod/try=> `cord`(scan "]" ser)
']'
~zod/try=> (ser [[1 1] "]"])
[p=[p=1 q=2] q=[~ [p=~~~5d. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (ser [[1 1] "[ ]"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++sig
Parse tilde
++ sig (just '~')
Parses ASCII character 126, the tilde.
~zod/try=> (scan "~" sig)
~~~~
~zod/try=> `cord`(scan "~" sig)
'~'
~zod/try=> (sig [[1 1] "~"])
[p=[p=1 q=2] q=[~ [p=~~~~ q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (sig [[1 1] "?~"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++soq
Parse single quote
++ soq (just '\'')
Parses ASCII character 39, soq. Note the extra '' is to escape the first
`soq` because soq delimits a cord.
~zod/try=> (scan "'" soq)
~~~27.
~zod/try=> `cord`(scan "'" soq)
'''
~zod/try=> (soq [[1 1] "'"])
[p=[p=1 q=2] q=[~ [p=~~~27. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (soq [[1 1] ">'"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++tar
Parse asterisk
++ tar (just '*')
Parses ASCII character 42, the asterisk.
~zod/try=> (scan "*" tar)
~~~2a.
~zod/try=> `cord`(scan "*" tar)
'*'
~zod/try=> (tar [[1 1] "*"])
[p=[p=1 q=2] q=[~ [p=~~~2a. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (tar [[1 1] ".*"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++tec
Parse backtick
++ tec (just '`') :: backTiCk
Parses ASCII character 96, the backtick (also known as the "grave
accent".
~zod/try=> (scan "`" tec)
~~~6.
~zod/try=> `cord`(scan "`" tec)
'`'
~zod/try=> (tec [[1 1] "`"])
[p=[p=1 q=2] q=[~ [p=~~~6. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (tec [[1 1] " `"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++tis
Parse equals sign
++ tis (just '=')
Parses ASCII character 61, the equals sign.
~zod/try=> (scan "=" tis)
~~~3d.
~zod/try=> `cord`(scan "=" tis)
'='
~zod/try=> (tis [[1 1] "="])
[p=[p=1 q=2] q=[~ [p=~~~3d. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (tis [[1 1] "|="])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++wut
Parses question mark
++ wut (just '?')
Parses ASCII character 63, wut.
~zod/try=> (scan "?" wut)
~~~3f.
~zod/try=> `cord`(scan "?" wut)
'?'
~zod/try=> (wut [[1 1] "?"])
[p=[p=1 q=2] q=[~ [p=~~~3f. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (wut [[1 1] ".?"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------
### ++zap
Exclamation point
++ zap (just '!')
Parses ASCII character 33, the exclamation point zap.
~zod/try=> (scan "!" zap)
~~~21.
~zod/try=> `cord`(scan "!" zap)
'!'
~zod/try=> (zap [[1 1] "!"])
[p=[p=1 q=2] q=[~ [p=~~~21. q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (zap [[1 1] "?!"])
[p=[p=1 q=1] q=~]
------------------------------------------------------------------------

View File

@ -0,0 +1,160 @@
section 2eG, parsing (whitespace)
=================================
### ++dog
`.` optional gap
++ dog ;~(plug dot gay) ::
Dot followed by an optional gap, used in numbers.
/~zod/try=> 1.234.
703
1.234.703
~zod/try=> (scan "a. " ;~(pfix alf dog))
[~~~. ~]
------------------------------------------------------------------------
### ++doh
`@p` separator
++ doh ;~(plug ;~(plug hep hep) gay) ::
Phonetic base phrase separator
/~zod/try=> ~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
/~zod/try=> ~nopfel-botduc-nilnev-dolfyn--
haspub-natlun-lodmur-holtyd
~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
~zod/try=> (scan "--" doh)
[[~~- ~~-] ~]
~zod/try=> (scan "-- " doh)
[[~~- ~~-] ~]
------------------------------------------------------------------------
### ++dun
`--` to `~`
++ dun (cold ~ ;~(plug hep hep)) :: -- (phep) to ~
Parse phep, `--`, to null, `~`.
~zod/try=> (scan "--" dun)
~
~zod/try=> (dun [[1 1] "--"])
[p=[p=1 q=3] q=[~ u=[p=~ q=[p=[p=1 q=3] q=""]]]]
------------------------------------------------------------------------
### ++duz
`==` to `~`
++ duz (cold ~ ;~(plug tis tis)) :: == (stet) to ~
Parse stet, `==`, to null `~`.
~zod/try=> (scan "==" duz)
~
~zod/try=> (duz [[1 1] "== |=..."])
[p=[p=1 q=3] q=[~ u=[p=~ q=[p=[p=1 q=3] q=" |=..."]]]]
------------------------------------------------------------------------
### ++gah
Newline or ' '
++ gah (mask [`@`10 ' ' ~]) :: newline or ace
Whitespace component, either newline or space.
/~zod/try=> ^- * :: show spaces
"""
-
-
-
"""
[32 32 32 45 10 32 45 10 32 32 45 0]
/~zod/try=> ^- *
"""
"""
[32 32 32 10 32 10 32 32 0]
/~zod/try=> ^- (list ,@)
%- scan :_ (star gah)
"""
"""
~[32 32 32 10 32 10 32 32]
------------------------------------------------------------------------
### ++gap
Plural whitespace
++ gap (cold ~ ;~(plug gaq (star ;~(pose vul gah)))) :: plural whitespace
Separates tall runes
------------------------------------------------------------------------
### ++gaq
End of line
++ gaq ;~ pose :: end of line
(just `@`10)
;~(plug gah ;~(pose gah vul))
vul
==
Two spaces, a newline, or comment.
------------------------------------------------------------------------
### ++gaw
Classic whitespace
++ gaw (cold ~ (star ;~(pose vul gah))) :: classic white
Terran whitespace
------------------------------------------------------------------------
### ++gay
Optional gap.
++ gay ;~(pose gap (easy ~)) ::
Optional gap.
------------------------------------------------------------------------
### ++vul
++ vul %- cold :- ~ :: comments
;~ plug col col
(star prn)
(just `@`10)
==
Parse comments and produce a null. Note that a comment must be ended
with a newline character.
~zod/try=> (scan "::this is a comment \0a" vul)
~
~zod/try=> (scan "::this is a comment " vul)
! {1 21}
! exit
------------------------------------------------------------------------

View File

@ -0,0 +1,531 @@
section 2eH, parsing (idioms)
=============================
### ++alf
Alphabetic characters
++ alf ;~(pose low hig) :: alphabetic
Parse alphabetic characters, both upper and lowercase.
~zod/try=> (scan "a" alf)
~~a
~zod/try=> (scan "A" alf)
~~~41.
~zod/try=> (scan "AaBbCc" (star alf))
"AaBbCc"
------------------------------------------------------------------------
### ++aln
Alphanumeric characters
++ aln ;~(pose low hig nud) :: alphanumeric
Parse alphanumeric characters - both alphabetic characters and numbers.
~zod/try=> (scan "0" aln)
~~0
~zod/try=> (scan "alf42" (star aln))
"alf42"
~zod/try=> (scan "0123456789abcdef" (star aln))
"0123456789abcdef"
------------------------------------------------------------------------
### ++alp
Alphanumeric and `-`
++ alp ;~(pose low hig nud hep) :: alphanumeric and -
Parse alphanumeric strings and hep, "-".
~zod/try=> (scan "7" alp)
~~7
~zod/try=> (scan "s" alp)
~~s
~zod/try=> (scan "123abc-" (star alp))
"123abc-"
------------------------------------------------------------------------
### ++bet
Axis syntax `-`, `+`
++ bet ;~(pose (cold 2 hep) (cold 3 lus)) :: axis syntax - +
Parse the hep and lus axis syntax.
~zod/try=> (scan "-" bet)
2
~zod/try=> (scan "+" bet)
3
------------------------------------------------------------------------
### ++bin
Binary to atom
++ bin (bass 2 (most gon but)) :: binary to atom
Parse a tape of binary (0s and 1s) and produce its atomic
representation.
~zod/try=> (scan "0000" bin)
0
~zod/try=> (scan "0001" bin)
1
~zod/try=> (scan "0010" bin)
2
~zod/try=> (scan "100000001111" bin)
2.063
------------------------------------------------------------------------
### ++but
Binary digit
++ but (cook |=(a=@ (sub a '0')) (shim '0' '1')) :: binary digit
Parse a single binary digit.
~zod/try=> (scan "0" but)
0
~zod/try=> (scan "1" but)
1
~zod/try=> (scan "01" but)
! {1 2}
! 'syntax-error'
! exit
~zod/try=> (scan "01" (star but))
~[0 1]
------------------------------------------------------------------------
### ++cit
Octal digit
++ cit (cook |=(a=@ (sub a '0')) (shim '0' '7')) :: octal digit
Parse a single octal digit.
~zod/try=> (scan "1" cit)
1
~zod/try=> (scan "7" cit)
7
~zod/try=> (scan "8" cit)
! {1 1}
! 'syntax-error'
! exit
~zod/try=> (scan "60" (star cit))
~[6 0]
------------------------------------------------------------------------
### ++dem
Decimal to atom
++ dem (bass 10 (most gon dit)) :: decimal to atom
Parse a decimal number to an atom.
~zod/try=> (scan "7" dem)
7
~zod/try=> (scan "42" dem)
42
~zod/try=> (scan "150000000" dem)
150.000.000
~zod/try=> (scan "12456" dem)
12.456
------------------------------------------------------------------------
### ++dit
Decimal digit
++ dit (cook |=(a=@ (sub a '0')) (shim '0' '9')) :: decimal digit
Parse a single decimal digit.
~zod/try=> (scan "7" dit)
7
~zod/try=> (scan "42" (star dit))
~[4 2]
~zod/try=> (scan "26000" (star dit))
~[2 6 0 0 0]
------------------------------------------------------------------------
### ++gul
Axis syntax `<` or `>`
++ gul ;~(pose (cold 2 gal) (cold 3 gar)) :: axis syntax < >
Parse the axis gal and gar axis syntax.
~zod/try=> (scan "<" gul)
2
~zod/try=> (scan ">" gul)
3
------------------------------------------------------------------------
### ++gon
Long numbers
++ gon ;~(pose ;~(plug bas gay fas) (easy ~)) :: long numbers \ /
Parse long numbers - Numbers which wrap around the shell with the line
break characters bas and fas.
~zod/try=> (scan "\\/" gon)
[~~~5c. ~ ~~~2f.]
~zod/try=> (gon [[1 1] "\\/"])
[p=[p=1 q=3] q=[~ u=[p=[~~~5c. ~ ~~~2f.] q=[p=[p=1 q=3] q=""]]]]
------------------------------------------------------------------------
### ++hex
Hex to atom
++ hex (bass 16 (most gon hit)) :: hex to atom
Parse any hexadecimal number to an atom.
~zod/try=> (scan "a" hex)
10
~zod/try=> (scan "A" hex)
10
~zod/try=> (scan "2A" hex)
42
~zod/try=> (scan "1ee7" hex)
7.911
~zod/try=> (scan "1EE7" hex)
7.911
~zod/try=> (scan "1EE7F7" hex)
2.025.463
~zod/try=> `@ux`(scan "1EE7F7" hex)
0x1e.e7f7
------------------------------------------------------------------------
### ++hig
Uppercase
++ hig (shim 'A' 'Z') :: uppercase
Parse a single uppercase letter.
~zod/try=> (scan "G" hig)
~~~47.
~zod/try=> `cord`(scan "G" hig)
'G'
~zod/try=> (scan "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (star hig))
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
~zod/try=> (hig [[1 1] "G"])
[p=[p=1 q=2] q=[~ [p=~~~47. q=[p=[p=1 q=2] q=""]]]]
------------------------------------------------------------------------
### ++hit
Hex digits
++ hit ;~ pose :: hex digits
dit
(cook |=(a=char (sub a 87)) (shim 'a' 'f'))
(cook |=(a=char (sub a 55)) (shim 'A' 'F'))
==
Parse a single hexadecimal digit.
~zod/try=> (scan "a" hit)
10
~zod/try=> (scan "A" hit)
10
~zod/try=> (hit [[1 1] "a"])
[p=[p=1 q=2] q=[~ [p=10 q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (scan "2A" (star hit))
~[2 10]
------------------------------------------------------------------------
### ++low
Lowercase
++ low (shim 'a' 'z') :: lowercase
Parse a single lowercase letter.
~zod/try=> (scan "g" low)
~~g
~zod/try=> `cord`(scan "g" low)
'g'
~zod/try=> (scan "abcdefghijklmnopqrstuvwxyz" (star low))
"abcdefghijklmnopqrstuvwxyz"
~zod/try=> (low [[1 1] "g"])
[p=[p=1 q=2] q=[~ [p=~~g q=[p=[p=1 q=2] q=""]]]]
------------------------------------------------------------------------
### ++mes
Hexbyte
++ mes %+ cook :: hexbyte
|=([a=@ b=@] (add (mul 16 a) b))
;~(plug hit hit)
Parse a hexbyte.
~zod/try=> (scan "2A" mes)
42
~zod/try=> (mes [[1 1] "2A"])
[p=[p=1 q=3] q=[~ u=[p=42 q=[p=[p=1 q=3] q=""]]]]
~zod/try=> (scan "42" mes)
66
------------------------------------------------------------------------
### ++nix
Letters, `-`, and `_`
++ nix (boss 256 (star ;~(pose aln cab))) ::
Letters, `-`, and `_`
~zod/try=> (scan "as_me" nix)
q=435.626.668.897
~zod/try=> `@t`(scan "as_me" nix)
'as_me'
------------------------------------------------------------------------
### ++nud
Numeric
++ nud (shim '0' '9') :: numeric
Parse a numeric character - A number.
~zod/try=> (scan "0" nud)
~~0
~zod/try=> (scan "7" nud)
~~7
~zod/try=> (nud [[1 1] "1"])
[p=[p=1 q=2] q=[~ [p=~~1 q=[p=[p=1 q=2] q=""]]]]
~zod/try=> (scan "0123456789" (star nud))
"0123456789"
------------------------------------------------------------------------
### ++prn
Printable character
++ prn ;~(less (just `@`127) (shim 32 256))
Parse any printable character
~zod/try=> (scan "h" prn)
~~h
~zod/try=> (scan "!" prn)
~~~21.
~zod/try=> (scan "\01" prn)
! {1 1}
! exit
------------------------------------------------------------------------
### ++qat
Chars in blockcord
++ qat ;~ pose :: chars in blockcord
prn
;~(less ;~(plug (just `@`10) soqs) (just `@`10))
==
Parse character in cord block.
~zod/try=> (scan "h" qat)
~~h
~zod/try=> (scan "!" qat)
~~~21.
~zod/try=> (scan "\0a" qat)
~~~a.
~zod/try=> (scan "\00" qat)
! {1 1}
! exit
------------------------------------------------------------------------
### ++qit
Chars in cord
++ qit ;~ pose :: chars in a cord
;~(less bas soq prn)
;~(pfix bas ;~(pose bas soq mes)) :: escape chars
==
Parse an individual character to its cord atom representation.
~zod/try=> (scan "%" qit)
37
~zod/try=> `@t`(scan "%" qit)
'%'
~zod/try=> (scan "0" qit)
48
~zod/try=> (scan "E" qit)
69
~zod/try=> (scan "a" qit)
97
~zod/try=> (scan "\\0a" qit)
10
~zod/try=> `@ux`(scan "\\0a" qit)
0xa
~zod/try=> (scan "cord" (star qit))
~[99 111 114 100]
------------------------------------------------------------------------
### ++qut
Cord
++ qut ;~ pose :: cord
;~ less soqs
(ifix [soq soq] (boss 256 (more gon qit)))
==
%- inde %+ ifix
:- ;~ plug soqs
;~(pose ;~(plug (plus ace) vul) (just '\0a'))
==
;~(plug (just '\0a') soqs)
(boss 256 (star qat))
==
::
Parse single-soq cord with `\{gap}/` anywhere in the middle, or
triple-soq cord which must be in an indented block.
~zod/try=> (scan "'cord'" qut)
q=1.685.221.219
~zod/try=> 'cord'
'cord'
~zod/try=> `@ud`'cord'
1.685.221.219
/~zod/try=> '''
Heredoc isn't prohibited from containing quotes
'''
'Heredoc isn't prohibited from containing quotes'
------------------------------------------------------------------------
### ++soqs
Delimiting `'''`
++ soqs ;~(plug soq soq soq) :: delimiting '''
Triple single quote
~zod/try=> (scan "'''" soqs)
[~~~27. ~~~27. ~~~27.]
~zod/try=> (rash '"""' soqs)
! {1 1}
! exit
------------------------------------------------------------------------
### ++sym
Term
++ sym
%+ cook
|=(a=tape (rap 3 ^-((list ,@) a)))
;~(plug low (star ;~(pose nud low hep)))
::
A term: a letter(lowercase), followed by letters, numbers, or `-`.
~zod/try=> (scan "sam-2" sym)
215.510.507.891
~zod/try=> `@t`(scan "sam-2" sym)
'sam-2'
~zod/try=> (scan "sym" sym)
7.174.515
------------------------------------------------------------------------
### ++ven
`+>-` axis syntax
++ ven ;~ (comp |=([a=@ b=@] (peg a b))) :: +>- axis syntax
bet
=+ hom=`?`|
|= tub=nail
^- (like axis)
=+ vex=?:(hom (bet tub) (gul tub))
?~ q.vex
[p.tub [~ 1 tub]]
=+ wag=$(p.tub p.vex, hom !hom, tub q.u.q.vex)
?> ?=(^ q.wag)
[p.wag [~ (peg p.u.q.vex p.u.q.wag) q.u.q.wag]]
==
Axis syntax parser
~zod/arvo=/hoon/hoon> (scan "->+" ven)
11
~zod/arvo=/hoon/hoon> `@ub`(scan "->+" ven)
0b1011
~zod/arvo=/hoon/hoon> (peg (scan "->" ven) (scan "+" ven))
11
~zod/arvo=/hoon/hoon> ->+:[[1 2 [3 4]] 5]
[3 4]
------------------------------------------------------------------------
### ++vit
Base64 digit
++ vit :: base64 digit
;~ pose
(cook |=(a=@ (sub a 65)) (shim 'A' 'Z'))
(cook |=(a=@ (sub a 71)) (shim 'a' 'z'))
(cook |=(a=@ (add a 4)) (shim '0' '9'))
(cold 62 (just '-'))
(cold 63 (just '+'))
==
Terran base64
~zod/arvo=/hoon/hoon> (scan "C" vit)
2
~zod/arvo=/hoon/hoon> (scan "c" vit)
28
~zod/arvo=/hoon/hoon> (scan "2" vit)
54
~zod/arvo=/hoon/hoon> (scan "-" vit)
62

View File

@ -0,0 +1,107 @@
section 2eI, parsing (external)
===============================
### ++rash
Parse or crash
++ rash |*([naf=@ sab=_rule] (scan (trip naf) sab)) ::
Parse a cord with a given rule and crash if the cord isn't entirely
parsed.
`naf` is an [atom]().
`sab` is a [rule]().
~zod/try=> (rash 'I was the world in which I walked, and what I saw' (star (shim 0 200)))
"I was the world in which I walked, and what I saw"
~zod/try=> (rash 'abc' (just 'a'))
! {1 2}
! 'syntax-error'
! exit
~zod/try=> (rash 'abc' (jest 'abc'))
'abc'
`~zod/try=> (rash 'abc' (jest 'ab'))
! {1 3}
! 'syntax-error'
! exit
------------------------------------------------------------------------
### ++rush
Parse or null
++ rush |*([naf=@ sab=_rule] (rust (trip naf) sab))
Parse a given with a given rule and produce null if the cord isn't
entirely parsed.
`naf` is an [atom]().
`sab` is a [rule]().
~zod/try=> (rush 'I was the world in which I walked, and what I saw' (star (shim 0 200)))
[~ "I was the world in which I walked, and what I saw"]
~zod/try=> (rush 'abc' (just 'a'))
~
~zod/try=> (rush 'abc' (jest 'abc'))
[~ 'abc']
~zod/try=> (rush 'abc' (jest 'ac'))
~
~zod/try=> (rush 'abc' (jest 'ab'))
~
------------------------------------------------------------------------
### ++rust
Parse tape or null
++ rust |* [los=tape sab=_rule]
=+ vex=((full sab) [[1 1] los])
?~(q.vex ~ [~ u=p.u.q.vex])
Parse a tape with a given rule and produce null if the tape isn't
entirely parsed.
`los` is a [tape]().
`sab` is a [rule]().
~zod/try=> (rust "I was the world in which I walked, and what I saw" (star (shim 0 200)))
[~ "I was the world in which I walked, and what I saw"]
~zod/try=> (rust "Or heard or felt came not but from myself;" (star (shim 0 200)))
[~ "Or heard or felt came not but from myself;"]
~zod/try=> (rust "And there I found myself more truly and more strange." (jest 'And there I'))
~
------------------------------------------------------------------------
### ++scan
Parse tape or crash
++ scan |* [los=tape sab=_rule]
=+ vex=((full sab) [[1 1] los])
?~ q.vex
~_ (show [%m '{%d %d}'] p.p.vex q.p.vex ~)
~|('syntax-error' !!)
p.u.q.vex
Parse a tape with a given rule and crash if the tape isn't entirely
parsed.
`los` is a [tape]().
`sab` is a [rule]().
~zod/try=> (scan "I was the world in which I walked, and what I saw" (star (shim 0 200)))
"I was the world in which I walked, and what I saw"
~zod/try=> (scan "Or heard or felt came not but from myself;" (star (shim 0 200)))
"Or heard or felt came not but from myself;"
~zod/try=> (scan "And there I found myself more truly and more strange." (jest 'And there I'))
! {1 12}
! 'syntax-error'
! exit

View File

@ -0,0 +1,561 @@
section 2eJ, formatting (basic text)
====================================
### ++cass
To lowercase
++ cass :: lowercase
|= vib=tape
%+ rap 3
(turn vib |=(a=@ ?.(&((gte a 'A') (lte a 'Z')) a (add 32 a))))
::
Produce the case insensitive (all lowercase) cord of a tape.
`vib` is a [tape]().
~zod/try=> (cass "john doe")
7.309.170.810.699.673.450
~zod/try=> `cord`(cass "john doe")
'john doe'
~zod/try=> (cass "abc, 123, !@#")
2.792.832.775.110.938.439.066.079.945.313
~zod/try=> `cord`(cass "abc, 123, !@#")
'abc, 123, !@#'
------------------------------------------------------------------------
### ++cuss
To uppercase
++ cuss :: uppercase
|= vib=tape
^- @t
%+ rap 3
(turn vib |=(a=@ ?.(&((gte a 'a') (lte a 'z')) a (sub a 32))))
::
Turn all occurances of lowercase letters in any tape into uppercase
letters, as a cord.
`vib` is a [tape]().
~zod/try=> (cuss "john doe")
'JOHN DOE'
~zod/try=> (cuss "abc ABC 123 !@#")
'ABC ABC 123 !@#'
~zod/try=> `@ud`(cuss "abc")
4.407.873
~zod/try=> (cuss "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsQqRrVvWwXxYyZz")
'AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSQQRRVVWWXXYYZZ'
------------------------------------------------------------------------
### ++crip
Tape to cord
++ crip |=(a=tape `@t`(rap 3 a)) :: tape to cord
Produce cord from a tape.
`a` is a [tape]().
~zod/try=> (crip "john doe")
'john doe'
~zod/try=> (crip "abc 123 !@#")
'abc 123 !@#'
~zod/try=> `@ud`(crip "abc")
6.513.249
------------------------------------------------------------------------
### ++mesc
Escape special chars
++ mesc :: ctrl code escape
|= vib=tape
^- tape
?~ vib
~
?: =('\\' i.vib)
['\\' '\\' $(vib t.vib)]
?: ?|((gth i.vib 126) (lth i.vib 32) =(39 i.vib))
['\\' (welp ~(rux at i.vib) '/' $(vib t.vib))]
[i.vib $(vib t.vib)]
::
Escape special characters, used in [`++show`]()
`vib` is a [tape]().
/~zod/try=> (mesc "ham lus")
"ham lus"
/~zod/try=> (mesc "bas\\hur")
"bas\\\\hur"
/~zod/try=> (mesc "as'saß")
"as\0x27/sa\0xc3/\0x9f/"
------------------------------------------------------------------------
### ++runt
Prepend `n` times
++ runt :: prepend repeatedly
|= [[a=@ b=@] c=tape]
^- tape
?: =(0 a)
c
[b $(a (dec a))]
::
Add `a` repetitions of character `b` to the head of `c`
`a` and `b` are [atom]()s.
`c` is a [tape]().
/~zod/try=> (runt [2 '/'] "ham")
"//ham"
/~zod/try=> (runt [10 'a'] "")
"aaaaaaaaaa"
------------------------------------------------------------------------
### ++sand
Soft-cast by odor
++ sand :: atom sanity
|= a=@ta
|= b=@ ^- (unit ,@)
?.(((sane a) b) ~ [~ b])
::
Soft-cast validity by odor.
`a` is a [`@ta`]().
`b` is an [atom]().
/~zod/try=> `(unit ,@ta)`((sand %ta) 'sym-som')
[~ ~.sym-som]
/~zod/try=> `(unit ,@ta)`((sand %ta) 'err!')
~
------------------------------------------------------------------------
### ++sane
Check odor validity
++ sane :: atom sanity
|= a=@ta
|= b=@ ^- ?
?. =(%t (end 3 1 a))
~|(%sane-stub !!)
=+ [inx=0 len=(met 3 b)]
?: =(%tas a)
|- ^- ?
?: =(inx len) &
=+ cur=(cut 3 [inx 1] b)
?& ?| &((gte cur 'a') (lte cur 'z'))
&(=('-' cur) !=(0 inx) !=(len inx))
&(&((gte cur '0') (lte cur '9')) !=(0 inx))
==
$(inx +(inx))
==
?: =(%ta a)
|- ^- ?
?: =(inx len) &
=+ cur=(cut 3 [inx 1] b)
?& ?| &((gte cur 'a') (lte cur 'z'))
&((gte cur '0') (lte cur '9'))
|(=('-' cur) =('~' cur) =('_' cur) =('.' cur))
==
$(inx +(inx))
==
|- ^- ?
?: =(0 b) &
=+ cur=(end 3 1 b)
?: &((lth cur 32) !=(10 cur)) |
=+ len=(teff cur)
?& |(=(1 len) =+(i=1 |-(|(=(i len) &((gte (cut 3 [i 1] b) 128) $(i +(i)))))))
$(b (rsh 3 len b))
==
::
Check validity by odor. Produces a gate.
`a` is a [`@ta`]().
`b` is an [atom]().
/~zod/try=> ((sane %tas) %mol)
%.y
/~zod/try=> ((sane %tas) 'lam')
%.y
/~zod/try=> ((sane %tas) 'more ace')
%.n
------------------------------------------------------------------------
### ++trim
Tape split
++ trim :: tape split
|= [a=@ b=tape]
^- [p=tape q=tape]
?~ b
[~ ~]
?: =(0 a)
[~ b]
=+ c=$(a (dec a), b t.b)
[[i.b p.c] q.c]
::
Split first `a` characters off tape.
`a` is an [atom]().
`b` is a [tape]().
/~zod/try=> (trim 5 "lasok termun")
[p="lasok" q=" termun"]
/~zod/try=> (trim 5 "zam")
[p="zam" q=""]
------------------------------------------------------------------------
### ++trip
Cord to tape
++ trip :: cord to tape
~/ %trip
|= a=@ ^- tape
?: =(0 (met 3 a))
~
[^-(@ta (end 3 1 a)) $(a (rsh 3 1 a))]
::
Produce tape from cord.
`a` is an [atom]().
/~zod/try=> (trip 'john doe')
"john doe"
/~zod/try=> (trip 'abc 123 !@#')
"abc 123 !@#"
/~zod/try=> (trip 'abc')
"abc"
------------------------------------------------------------------------
### ++teff
UTF8 Length
++ teff :: length utf8
|= a=@t ^- @
=+ b=(end 3 1 a)
?: =(0 b)
?>(=(0 a) 0)
?> |((gte b 32) =(10 b))
?:((lte b 127) 1 ?:((lte b 223) 2 ?:((lte b 239) 3 4)))
::
Number of utf8 bytes.
`a` is a [`@t`]().
/~zod/try=> (teff 'a')
1
/~zod/try=> (teff 'ß')
2
------------------------------------------------------------------------
### ++turf
UTF8 to UTF32 cord
++ turf :: utf8 to utf32
|= a=@t
^- @c
%+ rap 5
|- ^- (list ,@c)
=+ b=(teff a)
?: =(0 b) ~
:- %+ can 0
%+ turn
^- (list ,[p=@ q=@])
?+ b !!
1 [[0 7] ~]
2 [[8 6] [0 5] ~]
3 [[16 6] [8 6] [0 4] ~]
4 [[24 6] [16 6] [8 6] [0 3] ~]
==
|=([p=@ q=@] [q (cut 0 [p q] a)])
$(a (rsh 3 b a))
::
Convert utf8 ([cord]()) to utf32 codepoints.
`a` is a [`@t`]().
/~zod/try=> (turf 'my ßam')
~-my.~df.am
/~zod/try=> 'я тут'
'я тут'
/~zod/try=> (turf 'я тут')
~-~44f..~442.~443.~442.
/~zod/try=> `@ux`'я тут'
0x82.d183.d182.d120.8fd1
/~zod/try=> `@ux`(turf 'я тут')
0x442.0000.0443.0000.0442.0000.0020.0000.044f
------------------------------------------------------------------------
### ++tuba
UTF8 to UTF32 tape
++ tuba :: utf8 to utf32 tape
|= a=tape
^- (list ,@c)
(rip 5 (turf (rap 3 a))) :: XX horrible
::
Convert tape to list of codepoints.
`a` is a [tape]()
/~zod/try=> (tuba "я тут")
~[~-~44f. ~-. ~-~442. ~-~443. ~-~442.]
/~zod/try=> (tuba "chars")
~[~-c ~-h ~-a ~-r ~-s]
------------------------------------------------------------------------
### ++tufa
UTF32 to UTF8 tape
++ tufa :: utf32 to utf8 tape
|= a=(list ,@c)
^- tape
?~ a ""
(weld (rip 3 (tuft i.a)) $(a t.a))
::
Wrap list of utf32 codepoints to utf8 [tape]().
`a` is a [list]() of [`@c`]().
/~zod/try=> (tufa ~[~-~44f. ~-. ~-~442. ~-~443. ~-~442.])
"я тут"
/~zod/try=> (tufa ((list ,@c) ~[%a %b 0xb1 %c]))
"ab±c"
------------------------------------------------------------------------
### ++tuft
UTF32 to UTF8 text
++ tuft :: utf32 to utf8 text
|= a=@c
^- @t
%+ rap 3
|- ^- (list ,@)
?: =(0 a)
~
=+ b=(end 5 1 a)
=+ c=$(a (rsh 5 1 a))
?: (lth b 0x7f)
[b c]
?: (lth b 0x7ff)
:* (mix 0b1100.0000 (cut 0 [6 5] b))
(mix 0b1000.0000 (end 0 6 b))
c
==
?: (lth b 0xffff)
:* (mix 0b1110.0000 (cut 0 [12 4] b))
(mix 0b1000.0000 (cut 0 [6 6] b))
(mix 0b1000.0000 (end 0 6 b))
c
==
:* (mix 0b1111.0000 (cut 0 [18 3] b))
(mix 0b1000.0000 (cut 0 [12 6] b))
(mix 0b1000.0000 (cut 0 [6 6] b))
(mix 0b1000.0000 (end 0 6 b))
c
==
::
Convert utf32 glyph to
[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) utf8 cord.
`a` is a [`@c`]().
/~zod/try=> (tuft `@c`%a)
'a'
/~zod/try=> (tuft `@c`0xb6)
'¶'
------------------------------------------------------------------------
### ++wack
Coin format encode
++ wack :: coin format
|= a=@ta
^- @ta
=+ b=(rip 3 a)
%+ rap 3
|- ^- tape
?~ b
~
?: =('~' i.b) ['~' '~' $(b t.b)]
?: =('_' i.b) ['~' '-' $(b t.b)]
[i.b $(b t.b)]
::
Escape span `~` as `~~` and `_` as `~-`. Used for printing.
`a` is a [`@ta`]().
/~zod/try=> (wack '~20_sam~')
~.~~20~-sam~~
/~zod/try=> `@t`(wack '~20_sam~')
'~~20~-sam~~'
~zod/try=> ~(rend co %many ~[`ud/5 `ta/'~20_sam'])
"._5_~~.~~20~-sam__"
~zod/try=> ._5_~~.~~20~-sam__
[5 ~.~20_sam]
------------------------------------------------------------------------
### ++wick
Coin format decode
++ wick :: coin format
|= a=@
^- @ta
=+ b=(rip 3 a)
%+ rap 3
|- ^- tape
?~ b
~
?: =('~' i.b)
?~ t.b !!
[?:(=('~' i.t.b) '~' ?>(=('-' i.t.b) '_')) $(b t.t.b)]
[i.b $(b t.b)]
::
Unescape span `~~` as `~` and `~-` as `_`.
`a` is a an [atom]().
/~zod/try=> `@t`(wick '~-ams~~lop')
'_ams~lop'
/~zod/try=> `@t`(wick (wack '~20_sam~'))
'~20_sam~'
------------------------------------------------------------------------
### ++woad
Unescape cord
++ woad :: cord format
|= a=@ta
^- @t
%+ rap 3
|- ^- (list ,@)
?: =(0 a)
~
=+ b=(end 3 1 a)
=+ c=(rsh 3 1 a)
?: =('.' b)
[' ' $(a c)]
?. =('~' b)
[b $(a c)]
=> .(b (end 3 1 c), c (rsh 3 1 c))
?+ b =- (weld (rip 3 (tuft p.d)) $(a q.d))
^= d
=+ d=0
|- ^- [p=@ q=@]
?: =('.' b)
[d c]
?< =(0 c)
%= $
b (end 3 1 c)
c (rsh 3 1 c)
d %+ add (mul 16 d)
%+ sub b
?: &((gte b '0') (lte b '9')) 48
?>(&((gte b 'a') (lte b 'z')) 87)
==
%'.' ['.' $(a c)]
%'~' ['~' $(a c)]
==
::
Unescape cord codepoints.
`a` is a [`@ta`]().
/~zod/try=> (woad ~.~b6.20.as)
'¶20 as'
------------------------------------------------------------------------
### ++wood
Escape cord
++ wood :: cord format
|= a=@t
^- @ta
%+ rap 3
|- ^- (list ,@)
?: =(0 a)
~
=+ b=(teff a)
=+ c=(turf (end 3 b a))
=+ d=$(a (rsh 3 b a))
?: ?| &((gte c 'a') (lte c 'z'))
&((gte c '0') (lte c '9'))
=('-' c)
==
[c d]
?+ c
:- '~'
=+ e=(met 2 c)
|- ^- tape
?: =(0 c)
['.' d]
=. e (dec e)
=+ f=(rsh 2 e c)
[(add ?:((lte f 9) 48 87) f) $(c (end 2 e c))]
::
%' ' ['.' d]
%'.' ['~' '.' d]
%'~' ['~' '~' d]
==
Escape cord codepoints.
`a` is a [`@ta`]().
/~zod/try=> (wood 'my ßam')
~.my.~df.am

View File

@ -0,0 +1,162 @@
section 2eK, formatting (layout)
================================
### ++re
Pretty-printing engine
++ re
|_ tac=tank
Pretty-printing engine.
`tac` is a [`++tank`]().
/~zod/try=> ~(. re leaf/"ham")
<2.ghl [[%leaf ""] <414.gly 100.xkc 1.ypj %164>]>
### ++ram
Flatten to tape
++ ram
^- tape
?- -.tac
%leaf p.tac
%palm ram(tac [%rose [p.p.tac (weld q.p.tac r.p.tac) s.p.tac] q.tac])
%rose
%+ weld
q.p.tac
|- ^- tape
?~ q.tac
r.p.tac
=+ voz=$(q.tac t.q.tac)
(weld ram(tac i.q.tac) ?~(t.q.tac voz (weld p.p.tac voz)))
==
::
Flatten tank out into a tape.
/~zod/try=> ~(ram re leaf/"foo")
"foo"
/~zod/try=> ~(ram re rose/["." "(" ")"]^~[leaf/"bar" leaf/"baz" leaf/"bam"])
"(bar.baz.bam)"
### ++win
Render at indent
++ win
|= [tab=@ edg=@]
=+ lug=`wall`~
|^ |- ^- wall
?- -.tac
%leaf (rig p.tac)
%palm
?: fit
(rig ram)
?~ q.tac
(rig q.p.tac)
?~ t.q.tac
(rig(tab (add 2 tab), lug $(tac i.q.tac)) q.p.tac)
=> .(q.tac `(list tank)`q.tac)
=+ lyn=(mul 2 (lent q.tac))
=+ ^= qyr
|- ^- wall
?~ q.tac
lug
%= ^$
tac i.q.tac
tab (add tab (sub lyn 2))
lug $(q.tac t.q.tac, lyn (sub lyn 2))
==
(wig(lug qyr) q.p.tac)
::
%rose
?: fit
(rig ram)
=+ ^= gyl
|- ^- wall
?~ q.tac
?:(=(%$ r.p.tac) lug (rig r.p.tac))
^$(tac i.q.tac, lug $(q.tac t.q.tac), tab din)
?: =(%$ q.p.tac)
gyl
(wig(lug gyl) q.p.tac)
==
::
Render at indent level `tab` and width `edg`.
`tab` and `edg` are [atom]()s.
/~zod/try=> (~(win re leaf/"samoltekon-lapdok") 0 20)
<<"samoltekon-lapdok">>
/~zod/try=> (~(win re leaf/"samoltekon-lapdok") 0 10)
<<"\/samolt\/" " ekon-l" " apdok" "\/ \/">>
/~zod/try=> (~(win re rose/["--" "[" "]"]^~[leaf/"1423" leaf/"2316"]) 0 20)
<<"[1423--2316]">>
/~zod/try=> (~(win re rose/["--" "[" "]"]^~[leaf/"1423" leaf/"2316"]) 0 10)
<<"[ 1423" " 2316" "]">>
### ++din
++ din (mod (add 2 tab) (mul 2 (div edg 3)))
XX document
### ++fit
Fit on one line test
++ fit (lte (lent ram) (sub edg tab))
Determine whether `tac` fits on one line. Internal to `++win`
### ++rig
Wrap in `\/`
++ rig
|= hom=tape
^- wall
?: (lte (lent hom) (sub edg tab))
[(runt [tab ' '] hom) lug]
=> .(tab (add tab 2), edg (sub edg 2))
=+ mut=(trim (sub edg tab) hom)
:- (runt [(sub tab 2) ' '] ['\\' '/' (weld p.mut `_hom`['\\' '/' ~])])
=> .(hom q.mut)
|-
?~ hom
:- %+ runt
[(sub tab 2) ' ']
['\\' '/' (runt [(sub edg tab) ' '] ['\\' '/' ~])]
lug
=> .(mut (trim (sub edg tab) hom))
[(runt [tab ' '] p.mut) $(hom q.mut)]
::
Wrap tape in `\/` if it doesn't fit at current indentation. Internal to
`++win`
### ++wig
`++win` render tape
++ wig
|= hom=tape
^- wall
?~ lug
(rig hom)
=+ lin=(lent hom)
=+ wug=:(add 1 tab lin)
?. =+ mir=i.lug
|- ?~ mir
|
?|(=(0 wug) ?&(=(' ' i.mir) $(mir t.mir, wug (dec wug))))
(rig hom) :: ^ XX regular form?
[(runt [tab ' '] (weld hom `tape`[' ' (slag wug i.lug)])) t.lug]
--
--
Render tape. Internal to `++win`.

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,758 @@
section 2eM, regular-expressions
================================
### ++pars
++ pars
|= [a=tape] :: parse tape to rege
^- (unit rege)
=+ foo=((full apex:rags) [[1 1] a])
?~ q.foo
~
[~ p.u.q.foo]
::
Parse regular expression
~zod/try=> (pars "samo")
[ ~
[ %pair
p=[%lite p=~~s]
q=[%pair p=[%lite p=~~a] q=[%pair p=[%lite p=~~m] q=[%lite p=~~o]]]
]
]
~zod/try=> (pars "so[,.0-9]")
[ ~
[ %pair
p=[%lite p=~~s]
q=[%pair p=[%lite p=~~o] q=[%brac p=288.036.862.105.223.168]]
]
]
~zod/try=> `@ub`288.036.862.105.223.168
0b11.1111.1111.0101.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
~zod/try=> `@ub`(lsh 0 `@`'9' 1)
0b10.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
~zod/try=> `@ub`(roll (turn ",.0123456789" |=(a=@ (lsh 0 a 1))) con)
0b11.1111.1111.0101.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
~zod/try=> (pars "sop.*")
[ ~
[ %pair
p=[%lite p=~~s]
q=[%pair p=[%lite p=~~o] q=[%pair p=[%lite p=~~p] q=[%mant p=%dote]]]
]
]
~zod/try=> (pars "(hel)?")
[ ~
[ %eith
p
[ %capt
p=[%pair p=[%lite p=~~h] q=[%pair p=[%lite p=~~e] q=[%lite p=~~l]]]
q=0
]
q=%empt
]
]
~zod/try=> (pars "(hel)??")
[ ~
[ %eith
p=%empt
q
[ %capt
p=[%pair p=[%lite p=~~h] q=[%pair p=[%lite p=~~e] q=[%lite p=~~l]]]
q=0
]
]
]
~zod/try=> (pars "a\{1,20}")
[~ [%betw p=[%lite p=~~a] q=1 r=20]]
### ++rags
++ rags :: rege parsers
=> |%
Regex parser arms
### ++nor
++ nor ;~(less (mask "^$()|*?+.[\\") (shim 1 127)) :: non-control char
XX document
### ++les
++ les ;~(less bas asp) :: not backslash
XX document
### ++lep
++ lep ;~(less (mask "^[]\\") asp) :: charset non-control
XX document
### ++asp
++ asp (shim 32 126) :: printable ascii
XX document
### ++alb
++ alb ;~(less ser asp) :: charset literal char
XX document
### ++mis
++ mis ;~(less aln asp) :: non alphanumeric
--
|%
XX document
### ++apex
++ apex :: top level
%+ knee *rege |. ~+
;~ pose
;~((bend |=(a=[rege rege] (some [%eith a]))) mall ;~(pfix bar apex))
(stag %eith ;~(plug (easy %empt) ;~(pfix bar apex)))
(easy %empt)
==
::
XX document
### ++mall
++ mall
%+ knee *rege |. ~+
;~((bend |=(a=[rege rege] (some [%pair a]))) bets mall)
::
XX document
### ++bets
++ bets
%+ knee *rege |. ~+
|= tub=nail
=+ vex=(chun tub)
?~ q.vex
vex
=+ a=p.u.q.vex
%- ;~ pose
(cold [%eith %empt a] (jest '??'))
(cold [%manl a] (jest '*?'))
(cold [%plll a] (jest '+?'))
(cold [%eith a %empt] wut)
(cold [%mant a] tar)
(cold [%plls a] lus)
(stag %betl ;~(plug (easy a) ;~(sfix rang wut)))
(stag %betw ;~(plug (easy a) rang))
(stag %binl ;~(plug (easy a) (ifix [kel (jest ',}?')] dim:ag)))
(stag %bant ;~(plug (easy a) (ifix [kel (jest '}?')] dim:ag)))
(stag %bant ;~(plug (easy a) (ifix [kel ker] dim:ag)))
(stag %bint ;~(plug (easy a) (ifix [kel (jest ',}')] dim:ag)))
(easy a)
==
q.u.q.vex
::
XX document
### ++ranc
++ ranc
|= [a=@ b=@]
^- @
?:((gth a b) 0 (con (bex a) $(a +(a))))
::
XX document
### ++flap
++ flap |=(a=@ (mix a (dec (bex 256))))
::
XX document
### ++rang
++ rang
%+ sear |=([a=@ b=@] ?:((lte a b) (some [a b]) ~))
(ifix [kel ker] ;~(plug dim:ag ;~(pfix com dim:ag)))
::
XX document
### ++chun
++ chun
%+ knee *rege |. ~+
;~ pose
(cold %ende buc)
(cold %sart ket)
(cold %dote dot)
%+ cook |=(a=(list char) (reel a |=([p=char q=rege] [%pair [%lite p] q])))
;~(pfix (jest '\\Q') cape)
|= tub=nail
=+ foo=;~(plug kel dim:ag ;~(pose ker (jest ',}') ;~(plug com dim:ag ker)))
=+ bar=(foo tub)
?~(q.bar (chad tub) (fail tub))
(cook |=([a=rege] [%capt a 0]) (ifix [pel per] apex))
%+ cook |=([a=rege] [%capt a 0])
(ifix [;~(plug (jest '(?P<') (plus aln) gar) per] apex)
(ifix [(jest '(?:') per] apex)
(stag %brac ;~(pfix sel seac))
==
::
XX document
### ++seac
++ seac
|= tub=nail
?~ q.tub
(fail tub)
?: =(i.q.tub '^')
(;~(pfix ket (cook flap sead)) tub)
(sead tub)
::
XX document
### ++sead
++ sead
%+ knee *@ |. ~+
;~ pose
|= tub=nail
?~ q.tub
(fail tub)
?. =(i.q.tub ']')
(fail tub)
?~ t.q.tub
(fail tub)
?: =(i.t.q.tub '-')
?~ t.t.q.tub
(fail tub)
?: =(i.t.t.q.tub ']')
(;~(pfix ser (cook |=(a=@ (con (bex ']') a)) sade)) tub)
(fail tub)
(;~(pfix ser (cook |=(a=@ (con (bex ']') a)) sade)) tub)
|= tub=nail
?~ q.tub
(fail tub)
?. =(i.q.tub '-')
(fail tub)
?~ t.q.tub
(fail tub)
?: =(i.t.q.tub '-')
?~ t.t.q.tub
(fail tub)
?: =(i.t.t.q.tub ']')
(;~(pfix hep (cook |=(a=@ (con (bex '-') a)) sade)) tub)
(fail tub)
(;~(pfix hep (cook |=(a=@ (con (bex '-') a)) sade)) tub)
(cook |=(a=[@ @] (con a)) ;~(plug seap sade))
==
::
XX document
### ++sade
++ sade
%+ knee *@ |. ~+
;~ pose
(cold (bex '-') (jest '-]'))
(cold 0 ser)
(cook |=([p=@ q=@] `@`(con p q)) ;~(plug seap sade))
==
::
XX document
### ++seap
++ seap
%+ knee *@ |. ~+
;~ pose
unid
%+ ifix (jest '[:')^(jest ':]')
;~(pose ;~(pfix ket (cook flap chas)) chas)
%+ sear |=([a=@ b=@] ?:((gth a b) ~ (some (ranc a b))))
;~(plug asp ;~(pfix hep alb))
|= tub=nail
?~ q.tub
(fail tub)
?~ t.q.tub
((cook bex les) tub)
?: =(i.t.q.tub '-')
?~ t.t.q.tub
((cook bex les) tub)
?: =(i.t.t.q.tub ']')
((cook bex les) tub)
(fail tub)
((cook bex les) tub)
;~(pfix bas escd)
==
::
XX document
### ++cape
++ cape
%+ knee *tape |. ~+
;~ pose
(cold ~ (jest '\\E'))
;~(plug next cape)
(cook |=(a=char (tape [a ~])) next)
(full (easy ~))
==
XX document
### ++chas
++ chas :: ascii character set
=- (sear ~(get by -) sym)
%- mo ^- (list ,[@tas @I])
:~ alnum/alnum alpha/alpha ascii/ascii blank/blank cntrl/cntrl
digit/digit graph/graph lower/lower print/print punct/punct
space/space upper/upper word/wordc xdigit/xdigit
==
:: Character sets
++ alnum :(con lower upper digit)
XX document
###++alpha
++ alpha :(con lower upper)
XX document
###++ascii
++ ascii (ranc 0 127)
++ blank (con (bex 32) (bex 9))
XX document
### ++cntrl
++ cntrl :(con (ranc 0 31) (bex 127))
XX document
### ++digit
++ digit (ranc '0' '9')
XX document
### ++graph
++ graph (ranc 33 126)
XX document
### ++lower
++ lower (ranc 'a' 'z')
XX document
### ++print
++ print (ranc 32 126)
XX document
### ++punct
++ punct ;: con
(ranc '!' '/')
(ranc ':' '@')
(ranc '[' '`')
(ranc '{' '~')
==
XX document
### ++space
++ space :(con (ranc 9 13) (bex ' '))
XX document
### ++upper
++ upper (ranc 'A' 'Z')
XX document
### ++white
++ white :(con (bex ' ') (ranc 9 10) (ranc 12 13))
XX document
### ++wordc
++ wordc :(con digit lower upper (bex '_'))
XX document
### ++xdigit
++ xdigit :(con (ranc 'a' 'f') (ranc 'A' 'F') digit)
::
XX document
### ++chad
++ chad
%+ knee *rege |. ~+
;~(pose (stag %lite nor) (stag %brac unid) ;~(pfix bas escp))
::
XX document
### ++escd
++ escd
%+ knee *@ |. ~+
;~ pose
(cold (bex 7) (just 'a'))
(cold (bex 9) (just 't'))
(cold (bex 10) (just 'n'))
(cold (bex 11) (just 'v'))
(cold (bex 12) (just 'f'))
(cold (bex 13) (just 'r'))
(cold (bex 0) (just '0'))
(sear |=(a=@ ?:((lth a 256) (some (bex a)) ~)) (bass 8 (stun [2 3] cit)))
(cook bex ;~(pfix (just 'x') (bass 16 (stun [2 2] hit))))
(cook bex (ifix [(jest 'x{') ker] (bass 16 (stun [2 2] hit))))
(cook bex mis)
==
::
XX document
### ++escp
++ escp
%+ knee *rege |. ~+
;~ pose
(cold %empt (just 'Q'))
(cold [%lite `@tD`0] (just '0'))
(cold [%lite `@tD`7] (just 'a'))
(cold [%lite `@tD`9] (just 't'))
(cold [%lite `@tD`10] (just 'n'))
(cold [%lite `@tD`11] (just 'v'))
(cold [%lite `@tD`12] (just 'f'))
(cold [%lite `@tD`13] (just 'r'))
(sear |=(a=@ ?:((lth a 256) (some [%lite a]) ~)) (bass 8 (stun [2 3] cit)))
(stag %lite ;~(pfix (just 'x') (bass 16 (stun [2 2] hit))))
(stag %lite (ifix [(jest 'x{') ker] (bass 16 (stun [2 2] hit))))
(cold %dote (just 'C'))
(cold %sart (just 'A'))
(cold %ende (just 'z'))
(cold %boun (just 'b'))
(cold %bout (just 'B'))
(stag %brac (cold wordc (just 'w')))
(stag %brac (cold (flap wordc) (just 'W')))
(stag %lite mis)
==
::
XX document
### ++unid
++ unid
%+ knee *@ |. ~+
;~ pose
(cold digit (jest '\\d'))
(cold (flap digit) (jest '\\D'))
(cold white (jest '\\s'))
(cold (flap white) (jest '\\S'))
(cold wordc (jest '\\w'))
(cold (flap wordc) (jest '\\W'))
==
--
::
XX document
### ++ra
++ ra :: regex engine
|_ a=rege
XX document
### ++proc
++ proc :: capture numbering
|= b=@
=- -(+ +>.$(a a))
^- [p=@ a=rege]
?- a
[%capt *] =+ foo=$(a p.a, b +(b))
[p.foo [%capt a.foo b]]
[%eith *] =+ foo=$(a p.a)
=+ bar=$(a q.a, b p.foo)
[p.bar [%eith a.foo a.bar]]
[%pair *] =+ foo=$(a p.a)
=+ bar=$(a q.a, b p.foo)
[p.bar [%pair a.foo a.bar]]
[%manl *] =+ foo=$(a p.a)
[p.foo [%manl a.foo]]
[%plll *] =+ foo=$(a p.a)
[p.foo [%plll a.foo]]
[%binl *] =+ foo=$(a p.a)
[p.foo [%binl a.foo q.a]]
[%betl *] =+ foo=$(a p.a)
[p.foo [%betl a.foo q.a r.a]]
[%mant *] =+ foo=$(a p.a)
[p.foo [%mant a.foo]]
[%plls *] =+ foo=$(a p.a)
[p.foo [%plls a.foo]]
[%bant *] =+ foo=$(a p.a)
[p.foo [%bant a.foo q.a]]
[%bint *] =+ foo=$(a p.a)
[p.foo [%bint a.foo q.a]]
[%betw *] =+ foo=$(a p.a)
[p.foo [%betw a.foo q.a r.a]]
* [b a]
==
::
XX document
### ++cont
++ cont
|= [a=(map ,@u tape) b=(map ,@u tape)]
(~(gas by _(map ,@u tape)) (weld (~(tap by a)) (~(tap by b))))
::
XX document
### ++abor
++ abor
|= [a=char b=(unit ,[tape (map ,@u tape)])]
^- (unit ,[tape (map ,@u tape)])
?~ b
b
[~ [[a -.u.b] +.u.b]]
::
XX document
### ++matc
++ matc
|= [b=tape c=tape]
^- (unit (map ,@u tape))
=+ foo=`(unit ,[tape (map ,@u tape)])`(deep b %empt c)
(bind foo |*(a=^ (~(put by +.a) 0 -.a)))
::
XX document
### ++chet
++ chet
|= [b=(unit ,[tape (map ,@u tape)]) c=tape d=tape]
^- (unit ,[tape (map ,@u tape)])
?~ b
b
?~ -.u.b
b
=+ bar=(deep (slag (lent -.u.b) c) %empt d)
?~ bar
bar
b
XX document
### ++blak
++ blak (some ["" _(map ,@u tape)])
XX document
### ++word
++ word |=(a=char =((dis wordc:rags (bex a)) 0))
XX document
### ++deep
++ deep
|= [b=tape c=rege d=tape]
^- (unit ,[tape (map ,@u tape)])
?- a
%dote ?~(b ~ (some [[i.b ~] _(map ,@u tape)]))
%ende ?~(b blak ~)
%sart ?:(=(b d) blak ~)
%empt blak
%boun =+ ^= luc
?: =(b d)
&
=+ foo=(slag (dec (sub (lent d) (lent b))) d)
(word -.foo)
=+ cuc=?~(b & (word -.b))
?:(!=(luc cuc) blak ~)
%bout =+ ^= luc
?: =(b d)
&
=+ foo=(slag (dec (sub (lent d) (lent b))) d)
(word -.foo)
=+ cuc=?~(b & (word -.b))
?:(=(luc cuc) blak ~)
[%capt *] =+ foo=$(a p.a)
?~ foo
foo
=+ ft=u.foo
=+ bar=$(a c, b (slag (lent -.ft) b), c %empt)
?~ bar
bar
[~ [-.ft (~(put by +.ft) q.a -.ft)]]
[%lite *] ?~(b ~ ?:(=(i.b p.a) (some [[i.b ~] _(map ,@u tape)]) ~))
[%brac *] ?~ b
~
?. =((dis (bex `@`i.b) p.a) 0)
(some [[i.b ~] _(map ,@u tape)])
~
[%eith *] =+ foo=(chet(a c) $(a p.a) b d)
=+ bar=(chet(a c) $(a q.a) b d)
?~ foo
bar
?~ bar
foo
=+ ft=u.foo
=+ bt=u.bar
?: (gte (lent -.ft) (lent -.bt))
foo
bar
[%pair *] =+ foo=$(a p.a, c [%pair q.a c])
?~ foo
foo
=+ ft=u.foo
=+ bar=$(a q.a, b (slag (lent -.ft) b))
?~ bar
bar
=+ bt=u.bar
[~ [(weld -.ft -.bt) (cont +.ft +.bt)]]
[%manl *] =+ foo=$(a p.a)
?~ foo
blak
?~ -.u.foo
blak
$(a [%eith %empt [%pair p.a [%eith %empt a]]])
[%mant *] =+ foo=$(a p.a)
?~ foo
blak
=+ ft=u.foo
?~ -.ft
blak
$(a [%eith [%pair p.a [%eith a %empt]] %empt])
[%plls *] $(a [%pair p.a [%mant p.a]])
[%plll *] $(a [%pair p.a [%manl p.a]])
[%binl *] =+ min=?:(=(q.a 0) 0 (dec q.a))
?: =(q.a 0)
$(a [%manl p.a])
$(a [%pair p.a [%binl p.a min]])
[%bant *] ?: =(0 q.a)
blak
$(a [%pair p.a [%bant p.a (dec q.a)]])
[%bint *] =+ min=?:(=(q.a 0) 0 (dec q.a))
?: =(q.a 0)
$(a [%mant p.a])
$(a [%pair p.a [%bint p.a min]])
[%betw *] ?: =(0 r.a)
blak
?: =(q.a 0)
$(a [%eith [%pair p.a [%betw p.a 0 (dec r.a)]] %empt])
$(a [%pair p.a [%betw p.a (dec q.a) (dec r.a)]])
[%betl *] ?: =(0 r.a)
blak
?: =(q.a 0)
$(a [%eith %empt [%pair p.a [%betl p.a 0 (dec r.a)]]])
$(a [%pair p.a [%betl p.a (dec q.a) (dec r.a)]])
==
--
::
XX document
### ++rexp
++ rexp :: Regex match
~/ %rexp
|= [a=tape b=tape]
^- (unit (unit (map ,@u tape)))
=+ ^= bar
|= [a=@ b=(map ,@u tape)]
?: =(a 0)
b
=+ c=(~(get by b) a)
?~ c
$(a (dec a), b (~(put by b) a ""))
$(a (dec a))
=+ par=(pars a)
?~ par ~
=+ poc=(~(proc ra u.par) 1)
=+ c=b
|-
=+ foo=(matc:poc c b)
?~ foo
?~ c
[~ ~]
$(c t.c)
[~ [~ (bar (dec p.poc) u.foo)]]
::
XX document
### ++repg
++ repg :: Global regex replace
~/ %repg
|= [a=tape b=tape c=tape]
^- (unit tape)
=+ par=(pars a)
?~ par ~
=+ poc=(~(proc ra u.par) 1)
=+ d=b
:- ~
|-
^- tape
=+ foo=(matc:poc d b)
?~ foo
?~ d
~
[i.d $(d t.d)]
=+ ft=(need (~(get by u.foo) 0))
?~ d
c
(weld c $(d `tape`(slag (lent ft) `tape`d)))
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

View File

@ -0,0 +1,257 @@
section 2eN, pseudo-cryptography
================================
### ++un
Reversible scrambling core
++ un :: =(x (wred (wren x)))
|%
A core that contains arms that perform reversible scrambling operations.
Used in the `@p` phonetic base.
------------------------------------------------------------------------
### ++wren
Conceal structure
++ wren :: conceal structure
|= pyn=@ ^- @
=+ len=(met 3 pyn)
?: =(0 len)
0
=> .(len (dec len))
=+ mig=(zaft (xafo len (cut 3 [len 1] pyn)))
%+ can 3
%- flop ^- (list ,[@ @])
:- [1 mig]
|- ^- (list ,[@ @])
?: =(0 len)
~
=> .(len (dec len))
=+ mog=(zyft :(mix mig (end 3 1 len) (cut 3 [len 1] pyn)))
[[1 mog] $(mig mog)]
::
Scrambles a bytestring `pyn` by adding the current position to each
byte, looking it up in an s-box, and then performing the XOR operation
on the result, pushing it forward. Produces an atom.
`pyn` is an [atom]().
~zod/try=> `@ux`(wren:un 'testing')
0x30.bf6a.b9fe.7d8f
~zod/try=> `@ux`'testing'
0x67.6e69.7473.6574
~zod/try=> `@da`(wred:un (wren:un ~2001.2.5))
~2001.2.5
------------------------------------------------------------------------
### ++wred
Restore structure
++ wred :: restore structure
|= cry=@ ^- @
=+ len=(met 3 cry)
?: =(0 len)
0
=> .(len (dec len))
=+ mig=(cut 3 [len 1] cry)
%+ can 3
%- flop ^- (list ,[@ @])
:- [1 (xaro len (zart mig))]
|- ^- (list ,[@ @])
?: =(0 len)
~
=> .(len (dec len))
=+ mog=(cut 3 [len 1] cry)
[[1 :(mix mig (end 3 1 len) (zyrt mog))] $(mig mog)]
::
Unscrambles a bytestring `cry` by subtracting the current position from
each byte, looking it up in an s-box, and performing the XOR operation
on the result, pushing it forward. Produces an atom.
`cry` is an [atom]().
~zod/try=> (wred:un 0x30.bf6a.b9fe.7d8f)
29.113.321.805.538.676
~zod/try=> `@t`(wred:un 0x30.bf6a.b9fe.7d8f)
'testing'
~zod/try=> (wred:un (wren:un 200.038.426))
200.038.426
------------------------------------------------------------------------
### ++xafo
Add modulo 255
++ xafo |=([a=@ b=@] +((mod (add (dec b) a) 255)))
Produces the sum of two atoms modulo 255, encoded as a nonzero byte.
~zod/try=> (xafo:un 5 6)
11
~zod/try=> (xafo:un 256 20)
21
------------------------------------------------------------------------
### ++xaro
Subtract modulo 255
++ xaro |=([a=@ b=@] +((mod (add (dec b) (sub 255 (mod a 255))) 255)))
Produces the difference between two atoms modulo 255, encoded as a
nonzero byte.
~zod/try=> (xaro:un 17 57)
40
~zod/try=> (xaro:un 265 12)
2
------------------------------------------------------------------------
### ++zaft
Look up in 255 sub box
++ zaft :: forward 255-sbox
|= a=@D
=+ ^= b
0xcc.75bc.86c8.2fb1.9a42.f0b3.79a0.92ca.21f6.1e41.cde5.fcc0.
7e85.51ae.1005.c72d.1246.07e8.7c64.a914.8d69.d9f4.59c2.8038.
1f4a.dca2.6fdf.66f9.f561.a12e.5a16.f7b0.a39f.364e.cb70.7318.
1de1.ad31.63d1.abd4.db68.6a33.134d.a760.edee.5434.493a.e323.
930d.8f3d.3562.bb81.0b24.43cf.bea5.a6eb.52b4.0229.06b2.6704.
78c9.45ec.d75e.58af.c577.b7b9.c40e.017d.90c3.87f8.96fa.1153.
0372.7f30.1c32.ac83.ff17.c6e4.d36d.6b55.e2ce.8c71.8a5b.b6f3.
9d4b.eab5.8b3c.e7f2.a8fe.9574.5de0.bf20.3f15.9784.9939.5f9c.
e609.564f.d8a4.b825.9819.94aa.2c08.8e4c.9b22.477a.2840.3ed6.
3750.6ef1.44dd.89ef.6576.d00a.fbda.9ed2.3b6c.7b0c.bde9.2ade.
5c88.c182.481a.1b0f.2bfd.d591.2726.57ba
(cut 3 [(dec a) 1] b)
::
The inverse of [`++zaft](). Looks up a nonzero byte`a\` in a substiution
box with 255 values, producing a unique nonzero byte.
`a` is an [atom]() of one byte in length.
~zod/try=> (zaft:un 0x12)
42
~zod/try=> (zaft:un 0xff)
204
~zod/try=> (zaft:un 0x0)
! decrement-underflow
! exit
------------------------------------------------------------------------
### ++zart
Reverse look up in 255 sub box
++ zart :: reverse 255-sbox
|= a=@D
=+ ^= b
0x68.4f07.ea1c.73c9.75c2.efc8.d559.5125.f621.a7a8.8591.5613.
dd52.40eb.65a2.60b7.4bcb.1123.ceb0.1bd6.3c84.2906.b164.19b3.
1e95.5fec.ffbc.f187.fbe2.6680.7c77.d30e.e94a.9414.fd9a.017d.
3a7e.5a55.8ff5.8bf9.c181.e5b6.6ab2.35da.50aa.9293.3bc0.cdc6.
f3bf.1a58.4130.f844.3846.744e.36a0.f205.789e.32d8.5e54.5c22.
0f76.fce7.4569.0d99.d26e.e879.dc16.2df4.887f.1ffe.4dba.6f5d.
bbcc.2663.1762.aed7.af8a.ca20.dbb4.9bc7.a942.834c.105b.c4d4.
8202.3e61.a671.90e6.273d.bdab.3157.cfa4.0c2e.df86.2496.f7ed.
2b48.2a9d.5318.a343.d128.be9c.a5ad.6bb5.6dfa.c5e1.3408.128d.
2c04.0339.97a1.2ff0.49d0.eeb8.6c0a.0b37.b967.c347.d9ac.e072.
e409.7b9f.1598.1d3f.33de.8ce3.8970.8e7a
(cut 3 [(dec a) 1] b)
::
The inverse of [`++zaft`](). Looks up the index of a nonzero byte `a` in
the substitution box with 255 values, producing a unique nonzero byte.
`a` is an [atom]() of one byte in length.
~zod/try=> `@ux`(zart:un 204)
0xff
~zod/try=> `@ux`(zart:un 42)
0x12
------------------------------------------------------------------------
### ++zyft
Lookup byte in 256 sub box
++ zyft :: forward 256-sbox
|= a=@D
=+ ^= b
0xbb49.b71f.b881.b402.17e4.6b86.69b5.1647.115f.dddb.7ca5.
8371.4bd5.19a9.b092.605d.0d9b.e030.a0cc.78ba.5706.4d2d.
986a.768c.f8e8.c4c7.2f1c.effe.3cae.01c0.253e.65d3.3872.
ce0e.7a74.8ac6.daac.7e5c.6479.44ec.4143.3d20.4af0.ee6c.
c828.deca.0377.249f.ffcd.7b4f.eb7d.66f2.8951.042e.595a.
8e13.f9c3.a79a.f788.6199.9391.7fab.6200.4ce5.0758.e2f1.
7594.c945.d218.4248.afa1.e61a.54fb.1482.bea4.96a2.3473.
63c2.e7cb.155b.120a.4ed7.bfd8.b31b.4008.f329.fca3.5380.
9556.0cb2.8722.2bea.e96e.3ac5.d1bc.10e3.2c52.a62a.b1d6.
35aa.d05e.f6a8.0f3b.31ed.559d.09ad.f585.6d21.fd1d.8d67.
370b.26f4.70c1.b923.4684.6fbd.cf8b.5036.0539.9cdc.d93f.
9068.1edf.8f33.b632.d427.97fa.9ee1
(cut 3 [a 1] b)
::
The inverse of [`++zyrt`](). Looks up a byte `a` in a substituion box
with 256 values, producing a byte.
`a` is an [atom]() of one byte in length.
~zod/try=> (zyft:un 0x12)
57
~zod/try=> (zyft:un 0x0)
225
~zod/try=> (zyft:un 0xff)
187
------------------------------------------------------------------------
### ++zyrt
Reverse lookup byte in 256 sub box
++ zyrt :: reverse 256-sbox
|= a=@D
=+ ^= b
0x9fc8.2753.6e02.8fcf.8b35.2b20.5598.7caa.c9a9.30b0.9b48.
47ce.6371.80f6.407d.00dd.0aa5.ed10.ecb7.0f5a.5c3a.e605.
c077.4337.17bd.9eda.62a4.79a7.ccb8.44cd.8e64.1ec4.5b6b.
1842.ffd8.1dfb.fd07.f2f9.594c.3be3.73c6.2cb6.8438.e434.
8d3d.ea6a.5268.72db.a001.2e11.de8c.88d3.0369.4f7a.87e2.
860d.0991.25d0.16b9.978a.4bf4.2a1a.e96c.fa50.85b5.9aeb.
9dbb.b2d9.a2d1.7bba.66be.e81f.1946.29a8.f5d2.f30c.2499.
c1b3.6583.89e1.ee36.e0b4.6092.937e.d74e.2f6f.513e.9615.
9c5d.d581.e7ab.fe74.f01b.78b1.ae75.af57.0ec2.adc7.3245.
12bf.2314.3967.0806.31dc.cb94.d43f.493c.54a6.0421.c3a1.
1c4a.28ac.fc0b.26ca.5870.e576.f7f1.616d.905f.ef41.33bc.
df4d.225e.2d56.7fd6.1395.a3f8.c582
(cut 3 [a 1] b)
The inverse of [`++zyft`](). Looks up a byte `a` in a substituion box
with 256 values, producing a byte.
`a` is an [atom]() of one byte in length.
~zod/try=> `@ux`(zyrt:un 57)
0x12
~zod/try=> `@ux`(zyrt:un 225)
0x0
~zod/try=> `@ux`(zyrt:un 187)
0xff

View File

@ -0,0 +1,453 @@
section 2eO, virtualization
===========================
### ++mack
Nock subject to unit
++ mack
|= [sub=* fol=*]
^- (unit)
=+ ton=(mink [sub fol] |=(* ~))
?.(?=([0 *] ton) ~ [~ p.ton])
::
Accepts a nock subject-formula cell and wraps it into a [`++unit`]().
`fol` is pure nock, meaning that nock `11` operations result in a block,
producing a `~`.
`sub` is a subject [noun]().
`fol` is a formula [noun](), which is generally a `++nock`.
~zod/try=> (mack [[1 2 3] [0 1]])
[~ [1 2 3]]
~zod/try=> (mack [41 4 0 1])
[~ 42]
~zod/try=> (mack [4 0 4])
~
~zod/try=> (mack [[[0 2] [1 3]] 4 4 4 4 0 5])
[~ 6]
~zod/try=> ;;((unit ,@tas) (mack [[1 %yes %no] 6 [0 2] [0 6] 0 7]))
[~ %no]
------------------------------------------------------------------------
### ++mink
Mock interpreter
++ mink
~/ %mink
|= [[sub=* fol=*] sky=$+(* (unit))]
=+ tax=*(list ,[@ta *])
|- ^- tone
?@ fol
[%2 tax]
?: ?=(^ -.fol)
=+ hed=$(fol -.fol)
?: ?=(%2 -.hed)
hed
=+ tal=$(fol +.fol)
?- -.tal
%0 ?-(-.hed %0 [%0 p.hed p.tal], %1 hed)
%1 ?-(-.hed %0 tal, %1 [%1 (weld p.hed p.tal)])
%2 tal
==
?+ fol
[%2 tax]
::
[0 b=@]
?: =(0 b.fol) [%2 tax]
?: =(1 b.fol) [%0 sub]
?: ?=(@ sub) [%2 tax]
=+ [now=(cap b.fol) lat=(mas b.fol)]
$(b.fol lat, sub ?:(=(2 now) -.sub +.sub))
::
[1 b=*]
[%0 b.fol]
::
[2 b=[^ *]]
=+ ben=$(fol b.fol)
?. ?=(%0 -.ben) ben
?>(?=(^ p.ben) $(sub -.p.ben, fol +.p.ben))
::?>(?=(^ p.ben) $([sub fol] p.ben)
::
[3 b=*]
=+ ben=$(fol b.fol)
?. ?=(%0 -.ben) ben
[%0 .?(p.ben)]
::
[4 b=*]
=+ ben=$(fol b.fol)
?. ?=(%0 -.ben) ben
?. ?=(@ p.ben) [%2 tax]
[%0 .+(p.ben)]
::
[5 b=*]
=+ ben=$(fol b.fol)
?. ?=(%0 -.ben) ben
?. ?=(^ p.ben) [%2 tax]
[%0 =(-.p.ben +.p.ben)]
::
[6 b=* c=* d=*]
$(fol =>(fol [2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]))
::
[7 b=* c=*] $(fol =>(fol [2 b 1 c]))
[8 b=* c=*] $(fol =>(fol [7 [[0 1] b] c]))
[9 b=* c=*] $(fol =>(fol [7 c 0 b]))
[10 @ c=*] $(fol c.fol)
[10 [b=* c=*] d=*]
=+ ben=$(fol c.fol)
?. ?=(%0 -.ben) ben
?: ?=(?(%hunk %lose %mean %spot) b.fol)
$(fol d.fol, tax [[b.fol p.ben] tax])
$(fol d.fol)
::
[11 b=*]
=+ ben=$(fol b.fol)
?. ?=(%0 -.ben) ben
=+ val=(sky p.ben)
?~(val [%1 p.ben ~] [%0 u.val])
::
==
::
Bottom-level [mock]() (virtual nock) interpreter. Produces a
[`++tone`](), a nock computation result. If nock 11 is invoked, `sky`
computes on the subject and produces a [`++unit`]() result. An empty
result becomes a `%1` `++tone`, indicating a block.
`sub` is the subject as a [noun]().
`fol` is the formula as a [noun]().
`sky` is an [`%iron`]() gate invoked with [nock operator 11]().
~zod/try=> (mink [20 [4 0 1]] ,~)
[%0 p=21]
~zod/try=> (mink [[90 5 3] [0 3]] ,~)
[%0 p=[5 3]]
~zod/try=> (mink 20^[4 0 1] ,~)
[%0 p=21]
~zod/try=> (mink [90 5 3]^[0 3] ,~)
[%0 p=[5 3]]
~zod/try=> (mink [0]^[11 1 20] ,~)
[%1 p=~[20]]
~zod/try=> (mink [0]^[11 1 20] |=(a=* `[40 a]))
[%0 p=[40 20]]
~zod/try=> (mink [5]^[0 2] ,~)
[%2 p=~]
~zod/try=> (mink [5]^[10 yelp/[0 1] 0 0] ,~)
[%2 p=~[[~.yelp 5]]]
------------------------------------------------------------------------
### ++mock
Compute formula on subject with hint
++ mock
|= [[sub=* fol=*] sky=$+(* (unit))]
(mook (mink [sub fol] sky))
::
Produces a [`++toon`](), which is either a sucessful, blocked, or
crashed result. If nock 11 is invoked, `sky` computes on the subject and
produces a [`++unit`]() result. An empty result becomes a `%1` `++tune`,
indicating a block.
`sub` is the subject as a [noun]().
`fol` is the formula as a [noun]().
`sky` is an [%iron]() gate invoked with [nock operator 11]().
~zod/try=> (mock [5 4 0 1] ,~)
[%0 p=6]
~zod/try=> (mock [~ 11 1 0] |=(* `999))
[%0 p=999]
~zod/try=> (mock [~ 0 1.337] ,~)
[%2 p=~]
~zod/try=> (mock [~ 11 1 1.337] ,~)
[%1 p=~[1.337]]
~zod/try=> (mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[+<]))
[%0 p=14]
~zod/try=> (mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[<+<>]))
[%0 p=[49 52 0]]
~zod/try=> ;;(tape +:(mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[<+<>])))
"14"
------------------------------------------------------------------------
### ++mook
Intelligently render crash annotation
++ mook
|= ton=tone
^- toon
?. ?=([2 *] ton) ton
:- %2
=+ yel=(lent p.ton)
=. p.ton
?. (gth yel 256) p.ton
%+ weld
(scag 128 p.ton)
^- (list ,[@ta *])
:_ (slag (sub yel 128) p.ton)
:- %lose
%+ rap 3
;: weld
"[skipped "
~(rend co %$ %ud (sub yel 256))
" frames]"
==
|- ^- (list tank)
?~ p.ton ~
=+ rex=$(p.ton t.p.ton)
?+ -.i.p.ton rex
%hunk [(tank +.i.p.ton) rex]
%lose [[%leaf (rip 3 (,@ +.i.p.ton))] rex]
%mean :_ rex
?@ +.i.p.ton [%leaf (rip 3 (,@ +.i.p.ton))]
=+ mac=(mack +.i.p.ton +<.i.p.ton)
?~(mac [%leaf "####"] (tank u.mac))
%spot :_ rex
=+ sot=(spot +.i.p.ton)
:- %leaf
;: weld
~(ram re (smyt p.sot))
":<["
~(rend co ~ %ud p.p.q.sot)
" "
~(rend co ~ %ud q.p.q.sot)
"].["
~(rend co ~ %ud p.q.q.sot)
" "
~(rend co ~ %ud q.q.q.sot)
"]>"
==
==
::
Converts a `%2` `++tone` nock stack trace to a list of [`++tank`]().
Each may be a tank, cord, [`++spot`](), or trapped tank. Produces a
[`++toon`]().
`ton` is a [`++tone`]().
~zod/try=> (mook [%0 5 4 5 1])
[%0 p=[5 4 5 1]]
~zod/try=> (mook [%2 ~[[%hunk %rose ["<" "," ">"] ~[[%leaf "err"]]]]])
[%2 p=~[[%rose p=[p="<" q="," r=">"] q=[i=[%leaf p="err"] t=~]]]]
~zod/try=> (mook [%2 ~[[%malformed %elem] [%lose 'do print']]])
[%2 p=~[[%leaf p="do print"]]]
~zod/try=> (mook [%2 ~[[%mean |.(>(add 5 6)<)]]])
[%2 p=~[[%leaf p="11"]]]
~zod/try=> (mook [%2 ~[[%spot /b/repl [1 1]^[1 2]] [%mean |.(!!)]]])
[%2 p=~[[%leaf p="/b/repl/:<[1 1].[1 2]>"] [%leaf p="####"]]]
------------------------------------------------------------------------
### ++mang
Unit: Slam gate with sample
++ mang
|= [[gat=* sam=*] sky=$+(* (unit))]
^- (unit)
=+ ton=(mong [[gat sam] sky])
?.(?=([0 *] ton) ~ [~ p.ton])
::
Produces a [`++unit`]() computation result from slamming `gat` with
`sam`, using `sky` to compute or block on nock 11 when applicable.
Similar to [`++mong`]().
`gat` is a [noun]() that is generally a [`gate`]().
`sam` is a [`sample`]() noun.
`sky` is an [%iron]() gate invoked with [nock operator 11]().
~zod/try=> (mang [|=(@ 20) ~] ,~)
[~ 20]
~zod/try=> (mang [|=(@ !!) ~] ,~)
~
~zod/try=> (mang [|=(a=@ (add 20 a)) ~] ,~)
[~ 20]
~zod/try=> (mang [|=(a=[@ @] (add 20 -.a)) ~] ,~)
~
~zod/try=> (mang [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
[~ 24]
~zod/try=> (mang [|=(a=@ .^(a)) ~] ,~)
~
~zod/try=> (mang [|=(a=@ .^(a)) ~] ,[~ %42])
[~ 42]
~zod/try=> (mang [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
[~ [0 6]]
~zod/try=> (mang [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
[~ [8 6]]
------------------------------------------------------------------------
### ++mong
Slam gate with sample
++ mong
|= [[gat=* sam=*] sky=$+(* (unit))]
^- toon
?. &(?=(^ gat) ?=(^ +.gat))
[%2 ~]
(mock [[-.gat [sam +>.gat]] -.gat] sky)
::
Produces a [`++toon`]() computation result from slamming `gat` with
`sam`, using `sky` to compute or block on nock 11 when applicable.
`gat` is a [noun]() that is generally a [`gate`]().
`sam` is a [`sample`]() noun.
`sky` is an [%iron]() gate invoked with [nock operator 11]().
~zod/try=> (mong [|=(@ 20) ~] ,~)
[%0 p=20]
~zod/try=> (mong [|=(@ !!) ~] ,~)
[%2 p=~]
~zod/try=> (mong [|=(a=@ (add 20 a)) ~] ,~)
[%0 p=20]
~zod/try=> (mong [|=(a=[@ @] (add 20 -.a)) ~] ,~)
[%2 p=~]
~zod/try=> (mong [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
[%0 p=24]
~zod/try=> (mong [|=(a=@ .^(a)) ~] ,~)
[%1 p=~[0]]
~zod/try=> (mong [|=(a=@ .^(a)) ~] ,[~ %42])
[%0 p=42]
~zod/try=> (mong [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
[%0 p=[0 6]]
~zod/try=> (mong [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
[%0 p=[8 6]]
------------------------------------------------------------------------
### ++mung
Virtualize slamming gate
++ mung
|= [[gat=* sam=*] sky=$+(* (unit))]
^- tone
?. &(?=(^ gat) ?=(^ +.gat))
[%2 ~]
(mink [[-.gat [sam +>.gat]] -.gat] sky)
::
Produces a [`++tone`]() computation result from slamming `gat` with
`sam`, using `sky` to compute or block on nock 11 when applicable.
`gat` is a [noun]() that is generally a [`gate`]().
`sam` is a [`sample`]() noun.
`sky` is an [%iron]() gate invoked with [nock operator 11]().
~zod/try=> (mung [|=(@ 20) ~] ,~)
[%0 p=20]
~zod/try=> (mung [|=(@ !!) ~] ,~)
[%2 p=~]
~zod/try=> (mung [|=(a=@ (add 20 a)) ~] ,~)
[%0 p=20]
~zod/try=> (mung [|=(a=[@ @] (add 20 -.a)) ~] ,~)
[%2 p=~]
~zod/try=> (mung [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
[%0 p=24]
~zod/try=> (mung [|=(a=@ .^(a)) ~] ,~)
[%1 p=~[0]]
~zod/try=> (mung [|=(a=@ .^(a)) ~] ,[~ %42])
[%0 p=42]
~zod/try=> (mung [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
[%0 p=[0 6]]
~zod/try=> (mung [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
[%0 p=[8 6]]
------------------------------------------------------------------------
### ++mule
Typed virtual
++ mule :: typed virtual
~/ %mule
|* taq=_|.(_*)
=+ mud=(mute taq)
?- -.mud
& [%& p=$:taq]
| [%| p=p.mud]
==
::
Kicks a `++trap`, producing its results or any errors that occur along
the way. Used to lazily compute stack traces.
`taq` is a [`++trap`](), generally producing a list of [`++tank`]()s.
~zod/try=> (mule |.(leaf/"hello"))
[%.y p=[%leaf "hello"]]
~zod/try=> (mule |.(!!))
[%.n p=~]
~zod/try=> (mule |.(.^(a//=pals/1)))
[ %.n
p
~[
[ %rose
p=[p="/" q="/" r="/"]
q
[ i=[%leaf p="a"]
t=[i=[%leaf p="~zod"] t=[i=[%leaf p="pals"] t=[i=[%leaf p="1"] t=~]]]
]
]
]
]
------------------------------------------------------------------------
### ++mute
Untyped virtual
++ mute :: untyped virtual
|= taq=_^?(|.(_*))
^- (each ,* (list tank))
=+ ton=(mock [taq 9 2 0 1] |=(* ~))
?- -.ton
%0 [%& p.ton]
%1 [%| (turn p.ton |=(a=* (smyt (path a))))]
%2 [%| p.ton]
==
Kicks a `++trap`, producing its result as a noun or the tanks of any
error that occurs. Similar to [`++mule`](), but preserves no type
information.
`taq` is a [`++trap`]().
~zod/try=> (mute |.(leaf/"hello"))
[%.y p=[1.717.658.988 104 101 108 108 111 0]]
~zod/try=> (mute |.(!!))
[%.n p=~]
~zod/try=> (mute |.(.^(a//=pals/1)))
[ %.n
p
~[
[ %rose
p=[p="/" q="/" r="/"]
q=[i=[%leaf p="a"] t=[i=[%leaf p="~zod"] t=[i=[%leaf p="pals"] t=[i=[%leaf p="1"] t=~]]]]
]
]
]
------------------------------------------------------------------------

View File

@ -0,0 +1,586 @@
section 2eP, diff
=================
A- more or less low priority and/or currently in the wrong section
anyway.
------------------------------------------------------------------------
------------------------------------------------------------------------
### ++berk
Invert diff patches
++ berk :: invert diff patch
|* bur=(urge)
|- ^+ bur
?~ bur ~
:_ $(bur t.bur)
?- -.i.bur
& i.bur
| [%| q.i.bur p.i.bur]
==
::
Inverts a list of changes `bur`. Skips stay constant and replaces are
swapped. Produces a `bur`.
`bur` is a [`++urge`]().
~zod/try=> (berk `(urge)`~[`10 %|^[~[2] ~[3 4]] `5])
~[[%.y p=10] [%.n p=~[3 4] q=~[2]] [%.y p=5]]
~zod/try=> (lurk "somes" `(urge char)`~[`1 [%| "o" "a"] `3])
"sames"
~zod/try=> (berk `(urge char)`~[`1 [%| "o" "a"] `3])
~[[%.y p=1] [%.n p="a" q="o"] [%.y p=3]]
~zod/try=> (lurk "sames" (berk `(urge char)`~[`1 [%| "o" "a"] `3]))
"somes"
------------------------------------------------------------------------
### ++diff
Generate patch
++ diff :: generate patch
|= pum=umph
|= [old=* new=*] ^- udon
:- pum
?+ pum ~|(%unsupported !!)
%a [%d (nude old new)]
%b =+ [hel=(cue ((hard ,@) old)) hev=(cue ((hard ,@) new))]
[%d (nude hel hev)]
%c =+ [hel=(lore ((hard ,@) old)) hev=(lore ((hard ,@) new))]
[%c (lusk hel hev (loss hel hev))]
==
::
Produces a patch between two nouns, by change type
`pum` is an [`++umph`]().
~zod/try=> ((diff %a) 20 21)
[p=%a q=[%d p=[%1 p=21] q=[%1 p=20]]]
~zod/try=> ((diff %a) [1 2 3] [1 2 4])
[ p=%a
q
[ %d
p=[p=[%0 p=2] q=[p=[%0 p=6] q=[%1 p=4]]]
q=[p=[%0 p=2] q=[p=[%0 p=6] q=[%1 p=3]]]
]
]
~zod/try=> ~04hh
[1 2]
~zod/try=> ~0ph
[1 1]
~zod/try=> ((diff %b) 0v4hh 0vph)
[p=%b q=[%d p=[p=[%0 p=2] q=[%0 p=2]] q=[p=[%0 p=3] q=[%1 p=2]]]]
~zod/try=> ((diff %c) (role 'sam' 'les' 'les' 'kor' ~) (role 'sam' 'mor' 'kor' ~))
[p=%c q=[%c p=~[[%.y p=1] [%.n p=~[7.562.604 7.562.604] q=~[7.499.629]] [%.y p=1]]]]
~[[%.y p=0] [%.y p=0] [%.y p=1] [%.n p=<|les les|> q=<|mor|>] [%.y p=1]]
~zod/try=> (,[%c %c (urge cord)] ((diff %c) (role 'sam' 'les' 'les' 'kor' ~) (role 'sam' 'mor' 'kor' ~)))
[%c %c ~[[%.y p=1] [%.n p=<|les les|> q=<|mor|>] [%.y p=1]]]
------------------------------------------------------------------------
### ++loss
Longest subsequence
++ loss :: longest subsequence
~/ %loss
|* [hel=(list) hev=(list)]
|- ^+ hev
=+ ^= sev
=+ [inx=0 sev=*(map ,@t (list ,@ud))]
|- ^+ sev
?~ hev sev
=+ guy=(~(get by sev) i.hev)
$(hev t.hev, inx +(inx), sev (~(put by sev) i.hev [inx ?~(guy ~ u.guy)]))
=| gox=[p=@ud q=(map ,@ud ,[p=@ud q=_hev])]
=< abet
=< main
|%
++ abet =.(q.rag ?:(=([& 0] p.rag) q.rag [p.rag q.rag]) (flop q.rag))
++ hink :: extend fits top
|= [inx=@ud goy=@ud] ^- ?
|(=(p.gox inx) (lth goy p:(need (~(get by q.gox) inx))))
::
++ lonk :: extend fits bottom
|= [inx=@ud goy=@ud] ^- ?
|(=(0 inx) (gth goy p:(need (~(get by q.gox) (dec inx)))))
::
++ lune :: extend
|= [inx=@ud goy=@ud]
^+ +>
%_ +>.$
gox
:- ?:(=(inx p.gox) +(p.gox) p.gox)
%+ ~(put by q.gox) inx
[goy (snag goy hev) ?:(=(0 inx) ~ q:(need (~(get by q.gox) (dec inx))))]
==
::
++ merg :: merge all matches
|= gay=(list ,@ud)
^+ +>
=+ ^= zes
=+ [inx=0 zes=*(list ,[p=@ud q=@ud])]
|- ^+ zes
?: |(?=(~ gay) (gth inx p.gox)) zes
?. (lonk inx i.gay) $(gay t.gay)
?. (hink inx i.gay) $(inx +(inx))
$(inx +(inx), gay t.gay, zes [[inx i.gay] zes])
|- ^+ +>.^$
?~(zes +>.^$ $(zes t.zes, +>.^$ (lune i.zes)))
::
++ main
|- ^+ +
?~ hel
?~ hev
?>(?=(~ lcs) +)
$(hev t.hev, rag (done %| ~ [i.hev ~]))
?~ hev
$(hel t.hel, rag (done %| [i.hel ~] ~))
?~ lcs
+(rag (done %| (flop hel) (flop hev)))
?: =(i.hel i.lcs)
?: =(i.hev i.lcs)
$(lcs t.lcs, hel t.hel, hev t.hev, rag (done %& 1))
$(hev t.hev, rag (done %| ~ [i.hev ~]))
?: =(i.hev i.lcs)
$(hel t.hel, rag (done %| [i.hel ~] ~))
$(hel t.hel, hev t.hev, rag (done %| [i.hel ~] [i.hev ~]))
--
Finds a subsequence of repeated elements within two [`++list`]()s, using
several internal helper arms. Produces a [`++tape`]().
`hel` is a [`++list`]() of characters.
`hev` is a [++list\`]() of characters.
~zod/try=> (loss "sam" "sem")
"sm"
~zod/try=> (loss "samo" "semo")
"smo"
~zod/try=> (loss "sakmo" "semo")
"smo"
~zod/try=> (loss "ferdinham" "ferdilapos
~ <syntax error at [1 30]>
~zod/try=> (loss "ferdinham" "ferdilapos")
"ferdia"
------------------------------------------------------------------------
### ++locz
Find common
++ locz :: trivial algorithm
|= [hel=tape hev=tape]
^- tape
=+ [leh=(lent hel) veh=(lent hev)]
=- (flop q.yun)
^= yun
|- ^- [p=@ud q=tape]
~+
?: |(=(0 leh) =(0 veh)) [0 ~]
=+ [dis=(snag (dec leh) hel) dat=(snag (dec veh) hev)]
?: =(dis dat)
=+ say=$(leh (dec leh), veh (dec veh))
[+(p.say) [dis q.say]]
=+ [lef=$(leh (dec leh)) rig=$(veh (dec veh))]
?:((gth p.lef p.rig) lef rig)
::
Finds a subsequence of repeated elements within two [`++list`]()s,
producing a [\`++tape]().
~zod/try=> (locz "samukot" "semelkot")
"smkot"
~zod/try=> (locz "samukot" "samelkot")
"samkot"
------------------------------------------------------------------------
### ++lore
Split on `\n`
++ lore :: atom to line list
~/ %lore
|= lub=@
=| tez=(list ,@t)
|- ^+ tez
?: =(0 lub) (flop tez)
=+ ^= meg
=+ meg=0
|- ^- @ud
=+ gam=(cut 3 [meg 1] lub)
?:(|(=(10 gam) =(0 gam)) meg $(meg +(meg)))
=+ res=(rsh 3 +(meg) lub)
?: &(=(0 (cut 3 [meg 1] lub)) !=(0 res))
!!
$(lub res, tez [(end 3 meg lub) tez])
::
Split on newlines, ascii `10`
~zod/try=> (lore 'soke\0alas\0amep')
<|soke las mep|>
~zod/try=> (lore '|= a=@\0a=+ b=(add a 5)\0a(mix b a)')
<||= a=@ =+ b=(add a 5) (mix b a)|>
~zod/try=> `wain`[(fil 3 80 ' ') (lore '|= a=@\0a=+ b=(add a 5)\0a(mix b a)')]
<|
|= a=@
=+ b=(add a 5)
(mix b a)
|>
------------------------------------------------------------------------
### ++role
Join with `\n`
++ role :: line list to atom
|= tez=(list ,@t)
(rap 3 (turn tez |=(a=@t (cat 3 a 10))))
::
Join line list with newlines.
~zod/try=> (role 'sep' 'tek' 'lap' ~)
3.230.709.852.558.292.782.985.274.739
~zod/try=> `@t`(role 'sep' 'tek' 'lap' ~)
'''
sep
tek
lap
'''
------------------------------------------------------------------------
### ++lump
Change with `++udon`
++ lump :: apply patch
|= [don=udon src=*]
^- *
?+ p.don ~|(%unsupported !!)
%a
?+ -.q.don ~|(%unsupported !!)
%a q.q.don
%c (lurk ((hard (list)) src) p.q.don)
%d (lure src p.q.don)
==
::
%c
=+ dst=(lore ((hard ,@) src))
%- role
?+ -.q.don ~|(%unsupported !!)
%a ((hard (list ,@t)) q.q.don)
%c (lurk dst p.q.don)
==
==
::
Use udon to change noun
~zod/try=> (lump [%a %a 20 25] 20)
25
~zod/try=> (lump [%a %d [[%0 1] [%0 1]] [%0 2]] 20)
[20 20]
~zod/try=> (lump [%c %a ~['sa' 'le'] ~['sa' 'lo']] 'sa\0ale')
11.473.670.267.251
~zod/try=> (,@t (lump [%c %a ~['sa' 'le'] ~['sa' 'lo']] 'sa\0ale'))
'''
sa
lo
'''
~zod/try=> (,@t (lump [%c %c `1 [%| ~['le'] ~['lo' 'ma']] ~] 'sa\0ale'))
'''
sa
ma
lo
'''
------------------------------------------------------------------------
### ++lure
Patch `a`
++ lure :: apply tree diff
|= [a=* b=upas]
^- *
?^ -.b
[$(b -.b) $(b +.b)]
?+ -.b ~|(%unsupported !!)
%0 .*(a [0 p.b])
%1 .*(a [1 p.b])
==
Patch a by references to axis and literal.
~zod/try=> (lure ~[1 2] [[%0 2] [%1 3] [%0 7]])
[1 3 0]
~zod/try=> (lure ~[1 2 4] [[%0 2] [%1 3] [%0 7]])
[1 3 4 0]
------------------------------------------------------------------------
### ++limp
Reverse patch
++ limp :: invert patch
|= don=udon ^- udon
:- p.don
?+ -.q.don ~|(%unsupported !!)
%a [%a q.q.don p.q.don]
%c [%c (berk p.q.don)]
%d [%d q.q.don p.q.don]
==
::
Reverse a patch (preprocessor unchanged)
~zod/try=> (limp [%a %a 20 40])
[p=%a q=[%a p=40 q=20]]
~zod/try=> (limp [%c %c ~[`20 [%| ~[52 53] ~[51]] `6]])
[p=%c q=[%c p=~[[%.y p=20] [%.n p=~[51] q=~[52 53]] [%.y p=6]]]]
~zod/try=> (limp [%a %d [[%0 1] [%0 1]] [%0 2]])
[p=%a q=[%d p=[%0 p=2] q=[p=[%0 p=1] q=[%0 p=1]]]]
------------------------------------------------------------------------
### ++hump
Prep for diff
++ hump :: general prepatch
|= [pum=umph src=*] ^- *
?+ pum ~|(%unsupported !!)
%a src
%b (cue ((hard ,@) src))
%c (lore ((hard ,@) src))
==
::
Prep atom for diff: leave alone, cue, or split by newlines.
~zod/try=> (hump %a ~)
0
~zod/try=> (hump %a 40)
40
~zod/try=> (hump %c 40)
[40 0]
~zod/try=> (hump %c 'as')
[29.537 0]
~zod/try=> (hump %c 'as\0alok')
[29.537 7.040.876 0]
~zod/try=> (hump %b 0vph)
[1 1]
------------------------------------------------------------------------
### ++husk
Atomize post diff
++ husk :: unprepatch
|= [pum=umph dst=*] ^- *
?+ pum ~|(%unsupported !!)
%a dst
%b (jam dst)
%c (role ((hard (list ,@)) dst))
==
::
Re-atomize after diff: leave alone, jam, or join with newlines.
~zod/try=> (husk %a 0)
0
~zod/try=> (husk %a 40)
40
~zod/try=> (husk %c [40 0])
2.600
~zod/try=> (rip 3 (,@ (husk %c [40 0])))
~[40 10]
~zod/try=> (husk %c [%as 0])
684.897
~zod/try=> (husk %c [%as 0])
684.897
~zod/try=> (,@t (husk %c [%as 0]))
'''
as
'''
~zod/try=> (husk %c [%as %lok 0])
2.932.876.065.272.673
~zod/try=> (,@t (husk %c [%as %lok 0]))
'''
as
lok
'''
~zod/try=> (husk %b [1 1])
817
~zod/try=> (,@uv (husk %b [1 1]))
0vph
~zod/try=> ~0ph
[1 1]
------------------------------------------------------------------------
### ++lurk
Apply list patch
++ lurk :: apply list patch
|* [hel=(list) rug=(urge)]
^+ hel
=+ war=`_hel`~
|- ^+ hel
?~ rug (flop war)
?- -.i.rug
&
%= $
rug t.rug
hel (slag p.i.rug hel)
war (weld (flop (scag p.i.rug hel)) war)
==
::
|
%= $
rug t.rug
hel =+ gur=(flop p.i.rug)
|- ^+ hel
?~ gur hel
?>(&(?=(^ hel) =(i.gur i.hel)) $(hel t.hel, gur t.gur))
war (weld q.i.rug war)
==
==
::
Amend list using an urge: list of `[%& {number skipped}]` and
`[%| old new]`
~zod/try=> (lurk "hema" `(urge char)`~[`1 [%| "e" "ru"] `2])
"hurma"
~zod/try=> (lurk "koltep" `(urge char)`~[`3 [%| "et" ""] `1])
"kolp"
------------------------------------------------------------------------
### ++lusk
`lcs` to list patch
++ lusk :: lcs to list patch
|* [hel=(list) hev=(list) lcs=(list)]
=+ ^= rag
^- $% [& p=@ud]
[| p=_lcs q=_lcs]
==
[%& 0]
=> .(rag [p=rag q=*(list ,_rag)])
=< abet =< main
|%
++ abet =.(q.rag ?:(=([& 0] p.rag) q.rag [p.rag q.rag]) (flop q.rag))
++ done
|= new=_p.rag
^+ rag
?- -.p.rag
| ?- -.new
| [[%| (weld p.new p.p.rag) (weld q.new q.p.rag)] q.rag]
& [new [p.rag q.rag]]
==
& ?- -.new
| [new ?:(=(0 p.p.rag) q.rag [p.rag q.rag])]
& [[%& (add p.p.rag p.new)] q.rag]
==
==
::
++ main
|- ^+ +
?~ hel
?~ hev
?>(?=(~ lcs) +)
$(hev t.hev, rag (done %| ~ [i.hev ~]))
?~ hev
$(hel t.hel, rag (done %| [i.hel ~] ~))
?~ lcs
+(rag (done %| (flop hel) (flop hev)))
?: =(i.hel i.lcs)
?: =(i.hev i.lcs)
$(lcs t.lcs, hel t.hel, hev t.hev, rag (done %& 1))
$(hev t.hev, rag (done %| ~ [i.hev ~]))
?: =(i.hev i.lcs)
$(hel t.hel, rag (done %| [i.hel ~] ~))
$(hel t.hel, hev t.hev, rag (done %| [i.hel ~] [i.hev ~]))
--
Using a common sequence, generate urge from two lists
~zod/try=> (lusk "hamok" "hasok" "haok")
~[[%.y p=2] [%.n p="m" q="s"] [%.y p=2]]
~zod/try=> (lusk "hamok" "hasok" "hak")
~[[%.y p=2] [%.n p="om" q="os"] [%.y p=1]]
~zod/try=> (lusk "telroga" "tesomga" "teoga")
~[[%.y p=2] [%.n p="rl" q="s"] [%.y p=1] [%.n p="" q="m"] [%.y p=2]]
~zod/try=> (lurk "telroga" `(urge char)`~[[%.y p=2] [%.n p="rl" q="s"] [%.y p=1] [%.n p="" q="m"] [%.y p=2]])
"tesomga"
------------------------------------------------------------------------
### ++nude
Tree change
++ nude :: tree change
|= [a=* b=*]
^- [p=upas q=upas]
=< [p=(tred a b) q=(tred b a)]
|%
++ axes :: locs of nouns
|= [a=@ b=*] ^- (map ,* axis)
=+ c=*(map ,* axis)
|- ^- (map ,* axis)
=> .(c (~(put by c) b a))
?@ b
c
%- ~(uni by c)
%- ~(uni by $(a (mul 2 a), b -.b))
$(a +((mul 2 a)), b +.b)
::
++ tred :: diff a->b
|= [a=* b=*] ^- upas
=| c=(unit ,*)
=+ d=(axes 1 a)
|- ^- upas
=> .(c (~(get by d) b))
?~ c
?@ b
[%1 b]
=+ e=^-(upas [$(b -.b) $(b +.b)])
?- e
[[%1 *] [%1 *]] [%1 [p.p.e p.q.e]]
* e
==
[%0 u.c]
--
Generate tree diff from two nouns.
~zod/try=> (nude 40 20)
[p=[%1 p=20] q=[%1 p=40]]
~zod/try=> (nude [5 5] 5)
[p=[%0 p=3] q=[p=[%0 p=1] q=[%0 p=1]]]
~zod/try=> (nude "sam" "sal")
[ p=[p=[%1 p=115] q=[p=[%1 p=97] q=[p=[%1 p=108] q=[%0 p=15]]]]
q=[p=[%1 p=115] q=[p=[%1 p=97] q=[p=[%1 p=109] q=[%0 p=15]]]]
]
------------------------------------------------------------------------

View File

@ -0,0 +1,439 @@
section 2eW, lite number theory
===============================
### ++egcd
GCD
++ egcd :: schneier's egcd
|= [a=@ b=@]
=+ si
=+ [c=(sun a) d=(sun b)]
=+ [u=[c=(sun 1) d=--0] v=[c=--0 d=(sun 1)]]
|- ^- [d=@ u=@ v=@]
?: =(--0 c)
[(abs d) d.u d.v]
:: ?> ?& =(c (sum (pro (sun a) c.u) (pro (sun b) c.v)))
:: =(d (sum (pro (sun a) d.u) (pro (sun b) d.v)))
:: ==
=+ q=(fra d c)
%= $
c (dif d (pro q c))
d c
u [(dif d.u (pro q c.u)) c.u]
v [(dif d.v (pro q c.v)) c.v]
==
::
Greatest common denominator
~zod/try=> (egcd 20 15)
[d=5 u=2 v=1]
~zod/try=> (egcd 24 16)
[d=8 u=2 v=1]
~zod/try=> (egcd 7 5)
[d=1 u=3 v=6]
~zod/try=> (egcd (shaf ~ %ham) (shaf ~ %sam))
[ d=1
u=59.983.396.314.566.203.239.184.568.129.921.874.787
v=38.716.650.351.034.402.960.165.718.823.532.275.722
]
------------------------------------------------------------------------
### ++pram
Probable prime
++ pram :: rabin-miller
|= a=@ ^- ?
?: ?| =(0 (end 0 1 a))
=(1 a)
=+ b=1
|- ^- ?
?: =(512 b)
|
?|(=+(c=+((mul 2 b)) &(!=(a c) =(a (mul c (div a c))))) $(b +(b)))
==
|
=+ ^= b
=+ [s=(dec a) t=0]
|- ^- [s=@ t=@]
?: =(0 (end 0 1 s))
$(s (rsh 0 1 s), t +(t))
[s t]
?> =((mul s.b (bex t.b)) (dec a))
=+ c=0
|- ^- ?
?: =(c 64)
&
=+ d=(~(raw og (add c a)) (met 0 a))
=+ e=(~(exp fo a) s.b d)
?& ?| =(1 e)
=+ f=0
|- ^- ?
?: =(e (dec a))
&
?: =(f (dec t.b))
|
$(e (~(pro fo a) e e), f +(f))
==
$(c +(c))
==
::
Probable prime test
~zod/try=> (pram 31)
%.y
~zod/try=> =+(a=2 |-(?:(=(a 31) ~ [i=(mod 31 a) t=$(a +(a))])))
~[1 1 3 1 1 3 7 4 1 9 7 5 3 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
~zod/try=> =+(a=2 |-(?:(=(a 31) ~ [i=(mod 30 a) t=$(a +(a))])))
~[0 0 2 0 0 2 6 3 0 8 6 4 2 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0]
~zod/try=> (pram 256)
%.n
~zod/try=> (pram (dec (bex 127)))
%.y
------------------------------------------------------------------------
### ++ramp
`r-m` prime
++ ramp :: make r-m prime
|= [a=@ b=(list ,@) c=@] ^- @ux :: [bits snags seed]
=> .(c (shas %ramp c))
=+ d=_@
|-
?: =((mul 100 a) d)
~|(%ar-ramp !!)
=+ e=(~(raw og c) a)
?: &((levy b |=(f=@ !=(1 (mod e f)))) (pram e))
e
$(c +(c), d (shax d))
::
Random `a` bit prime, which isn't 1 modulo a list of other numbers,
using salt `c`.
~zod/try=> (ramp 20 ~ %hamelok)
0xf.1f0d
~zod/try=> (ramp 20 ~ %hameloe)
0x2.d341
~zod/try=> (ramp 5 ~ %kole)
0x1f
~zod/try=> (ramp 7 ~ %kole)
0x4f
~zod/try=> (ramp 7 ~[0x4e] %kole)
0x43
~zod/try=> `@uw`(ramp 128 ~ %late)
0w3y.irKIL.l-pp1.2CkG4.3lsTF
------------------------------------------------------------------------
### ++fo
Prime engine
++ fo :: modulo prime
|_ a=@
XX DO NOT RERUN GET.LS, THERE EXIST ARM COLLISIONS
Core for performing arithmetic modulo a prime number
~zod/try=> ~(. fo 79)
<7.get [@ud <373.jdd 100.kzl 1.ypj %164>]>
------------------------------------------------------------------------
### ++dif
Difference
++ dif
|= [b=@ c=@]
(sit (sub (add a b) (sit c)))
::
Subtract
~zod/try=> (~(dif fo 79) 10 5)
5
~zod/try=> (~(dif fo 79) 5 10)
74
------------------------------------------------------------------------
### ++exp
Exponent
++ exp
|= [b=@ c=@]
?: =(0 b)
1
=+ d=$(b (rsh 0 1 b))
=+ e=(pro d d)
?:(=(0 (end 0 1 b)) e (pro c e))
::
Exponent
~zod/try=> (~(exp fo 79) 3 5)
46
------------------------------------------------------------------------
### ++fra
Divide
++ fra
|= [b=@ c=@]
(pro b (inv c))
::
Divide
~zod/try=> (~(fra fo 79) 20 4)
5
~zod/try=> (~(fra fo 79) 7 11)
15
------------------------------------------------------------------------
### ++inv
Inverse
++ inv
|= b=@
=+ c=(dul:si u:(egcd b a) a)
c
::
Multiplicative inverse
~zod/try=> (~(inv fo 79) 12)
33
~zod/try=> (~(pro fo 79) 12 33)
1
~zod/try=> (~(inv fo 79) 0)
0
------------------------------------------------------------------------
### ++pro
Product
++ pro
|= [b=@ c=@]
(sit (mul b c))
::
Product
~zod/try=> (~(pro fo 79) 5 10)
50
~zod/try=> (~(pro fo 79) 5 20)
21
------------------------------------------------------------------------
### ++sit
Bounds
++ sit
|= b=@
(mod b a)
::
Bounds check
~zod/try=> (~(sit fo 79) 9)
9
~zod/try=> (~(sit fo 79) 99)
20
------------------------------------------------------------------------
### ++sum
Sum
++ sum
|= [b=@ c=@]
(sit (add b c))
--
Add
~zod/try=> (~(sum fo 79) 9 9)
18
~zod/try=> (~(sum fo 79) 70 9)
0
------------------------------------------------------------------------
### ++ga
++ ga :: GF (bex p.a)
|= a=[p=@ q=@ r=@] :: dim poly gen
=+ si=(bex p.a)
=+ ma=(dec si)
=> |%
RSA internals
XX document
------------------------------------------------------------------------
### ++dif
++ dif :: add and sub
|= [b=@ c=@]
~| [%dif-ga a]
?> &((lth b si) (lth c si))
(mix b c)
::
XX document
------------------------------------------------------------------------
### ++dub
++ dub :: mul by x
|= b=@
~| [%dub-ga a]
?> (lth b si)
?: =(1 (cut 0 [(dec p.a) 1] b))
(dif (sit q.a) (sit (lsh 0 1 b)))
(lsh 0 1 b)
::
XX document
------------------------------------------------------------------------
### ++pro
++ pro :: slow multiply
|= [b=@ c=@]
?: =(0 b)
0
?: =(1 (dis 1 b))
(dif c $(b (rsh 0 1 b), c (dub c)))
$(b (rsh 0 1 b), c (dub c))
::
XX document
------------------------------------------------------------------------
### ++toe
++ toe :: exp/log tables
=+ ^= nu
|= [b=@ c=@]
^- (map ,@ ,@)
=+ d=*(map ,@ ,@)
|-
?: =(0 c)
d
%= $
c (dec c)
d (~(put by d) c b)
==
=+ [p=(nu 0 (bex p.a)) q=(nu ma ma)]
=+ [b=1 c=0]
|- ^- [p=(map ,@ ,@) q=(map ,@ ,@)]
?: =(ma c)
[(~(put by p) c b) q]
%= $
b (pro r.a b)
c +(c)
p (~(put by p) c b)
q (~(put by q) b c)
==
::
XX document
------------------------------------------------------------------------
### ++sit
++ sit :: reduce
|= b=@
(mod b (bex p.a))
--
XX document
------------------------------------------------------------------------
### ++fra
++ fra :: divide
|= [b=@ c=@]
(pro b (inv c))
::
XX document
------------------------------------------------------------------------
### ++inv
++ inv :: invert
|= b=@
~| [%inv-ga a]
=+ c=(~(get by q) b)
?~ c !!
=+ d=(~(get by p) (sub ma u.c))
(need d)
::
XX document
------------------------------------------------------------------------
### ++pow
++ pow :: exponent
|= [b=@ c=@]
=+ [d=1 e=c f=0]
|-
?: =(p.a f)
d
?: =(1 (cut 0 [f 1] b))
$(d (pro d e), e (pro e e), f +(f))
$(e (pro e e), f +(f))
::
XX document
------------------------------------------------------------------------
### ++pro
++ pro :: multiply
|= [b=@ c=@]
~| [%pro-ga a]
=+ d=(~(get by q) b)
?~ d 0
=+ e=(~(get by q) c)
?~ e 0
=+ f=(~(get by p) (mod (add u.d u.e) ma))
(need f)
--
XX document
------------------------------------------------------------------------

View File

@ -0,0 +1,717 @@
section 2eX, jetted crypto
==========================
------------------------------------------------------------------------
### ++aesc
++ aesc :: AES-256
~% %aesc + ~
|%
XX document
### ++en
++ en :: ECB enc
~/ %en
|= [a=@I b=@H] ^- @uxH
=+ ahem
(be & (ex a) b)
XX document
### ++de
++ de :: ECB dec
~/ %de
|= [a=@I b=@H] ^- @uxH
=+ ahem
(be | (ix (ex a)) b)
--
XX document
### ++ahem
++ ahem :: AES helpers
:: XX should be in aesc, isn't for performance reasons
=>
=+ =+ [gr=(ga 8 0x11b 3) few==>(fe .(a 5))]
=+ [pro=pro.gr dif=dif.gr pow=pow.gr ror=ror.few]
[pro=pro dif=dif pow=pow ror=ror nnk=8 nnb=4 nnr=14]
=> |%
XX document
### ++cipa
++ cipa :: AES params
$_ ^? |%
XX document
### ++co
++ co [0xe 0xb 0xd 0x9]
XX document
### ++ix
++ ix :: key expand, inv
|= a=@ ^- @
=+ [i=1 j=_@ b=_@ c=co:pin]
|-
?: =(nnr i)
a
=> .(b (cut 7 [i 1] a))
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
=> .(j (sub nnr i))
%= $
i +(i)
a
%+ can 7
:~ [i (cut 7 [0 i] a)]
[1 b]
[j (cut 7 [+(i) j] a)]
==
==
--
::
XX document
### ++ro
++ ro [0 3 2 1]
XX document
### ++su
++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
849d.8da7.5746.155e.dab9.edfd.5048.706c.
92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
--
::
XX document
### ++pen
++ pen :: encrypt
^- cipa
|%
XX document
### ++co
++ co [0xe 0xb 0xd 0x9]
XX document
### ++ix
++ ix :: key expand, inv
|= a=@ ^- @
=+ [i=1 j=_@ b=_@ c=co:pin]
|-
?: =(nnr i)
a
=> .(b (cut 7 [i 1] a))
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
=> .(j (sub nnr i))
%= $
i +(i)
a
%+ can 7
:~ [i (cut 7 [0 i] a)]
[1 b]
[j (cut 7 [+(i) j] a)]
==
==
--
::
XX document
### ++ro
++ ro [0 3 2 1]
XX document
### ++su
++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
849d.8da7.5746.155e.dab9.edfd.5048.706c.
92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
--
::
XX document
### ++pin
++ pin :: decrypt
^- cipa
|%
XX document
### ++co
++ co [0xe 0xb 0xd 0x9]
XX document
### ++ix
++ ix :: key expand, inv
|= a=@ ^- @
=+ [i=1 j=_@ b=_@ c=co:pin]
|-
?: =(nnr i)
a
=> .(b (cut 7 [i 1] a))
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
=> .(j (sub nnr i))
%= $
i +(i)
a
%+ can 7
:~ [i (cut 7 [0 i] a)]
[1 b]
[j (cut 7 [+(i) j] a)]
==
==
--
::
XX document
### ++ro
++ ro [0 3 2 1]
XX document
### ++su
++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
849d.8da7.5746.155e.dab9.edfd.5048.706c.
92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
--
::
XX document
### ++mcol
++ mcol
|= [a=(list ,@) b=[p=@ q=@ r=@ s=@]] ^- (list ,@)
=+ c=[p=_@ q=_@ r=_@ s=_@]
|- ^- (list ,@)
?~ a ~
=> .(p.c (cut 3 [0 1] i.a))
=> .(q.c (cut 3 [1 1] i.a))
=> .(r.c (cut 3 [2 1] i.a))
=> .(s.c (cut 3 [3 1] i.a))
:_ $(a t.a)
%+ rep 3
%+ turn
%- limo
:~ [[p.c p.b] [q.c q.b] [r.c r.b] [s.c s.b]]
[[p.c s.b] [q.c p.b] [r.c q.b] [s.c r.b]]
[[p.c r.b] [q.c s.b] [r.c p.b] [s.c q.b]]
[[p.c q.b] [q.c r.b] [r.c s.b] [s.c p.b]]
==
|= [a=[@ @] b=[@ @] c=[@ @] d=[@ @]]
:(dif (pro a) (pro b) (pro c) (pro d))
::
XX document
### ++pode
++ pode :: explode to block
|= [a=bloq b=@ c=@] ^- (list ,@)
=+ d=(rip a c)
=+ m=(met a c)
|-
?: =(m b)
d
$(m +(m), d (weld d (limo [0 ~])))
XX document
### ++sube
++ sube :: s-box word
|= [a=@ b=@] ^- @
(rep 3 (turn (pode 3 4 a) |=(c=@ (cut 3 [c 1] b))))
--
|%
XX document
### ++be
++ be :: block cipher
|= [a=? b=@ c=@H] ^- @uxH
~| %be-aesc
=> %= .
+
=> +
|%
XX document
### ++ankh
++ ankh
|= [a=cipa b=@ c=@]
(pode 5 nnb (cut 5 [(mul (ix.a b) nnb) nnb] c))
XX document
### ++sark
++ sark
|= [c=(list ,@) d=(list ,@)] ^- (list ,@)
?~ c ~
?~ d !!
[(mix i.c i.d) $(c t.c, d t.d)]
XX document
### ++srow
++ srow
|= [a=cipa b=(list ,@)] ^- (list ,@)
=+ [c=0 d=~ e=ro.a]
|-
?: =(c nnb)
d
:_ $(c +(c))
%+ rep 3
%+ turn
(limo [0 p.e] [1 q.e] [2 r.e] [3 s.e] ~)
|= [f=@ g=@]
(cut 3 [f 1] (snag (mod (add g c) nnb) b))
XX document
### ++subs
++ subs
|= [a=cipa b=(list ,@)] ^- (list ,@)
?~ b ~
[(sube i.b su.a) $(b t.b)]
--
==
=+ [d=?:(a pen pin) e=(pode 5 nnb c) f=1]
=> .(e (sark e (ankh d 0 b)))
|-
?. =(nnr f)
=> .(e (subs d e))
=> .(e (srow d e))
=> .(e (mcol e co.d))
=> .(e (sark e (ankh d f b)))
$(f +(f))
=> .(e (subs d e))
=> .(e (srow d e))
=> .(e (sark e (ankh d nnr b)))
(rep 5 e)
XX document
### ++ex
++ ex :: key expand
|= a=@I ^- @
=+ [b=a c=0 d=su:pen i=nnk]
|-
?: =(i (mul nnb +(nnr)))
b
=> .(c (cut 5 [(dec i) 1] b))
=> ?: =(0 (mod i nnk))
=> .(c (ror 3 1 c))
=> .(c (sube c d))
.(c (mix c (pow (dec (div i nnk)) 2)))
?: &((gth nnk 6) =(4 (mod i nnk)))
.(c (sube c d))
.
=> .(c (mix c (cut 5 [(sub i nnk) 1] b)))
=> .(b (can 5 [i b] [1 c] ~))
$(i +(i))
XX document
### ++ix
++ ix :: key expand, inv
|= a=@ ^- @
=+ [i=1 j=_@ b=_@ c=co:pin]
|-
?: =(nnr i)
a
=> .(b (cut 7 [i 1] a))
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
=> .(j (sub nnr i))
%= $
i +(i)
a
%+ can 7
:~ [i (cut 7 [0 i] a)]
[1 b]
[j (cut 7 [+(i) j] a)]
==
==
--
::
XX document
### ++curt
++ curt :: curve25519
|= [a=@ b=@]
=> %= .
+
=> +
=+ =+ [p=486.662 q=(sub (bex 255) 19)]
=+ fq=~(. fo q)
[p=p q=q fq=fq]
|%
XX document
### ++cla
++ cla
|= raw=@
=+ low=(dis 248 (cut 3 [0 1] raw))
=+ hih=(con 64 (dis 127 (cut 3 [31 1] raw)))
=+ mid=(cut 3 [1 30] raw)
(can 3 [[1 low] [30 mid] [1 hih] ~])
XX document
### ++sqr
++ sqr |=(a=@ (mul a a))
XX document
### ++inv
++ inv |=(a=@ (~(exp fo q) (sub q 2) a))
XX document
### ++cad
++ cad
|= [n=[x=@ z=@] m=[x=@ z=@] d=[x=@ z=@]]
=+ ^= xx
;: mul 4 z.d
%- sqr %- abs:si
%+ dif:si
(sun:si (mul x.m x.n))
(sun:si (mul z.m z.n))
==
=+ ^= zz
;: mul 4 x.d
%- sqr %- abs:si
%+ dif:si
(sun:si (mul x.m z.n))
(sun:si (mul z.m x.n))
==
[(sit.fq xx) (sit.fq zz)]
XX document
### ++cub
++ cub
|= [x=@ z=@]
=+ ^= xx
%+ mul
%- sqr %- abs:si
(dif:si (sun:si x) (sun:si z))
(sqr (add x z))
=+ ^= zz
;: mul 4 x z
:(add (sqr x) :(mul p x z) (sqr z))
==
[(sit.fq xx) (sit.fq zz)]
--
==
=+ one=[b 1]
=+ i=253
=+ r=one
=+ s=(cub one)
|-
?: =(i 0)
=+ x=(cub r)
(sit.fq (mul -.x (inv +.x)))
=+ m=(rsh 0 i a)
?: =(0 (mod m 2))
$(i (dec i), s (cad r s one), r (cub r))
$(i (dec i), r (cad r s one), s (cub s))
::
XX document
### ++ed
++ ed :: ed25519
=>
=+ =+ [b=256 q=(sub (bex 255) 19)]
=+ fq=~(. fo q)
=+ ^= l
%+ add
(bex 252)
27.742.317.777.372.353.535.851.937.790.883.648.493
=+ d=(dif.fq 0 (fra.fq 121.665 121.666))
=+ ii=(exp.fq (div (dec q) 4) 2)
[b=b q=q fq=fq l=l d=d ii=ii]
~% %coed +> ~
|%
### ++norm
++ norm |=(x=@ ?:(=(0 (mod x 2)) x (sub q x)))
::
XX document
### ++xrec
++ xrec :: recover x-coord
|= y=@ ^- @
=+ ^= xx
%+ mul (dif.fq (mul y y) 1)
(inv.fq +(:(mul d y y)))
=+ x=(exp.fq (div (add 3 q) 8) xx)
?: !=(0 (dif.fq (mul x x) (sit.fq xx)))
(norm (pro.fq x ii))
(norm x)
::
XX document
### ++ward
++ ward :: edwards multiply
|= [pp=[@ @] qq=[@ @]] ^- [@ @]
=+ dp=:(pro.fq d -.pp -.qq +.pp +.qq)
=+ ^= xt
%+ pro.fq
%+ sum.fq
(pro.fq -.pp +.qq)
(pro.fq -.qq +.pp)
(inv.fq (sum.fq 1 dp))
=+ ^= yt
%+ pro.fq
%+ sum.fq
(pro.fq +.pp +.qq)
(pro.fq -.pp -.qq)
(inv.fq (dif.fq 1 dp))
[xt yt]
::
XX document
### ++scam
++ scam :: scalar multiply
|= [pp=[@ @] e=@] ^- [@ @]
?: =(0 e)
[0 1]
=+ qq=$(e (div e 2))
=> .(qq (ward qq qq))
?: =(1 (dis 1 e))
(ward qq pp)
qq
::
XX document
### ++etch
++ etch :: encode point
|= pp=[@ @] ^- @
(can 0 ~[[(sub b 1) +.pp] [1 (dis 1 -.pp)]])
::
XX document
### ++curv
++ curv :: point on curve?
|= [x=@ y=@] ^- ?
.= 0
%+ dif.fq
%+ sum.fq
(pro.fq (sub q (sit.fq x)) x)
(pro.fq y y)
(sum.fq 1 :(pro.fq d x x y y))
::
XX document
### ++deco
++ deco :: decode point
|= s=@ ^- (unit ,[@ @])
=+ y=(cut 0 [0 (dec b)] s)
=+ si=(cut 0 [(dec b) 1] s)
=+ x=(xrec y)
=> .(x ?:(!=(si (dis 1 x)) (sub q x) x))
=+ pp=[x y]
?. (curv pp)
~
[~ pp]
::
XX document
### ++bb
++ bb
=+ bby=(pro.fq 4 (inv.fq 5))
[(xrec bby) bby]
::
--
~% %ed + ~
|%
XX document
### ++puck
++ puck :: public key
~/ %puck
|= sk=@I ^- @
?: (gth (met 3 sk) 32) !!
=+ h=(shal (rsh 0 3 b) sk)
=+ ^= a
%+ add
(bex (sub b 2))
(lsh 0 3 (cut 0 [3 (sub b 5)] h))
=+ aa=(scam bb a)
(etch aa)
XX document
### ++suck
++ suck :: keypair from seed
|= se=@I ^- @uJ
=+ pu=(puck se)
(can 0 ~[[b se] [b pu]])
::
XX document
### ++sign
++ sign :: certify
~/ %sign
|= [m=@ se=@] ^- @
=+ sk=(suck se)
=+ pk=(cut 0 [b b] sk)
=+ h=(shal (rsh 0 3 b) sk)
=+ ^= a
%+ add
(bex (sub b 2))
(lsh 0 3 (cut 0 [3 (sub b 5)] h))
=+ ^= r
=+ hm=(cut 0 [b b] h)
=+ ^= i
%+ can 0
:~ [b hm]
[(met 0 m) m]
==
(shaz i)
=+ rr=(scam bb r)
=+ ^= ss
=+ er=(etch rr)
=+ ^= ha
%+ can 0
:~ [b er]
[b pk]
[(met 0 m) m]
==
(~(sit fo l) (add r (mul (shaz ha) a)))
(can 0 ~[[b (etch rr)] [b ss]])
::
XX document
### ++veri
++ veri :: validate
~/ %veri
|= [s=@ m=@ pk=@] ^- ?
?: (gth (div b 4) (met 3 s)) |
?: (gth (div b 8) (met 3 pk)) |
=+ cb=(rsh 0 3 b)
=+ rr=(deco (cut 0 [0 b] s))
?~ rr |
=+ aa=(deco pk)
?~ aa |
=+ ss=(cut 0 [b b] s)
=+ ha=(can 3 ~[[cb (etch u.rr)] [cb pk] [(met 3 m) m]])
=+ h=(shaz ha)
=((scam bb ss) (ward u.rr (scam u.aa h)))
::
--
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
XX document
------------------------------------------------------------------------

View File

@ -0,0 +1,399 @@
section 2eY, SHA-256
====================
### ++shad
++ shad |=(ruz=@ (shax (shax ruz))) :: double sha-256
XX document
### ++shaf
++ shaf :: half sha-256
|= [sal=@ ruz=@]
=+ haz=(shas sal ruz)
(mix (end 7 1 haz) (rsh 7 1 haz))
::
XX document
### ++shak
++ shak :: XX shd be PBKDF
|= [who=@p wud=@]
(shas (mix %shak who) wud)
::
XX document
### ++sham
++ sham :: noun hash
|= yux=* ^- @uvH ^- @
?@ yux
(shaf %mash yux)
(shaf %sham (jam yux))
::
XX document
### ++shas
++ shas :: salted hash
|= [sal=@ ruz=@]
(shax (mix sal (shax ruz)))
::
XX document
### ++shax
++ shax :: sha-256
~/ %shax
|= ruz=@ ^- @
~| %sha
=+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
=+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
=+ ral=(lsh 0 3 (met 3 ruz))
=+ ^= ful
%+ can 0
:~ [ral ruz]
[8 128]
[(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
[64 (~(net fe 6) ral)]
==
=+ lex=(met 9 ful)
=+ ^= kbx 0xc671.78f2.bef9.a3f7.a450.6ceb.90be.fffa.
8cc7.0208.84c8.7814.78a5.636f.748f.82ee.
682e.6ff3.5b9c.ca4f.4ed8.aa4a.391c.0cb3.
34b0.bcb5.2748.774c.1e37.6c08.19a4.c116.
106a.a070.f40e.3585.d699.0624.d192.e819.
c76c.51a3.c24b.8b70.a81a.664b.a2bf.e8a1.
9272.2c85.81c2.c92e.766a.0abb.650a.7354.
5338.0d13.4d2c.6dfc.2e1b.2138.27b7.0a85.
1429.2967.06ca.6351.d5a7.9147.c6e0.0bf3.
bf59.7fc7.b003.27c8.a831.c66d.983e.5152.
76f9.88da.5cb0.a9dc.4a74.84aa.2de9.2c6f.
240c.a1cc.0fc1.9dc6.efbe.4786.e49b.69c1.
c19b.f174.9bdc.06a7.80de.b1fe.72be.5d74.
550c.7dc3.2431.85be.1283.5b01.d807.aa98.
ab1c.5ed5.923f.82a4.59f1.11f1.3956.c25b.
e9b5.dba5.b5c0.fbcf.7137.4491.428a.2f98
=+ ^= hax 0x5be0.cd19.1f83.d9ab.9b05.688c.510e.527f.
a54f.f53a.3c6e.f372.bb67.ae85.6a09.e667
=+ i=0
|- ^- @
?: =(i lex)
(rep 5 (turn (rip 5 hax) net))
=+ ^= wox
=+ dux=(cut 9 [i 1] ful)
=+ wox=(rep 5 (turn (rip 5 dux) net))
=+ j=16
|- ^- @
?: =(64 j)
wox
=+ :* l=(wac (sub j 15) wox)
m=(wac (sub j 2) wox)
n=(wac (sub j 16) wox)
o=(wac (sub j 7) wox)
==
=+ x=:(mix (ror 0 7 l) (ror 0 18 l) (rsh 0 3 l))
=+ y=:(mix (ror 0 17 m) (ror 0 19 m) (rsh 0 10 m))
=+ z=:(sum n x o y)
$(wox (con (lsh 5 j z) wox), j +(j))
=+ j=0
=+ :* a=(wac 0 hax)
b=(wac 1 hax)
c=(wac 2 hax)
d=(wac 3 hax)
e=(wac 4 hax)
f=(wac 5 hax)
g=(wac 6 hax)
h=(wac 7 hax)
==
|- ^- @
?: =(64 j)
%= ^$
i +(i)
hax %+ rep 5
:~ (sum a (wac 0 hax))
(sum b (wac 1 hax))
(sum c (wac 2 hax))
(sum d (wac 3 hax))
(sum e (wac 4 hax))
(sum f (wac 5 hax))
(sum g (wac 6 hax))
(sum h (wac 7 hax))
==
==
=+ l=:(mix (ror 0 2 a) (ror 0 13 a) (ror 0 22 a)) :: s0
=+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
=+ n=(sum l m) :: t2
=+ o=:(mix (ror 0 6 e) (ror 0 11 e) (ror 0 25 e)) :: s1
=+ p=(mix (dis e f) (dis (inv e) g)) :: ch
=+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
$(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
::
XX document
### ++shaw
++ shaw :: hash to nbits
|= [sal=@ len=@ ruz=@]
(~(raw og (shas sal (mix len ruz))) len)
::
XX document
### ++og
++ og :: shax-powered rng
~/ %og
|_ a=@
XX document
### ++rad
++ rad :: random in range
|= b=@ ^- @
=+ c=(raw (met 0 b))
?:((lth c b) c $(a +(a)))
::
XX document
### ++rads
++ rads :: random continuation
|= b=@
=+ r=(rad b)
[r +>.$(a (shas %og-s r))]
XX document
### ++raw
++ raw :: random bits
~/ %raw
|= b=@ ^- @
%+ can
0
=+ c=(shas %og-a (mix b a))
|- ^- (list ,[@ @])
?: =(0 b)
~
=+ d=(shas %og-b (mix b (mix a c)))
?: (lth b 256)
[[b (end 0 b d)] ~]
[[256 d] $(c d, b (sub b 256))]
XX document
### ++raws
++ raws :: random bits continuation
|= b=@
=+ r=(raw b)
[r +>.$(a (shas %og-s r))]
--
XX document
### ++shaz
++ shaz :: sha-512
|= ruz=@ ^- @
(shal [(met 3 ruz) ruz])
XX document
### ++shal
++ shal :: sha-512 with length
~/ %shal
|= [len=@ ruz=@] ^- @
=> .(ruz (cut 3 [0 len] ruz))
=+ [few==>(fe .(a 6)) wac=|=([a=@ b=@] (cut 6 [a 1] b))]
=+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
=+ ral=(lsh 0 3 len)
=+ ^= ful
%+ can 0
:~ [ral ruz]
[8 128]
[(mod (sub 1.920 (mod (add 8 ral) 1.024)) 1.024) 0]
[128 (~(net fe 7) ral)]
==
=+ lex=(met 10 ful)
=+ ^= kbx 0x6c44.198c.4a47.5817.5fcb.6fab.3ad6.faec.
597f.299c.fc65.7e2a.4cc5.d4be.cb3e.42b6.
431d.67c4.9c10.0d4c.3c9e.be0a.15c9.bebc.
32ca.ab7b.40c7.2493.28db.77f5.2304.7d84.
1b71.0b35.131c.471b.113f.9804.bef9.0dae.
0a63.7dc5.a2c8.98a6.06f0.67aa.7217.6fba.
f57d.4f7f.ee6e.d178.eada.7dd6.cde0.eb1e.
d186.b8c7.21c0.c207.ca27.3ece.ea26.619c.
c671.78f2.e372.532b.bef9.a3f7.b2c6.7915.
a450.6ceb.de82.bde9.90be.fffa.2363.1e28.
8cc7.0208.1a64.39ec.84c8.7814.a1f0.ab72.
78a5.636f.4317.2f60.748f.82ee.5def.b2fc.
682e.6ff3.d6b2.b8a3.5b9c.ca4f.7763.e373.
4ed8.aa4a.e341.8acb.391c.0cb3.c5c9.5a63.
34b0.bcb5.e19b.48a8.2748.774c.df8e.eb99.
1e37.6c08.5141.ab53.19a4.c116.b8d2.d0c8.
106a.a070.32bb.d1b8.f40e.3585.5771.202a.
d699.0624.5565.a910.d192.e819.d6ef.5218.
c76c.51a3.0654.be30.c24b.8b70.d0f8.9791.
a81a.664b.bc42.3001.a2bf.e8a1.4cf1.0364.
9272.2c85.1482.353b.81c2.c92e.47ed.aee6.
766a.0abb.3c77.b2a8.650a.7354.8baf.63de.
5338.0d13.9d95.b3df.4d2c.6dfc.5ac4.2aed.
2e1b.2138.5c26.c926.27b7.0a85.46d2.2ffc.
1429.2967.0a0e.6e70.06ca.6351.e003.826f.
d5a7.9147.930a.a725.c6e0.0bf3.3da8.8fc2.
bf59.7fc7.beef.0ee4.b003.27c8.98fb.213f.
a831.c66d.2db4.3210.983e.5152.ee66.dfab.
76f9.88da.8311.53b5.5cb0.a9dc.bd41.fbd4.
4a74.84aa.6ea6.e483.2de9.2c6f.592b.0275.
240c.a1cc.77ac.9c65.0fc1.9dc6.8b8c.d5b5.
efbe.4786.384f.25e3.e49b.69c1.9ef1.4ad2.
c19b.f174.cf69.2694.9bdc.06a7.25c7.1235.
80de.b1fe.3b16.96b1.72be.5d74.f27b.896f.
550c.7dc3.d5ff.b4e2.2431.85be.4ee4.b28c.
1283.5b01.4570.6fbe.d807.aa98.a303.0242.
ab1c.5ed5.da6d.8118.923f.82a4.af19.4f9b.
59f1.11f1.b605.d019.3956.c25b.f348.b538.
e9b5.dba5.8189.dbbc.b5c0.fbcf.ec4d.3b2f.
7137.4491.23ef.65cd.428a.2f98.d728.ae22
=+ ^= hax 0x5be0.cd19.137e.2179.1f83.d9ab.fb41.bd6b.
9b05.688c.2b3e.6c1f.510e.527f.ade6.82d1.
a54f.f53a.5f1d.36f1.3c6e.f372.fe94.f82b.
bb67.ae85.84ca.a73b.6a09.e667.f3bc.c908
=+ i=0
|- ^- @
?: =(i lex)
(rep 6 (turn (rip 6 hax) net))
=+ ^= wox
=+ dux=(cut 10 [i 1] ful)
=+ wox=(rep 6 (turn (rip 6 dux) net))
=+ j=16
|- ^- @
?: =(80 j)
wox
=+ :* l=(wac (sub j 15) wox)
m=(wac (sub j 2) wox)
n=(wac (sub j 16) wox)
o=(wac (sub j 7) wox)
==
=+ x=:(mix (ror 0 1 l) (ror 0 8 l) (rsh 0 7 l))
=+ y=:(mix (ror 0 19 m) (ror 0 61 m) (rsh 0 6 m))
=+ z=:(sum n x o y)
$(wox (con (lsh 6 j z) wox), j +(j))
=+ j=0
=+ :* a=(wac 0 hax)
b=(wac 1 hax)
c=(wac 2 hax)
d=(wac 3 hax)
e=(wac 4 hax)
f=(wac 5 hax)
g=(wac 6 hax)
h=(wac 7 hax)
==
|- ^- @
?: =(80 j)
%= ^$
i +(i)
hax %+ rep 6
:~ (sum a (wac 0 hax))
(sum b (wac 1 hax))
(sum c (wac 2 hax))
(sum d (wac 3 hax))
(sum e (wac 4 hax))
(sum f (wac 5 hax))
(sum g (wac 6 hax))
(sum h (wac 7 hax))
==
==
=+ l=:(mix (ror 0 28 a) (ror 0 34 a) (ror 0 39 a)) :: S0
=+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
=+ n=(sum l m) :: t2
=+ o=:(mix (ror 0 14 e) (ror 0 18 e) (ror 0 41 e)) :: S1
=+ p=(mix (dis e f) (dis (inv e) g)) :: ch
=+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
$(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
::
XX document
### ++shan
++ shan :: sha-1 (deprecated)
|= ruz=@
=+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
=+ [sum=sum.few ror=ror.few rol=rol.few net=net.few inv=inv.few]
=+ ral=(lsh 0 3 (met 3 ruz))
=+ ^= ful
%+ can 0
:~ [ral ruz]
[8 128]
[(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
[64 (~(net fe 6) ral)]
==
=+ lex=(met 9 ful)
=+ kbx=0xca62.c1d6.8f1b.bcdc.6ed9.eba1.5a82.7999
=+ hax=0xc3d2.e1f0.1032.5476.98ba.dcfe.efcd.ab89.6745.2301
=+ i=0
|-
?: =(i lex)
(rep 5 (flop (rip 5 hax)))
=+ ^= wox
=+ dux=(cut 9 [i 1] ful)
=+ wox=(rep 5 (turn (rip 5 dux) net))
=+ j=16
|- ^- @
?: =(80 j)
wox
=+ :* l=(wac (sub j 3) wox)
m=(wac (sub j 8) wox)
n=(wac (sub j 14) wox)
o=(wac (sub j 16) wox)
==
=+ z=(rol 0 1 :(mix l m n o))
$(wox (con (lsh 5 j z) wox), j +(j))
=+ j=0
=+ :* a=(wac 0 hax)
b=(wac 1 hax)
c=(wac 2 hax)
d=(wac 3 hax)
e=(wac 4 hax)
==
|- ^- @
?: =(80 j)
%= ^$
i +(i)
hax %+ rep 5
:~
(sum a (wac 0 hax))
(sum b (wac 1 hax))
(sum c (wac 2 hax))
(sum d (wac 3 hax))
(sum e (wac 4 hax))
==
==
=+ fx=(con (dis b c) (dis (not 5 1 b) d))
=+ fy=:(mix b c d)
=+ fz=:(con (dis b c) (dis b d) (dis c d))
=+ ^= tem
?: &((gte j 0) (lte j 19))
:(sum (rol 0 5 a) fx e (wac 0 kbx) (wac j wox))
?: &((gte j 20) (lte j 39))
:(sum (rol 0 5 a) fy e (wac 1 kbx) (wac j wox))
?: &((gte j 40) (lte j 59))
:(sum (rol 0 5 a) fz e (wac 2 kbx) (wac j wox))
:(sum (rol 0 5 a) fy e (wac 3 kbx) (wac j wox))
$(j +(j), a tem, b a, c (rol 0 30 b), d c, e d)
XX document
--

View File

@ -0,0 +1,252 @@
section 2eZ, OLD rendering
--------------------------
------------------------------------------------------------------------
### ++show
++ show :: XX deprecated, use type
|= vem=*
|^ ^- tank
?: ?=(@ vem)
[%leaf (mesc (trip vem))]
?- vem
[s=~ c=*]
[%leaf '\'' (weld (mesc (tape +.vem)) `tape`['\'' ~])]
::
[s=%a c=@] [%leaf (mesc (trip c.vem))]
[s=%b c=*] (shop c.vem |=(a=@ ~(rub at a)))
[s=[%c p=@] c=*]
:+ %palm
[['.' ~] ['-' ~] ~ ~]
[[%leaf (mesc (trip p.s.vem))] $(vem c.vem) ~]
::
[s=%d c=*] (shop c.vem |=(a=@ ~(rud at a)))
[s=%k c=*] (tank c.vem)
[s=%h c=*]
?: =(0 c.vem) :: XX remove after 220
[%leaf '#' ~]
:+ %rose
[['/' ~] ['/' ~] ~]
=+ yol=((list ,@ta) c.vem)
(turn yol |=(a=@ta [%leaf (trip a)]))
::
[s=%o c=*]
%= $
vem
:- [%m '%h:<[%d %d].[%d %d]>']
[-.c.vem +<-.c.vem +<+.c.vem +>-.c.vem +>+.c.vem ~]
==
::
[s=%p c=*] (shop c.vem |=(a=@ ~(rup at a)))
[s=%q c=*] (shop c.vem |=(a=@ ~(r at a)))
[s=%r c=*] $(vem [[%r ' ' '{' '}'] c.vem])
[s=%t c=*] (shop c.vem |=(a=@ ~(rt at a)))
[s=%v c=*] (shop c.vem |=(a=@ ~(ruv at a)))
[s=%x c=*] (shop c.vem |=(a=@ ~(rux at a)))
[s=[%m p=@] c=*] (shep p.s.vem c.vem)
[s=[%r p=@] c=*]
$(vem [[%r ' ' (cut 3 [0 1] p.s.vem) (cut 3 [1 1] p.s.vem)] c.vem])
::
[s=[%r p=@ q=@ r=@] c=*]
:+ %rose
:* p=(mesc (trip p.s.vem))
q=(mesc (trip q.s.vem))
r=(mesc (trip r.s.vem))
==
|- ^- (list tank)
?@ c.vem
~
[^$(vem -.c.vem) $(c.vem +.c.vem)]
::
[s=%z c=*] $(vem [[%r %$ %$ %$] c.vem])
* !!
==
XX document
### ++shep
++ shep
|= [fom=@ gar=*]
^- tank
=+ l=(met 3 fom)
=+ i=0
:- %leaf
|- ^- tape
?: (gte i l)
~
=+ c=(cut 3 [i 1] fom)
?. =(37 c)
(weld (mesc [c ~]) $(i +(i)))
=+ d=(cut 3 [+(i) 1] fom)
?. .?(gar)
['\\' '#' $(i (add 2 i))]
(weld ~(ram re (show d -.gar)) $(i (add 2 i), gar +.gar))
::
XX document
### ++shop
++ shop
|= [aug=* vel=$+(a=@ tape)]
^- tank
?: ?=(@ aug)
[%leaf (vel aug)]
:+ %rose
[[' ' ~] ['[' ~] [']' ~]]
=> .(aug `*`aug)
|- ^- (list tank)
?: ?=(@ aug)
[^$ ~]
[^$(aug -.aug) $(aug +.aug)]
--
XX document
### ++at
++ at
|_ a=@
XX document
### ++r
++ r
?: ?& (gte (met 3 a) 2)
|-
?: =(0 a)
&
=+ vis=(end 3 1 a)
?& ?|(=('-' vis) ?&((gte vis 'a') (lte vis 'z')))
$(a (rsh 3 1 a))
==
==
rtam
?: (lte (met 3 a) 2)
rud
rux
::
XX document
### ++rf
++ rf `tape`[?-(a & '&', | '|', * !!) ~]
XX document
### ++rn
++ rn `tape`[?>(=(0 a) '~') ~]
XX document
### ++rt
++ rt `tape`['\'' (weld (mesc (trip a)) `tape`['\'' ~])]
XX document
### ++rta
++ rta rt
XX document
### ++rtam
++ rtam `tape`['%' (trip a)]
XX document
### ++rub
++ rub `tape`['0' 'b' (rum 2 ~ |=(b=@ (add '0' b)))]
XX document
### ++rud
++ rud (rum 10 ~ |=(b=@ (add '0' b)))
XX document
### ++rum
++ rum
|= [b=@ c=tape d=$+(@ @)]
^- tape
?: =(0 a)
[(d 0) c]
=+ e=0
|- ^- tape
?: =(0 a)
c
=+ f=&(!=(0 e) =(0 (mod e ?:(=(10 b) 3 4))))
%= $
a (div a b)
c [(d (mod a b)) ?:(f [?:(=(10 b) ',' '-') c] c)]
e +(e)
==
::
XX document
### ++rup
++ rup
=+ b=(met 3 a)
^- tape
:- '-'
|- ^- tape
?: (gth (met 5 a) 1)
%+ weld
$(a (rsh 5 1 a), b (sub b 4))
`tape`['-' '-' $(a (end 5 1 a), b 4)]
?: =(0 b)
['~' ~]
?: (lte b 1)
(trip (tos:po a))
|- ^- tape
?: =(2 b)
=+ c=(rsh 3 1 a)
=+ d=(end 3 1 a)
(weld (trip (tod:po c)) (trip (tos:po (mix c d))))
=+ c=(rsh 3 2 a)
=+ d=(end 3 2 a)
(weld ^$(a c, b (met 3 c)) `tape`['-' $(a (mix c d), b 2)])
::
XX document
### ++ruv
++ ruv
^- tape
:+ '0'
'v'
%^ rum
64
~
|= b=@
?: =(63 b)
'+'
?: =(62 b)
'-'
?:((lth b 26) (add 65 b) ?:((lth b 52) (add 71 b) (sub b 4)))
::
XX document
### ++rux
++ rux `tape`['0' 'x' (rum 16 ~ |=(b=@ (add b ?:((lth b 10) 48 87))))]
--
:::::::::::::::::::::::::::::::::::::::::::::::::::::: ::
XX document
------------------------------------------------------------------------

View File

@ -0,0 +1,67 @@
section 3bA, lite number theory
===============================
### ++fu
++ fu :: modulo (mul p q)
|= a=[p=@ q=@]
=+ b=?:(=([0 0] a) 0 (~(inv fo p.a) (~(sit fo p.a) q.a)))
|%
XX document
### ++dif
++ dif
|= [c=[@ @] d=[@ @]]
[(~(dif fo p.a) -.c -.d) (~(dif fo q.a) +.c +.d)]
::
XX document
### ++exp
++ exp
|= [c=@ d=[@ @]]
:- (~(exp fo p.a) (mod c (dec p.a)) -.d)
(~(exp fo q.a) (mod c (dec q.a)) +.d)
::
XX document
### ++out
++ out :: garner's formula
|= c=[@ @]
%+ add
+.c
(mul q.a (~(pro fo p.a) b (~(dif fo p.a) -.c (~(sit fo p.a) +.c))))
::
XX document
### ++pro
++ pro
|= [c=[@ @] d=[@ @]]
[(~(pro fo p.a) -.c -.d) (~(pro fo q.a) +.c +.d)]
::
XX document
### ++sum
++ sum
|= [c=[@ @] d=[@ @]]
[(~(sum fo p.a) -.c -.d) (~(sum fo q.a) +.c +.d)]
::
XX document
### ++sit
++ sit
|= c=@
[(mod c p.a) (mod c q.a)]
XX document

View File

@ -0,0 +1,600 @@
section 3bB, cryptosuites
=========================
### ++crua
++ crua !: :: cryptosuite A (RSA)
^- acru
=| [mos=@ pon=(unit ,[p=@ q=@ r=[p=@ q=@] s=_*fu])]
=> |%
XX document
### ++mx
++ mx (dec (met 0 mos)) :: bit length
XX document
### ++dap
++ dap :: OEAP decode
|= [wid=@ xar=@ dog=@] ^- [p=@ q=@]
=+ pav=(sub wid xar)
=+ qoy=(cut 0 [xar pav] dog)
=+ dez=(mix (end 0 xar dog) (shaw %pad-b xar qoy))
[dez (mix qoy (shaw %pad-a pav dez))]
::
XX document
### ++pad
++ pad :: OEAP encode
|= [wid=@ rax=[p=@ q=@] meg=@] ^- @
=+ pav=(sub wid p.rax)
?> (gte pav (met 0 meg))
^- @
=+ qoy=(mix meg (shaw %pad-a pav q.rax))
=+ dez=(mix q.rax (shaw %pad-b p.rax qoy))
(can 0 [p.rax dez] [pav qoy] ~)
|%
XX document
### ++pull
++ pull |=(a=@ (~(exp fo mos) 3 a))
XX document
### ++push
++ push |=(a=@ (~(exp fo mos) 5 a))
XX document
### ++pump
++ pump
|= a=@ ^- @
?~ pon !!
(out.s.u.pon (exp.s.u.pon p.r.u.pon (sit.s.u.pon a)))
::
XX document
### ++punt
++ punt
|= a=@ ^- @
?~ pon !!
(out.s.u.pon (exp.s.u.pon q.r.u.pon (sit.s.u.pon a)))
|%
XX document
### ++as
++ as
=> |%
XX document
### ++haul
++ haul :: revealing haul
|= a=pass
!!
^?
|% ++ seal
|= [a=pass b=@ c=@]
^- @
!!
XX document
### ++seal
XX document
###++sign
```
++ sign
|= [a=@ b=@] ^- @
!!
```
XX document
###++sure
```
++ sure
|= [a=@ b=@]
^- (unit ,@)
!!
```
XX document
###++tear
```
++ tear
|= [a=pass b=@]
^- (unit ,[p=@ q=@])
!!
::
```
XX document
###++de
```
++ de
|+ [key=@ cep=@] ^- (unit ,@)
!!
::
```
XX document
###++dy
```
++ dy
|+ [a=@ b=@] ^- @
!!
```
XX document
###++en
```
++ en
|+ [key=@ msg=@] ^- @ux
!!
::
```
XX document
###++ex
```
++ ex ^?
|% ++ fig ^- @uvH (shaf %bfig puc)
```
XX document
###++fig
XX document
### ++pac
++ pac ^- @uvG (end 6 1 (shaf %acod sec))
XX document
### ++pub
++ pub ^- pass (cat 3 'b' puc)
XX document
### ++sec
++ sec ^- ring sed
::
XX document
### ++nu
++ nu
^?
|% ++ com
|= a=@
^+ ^?(..nu)
..nu(sed ~, puc a)
::
XX document
### ++elcm
++ elcm
|= [a=@ b=@]
(div (mul a b) d:(egcd a b))
::
XX document
### ++eldm
++ eldm
|= [a=@ b=@ c=@]
(~(inv fo (elcm (dec b) (dec c))) a)
::
XX document
### ++ersa
++ ersa
|= [a=@ b=@]
[a b [(eldm 3 a b) (eldm 5 a b)] (fu a b)]
^?
|% ++ com
|= a=@
^+ ^?(..nu)
..nu(mos a, pon ~)
::
XX document
### ++com
XX document
###++pit
```
++ pit
|= [a=@ b=@]
^+ ^?(..nu)
..nu(sed b, puc (puck:ed b))
::
```
XX document
###++nol
```
++ nol
|= a=@
^+ ^?(..nu)
..nu(sed a, puc (puck:ed a))
```
XX document
###++bruw
```
++ bruw :: create keypair
|= [a=@ b=@] :: width seed
^- acru
(pit:nu:crua a b)
::
```
XX document
###++haul
```
++ haul :: revealing haul
|= a=pass
!!
^?
|% ++ seal
|= [a=pass b=@ c=@]
^- @
!!
```
XX document
###++weur
```
++ weur :: activate secret key
|= a=ring
^- acru
=+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
?> =('A' mag)
(nol:nu:crua bod)
::
```
XX document
###++trua
```
++ trua :: test rsa
|= msg=@tas
^- @
=+ ali=(bruw 1.024 (shax 'ali'))
=+ bob=(bruw 1.024 (shax 'bob'))
=+ tef=(sign:as.ali [0 msg])
=+ lov=(sure:as.ali [0 tef])
?. &(?=(^ lov) =(msg u.lov))
~|(%test-fail-sign !!)
=+ key=(shax (shax (shax msg)))
=+ sax=(seal:as.ali pub:ex.bob key msg)
=+ tin=(tear:as.bob pub:ex.ali sax)
?. &(?=(^ tin) =(key p.u.tin) =(msg q.u.tin))
~|(%test-fail-seal !!)
msg
::
```
XX document
###++crub
```
++ crub :: cryptosuite B (Ed)
^- acru
=| [puc=pass sed=ring]
=> |%
```
XX document
###++dap
```
++ dap :: OEAP decode
|= [wid=@ xar=@ dog=@] ^- [p=@ q=@]
=+ pav=(sub wid xar)
=+ qoy=(cut 0 [xar pav] dog)
=+ dez=(mix (end 0 xar dog) (shaw %pad-b xar qoy))
[dez (mix qoy (shaw %pad-a pav dez))]
::
```
XX document
###++pad
```
++ pad :: OEAP encode
|= [wid=@ rax=[p=@ q=@] meg=@] ^- @
=+ pav=(sub wid p.rax)
?> (gte pav (met 0 meg))
^- @
=+ qoy=(mix meg (shaw %pad-a pav q.rax))
=+ dez=(mix q.rax (shaw %pad-b p.rax qoy))
(can 0 [p.rax dez] [pav qoy] ~)
|%
```
XX document
###++as
```
++ as
=> |%
```
XX document
###++haul
```
++ haul :: revealing haul
|= a=pass
!!
^?
|% ++ seal
|= [a=pass b=@ c=@]
^- @
!!
```
XX document
###++seal
XX document
### ++sign
++ sign
|= [a=@ b=@] ^- @
!!
XX document
### ++sure
++ sure
|= [a=@ b=@]
^- (unit ,@)
!!
XX document
### ++tear
++ tear
|= [a=pass b=@]
^- (unit ,[p=@ q=@])
!!
::
XX document
### ++de
++ de
|+ [key=@ cep=@] ^- (unit ,@)
!!
::
XX document
### ++dy
++ dy
|+ [a=@ b=@] ^- @
!!
XX document
### ++en
++ en
|+ [key=@ msg=@] ^- @ux
!!
::
XX document
### ++ex
++ ex ^?
|% ++ fig ^- @uvH (shaf %bfig puc)
XX document
### ++fig
XX document
###++pac
```
++ pac ^- @uvG (end 6 1 (shaf %acod sec))
```
XX document
###++pub
```
++ pub ^- pass (cat 3 'b' puc)
```
XX document
###++sec
```
++ sec ^- ring sed
::
```
XX document
###++nu
```
++ nu
^?
|% ++ com
|= a=@
^+ ^?(..nu)
..nu(sed ~, puc a)
::
```
XX document
###++com
XX document
### ++pit
++ pit
|= [a=@ b=@]
^+ ^?(..nu)
..nu(sed b, puc (puck:ed b))
::
XX document
### ++nol
++ nol
|= a=@
^+ ^?(..nu)
..nu(sed a, puc (puck:ed a))
XX document
### ++brew
++ brew :: create keypair
|= [a=@ b=@] :: width seed
^- acru
(pit:nu:crub a b)
::
XX document
### ++hail
++ hail :: activate public key
|= a=pass
^- acru
=+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
?> =('b' mag)
(com:nu:crub bod)
::
XX document
### ++wear
++ wear :: activate secret key
|= a=ring
^- acru
=+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
?> =('b' mag)
(nol:nu:crub bod)
::
XX document
### ++trub
++ trub :: test ed
|= msg=@tas
^- @
=+ ali=(brew 1.024 (shax 'ali'))
=+ bob=(brew 1.024 (shax 'bob'))
=+ tef=(sign:as.ali [0 msg])
=+ lov=(sure:as.ali [0 tef])
?. &(?=(^ lov) =(msg u.lov))
~|(%test-fail-sign !!)
=+ key=(shax (shax (shax msg)))
=+ sax=(seal:as.ali pub:ex.bob key msg)
=+ tin=(tear:as.bob pub:ex.ali sax)
?. &(?=(^ tin) =(key p.u.tin) =(msg q.u.tin))
~|(%test-fail-seal !!)
msg
::
XX document
### ++hmac
++ hmac :: HMAC-SHA1
|= [key=@ mes=@]
=+ ip=(fil 3 64 0x36)
=+ op=(fil 3 64 0x5c)
=+ ^= kex
?: (gth (met 3 key) 64)
(lsh 3 44 (shan (swap 3 key)))
(lsh 3 (sub 64 (met 3 key)) (swap 3 key))
=+ inn=(shan (swap 3 (cat 3 (swap 3 mes) (mix ip kex))))
(shan (swap 3 (cat 3 inn (mix op kex))))
::
XX document

View File

@ -0,0 +1,380 @@
section 3bC, Gregorian UTC
==========================
### ++dawn
Weekday of Jan 1
++ dawn :: weekday of jan 1
|= yer=@ud
=+ yet=(sub yer 1)
%- mod :_ 7
:(add 1 (mul 5 (mod yet 4)) (mul 4 (mod yet 100)) (mul 6 (mod yet 400)))
::
Computes which day of the week January 1st falls on for a year `yer`,
producing an atom. Weeks are zero-indexed beginning on Sunday.
`yer` is an unsigned decimal, [`@ud`]().
~zod/try=> (dawn 2.015)
4
~zod/try=> (dawn 1)
1
~zod/try=> (dawn 0)
! subtract-underflow
! exit
------------------------------------------------------------------------
### ++daws
Weekday of date
++ daws :: weekday of date
|= yed=date
%- mod :_ 7
(add (dawn y.yed) (sub (yawn [y.yed m.yed d.t.yed]) (yawn y.yed 1 1)))
::
Produces the day of the week of a given date `yed` as an atom. Weeks are
zero-indexed beginning on Sunday.
`yed` is a [`date`]().
~zod/try=> (daws [[a=%.y y=2.014] m=6 t=[d=6 h=21 m=9 s=15 f=~[0xa16]]])
5
~zod/try=> (daws (yore -<-))
2
(second example always returns the current date).
------------------------------------------------------------------------
### ++deal
Add leap seconds
++ deal :: to leap sec time
|= yer=@da
=+ n=0
=+ yud=(yore yer)
|- ^- date
?: (gte yer (add (snag n lef:yu) ~s1))
(yore (year yud(s.t (add n s.t.yud))))
?: &((gte yer (snag n lef:yu)) (lth yer (add (snag n lef:yu) ~s1)))
yud(s.t (add +(n) s.t.yud))
?: =(+(n) (lent lef:yu))
(yore (year yud(s.t (add +(n) s.t.yud))))
$(n +(n))
::
Produces a [`date`]() with the 25 leap seconds added.
`yer` is an absolute date, [`@da`]().
~zod/try=> (yore (bex 127))
[[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=8 f=~]]
~zod/try=> (deal `@da`(bex 127))
[[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=33 f=~]]
~zod/try=> (yore (bex 126))
[[a=%.n y=146.138.512.088] m=6 t=[d=19 h=7 m=45 s=4 f=~]]
------------------------------------------------------------------------
### ++lead
Subtract leap seconds
++ lead :: from leap sec time
|= ley=date
=+ ler=(year ley)
=+ n=0
|- ^- @da
=+ led=(sub ler (mul n ~s1))
?: (gte ler (add (snag n les:yu) ~s1))
led
?: &((gte ler (snag n les:yu)) (lth ler (add (snag n les:yu) ~s1)))
?: =(s.t.ley 60)
(sub led ~s1)
led
?: =(+(n) (lent les:yu))
(sub led ~s1)
$(n +(n))
::
Produces an absolute date ([`@ud`]()) with the 25 leap seconds
subtracted.
`ley` is a [`date`]().
~zod/try=> (yore `@da`(bex 127))
[[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=8 f=~]]
~zod/try=> (lead (yore `@da`(bex 127)))
~226.12.5..15.29.43
~zod/try=> (lead (yore `@da`(bex 126)))
~146138512088-.6.19..07.44.39
------------------------------------------------------------------------
### ++dust
Print UTC format
++ dust :: print UTC format
|= yed=date
^- tape
=+ wey=(daws yed)
;: weld
`tape`(snag wey (turn wik:yu |=(a=tape (scag 3 a))))
", " ~(rud at d.t.yed) " "
`tape`(snag (dec m.yed) (turn mon:yu |=(a=tape (scag 3 a))))
" " (scag 1 ~(rud at y.yed)) (slag 2 ~(rud at y.yed)) " "
~(rud at h.t.yed) ":" ~(rud at m.t.yed) ":" ~(rud at s.t.yed)
" " "+0000"
==
::
Produces a [tape]() of the date in UTC format.
`yed` is a [`date`]().
~zod/try=> (dust (yore -<-))
"Tue, 21 Oct 2014 21:35:12 +0000"
~zod/try=> (dust [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]])
"Fri, 11 Oct 2002 12:20:55 +0000"
------------------------------------------------------------------------
### ++stud
Parse UTC format
++ stud :: parse UTC format
|= cud=tape
^- (unit date)
=- ?~ tud ~
`[[%.y &3.u.tud] &2.u.tud &1.u.tud &4.u.tud &5.u.tud &6.u.tud ~]
^= tud
%+ rust cud
;~ plug
;~(pfix (stun [5 5] next) dim:ag)
::
%+ cook
|= a=tape
=+ b=0
|- ^- @
?: =(a (snag b (turn mon:yu |=(a=tape (scag 3 a)))))
+(b)
$(b +(b))
(ifix [ace ace] (star alf))
::
;~(sfix dim:ag ace)
;~(sfix dim:ag col)
;~(sfix dim:ag col)
dim:ag
(cold ~ (star next))
==
::
Accepts a [tape]() containing a date in UTC format and produces the
[unit]() of a [`date`]().
~zod/try=> (stud "Tue, 21 Oct 2014 21:21:55 +0000")
[~ [[a=%.y y=2.014] m=10 t=[d=21 h=21 m=21 s=55 f=~]]]
~zod/try=> (stud "Wed, 11 Oct 2002 12:20:55 +0000")
[~ [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]]]
~zod/try=> (stud "Wed, 11 Oct 2002")
~
------------------------------------------------------------------------
### ++unt
UGT to UTC time
++ unt :: UGT to UTC time
|= a=@da
(div (sub a ~1970.1.1) (bex 64))
::
~zod/try=/hom> (unt -<-)
1.413.927.704
~zod/try=> (unt ~20014.1.1)
569.413.670.400
~zod/try=> (unt ~2014.1.1)
1.388.534.400
Transforms Urbit Galactic Time to UTC time, producing an atom.
`a` is an [atom]().
------------------------------------------------------------------------
### ++yu
UTC format constants
++ yu :: UTC format constants
|%
~zod/try=/hom> yu
<4.pgn 250.tmw 41.cmo 414.rvm 101.jzo 1.ypj %164>
------------------------------------------------------------------------
### ++mon
Months
++ mon ^- (list tape)
:~ "January" "February" "March" "April" "May" "June" "July"
"August" "September" "October" "November" "December"
==
::
Produces a list of [tapes]() containing the 12 months of the year.
~zod/try=/hom> mon:yu
<<
"January"
"February"
"March"
"April"
"May"
"June"
"July"
"August"
"September"
"October"
"November"
"December"
>>
~zod/try=/hom> (snag 1 mon:yu)
"February"
------------------------------------------------------------------------
### ++wik
Weeks
++ wik ^- (list tape)
:~ "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday"
"Friday" "Saturday"
==
::
Produces a list of [tapes]() containing the 7 days of the week,
beginning with Sunday.
~zod/try=/hom> wik:yu
<<"Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday">>
~zod/try=/hom> (snag 2 wik:yu)
"Tuesday"
~zod/try=/hom> (snag (daws (yore -<-)) wik:yu)
"Tuesday"
------------------------------------------------------------------------
### ++les
Leap second dates
++ les ^- (list ,@da)
:~ ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1 ~1996.1.1
~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1 ~1988.1.1
~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1 ~1979.1.1
~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1 ~1973.1.1
~1972.7.1
==
Produces a list of the (absolute) dates ([`@da`]) of the 25 leap seconds
~zod/try=/hom> les:yu
~[
~2012.7.1
~2009.1.1
~2006.1.1
~1999.1.1
~1997.7.1
~1996.1.1
~1994.7.1
~1993.7.1
~1992.7.1
~1991.1.1
~1990.1.1
~1988.1.1
~1985.7.1
~1983.7.1
~1982.7.1
~1981.7.1
~1980.1.1
~1979.1.1
~1978.1.1
~1977.1.1
~1976.1.1
~1975.1.1
~1974.1.1
~1973.1.1
~1972.7.1
]
~zod/try=/hom> (snag 2 les:yu)
~2006.1.1
------------------------------------------------------------------------
### ++lef
Back-shifted leap second dates
++ lef ^- (list ,@da)
:~ ~2012.6.30..23.59.59 ~2008.12.31..23.59.58
~2005.12.31..23.59.57 ~1998.12.31..23.59.56
~1997.6.30..23.59.55 ~1995.12.31..23.59.54
~1994.6.30..23.59.53 ~1993.6.30..23.59.52
~1992.6.30..23.59.51 ~1990.12.31..23.59.50
~1989.12.31..23.59.49 ~1987.12.31..23.59.48
~1985.6.30..23.59.47 ~1983.6.30..23.59.46
~1982.6.30..23.59.45 ~1981.6.30..23.59.44
~1979.12.31..23.59.43 ~1978.12.31..23.59.42
~1977.12.31..23.59.41 ~1976.12.31..23.59.40
~1975.12.31..23.59.39 ~1974.12.31..23.59.38
~1973.12.31..23.59.37 ~1972.12.31..23.59.36
~1972.6.30..23.59.35
==
::
Produces a list of absolute dates ([`@da`]()) that represent the Urbit
Galactc Time equivalents of the UTC leap second dates in [`++les`]().
~zod/try=/hom> lef:yu
~[
~2012.6.30..23.59.59
~2008.12.31..23.59.58
~2005.12.31..23.59.57
~1998.12.31..23.59.56
~1997.6.30..23.59.55
~1995.12.31..23.59.54
~1994.6.30..23.59.53
~1993.6.30..23.59.52
~1992.6.30..23.59.51
~1990.12.31..23.59.50
~1989.12.31..23.59.49
~1987.12.31..23.59.48
~1985.6.30..23.59.47
~1983.6.30..23.59.46
~1982.6.30..23.59.45
~1981.6.30..23.59.44
~1979.12.31..23.59.43
~1978.12.31..23.59.42
~1977.12.31..23.59.41
~1976.12.31..23.59.40
~1975.12.31..23.59.39
~1974.12.31..23.59.38
~1973.12.31..23.59.37
~1972.12.31..23.59.36
~1972.6.30..23.59.35
]
~zod/try=/hom> (snag 2 lef:yu)
~2005.12.31..23.59.57

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,267 @@
section 3bF, filesystem interface
=================================
### ++feel
Generate file diff
++ feel :: simple file write
|= [pax=path val=*]
^- miso
=+ dir=((hard arch) .^(%cy pax))
?~ q.dir [%ins val]
:- %mut
^- udon
[%a %a .^(%cx pax) val]
::
Generates a diff between a file located at `pax` and an input value
`val`.
`pax` is a [`++path`]().
`val` is a value as a [noun]().
~zod/try=> + %/mel 'test'
+ /~zod/try/2/mel
~zod/try=> (feel %/mel 'tesh?')
[%mut p=[p=%a q=[%a p=44.903.392.628 q=272.335.332.724]]]
~zod/try=> `@t`44.903.392.628
'''
test
'''
~zod/try=> `@t`272.335.332.724
'tesh?'
### ++file
Simple file load
++ file :: simple file load
|= pax=path
^- (unit)
=+ dir=((hard arch) .^(%cy pax))
?~(q.dir ~ [~ .^(%cx pax)])
::
Reads the value of a file located at `pax` and renders it as a
[`++unit`]().
`pax` is a [`++path`]().
~zod/try=> %/zak
~zod/try=/zak> :ls %
~zod/try=/zak> + %/mop 20
+ /~zod/try/3/zak/mop
~zod/try=/zak> :ls %
mop
~zod/try=/zak> (file %/mop)
[~ 20]
~zod/try=/zak> (file %/lak)
~
~zod/try=/zak> (file /==2%/mop)
~
### ++foal
Write high-level change
++ foal :: high-level write
|= [pax=path val=*]
^- toro
?> ?=([* * * *] pax)
[i.t.pax [%& [*cart [[t.t.t.pax (feel pax val)] ~]]]]
::
Produces a [`++toro`](), a change intended for whatever file is located
at `pax`. Handled by `%clay`.
`pax` is a [`++path`]().
`val` is a value as a [noun]().
~zod/try=> + %/mek 'a'
+ /~zod/try/4/mek
~zod/try=> (foal %/mek 'b')
[ p=~.try
q
[%.y q=[p=[p=0v0 q=0v0] q=~[[p=/mek q=[%mut p=[p=%a q=[%a p=97 q=98]]]]]]]
]
~zod/try=> (feel %/mek 'b')
[%mut p=[p=%a q=[%a p=97 q=98]]]
### ++fray
High-level delete
++ fray :: high-level delete
|= pax=path
^- toro
?> ?=([* * * *] pax)
[i.t.pax [%& [*cart [[t.t.t.pax [%del .^(%cx pax)]] ~]]]]
::
Produces a deletion [`++toro`]() for a file located at path `pax`.
Handled by `%clay`.
`pax` is a [`++path`]().
~zod/try=> + %/mek 'a'
+ /~zod/try/4/mek
~zod/try=> (fray %/mek)
[p=~.try q=[%.y q=[p=[p=0v0 q=0v0] q=~[[p=/mek q=[%del p=97]]]]]]
~zod/try=> `@t`97
'a'
### ++furl
Unify changes
++ furl :: unify changes
|= [one=toro two=toro]
^- toro
~| %furl
?> ?& =(p.one p.two) :: same path
&(?=(& -.q.one) ?=(& -.q.two)) :: both deltas
==
[p.one [%& [*cart (weld q.q.q.one q.q.q.two)]]]
::
Merge two [`++toro`]()s `one` and `two` that are in the same [`desk`]()
and pointed at the same [`++path`]().
`one` is a [`++toro`]().
`two` is a [`++toro`]().
~zod/try=> %/zak
~zod/try=/zak> :ls %
mop
~zod/try=/zak> (furl (fray %/mop) (foal %/mok 'hi'))
[ p=~.try
q
[ %.y
q
[ p=[p=0v0 q=0v0]
q=~[[p=/zak/mop q=[%del p=20]] [p=/zak/mok q=[%ins p=26.984]]]
]
]
]
### ++meat
Kite to .\^ path
++ meat :: kite to .^ path
|= kit=kite
^- path
[(cat 3 'c' p.kit) (scot %p r.kit) s.kit (scot `dime`q.kit) t.kit]
::
Converts a type request name to a [`++path`]().
`kit` is a [`++kite`]().
zod/try=/zop> `kite`[%x ud/1 ~zod %main /sur/down/gate/hook]
[p=%x q=[%ud p=1] r=~zod s=%main t=/sur/down/gate/hook]
~zod/try=/zop> (meat [%x ud/1 ~zod %main /sur/down/gate/hook])
/cx/~zod/main/1/sur/down/gate/hook
~zod/try=/zop> .^((meat [%x ud/1 ~zod %main /sur/down/gate/hook]))
8.024.240.839.827.090.233.853.057.929.619.452.695.436.878.709.611.140.677.
745.908.646.440.925.885.935.296.374.867.974.972.908.054.571.544.099.882.490.
677.391.983.737.511.220.072.391.888.081.664.570
~zod/try=/zop> (,@t .^((meat [%x ud/1 ~zod %main /sur/down/gate/hook])))
'''
::
:::: /hoon/gate/down/sur
::
/? 314
/- *markdown
down
'''
### ++tame
Parse kite path
++ tame :: parse kite path
|= hap=path
^- (unit kite)
?. ?=([@ @ @ @ *] hap) ~
=+ :* hyr=(slay i.hap)
fal=(slay i.t.hap)
dyc=(slay i.t.t.hap)
ved=(slay i.t.t.t.hap)
:: ved=(slay i.t.hap)
:: fal=(slay i.t.t.hap)
:: dyc=(slay i.t.t.t.hap)
tyl=t.t.t.t.hap
==
?. ?=([~ %$ %tas @] hyr) ~
?. ?=([~ %$ %p @] fal) ~
?. ?=([~ %$ %tas @] dyc) ~
?. ?=([~ %$ case] ved) ~
=+ his=`@p`q.p.u.fal
=+ [dis=(end 3 1 q.p.u.hyr) rem=(rsh 3 1 q.p.u.hyr)]
?. ?&(?=(%c dis) ?=(?(%v %w %x %y %z) rem)) ~
[~ rem p.u.ved q.p.u.fal q.p.u.dyc tyl]
::
Parses a clay [.\^]()
[`++path]()to request details. Produces the [`++unit`]() of a [`++kite\`]().
`hap` is a [`++path`]().
~zod/try=/zop> (tame /cx/~zod/main/1/sur/down/gate/hook)
[~ [p=%x q=[%ud p=1] r=~zod s=%main t=/sur/down/gate/hook]]
~zod/try=/zop> (tame /cx/0/main/1/sur/down/gate/hook)
~
~zod/try=/zop> (tame /~zod/main/0x12/sur/down/gate/hook)
~
### ++tome
Parse path to beam
++ tome :: parse path to beam
|= pax=path
^- (unit beam)
?. ?=([* * * *] pax) ~
%+ biff (slaw %p i.pax)
|= who=ship
%+ biff (slaw %tas i.t.pax)
|= dex=desk
%+ biff (slay i.t.t.pax)
|= cis=coin
?. ?=([%$ case] cis) ~
`(unit beam)`[~ [who dex `case`p.cis] (flop t.t.t.pax)]
::
Parses a [`++path`]() `pax` to a [\`++beam](), a well-typed location.
~zod/try=/zop> (tome /~fyr/try/2/for/me)
[~ [[p=~fyr q=%try r=[%ud p=2]] s=/me/for]]
~zod/try=/zop> (tome /~zod/main/1)
[~ [[p=~zod q=%main r=[%ud p=1]] s=/]]
~zod/try=/zop> (tome /0/main/1)
~
~zod/try=/zop> (tome /~zod/main/0x12)
~
### ++tope :: beam to path
Parse beam to path
|= bem=beam
^- path
[(scot %p p.bem) q.bem (scot r.bem) (flop s.bem)]
Parses a [`++beam`]() to a [`++path`]().
~zod/try=/zop> (tope [~zod %main ud/1] /hook/down/sur)
/~zod/main/1/sur/down/hook
~zod/try=/zop> (tope [~fyr %try da/~2015.1.1] /txt/test)
/~fyr/try/~2015.1.1/test/txt
~zod/try=/zop> (tope [~doznec %try da/-<-] /txt/test)
/~doznec/try/~2014.10.30..00.32.48..3ae4/test/txt

View File

@ -0,0 +1,943 @@
section 3bG, URL handling
=========================
### ++deft
Import URL path
++ deft :: import url path
|= rax=(list ,@t)
|- ^- pork
?~ rax
[~ ~]
?~ t.rax
=+ den=(trip i.rax)
=+ ^= vex
%- %- full
;~(plug sym ;~(pose (stag ~ ;~(pfix dot sym)) (easy ~)))
[[1 1] (trip i.rax)]
?~ q.vex
[~ [i.rax ~]]
[+.p.u.q.vex [-.p.u.q.vex ~]]
=+ pok=$(rax t.rax)
:- p.pok
[i.rax q.pok]
::
Parse the extension the from last element of url, which is delimited
either by a `.` or a `/`.
`rax` is a [`++list`]() of [`@t`]().
~zod/try=> (deft /foo/bar/'baz.txt')
[p=[~ ~.txt] q=<|foo bar baz|>]
~zod/try=> (deft /foo/bar/baz)
[p=~ q=<|foo bar baz|>]
### ++fain
Restructure path
++ fain :: path restructure
|= [hom=path raw=path]
=+ bem=(need (tome raw))
=+ [mer=(flop s.bem) moh=(flop hom)]
|- ^- (pair beam path)
?~ moh
[bem(s hom) (flop mer)]
?> &(?=(^ mer) =(i.mer i.moh))
$(mer t.mer, moh t.moh)
::
Splits a concrete
[`++spur]() out of a full`++path`, producing a location [`++beam`]() and a remainder [`++path\`]().
`hom` is a [`++path`]()
~zod/try=> (fain / %)
[p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.07.17..c835]] s=/] q=/]
~zod/try=> (fain /lok %)
! exit
~zod/try=> (fain / %/mer/lok/tem)
[ p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.08.03..bfdf]] s=/]
q=/tem/lok/mer
]
~zod/try=> (fain /mer %/mer/lok/tem)
[p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.08.15..4da0]] s=/mer] q=/tem/lok]
~zod/try=> (fain /lok/mer %/mer/lok/tem)
[p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.08.24..4d9e]] s=/lok/mer] q=/tem]
~zod/try=> (fain /lok/mer %/mer)
! exit
~zod/try=> (fain /hook/hymn/tor %/tor/hymn/hook/'._req_1234__')
[ p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.09.25..c321]] s=/hook/hymn/tor]
q=/._req_1234__
]
### ++fuel
Parse fcgi
++ fuel :: parse fcgi
|= [bem=beam but=path]
^- epic
?> ?=([%web @ *] but)
=+ dyb=(slay i.t.but)
?> ?& ?=([~ %many *] dyb)
?=([* * *] p.u.dyb)
:: ?=([%$ %tas *] i.p.u.dyb)
?=([%many *] i.p.u.dyb)
?=([%blob *] i.t.p.u.dyb)
==
=+ ced=((hard cred) p.i.t.p.u.dyb)
:: =+ nep=q.p.i.p.u.dyb
=+ ^= nyp ^- path
%+ turn p.i.p.u.dyb
|= a=coin ^- @ta
?> ?=([%$ %ta @] a)
?>(((sane %ta) q.p.a) q.p.a)
=+ ^= gut ^- (list ,@t)
%+ turn t.t.p.u.dyb
|= a=coin ^- @t
?> ?=([%$ %t @] a)
?>(((sane %t) q.p.a) q.p.a)
=+ ^= quy
|- ^- (list ,[p=@t q=@t])
?~ gut ~
?> ?=(^ t.gut)
[[i.gut i.t.gut] $(gut t.t.gut)]
:* (~(gas by *(map cord cord)) quy)
ced
bem
t.t.but
nyp
==
::
Retrieieves the %eyre FCGI, producing a [`++epic`](). Used primarily in
[`/hook`]() files. See the [`%eyre`]() doc for more detail.
`bem` is a [`++beam`]().
`but` is a [`++path`]().
~zod/main=> (fuel [[p=~zod q=%try r=[%ud p=2]] s=/psal] /web/'._.~-~~~~.gen~-~-_~~05vg0001v09f0n30fbh7dn6ab2jakmmspdq04nef5h70qbd5lh6atr4c5j2qrbldpp62q1df1in0sr1ding0c3qgt7kclj74qb65lm6atrkc5k2qpr5e1mmispdchin4p3fegmiqrjpdlo62p1dchsn4p39comn8pbcehgmsbbef5p7crrifr3o035dhgfrk2b5__')
[ qix={}
ced
[ hut=[p=%.y q=[~ 8.445] r=[%.n p=.0.0.0.0]]
aut={[p=%$ q={'~rovryn-natlet-fidryd-dapmyn--todred-simpeg-hatwel-firfet'}]}
orx='laspex-harnum-fadweb-mipbyn'
acl=[~ 'en-US,en;q=0.8']
cip=[%.y p=.127.0.0.1]
cum={}
]
bem=[[p=~zod q=%try r=[%ud p=2]] s=/psal]
but=/
nyp=/gen
]
### ++sifo
64-bit encode
++ sifo :: 64-bit encode
|= tig=@
^- tape
=+ poc=(~(dif fo 3) 0 (met 3 tig))
=+ pad=(lsh 3 poc (swap 3 tig))
=+ ^= cha
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
=+ ^= sif
|- ^- tape
?~ pad
~
=+ d=(end 0 6 pad)
[(cut 3 [d 1] cha) $(pad (rsh 0 6 pad))]
(weld (flop (slag poc sif)) (trip (fil 3 poc '=')))
::
Encodes an atom to MIME base64, producing a [`++tape`]().
~zod/main=> (sifo 'foobar')
"Zm9vYmFy"
~zod/main=> (sifo 1)
"Q=="
~zod/main=> (sifo (shax %hi))
"j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ="
### ++urle
Encode URL
++ urle :: URL encode
|= tep=tape
^- tape
%- zing
%+ turn tep
|= tap=char
=+ xen=|=(tig=@ ?:((gte tig 10) (add tig 55) (add tig '0')))
?: ?| &((gte tap 'a') (lte tap 'z'))
&((gte tap 'A') (lte tap 'Z'))
&((gte tap '0') (lte tap '9'))
=('.' tap)
=('-' tap)
=('~' tap)
=('_' tap)
==
[tap ~]
['%' (xen (rsh 0 4 tap)) (xen (end 0 4 tap)) ~]
::
The inverse of [`++urld`](). Accepts a tape `tep` and replaces all
characters other than alphanumerics and `.`, `-`, `~`, and `_`, with URL
escape sequences.
~zod/main=> (urle "hello")
"hello"
~zod/main=> (urle "hello dear")
"hello%20dear"
~zod/main=> (urle "hello-my?=me !")
"hello-my%3F%3Dme%20%20%21"
### ++urld
Decode URL
++ urld :: URL decode
|= tep=tape
^- (unit tape)
?~ tep [~ ~]
?: =('%' i.tep)
?. ?=([@ @ *] t.tep) ~
=+ nag=(mix i.t.tep (lsh 3 1 i.t.t.tep))
=+ val=(rush nag hex:ag)
?~ val ~
=+ nex=$(tep t.t.t.tep)
?~(nex ~ [~ [`@`u.val u.nex]])
=+ nex=$(tep t.tep)
?~(nex ~ [~ i.tep u.nex])
::
The inverse of [`++urle`](). Parses a URL escaped tape to the
[`++unit`]() of an unescaped `++tape`.
`tep` is a [`++tape`]().
~zod/main=> (urld "hello")
[~ "hello"]
~zod/main=> (urld "hello%20dear")
[~ "hello dear"]
~zod/main=> (urld "hello-my%3F%3Dme%20%20%21")
[~ "hello-my?=me !"]
~zod/main=> (urld "hello-my%3F%3Dme%20%2%21")
~
### ++earl
Localize purl
++ earl :: localize purl
|= [who=@p pul=purl]
^- purl
pul(q.q [(rsh 3 1 (scot %p who)) q.q.pul])
::
Prepends a ship name to the spur of a [`++purl`]().
`who` is a [`@p`](), a ship name.
`pul` is a [`++purl`]().
~zod/main=> (need (epur 'http://123.1.1.1/me.ham'))
[p=[p=%.n q=~ r=[%.n p=.123.1.1.1]] q=[p=[~ ~.ham] q=<|me|>] r=~]
~zod/main=> (earl ~zod (need (epur 'http://123.1.1.1/me.ham')))
[p=[p=%.n q=~ r=[%.n p=.123.1.1.1]] q=[p=[~ ~.ham] q=<|zod me|>] r=~]
~zod/main=> (earl ~pittyp (need (epur 'http://123.1.1.1/me.ham')))
[p=[p=%.n q=~ r=[%.n p=.123.1.1.1]] q=[p=[~ ~.ham] q=<|pittyp me|>] r=~]
~zod/main=> (earn (earl ~pittyp (need (epur 'http://123.1.1.1/me.ham'))))
"http://123.1.1.1/pittyp/me"
### ++earn
Purl to tape
++ earn :: purl to tape
|^ |= pul=purl
^- tape
:(weld (head p.pul) "/" (body q.pul) (tail r.pul))
::
Parses a `++purl` `pul` to a [`++tape`]().
`pul` is a [`++purl`]().
~zod/main=> (earn [| ~ [%| .127.0.0.1]] [~ ~] ~)
"http://127.0.0.1/"
~zod/main=> (earn [| ~ `/com/google/www] [~ ~] ~)
"http://www.google.com/"
~zod/main=> (earn [& ~ `/com/google/www] [~ ~] ~)
"https://www.google.com/"
~zod/main=> (earn [& `200 `/com/google/www] [~ ~] ~)
"https://www.google.com:200/"
~zod/main=> (earn [& `200 `/com/google/www] [~ /search] ~)
"https://www.google.com:200/search"
~zod/main=> (earn [& ~ `/com/google/www] [`%html /search] ~)
"https://www.google.com/search"
~zod/main=> (earn [& ~ `/com/google/www] [~ /search] [%q 'urbit'] ~)
"https://www.google.com/search?q=urbit"
~zod/main=> (earn [& ~ `/com/google/www] [~ /search] [%q 'urbit escaping?'] ~)
"https://www.google.com/search?q=urbit%20escaping%3F"
### ++body
Render URL path
++ body
|= pok=pork ^- tape
?~ q.pok ~
|-
=+ seg=(trip i.q.pok)
?~ t.q.pok
?~(p.pok seg (welp seg '.' (trip u.p.pok)))
(welp seg '/' $(q.pok t.q.pok))
::
Renders URL path `pok` as a [`++tape`]().
~zod/main=> (body:earn ~ /foo/mol/lok)
"foo/mol/lok"
~zod/main=> (body:earn `%htm /foo/mol/lok)
"foo/mol/lok.htm"
~zod/main=> (body:earn `%htm /)
""
### ++head
Render URL beginning
++ head
|= har=hart
^- tape
;: weld
?:(&(p.har !=([& /localhost] r.har)) "https://" "http://")
::
?- -.r.har
| (trip (rsh 3 1 (scot %if p.r.har)))
& =+ rit=(flop p.r.har)
|- ^- tape
?~(rit ~ (weld (trip i.rit) ?~(t.rit "" `tape`['.' $(rit t.rit)])))
==
::
?~(q.har ~ `tape`[':' (trip (rsh 3 2 (scot %ui u.q.har)))])
==
::
Renders a `++hart`, usually the beginning of a URL, as the [`++tape`]()
of a traditional URL.
~zod/main=> (head:earn | ~ %| .127.0.0.1)
"http://127.0.0.1"
~zod/main=> (head:earn & ~ %| .127.0.0.1)
"https://127.0.0.1"
~zod/main=> (head:earn & [~ 8.080] %| .127.0.0.1)
"https://127.0.0.1:8080"
~zod/main=> (head:earn & [~ 8.080] %& /com/google/www)
"https://www.google.com:8080"
### ++tail
Render query string
++ tail
|= kay=quay
^- tape
?: =(~ kay) ~
:- '?'
|- ^- tape
?~ kay ~
;: weld
(urle (trip p.i.kay))
"="
(urle (trip q.i.kay))
?~(t.kay ~ `tape`['&' $(kay t.kay)])
==
--
::
Renders a `quay`, a query string in hoon, to the [`++tape`]() of a
traditional query string.
`kay` is a [`++quay`]().
~zod/main=> (tail:earn ~)
""
~zod/main=> (tail:earn [%ask 'bid'] ~)
"?ask=bid"
~zod/main=> (tail:earn [%ask 'bid'] [%make 'well'] ~)
"?ask=bid&make=well"
### ++epur
Top-level URL parser
++ epur :: url/header parser
=< |=(a=cord (rush a auri))
|%
Toplevel URL parser.
`a` is a [`++cord`]().
~zod/main=> (epur 'http://127.0.0.1/')
[~ [p=[p=%.n q=~ r=[%.n p=.127.0.0.1]] q=[p=~ q=<||>] r=~]]
~zod/main=> (epur 'http://www.google.com/')
[~ [p=[p=%.n q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]]
~zod/main=> (epur 'https://www.google.com/')
[~ [p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]]
~zod/main=> (epur 'https//www.google.com/')
~
~zod/main=> (epur 'https://www.google.com:200/')
[~ [p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]]
~zod/main=> (epur 'https://www.google.com:200/search')
[ ~
[p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~]
]
~zod/main=> (epur 'https://www.google.com/search')
[~ [p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~]]
~zod/main=> (epur 'https://www.google.com/search?q=urbit')
[ ~
[ p=[p=%.y q=~ r=[%.y p=<|com google www|>]]
q=[p=~ q=<|search|>]
r=~[[p='q' q='urbit']]
]
]
~zod/main=> (epur 'https://www.google.com/search?q=urb it')
~
~zod/main=> (epur 'https://www.google.com/search?q=urb%20it')
[ ~
[ p=[p=%.y q=~ r=[%.y p=<|com google www|>]]
q=[p=~ q=<|search|>]
r=~[[p='q' q='urb it']]
]
]
~zod/main=> (epur 'https://www.google.com/search?q=urbit%20escaping%3F')
[ ~
[ p=[p=%.y q=~ r=[%.y p=<|com google www|>]]
q=[p=~ q=<|search|>]
r=~[[p='q' q='urbit escaping?']]
]
]
### ++apat
++ apat :: 2396 abs_path
%+ cook deft
(ifix [fas ;~(pose fas (easy ~))] (more fas smeg))
URL path as ++pork
~zod/try=> (scan "/foo/mol/lok" apat:epur)
[p=~ q=<|foo mol lok|>]
~zod/try=> (scan "/foo/mol/lok.htm" apat:epur)
[p=[~ ~.htm] q=<|foo mol lok|>]
### ++auri
++ auri
%+ cook
|= a=purl
?.(=([& /localhost] r.p.a) a a(p.p &))
;~ plug
;~ plug
%+ sear
|= a=@t
^- (unit ,?)
?+(a ~ %http [~ %|], %https [~ %&])
;~(sfix scem ;~(plug col fas fas))
thor
==
;~(plug ;~(pose apat (easy *pork)) yque)
==
URL parsing rule
~zod/main=> (auri:epur [1 1] "http://127.0.0.1/")
[ p=[p=1 q=18]
q
[ ~
u
[ p=[p=[p=%.n q=~ r=[%.n p=.127.0.0.1]] q=[p=~ q=<||>] r=~]
q=[p=[p=1 q=18] q=""]
]
]
]
~zod/main=> (auri:epur [1 1] "http://www.google.com/")
[ p=[p=1 q=23]
q
[ ~
u
[ p=[p=[p=%.n q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]
q=[p=[p=1 q=23] q=""]
]
]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com/")
[ p=[p=1 q=24]
q
[ ~
u
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]
q=[p=[p=1 q=24] q=""]
]
]
]
~zod/main=> (auri:epur [1 1] "https//www.google.com/")
[ p=[p=1 q=6] q=~]
~zod/main=> (auri:epur [1 1] "https://www.google.com:200/")
[ p=[p=1 q=28]
q=[~ u=[p=[p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~] q=[p=[p=1 q=28] q=""]]]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com:200/search")
[ p=[p=1 q=34]
q=[~ u=[p=[p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~] q=[p=[p=1 q=34] q=""]]]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com/search")
[ p=[p=1 q=30]
q=[~ u=[p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~] q=[p=[p=1 q=30] q=""]]]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urbit")
[ p=[p=1 q=38]
q
[ ~
u
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urbit']]]
q=[p=[p=1 q=38] q=""]
]
]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urb it")
[ p=[p=1 q=36]
q
[ ~
u
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urb']]]
q=[p=[p=1 q=36] q=" it"]
]
]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urb%20it")
[ p=[p=1 q=41]
q
[ ~
u
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urb it']]]
q=[p=[p=1 q=41] q=""]
]
]
]
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urbit%20escaping%3F")
[ p=[p=1 q=52]
q
[ ~
u
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urbit escaping?']]]
q=[p=[p=1 q=52] q=""]
]
]
]
### ++cock
++ cock :: cookie
(most ;~(plug sem ace) ;~(plug toke ;~(pfix tis tosk)))
HTTP cookies, results in associative list of cord to cord.
~zod/try=> (scan "sam=lop" cock:epur)
[['sam' 'lop'] ~]
~zod/try=> (scan "sam=lop; res=\"salo don -keg!mo\"" cock:epur)
[['sam' 'lop'] ~[['res' 'salo don -keg!mo']]]
~zod/try=> (scan "sam=lop; res=\"salo don -keg!mo\"; so" cock:epur)
! {1 34}
! exit
### ++dlab
++ dlab :: 2396 domainlabel
%+ sear
|= a=@ta
?.(=('-' (rsh 3 (dec (met 3 a)) a)) [~ u=a] ~)
%+ cook cass
;~(plug aln (star alp))
::
Domain label: alphanumeric, with `-` allowed in middle.
~zod/try=> (scan "google" dlab:epur)
~.google
~zod/try=> (scan "lera2" dlab:epur)
~.lera2
~zod/try=> (scan "gor-tem" dlab:epur)
~.gor-tem
~zod/try=> (scan "gortem-" dlab:epur)
! {1 8}
! exit
### ++fque
++ fque (cook crip (plus pquo)) :: normal query field
One or more query string characters
~zod/try=> (scan "%20" fque:epur)
' '
~zod/try=> (scan "sam" fque:epur)
'sam'
~zod/try=> (scan "les+tor" fque:epur)
'les tor'
~zod/try=> (scan "sore-%22mek%22" fque:epur)
'sore-"mek"'
~zod/try=> (scan "" fque:epur)
! {1 1}
! exit
### ++fquu
++ fquu (cook crip (star pquo)) :: optional field
Zero or more query string characters
~zod/try=> (scan "%20" fquu:epur)
' '
~zod/try=> (scan "sam" fquu:epur)
'sam'
~zod/try=> (scan "les+tor" fquu:epur)
'les tor'
~zod/try=> (scan "sore-%22mek%22" fquu:epur)
'sore-"mek"'
~zod/try=> (scan "" fquu:epur)
''
### ++pcar
++ pcar ;~(pose pure pesc psub col pat) :: 2396 path char
Single URL path character: literal, `%` escape, subpath delimiter, `:`
or `@`
~zod/try=> (scan "a" pcar:epur)
~~a
~zod/try=> (scan "ab" pcar:epur)
! {1 2}
! exit
~zod/try=> (scan "-" pcar:epur)
~~-
~zod/try=> (scan "." pcar:epur)
~~~.
~zod/try=> (scan "%20" pcar:epur)
~~.
~zod/try=> (scan "!" pcar:epur)
~~~21.
### ++pcok
++ pcok ;~(less bas sem com doq prn) :: cookie char
Cookie character
~zod/try=> (scan "a" pcok:epur)
~~a
~zod/try=> (scan "ab" pcok:epur)
! {1 2}
! exit
~zod/try=> (scan "!" pcok:epur)
~~~21.
~zod/try=> (scan ";" pcok:epur)
! {1 2}
! exit
### ++pesc
++ pesc ;~(pfix cen mes) :: 2396 escaped
URL `%` escape, by two hex characters.
~zod/try=> `@t`(scan "%22" pesc:epur)
'"'
~zod/try=> `@t`(scan "%20" pesc:epur)
' '
### ++pold
++ pold (cold ' ' (just '+')) :: old space code
Old URL `' '` escape
~zod/try=> `@t`(scan "+" pold:epur)
' '
~zod/try=> `@t`(scan " " pold:epur)
! {1 1}
! exit
### ++pque
++ pque ;~(pose pcar fas wut) :: 3986 query char
Irregular query string character.
~zod/try=> `@t`(scan "a" pque:epur)
'a'
~zod/try=> `@t`(scan "?" pque:epur)
'?'
~zod/try=> `@t`(scan "%20" pque:epur)
' '
~zod/try=> `@t`(scan "+" pque:epur)
'+'
### ++pquo
++ pquo ;~(pose pure pesc pold) :: normal query char
Character in query string key/value
~zod/try=> (scan "a" pquo:epur)
'a'
~zod/try=> (scan "ab" pquo:epur)
! {1 2}
! exit
~zod/try=> (scan "%22" pquo:epur)
'"'
~zod/try=> (scan "%20" pquo:epur)
' '
~zod/try=> (scan "+" pquo:epur)
' '
### ++pure
++ pure ;~(pose aln hep dot cab sig) :: 2396 unreserved
URL-safe character
~zod/try=> (scan "a" pure:epur)
~~a
~zod/try=> (scan "%20" pure:epur)
! {1 1}
! exit
~zod/try=> (scan "." pure:epur)
~~~.
~zod/try=> (scan "-" pure:epur)
~~-
### ++psub
++ psub ;~ pose :: 3986 sub-delims
zap buc pam soq pel per
tar lus com sem tis
==
URL path subdelimeter
~zod/try=> `@t`(scan "+" psub:epur)
'+'
~zod/try=> `@t`(scan "(" psub:epur)
'('
~zod/try=> `@t`(scan "$" psub:epur)
'$'
~zod/try=> `@t`(scan "a" psub:epur)
! {1 1}
! exit
### ++ptok
++ ptok ;~ pose :: 2616 token
aln zap hax buc cen pam soq tar lus
hep dot ket cab tec bar sig
==
Character valid in HTTP token
~zod/try=> `tape`(murn =+(a=' ' |-(`tape`?:(=(0x7f a) ~ [a $(a +(a))]))) (curr rush ptok):epur)
"!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"
~zod/try=> `tape`(skim =+(a=' ' |-(`tape`?:(=(0x7f a) ~ [a $(a +(a))]))) |=(a=char ?=(~ (rush a ptok:epur))))
" "(),/:;<=>?@[\]{}"
### ++scem
++ scem :: 2396 scheme
%+ cook cass
;~(plug alf (star ;~(pose aln lus hep dot)))
::
URI scheme: alphabetic character, followed by any number of
alphanumeric, `+` `-` or `.`
~zod/try=> `@t`(scan "http" scem:epur)
'http'
~zod/try=> `@t`(scan "https" scem:epur)
'https'
~zod/try=> `@t`(scan "chrome-extension" scem:epur)
'chrome-extension'
### ++smeg
++ smeg (cook crip (plus pcar)) :: 2396 segment
URL path segment
~zod/try=> (scan "foo" smeg:epur)
'foo'
~zod/try=> (scan "bar%20baz-bam" smeg:epur)
'bar baz-bam'
### ++tock
++ tock (cook crip (plus pcok)) :: 6265 cookie-value
HTTP cookie value
~zod/try=> (rush 'sam' tock:epur)
[~ 'sam']
~zod/try=> (rush 'las!tore' tock:epur)
[~ 'las!tore']
~zod/try=> (rush '"sop""les"tor' tock:epur)
~
~zod/try=> (rush '"zemug"' tock:epur)
~
### ++tosk
++ tosk ;~(pose tock (ifix [doq doq] tock)) :: 6265 cookie-value
Possibly quoted HTTP cookie value
~zod/try=> (rush 'sam' tosk:epur)
[~ 'sam']
~zod/try=> (rush 'las!tore' tosk:epur)
[~ 'las!tore']
~zod/try=> (rush '"sop""les"tor' tosk:epur)
~
~zod/try=> (rush '"zemug"' tosk:epur)
[~ 'zemug']
### ++toke
++ toke (cook crip (plus ptok)) :: 2616 token
HTTP cookie name
~zod/try=> (rush 'sam' toke:epur)
[~ 'sam']
~zod/try=> (rush 'las!tore' toke:epur)
[~ 'las!tore']
~zod/try=> (rush 'sop""les"tor' toke:epur)
~
~zod/try=> (rush '"zemug"' toke:epur)
~
### ++thor
++ thor :: 2396 host/port
%+ cook |*(a=[* *] [+.a -.a])
;~ plug
thos
;~(pose (stag ~ ;~(pfix col dim:ag)) (easy ~))
==
Parse ++host and unit `@ui` port.
~zod/try=> (scan "localhost" thor:epur)
[~ [%.y i='localhost' t=~]]
~zod/try=> (scan "localhost:8080" thor:epur)
[[~ q=8.080] [%.y i='localhost' t=~]]
~zod/try=> (scan "192.168.0.1:8080" thor:epur)
[[~ q=8.080] [%.n q=3.232.235.521]]
~zod/try=> (scan "www.google.com" thor:epur)
[~ [%.y i='com' t=~['google' 'www']]]
### ++thos
++ thos :: 2396 host, no local
;~ plug
;~ pose
%+ stag %&
%+ sear :: LL parser weak here
|= a=(list ,@t)
=+ b=(flop a)
?> ?=(^ b)
=+ c=(end 3 1 i.b)
?.(&((gte c 'a') (lte c 'z')) ~ [~ u=b])
(most dot dlab)
::
%+ stag %|
=+ tod=(ape:ag ted:ab)
%+ bass 256
;~(plug tod (stun [3 3] ;~(pfix dot tod)))
==
==
URI host: dot-separated segments, or IP address.
~zod/try=> (scan "localhost" thos:epur)
[%.y i='localhost' t=~]
~zod/try=> (scan "192.168.0.1" thos:epur)
[%.n q=3.232.235.521]
~zod/try=> (scan "192.168.0.1:80" thos:epur)
! {1 12}
! exit
~zod/try=> (scan "www.google.com" thos:epur)
[%.y i='com' t=~['google' 'www']]
### ++yque
++ yque :: query ending
;~ pose
;~(pfix wut yquy)
(easy ~)
==
Parses query string, or lack thereof. Result type ++quay
~zod/try=> (scan "?sar=tok" yque:epur)
[['sar' 'tok'] ~]
~zod/try=> (scan "?les=urbit%20sep&met=kam" yque:epur)
[['les' 'urbit sep'] ~[['met' 'kam']]]
~zod/try=> (scan "" yque:epur)
~
### ++yquy
++ yquy :: query
;~ pose :: proper query
%+ more
;~(pose pam sem)
;~(plug fque ;~(pose ;~(pfix tis fquu) (easy '')))
::
%+ cook :: funky query
|=(a=tape [[%$ (crip a)] ~])
(star pque)
==
Parse query string after `?`
~zod/try=> (scan "sar=tok" yquy:epur)
[['sar' 'tok'] ~]
~zod/try=> (scan "les=urbit%20sep&met=kam" yquy:epur)
[['les' 'urbit sep'] ~[['met' 'kam']]]
~zod/try=> (scan "" yquy:epur)
~
### ++zest
++ zest :: 2616 request-uri
;~ pose
(stag %& (cook |=(a=purl a) auri))
(stag %| ;~(plug apat yque))
==
--
Parse ++quri absolute or relative request path
~zod/try=> (scan "http://www.google.com:80/search?q=foo" zest:epur)
[%.y p=[p=%.n q=[~ 80] r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='foo']]]
~zod/try=> (scan "/rel/bat" zest:epur)
[%.n [p=~ q=<|rel bat|>] ~]

View File

@ -0,0 +1,466 @@
section 3bH, names etc
======================
### ++clan
++ clan :: ship to rank
|= who=ship ^- rank
=+ wid=(met 3 who)
?: (lte wid 1) %czar
?: =(2 wid) %king
?: (lte wid 4) %duke
?: (lte wid 8) %earl
?> (lte wid 16) %pawn
::
Ship class
~zod/main=> (clan ~zod)
%czar
~zod/main=> (clan ~tyr)
%czar
~zod/main=> (clan ~doznec)
%king
~zod/main=> (clan ~tasfyn-partyv)
%duke
### ++glam
++ glam
|= zar=@pD ^- tape
%+ snag zar
^- (list tape)
:~ "Tianming" "Pepin the Short" "Haile Selassie" "Alfred the Great"
"Tamerlane" "Pericles" "Talleyrand" "Yongle" "Seleucus"
"Uther Pendragon" "Louis XVI" "Ahmad Shāh Durrānī" "Constantine"
"Wilhelm I" "Akbar" "Louis XIV" "Nobunaga" "Alexander VI"
"Philippe II" "Julius II" "David" "Niall Noígíallach" "Kublai Khan"
"Öz Beg Khan" "Ozymandias" "Ögedei Khan" "Jiang Jieshi" "Darius"
"Shivaji" "Qianlong" "Bolesław I Chrobry" "Tigranes" "Han Wudi"
"Charles X" "Naresuan" "Frederick II" "Simeon" "Kangxi"
"Suleiman the Magnificent" "Pedro II" "Genghis Khan" "Laozi"
"Porfirio Díaz" "Pakal" "Wu Zetian" "Garibaldi" "Matthias Corvinus"
"Leopold II" "Leonidas" "Sitting Bull" "Nebuchadnezzar II"
"Rhodes" "Henry VIII" "Attila" "Catherine II" "Chulalongkorn"
"Uthmān" "Augustus" "Faustin" "Chongde" "Justinian"
"Afonso de Albuquerque" "Antoninus Pius" "Cromwell" "Innocent X"
"Fidel" "Frederick the Great" "Canute" "Vytautas" "Amina"
"Hammurabi" "Suharto" "Victoria" "Hiawatha" "Paul V" "Shaka"
"Lê Thánh Tông" "Ivan Asen II" "Tiridates" "Nefertiti" "Gwangmu"
"Ferdinand & Isabella" "Askia" "Xuande" "Boris Godunov" "Gilgamesh"
"Maximillian I" "Mao" "Charlemagne" "Narai" "Hanno" "Charles I & V"
"Alexander II" "Mansa Musa" "Zoe Porphyrogenita" "Metternich"
"Robert the Bruce" "Pachacutec" "Jefferson" "Solomon" "Nicholas I"
"Barbarossa" "FDR" "Pius X" "Gwanggaeto" "Abbas I" "Julius Caesar"
"Lee Kuan Yew" "Ranavalona I" "Go-Daigo" "Zenobia" "Henry V"
"Bảo Đại" "Casimir III" "Cyrus" "Charles the Wise" "Sandrokottos"
"Agamemnon" "Clement VII" "Suppiluliuma" "Deng Xiaoping"
"Victor Emmanuel" "Ajatasatru" "Jan Sobieski" "Huangdi" "Xuantong"
"Narmer" "Cosimo de' Medici" "Möngke Khan" "Stephen Dušan" "Henri IV"
"Mehmed Fatih" "Conn Cétchathach" "Francisco Franco" "Leo X"
"Kammu" "Krishnadevaraya" "Elizabeth I" "Norton I" "Washington"
"Meiji" "Umar" "TR" "Peter the Great" "Agustin I" "Ashoka"
"William the Conqueror" "Kongolo Mwamba" "Song Taizu"
"Ivan the Terrible" "Yao" "Vercingetorix" "Geronimo" "Rurik"
"Urban VIII" "Alexios Komnenos" "Maria I" "Tamar" "Bismarck"
"Arthur" "Jimmu" "Gustavus Adolphus" "Suiko" "Basil I" "Montezuma"
"Santa Anna" "Xerxes" "Beyazıt Yıldırım" "Samudragupta" "James I"
"George III" "Kamehameha" "Francesco Sforza" "Trajan"
"Rajendra Chola" "Hideyoshi" "Cleopatra" "Alexander"
"Ashurbanipal" "Paul III" "Vespasian" "Tecumseh" "Narasimhavarman"
"Suryavarman II" "Bokassa I" "Charles Canning" "Theodosius"
"Francis II" "Zhou Wen" "William Jardine" "Ahmad al-Mansur"
"Lajos Nagy" "Theodora" "Mussolini" "Samuil" "Osman Gazi"
"Kim Il-sung" "Maria Theresa" "Lenin" "Tokugawa" "Marcus Aurelius"
"Nzinga Mbande" "Edward III" "Joseph II" "Pulakesi II" "Priam"
"Qin Shi Huang" "Shah Jahan" "Sejong" "Sui Wendi" "Otto I"
"Napoleon III" "Prester John" "Dido" "Joao I" "Gregory I"
"Gajah Mada" "Abd-ar Rahmān III" "Taizong" "Franz Josef I"
"Nicholas II" "Gandhi" "Chandragupta II" "Peter III"
"Oba Ewuare" "Louis IX" "Napoleon" "Selim Yavuz" "Shun"
"Hayam Wuruk" "Jagiełło" "Nicaule" "Sargon" "Saladin" "Charles II"
"Brian Boru" "Da Yu" "Antiochus III" "Charles I"
"Jan Pieterszoon Coen" "Hongwu" "Mithridates" "Hadrian" "Ptolemy"
"Benito Juarez" "Sun Yat-sen" "Raja Raja Chola" "Bolivar" "Pius VII"
"Shapur II" "Taksin" "Ram Khamhaeng" "Hatshepsut" "Alī" "Matilda"
"Ataturk"
==
::
Retrieve carrier name.
~zod/main=> (glam ~zod)
"Tianming"
~zod/main=> (glam ~fyr)
"Bolivar"
### ++glon
++ glon
|= lag=lang
^- (unit tape)
?+ lag ~
%aa [~ "Afar"]
%ab [~ "Abkhazian"]
%ae [~ "Avestan"]
%af [~ "Afrikaans"]
%ak [~ "Akan"]
%am [~ "Amharic"]
%an [~ "Aragonese"]
%ar [~ "Arabic"]
%as [~ "Assamese"]
%av [~ "Avaric"]
%ay [~ "Aymara"]
%az [~ "Azerbaijani"]
%ba [~ "Bashkir"]
%be [~ "Belarusian"]
%bg [~ "Bulgarian"]
%bh [~ "Bihari"]
%bi [~ "Bislama"]
%bm [~ "Bambara"]
%bn [~ "Bengali"]
%bo [~ "Tibetan"]
%br [~ "Breton"]
%bs [~ "Bosnian"]
%ca [~ "Catalan"]
%ce [~ "Chechen"]
%ch [~ "Chamorro"]
%co [~ "Corsican"]
%cr [~ "Cree"]
%cs [~ "Czech"]
%cu [~ "Slavonic"]
%cv [~ "Chuvash"]
%cy [~ "Welsh"]
%da [~ "Danish"]
%de [~ "German"]
%dv [~ "Maldivian"]
%dz [~ "Dzongkha"]
%ee [~ "Ewe"]
%el [~ "Greek"]
%en [~ "English"]
%eo [~ "Esperanto"]
%es [~ "Spanish"]
%et [~ "Estonian"]
%eu [~ "Basque"]
%fa [~ "Persian"]
%ff [~ "Fulah"]
%fi [~ "Finnish"]
%fj [~ "Fijian"]
%fo [~ "Faroese"]
%fr [~ "French"]
%fy [~ "Frisian"]
%ga [~ "Irish Gaelic"]
%gd [~ "Scottish Gaelic"]
%gl [~ "Galician"]
%gn [~ "Guarani"]
%gu [~ "Gujarati"]
%gv [~ "Manx"]
%ha [~ "Hausa"]
%he [~ "Hebrew"]
%hi [~ "Hindi"]
%ho [~ "Hiri Motu"]
%hr [~ "Croatian"]
%ht [~ "Haitian Creole"]
%hu [~ "Hungarian"]
%hy [~ "Armenian"]
%hz [~ "Herero"]
%ia [~ "Interlingua"]
%id [~ "Indonesian"]
%ie [~ "Occidental"]
%ig [~ "Igbo"]
%ii [~ "Nuosu"]
%ik [~ "Inupiaq"]
%io [~ "Ido"]
%is [~ "Icelandic"]
%it [~ "Italian"]
%iu [~ "Inuktitut"]
%ja [~ "Japanese"]
%jv [~ "Javanese"]
%ka [~ "Georgian"]
%kg [~ "Kongo"]
%ki [~ "Kikuyu"]
%kj [~ "Kwanyama"]
%kk [~ "Kazakh"]
%kl [~ "Kalaallisut"]
%km [~ "Central Khmer"]
%kn [~ "Kannada"]
%ko [~ "Korean"]
%kr [~ "Kanuri"]
%ks [~ "Kashmiri"]
%ku [~ "Kurdish"]
%kv [~ "Komi"]
%kw [~ "Cornish"]
%ky [~ "Kyrgyz"]
%la [~ "Latin"]
%lb [~ "Luxembourgish"]
%lg [~ "Ganda"]
%li [~ "Limburgish"]
%ln [~ "Lingala"]
%lo [~ "Lao"]
%lt [~ "Lithuanian"]
%lu [~ "Luba-Katanga"]
%lv [~ "Latvian"]
%mg [~ "Malagasy"]
%mh [~ "Marshallese"]
%mi [~ "Maori"]
%mk [~ "Macedonian"]
%ml [~ "Malayalam"]
%mn [~ "Mongolian"]
%mr [~ "Marathi"]
%ms [~ "Malay"]
%mt [~ "Maltese"]
%my [~ "Burmese"]
%na [~ "Nauru"]
%nb [~ "Norwegian Bokmål"]
%nd [~ "North Ndebele"]
%ne [~ "Nepali"]
%ng [~ "Ndonga"]
%nl [~ "Dutch"]
%nn [~ "Norwegian Nynorsk"]
%no [~ "Norwegian"]
%nr [~ "South Ndebele"]
%nv [~ "Navajo"]
%ny [~ "Chichewa"]
%oc [~ "Occitan"]
%oj [~ "Ojibwa"]
%om [~ "Oromo"]
%or [~ "Oriya"]
%os [~ "Ossetian"]
%pa [~ "Punjabi"]
%pi [~ "Pali"]
%pl [~ "Polish"]
%ps [~ "Pashto"]
%pt [~ "Portuguese"]
%qu [~ "Quechua"]
%rm [~ "Romansh"]
%rn [~ "Rundi"]
%ro [~ "Romanian"]
%ru [~ "Russian"]
%rw [~ "Kinyarwanda"]
%sa [~ "Sanskrit"]
%sc [~ "Sardinian"]
%sd [~ "Sindhi"]
%se [~ "Northern Sami"]
%sg [~ "Sango"]
%si [~ "Sinhala"]
%sk [~ "Slovak"]
%sl [~ "Slovenian"]
%sm [~ "Samoan"]
%sn [~ "Shona"]
%so [~ "Somali"]
%sq [~ "Albanian"]
%sr [~ "Serbian"]
%ss [~ "Swati"]
%st [~ "Sotho"]
%su [~ "Sundanese"]
%sv [~ "Swedish"]
%sw [~ "Swahili"]
%ta [~ "Tamil"]
%te [~ "Telugu"]
%tg [~ "Tajik"]
%th [~ "Thai"]
%ti [~ "Tigrinya"]
%tk [~ "Turkmen"]
%tl [~ "Tagalog"]
%tn [~ "Tswana"]
%to [~ "Tonga"]
%tr [~ "Turkish"]
%ts [~ "Tsonga"]
%tt [~ "Tatar"]
%tw [~ "Twi"]
%ty [~ "Tahitian"]
%ug [~ "Uighur"]
%uk [~ "Ukrainian"]
%ur [~ "Urdu"]
%uz [~ "Uzbek"]
%ve [~ "Venda"]
%vi [~ "Vietnamese"]
%vo [~ "Volapük"]
%wa [~ "Walloon"]
%wo [~ "Wolof"]
%xh [~ "Xhosa"]
%yi [~ "Yiddish"]
%yo [~ "Yoruba"]
%za [~ "Zhuang"]
%zh [~ "Chinese"]
%zu [~ "Zulu"]
==
::
ISO language code
~zod/main=> (glon %cs)
[~ "Czech"]
~zod/main=> (glon %en)
[~ "English"]
~zod/main=> (glon %mz)
~
### ++gnom
++ gnom :: ship display name
|= [[our=@p now=@da] him=@p] ^- @t
=+ yow=(scot %p him)
=+ pax=[(scot %p our) %name (scot %da now) yow ~]
=+ woy=((hard ,@t) .^(%a pax))
?: =(%$ woy) yow
(rap 3 yow ' ' woy ~)
::
Fetch display name from %ames
~zod/main=> (gnom [->-< -<-] ~zod)
'~zod |Tianming|'
~zod/main=> (gnom [->-< -<-] ~doznec)
'~doznec ~doznec'
~zod/main=> (gnom [->-< -<-] ~tug)
'~tug |Go-Daigo|'
### ++gnow
++ gnow
|= [who=@p gos=gcos] ^- @t
?- -.gos
%czar (rap 3 '|' (rap 3 (glam who)) '|' ~)
%king (rap 3 '_' p.gos '_' ~)
%earl (rap 3 ':' p.gos ':' ~)
%pawn ?~(p.gos %$ (rap 3 '.' u.p.gos '.' ~))
%duke
?: ?=(%anon -.p.gos) %$
%+ rap 3
^- (list ,@)
?- -.p.gos
%punk ~['"' q.p.gos '"']
?(%lord %lady)
=+ ^= nad
=+ nam=`name`s.p.p.gos
%+ rap 3
:~ p.nam
?~(q.nam 0 (cat 3 ' ' u.q.nam))
?~(r.nam 0 (rap 3 ' (' u.r.nam ')' ~))
' '
s.nam
==
?:(=(%lord -.p.gos) ~['[' nad ']'] ~['(' nad ')'])
==
==
::
XX Document
### ++hunt
++ hunt :: first of unit dates
|= [one=(unit ,@da) two=(unit ,@da)]
^- (unit ,@da)
?~ one two
?~ two one
?:((lth u.one u.two) one two)
::
XX Document
### ++mojo
++ mojo :: compiling load
|= [pax=path src=*]
^- (each twig (list tank))
?. ?=(@ src)
[%| ~[[leaf/"musk: malformed: {<pax>}"]]]
=+ ^= mud
%- mule |.
((full vest) [1 1] (trip src))
?: ?=(| -.mud) mud
?~ q.p.mud
:~ %|
leaf/"musk: syntax error: {<pax>}"
leaf/"musk: line {<p.p.p.mud>}, column {<q.p.p.mud>}"
==
[%& p.u.q.p.mud]
::
XX Document
### ++mole
++ mole :: new to old sky
|= ska=$+(* (unit (unit)))
|= a=*
^- (unit)
=+ b=(ska a)
?~ b ~
?~ u.b ~
[~ u.u.b]
::
XX Document
### ++much
++ much :: constructing load
|= [pax=path src=*]
^- gank
=+ moj=(mojo pax src)
?: ?=(| -.moj) moj
(mule |.((slap !>(+>.$) `twig`p.moj)))
::
XX Document
### ++musk
++ musk :: compiling apply
|= [pax=path src=* sam=vase]
^- gank
=+ mud=(much pax src)
?: ?=(| -.mud) mud
(mule |.((slam p.mud sam)))
::
XX Document
### ++saxo
++ saxo :: autocanon
|= who=ship
^- (list ship)
?: (lth who 256) [who ~]
[who $(who (sein who))]
::
Compute list of ancestors
~zod/main=> (saxo ~pittyp-pittyp)
~[~pittyp-pittyp ~dalnel ~del]
~zod/main=> (saxo ~tasfyn-partyv)
~[~tasfyn-partyv ~doznec ~zod]
~zod/main=> (saxo ~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet)
~[~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet ~zod]
### ++sein
++ sein :: autoboss
|= who=ship ^- ship
=+ mir=(clan who)
?- mir
%czar who
%king (end 3 1 who)
%duke (end 4 1 who)
%earl (end 5 1 who)
%pawn `@p`0
==
Compute direct senior.
~zod/main=> (sein ~tasfyn-partyv)
~doznec
~zod/main=> (sein ~doznec)
~zod
~zod/main=> (sein ~zod)
~zod
~zod/main=> (sein ~pittyp-pittyp)
~dalnel
~zod/main=> (sein ~dalnel)
~del
~zod/main=> (sein ~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet)
~zod

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
References
==========
Aside from the runes and standard library there are a few things worth
knowing about the hoon language. You can find those here.
<list></list>

View File

@ -0,0 +1,686 @@
Odors
=====
Overview
--------
Since Everything in Hoon is a natural number, the interpreter needs to
know both how to render them and subject them to type enforcement.
Odors, which are just ASCII spans beginning with a `@`, carry all of the
information necessary for the interpreter to do this. For instance, the
interpreter knows to render an atom of odor `@t` as UTF-8 text.
The span composing the Odor consists of two parts: a lowercase prefix
carrying type information, and an upper-case suffix containing
information about its size. The prefix is a taxonomy that grows more
specific to the right. For example, atoms of the odor `@ta` are URL-safe
ASCII text, and Atoms of the odor `@tas` are the more specific subset of
ASCII text that is acceptable in hoon.
The general principle of type enforcement is that atoms change freely
either up or down the taxonomy, but not across. You can treat a `@tas`
as a `@t`, as in a strong type system; but you can also treat a `@t` as
a `@tas`, or an `@` as anything. However, passing a `@t` to a function
that expects an `@ux` is a type error.
XXDIAGRAMXX
For example, you can cast a `@t` to a `@tas`, or vice-versa:
~zod/try=> =a `@t`'permitted'
~zod/try=> a
'permitted'
~zod/try=> `@tas`a
%permitted
However, you cannot pass a `@ux` to a function that expects a `@t`
without casting it to a `@` first:
~zod/try=> (|=(a=@t [%foo a]) 0x20)
! type-fail
! exit
~zod/try=> =a 0x21
~zod/try=> (|=(a=@t [%foo a]) `@t`a)
[%foo '!']
Note that when explicitly casting a `@ux` to a `@t`, the interpreter
automatically casts the `@ux` to a `@` first.
Comprehensive list of the Hoon Odors
------------------------------------
@c UTF-32 codepoint
@d date
@da absolute date
@dr relative date (ie, timespan)
@f yes or no (inverse boolean)
@n nil
@p phonemic base
@r IEEE floating-point
@rd double precision (64 bits)
@rh half precision (16 bits)
@rq quad precision (128 bits)
@rs single precision (32 bits)
@s signed integer, sign bit low
@sb signed binary
@sd signed decimal
@sv signed base32
@sw signed base64
@sx signed hexadecimal
@t UTF-8 text (cord)
@ta ASCII text (span)
@tas ASCII symbol (term)
@u unsigned integer
@ub unsigned binary
@ud unsigned decimal
@uv unsigned base32
@uw unsigned base64
@ux unsigned hexadecimal
Odor Size Suffixes
------------------
The suffix of an odor, if present, is a single upper-case character A-Z
`c`, which indicates the size of an atom. This is possible, because in
Hoon, a letter maps to an ASCII code number, thus a number.
Size is specified in bits in the form of `1 << (c - 'A')` resp. `2^c`,
since most data aligns to the power of 2 or can be composed of such
blocks.
The size of a block of size `N` can be calculated for example using
`(bex (sub 'N' 'A'))` in bits or `(div (bex (sub 'N' 'A')) 8)` in bytes.
Thus, `@tD` is one UTF-8 byte (whatever that means) and `@tN` is 1
kilobyte or less of UTF-8.
For reference:
A 1 bit
B 2 bits
C 4 bits
D 1 byte
E 2 bytes
F 4 bytes
G 8 bytes
H 16 bytes
I 32 bytes
J 64 bytes
K 128 bytes
L 256 bytes
M 512 bytes
N 1K
O 2K
P 4K
Q 8K
R 16K
S 32K
T 64K
U 128K
V 256K
W 512K
X 1MB
Y 2MB
Z 4MB
It is possible to construct an atom bigger than 4Mb in size, but the
type system would not be able to express an odor size for it.
There is also the datatype `++bloq` to hold a to-the-power-of block size
(though it is just an alias for `@`).
------------------------------------------------------------------------
### @c
UTF-32 codepoint
Atoms of the odor `@c` represent Unicode text, constructed with a UTF-32
bytestream, with the lowest-significant bit first. Although we usually
use a UTF-8 bytestream, sometimes it's useful to build atoms of one or
more UTF-32 words.
##### Forms
`~-[text]`
##### Examples
~zod/try=> :type; ~-foo
~-foo
@c
~zod/try=> ~-i~2764.u
~-i~2764.u
~zod/try=> (tuft ~-i~2764.u)
'i❤u'
~zod/try=> `@ux`~-foo
0x6f.0000.006f.0000.0066
~zod/try=> `@ux`~-i~2764.u
0x75.0000.2764.0000.0069
~zod/try=> `@ux`(tuft ~-i~2764.u)
0x75.a49d.e269
------------------------------------------------------------------------
### @d
Date
#### @da
Absolute date
Atoms of the odor `@da` represent absolute Urbit dates. Urbit dates
represent 128-bit chronological time, with 2\^64 seconds from the start
of the universe. For example, 2\^127 is 3:30:08 PM on December 5, AD
226. The time of day and/or second fragment is optional. As the last
example shows, BC times are also possible.
##### Forms
`~~[year].[month].[date]..[hour].[minute].[second]..[millisecond]`
Note: the time of day and/or millisecond fragment is optional.
##### Examples
~zod/try=> ~2014.1.1
~2014.1.1
~zod/try=> :type; ~2014.1.1
~2014.1.1
@da
~zod/try=> ~2014.1.1..01.01.01
~2014.1.1..01.01.01
~zod/try=> :type; ~2014.1.1..01.01.01
~2014.1.1..01.01.01
@da
~zod/try=> ~2014.1.1..01.01.01..1234
~2014.1.1..01.01.01..1234
~zod/try=> `@da`(bex 127)
~226.12.5..15.30.08
~zod/try=> `@da`(dec (bex 127))
~226.12.5..15.30.07..ffff.ffff.ffff.ffff
~zod/try=> `@ux`~2013.12.7
0x8000.000d.2140.7280.0000.0000.0000.0000
~zod/try=> `@ux`~2013.12.7..15.30.07
0x8000.000d.2141.4c7f.0000.0000.0000.0000
~zod/try=> `@ux`~2013.12.7..15.30.07..1234
0x8000.000d.2141.4c7f.1234.0000.0000.0000
~zod/try=> `@ux`~2013.12.7..15.30.07..1234
0x8000.000d.2141.4c7f.1234.0000.0000.0000
------------------------------------------------------------------------
#### @dr
Relative date (ie, timespan)
Atoms of the odor `@dr` atoms represent basic time intervals in
milliseconds. There are no `@dr` intervals under a second or over a day
in length.
##### Forms
`~d[day].h[hour]m[minute].s[second]..[fractionals]`
Note: Every measurement is optional, so long as those that are present
are in order. The largest measurement is preceded by a `~`.
##### Examples
~zod/try=> ~d1.h19.m5.s29
~d1.h19.m5.s29
~zod/try=> :type; ~d1.h19.m5.s29
~d1.h19.m5.s29
@dr
~zod/try=> `@dr`(div ~s1 1.000)
~.s0..0041.8937.4bc6.a7ef
~zod/try=> ~d1.h19.m5.s29..0041
~d1.h19.m5.s29..0041
~zod/try=> `@ux`~s1
0x1.0000.0000.0000.0000
~zod/try=> `@ux`~m1
0x3c.0000.0000.0000.0000
~zod/try=> `@dr`(div ~d1 5)
~h4.m48
~zod/try=> (div ~m1 ~s1)
60
~zod/try=> (div ~h1 ~m1)
60
~zod/try=> (div ~h1 ~s1)
3.600
~zod/try=> (div ~d1 ~h1)
24
~zod/try=> `@da`(add ~2013.11.30 ~d1)
~2013.12.1
------------------------------------------------------------------------
#### @f
Loobean(inverse boolean)
Atoms of the odor `@f` represent loobeans, where `0` is yes and `1` is
no. Loobeans are often represented in their cubic and runic forms shown
below.
##### Forms
`0`, `1` as numbers. `%.y`, `%.n` as [`%cube`]()s. `&`, `|` as short
forms.
##### Examples
~zod/try=> `@ud`.y
0
~zod/try=> :type; .y
%.y
{%.y %.n}
~zod/try=> `@ud`.n
1
~zod/try=> .y
%.y
~zod/try=> &
%.y
~zod/try=> |
%.n
------------------------------------------------------------------------
### @n
Nil
Atoms of the odor `@n` indicate an absence of information, as in a list
terminator. The only value is `~`, which is just `0`.
~zod/try=> :type; ~
~
%~
~zod/try=> `@ud`%~
0
~zod/try=> `@ud`~
0
------------------------------------------------------------------------
### @p
Phonemic base
Atoms of `@p` are primarily used to represent ships names, but they can
be used to optimize any short number for memorability. For example, it
is great for checksums.
##### Forms
`~[phonemic]`
Every syllable is a byte. Pairs of two bytes are separated by `-`, and
phrases of four pairs are separated by `--`.
~zod/try=> ~pasnut
~pasnut
~zod/try=> :type; ~pasnut
~pasnut
@p
~zod/try=> `@p`0x4321
~pasnut
~zod/try=> `@p`0x8765.4321
~famsyr-dirwes
~zod/try=> `@p`0x8766.4321
~lidlug-maprec
~zod/try=> `@p`(shaf %foo %bar)
~ralnyl-panned-tinmul-winpex--togtux-ralsem-lanrus-pagrup
------------------------------------------------------------------------
### @r
IEEE floating-points
Hoon does not yet support floating point, so these syntaxes don't work
yet. But the syntax for a single-precision float is the normal English
syntax, with a `.` prefix:
------------------------------------------------------------------------
### @s
Signed integer, sign bit low
Without finite-sized integers, the sign extension trick obviously does
not work. A signed integer in Hoon is a different way to use atoms than
an unsigned integer; even for positive numbers, the signed integer
cannot equal the unsigned.
The prefix for a negative signed integer is a single `-` before the
unsigned syntax. The prefix for a positive signed integer is `--`. The
least significant represents the sign. The representation is similar to
a folded number line.
#### @sb
Signed binary
Atoms of the odor `@sb` represent signed binary numbers.
#### Forms
`-0b[negative_binary]` `--0b[postive_binary]`
#### Examples
~zod/try=> :type; -0b1
-0b1
@sb
~zod/try=> `@sd`-0b1
-1
~zod/try=> `@sd`--0b1
--1
~zod/try=> `@sd`--0b11
--3
~zod/try=> `@sb`(sum:si -0b10 -0b10)
-0b100
------------------------------------------------------------------------
#### @sd
Signed decimal
Atoms of odor `@sd` represent signed decimal numbers.
#### Forms
`-[negative[decimal]()]` `--[postive_[decimal]()]`
#### Examples
~zod/try=> -234
-234
~zod/try=> :type; -234
-234
@sd
~zod/try=> :type; --234
--234
@sd
~zod/try=> (sum:si -234 --234)
--0
------------------------------------------------------------------------
#### @sv
Signed base32
Atoms of odor `@sv` represent signed base32 numbers.
##### Forms
`-0v[negative_base32]` The digits are, in order, `0-9`, `a-v`.
`--0v[positive_base32]`
##### Examples
~zod/try=> -0vv
-0vv
~zod/try=> :type; -0vv
-0vv
@sv
~zod/try=> --0vb
--0vb
~zod/try=> `@sd`-0vv
-31
~zod/try=> `@sd`--0vb
--11
~zod/try=> `@sd`(sum:si -0vv --0vb)
-20
------------------------------------------------------------------------
#### @sw
Signed base64
Atoms of odor `@sw` represent base64 numbers.
##### Forms
`-0w[negative_base64]` The digits are, in order, `0-9`, `a-z`,
`A-Z`,`-`, and `~`. `--0w[positive_base64]` The digits are, in order,
`0-9`
##### Examples
~zod/try=> -0w--
-0w--
~zod/try=> :type; -0w--
-0w--
@sw
~zod/try=> `@sd`(sum:si -0w-A -0w--)
-8.034
#### @sx
Signed hexadecimal
Atoms of odor `@sx` represent signed hexadecimal numbers.
##### Forms
`-[negative_hexadecimal]` `--[positive_hexadecimal]`
##### Examples
~~zod/try=> -0x0
--0x0
~zod/try=> `@sd`--0x17
--23
~zod/try=> `@ux`(bex 20)
0x10.0000
~zod/try=> 0x10. 0000
0x10.0000
~zod/try=> `@sd`(sum:si --0x17 -0x0)
--23
~zod/try=> `@sd`(sum:si --0x17 -0xa)
--13
------------------------------------------------------------------------
### @t
UTF-8 text (cord)
Atoms of the odor `@t` represent a
[cord](http://en.wikipedia.org/wiki/Rope_data_structure), sequence of
UTF-8 bytes, LSB first. It is sometimes called a cord.
##### Forms
`~~[text]` `'[text]'`
##### Examples
~zod/try=> ~~foo
'foo'
~zod/try=> :type; 'foo'
'foo'
@t
~zod/try=> :type; ~~foo
'foo'
@t
------------------------------------------------------------------------
#### @ta
ASCII text (span)
Atoms of the odor `@ta` represent the ASCII text subset used in hoon
literals: `a-z`, `0-9`, `~`, `-`, `.`, `_`.
##### Forms
`~.[text]` There are no escape sequences.
##### Examples
~zod/try=> ~..asdf
~..asdf
~zod/try=> :type; ~.asdf
~.asdf
@ta
~zod/try=> `@t`~.asdf
'asdf'
------------------------------------------------------------------------
#### @tas
ASCII symbol (term)
Atoms of `@tas` represent [`++term`]()s, the most exclusive text odor.
The only characters permitted are lowercase ASCII, except as the first
or last character, and 0-9, except as the first character.
##### Forms
`%[text]` This means a term is always [cubical]().
##### Examples
~zod/try=> %dead-fish9
%dead-fish9
~zod/try=> -:!>(%dead-fish9)
[%cube p=271.101.667.197.767.630.546.276 q=[%atom p=%tas]]
------------------------------------------------------------------------
### @u
Unsigned integer
------------------------------------------------------------------------
#### @ub
Unsigned binary
Atoms of the odor `@ub` represent unsigned binary numbers.
#### Forms
`0b[number]` Numbers are least-significant bit first.
##### Examples
~zod/try=> `@`0b1
1
~zod/try=> :type; 0b1
0b1
@ub
~zod/try=> `@`0b10
2
~zod/try=> `@`0b100
4
------------------------------------------------------------------------
#### @ud
Unsigned decimal
Atoms of `@ud` represent unsigned decimal numbers. It is the default
print format for both `@u` and and `@u`, namely unsigned numbers with no
printing preference, as well as opaque atoms.
##### Forms
Numbers of more than three digits must be delimited by `.`s. Whitespace
and linebreaks can appear between the dot and the next group.
~zod/try=> 0
0
~zod/try=> 19
19
~zod/try=> :type; 19
19
@ud
~zod/try=> 1.024
1.024
~zod/try=> 65.536
65.536
~zod/try=> (bex 20)
1.048.576
------------------------------------------------------------------------
#### @uv
Unsigned base32
Atoms of the odor `@uv` represent unsigned base64 numbers.
##### Forms
`0v[number]` The digits are, in order, `0-9`, `a-v`.
##### Examples
~zod/try=> `@ud`0vv
31
~zod/try=> :type; 0vv
0vv
@uv
~zod/try=> `@ud`(add 0vv 0v9)
40
------------------------------------------------------------------------
#### @uw
Unsigned base64
##### Forms
`ow[number]` The digits are, in order, `0-9`, `a-z`, `A-Z`,`-`, and `~`.
##### Examples
~zod/try=> 0w~
0w~
~zod/try=> :type; 0w~
0w~
@uw
~zod/try=> `@uv`(add 0w~ 0wZ)
0v3s
~zod/try=> `@ud``@uv`(add 0w~ 0wZ)
124
------------------------------------------------------------------------
#### @ux
Unsigned hexadecimal
Atoms of the odor `@ux` represent hexadecimal numbers.
##### Forms
`0x`number. Numbers with more than four digits must be delimited by
`.`s. Hex digits are lowercase only.
~zod/try=> 0x0
0x0
~zod/try=> :type; 0x0
0x0
@ux
~zod/try=> `@ud`0x17
23
~zod/try=> `@ux`(bex 20)
0x10.0000
~zod/try=> 0x10. 0000
0x10.0000
------------------------------------------------------------------------

130
docs/pub/doc/hoon/runes.md Normal file
View File

@ -0,0 +1,130 @@
<div class="short">
Runes
=====
In Hoon there are no reserved words. Instead, [`++twigs`]() (abstract
syntax trees), are formed using a diagraph of two ASCII symbols, which
is called a rune.
Runes are loosely divided into categories by their first character. To
find documentation on each individual category, follow these links:
<list></list>
</div>
------------------------------------------------------------------------
Introduction
------------
For example, the rune `?:`, pronounced "wutcol", is a rune that accepts
three `++twig` expressions to form an "if-then-else statement," where
`p` is the predicate, `q` is the "then" statement, and `r` is the "else"
statement:
[%wtcl p=twig q=twig r=twig]
In a program, it is used like so:
++ add
|= [a=@ b=@]
^- @
?: =(0 a) b
$(a (dec a), b +(b))
Here the `=(0 a)` is `p`, the `b` is `q`, and the bottom line is the
`r`.
There are several benefits to using runes in lieu of reserved words.
First, it prevents the programmer from accidentally misusing a reserved
word as a variable name, which also allows her to be sure that any word
in her progam is an identifier. Next, as the first ASCII symbol of the
rune digraphs bears semantic significance, the programmer can look at
any rune and immediately have a basic, intuitive understanding as to
what it does.
Next, rune syntax addresses several issues that arise in other
languages. First, it produces cleaner, less verbose code that
conveniently flows downward. To highlight the verbosity Hoon avoids by
implementing runes, here is the C equivalent of the `++add` source code
printed above:
attribute add {
function(left-operand: atom, right-operand: atom)
produce atom
if equals(0, left-operand) {
right-operand
} else {
recurse(left-operand (decrement left-operand)),
right-operand (increment right-operand))
}
}
What is more, Hoon solves two problems that arise in functional
programming languages with very deep expression trees: first, the
collection of huge piles of closing parens at the end of large blocks;
and second, the fact that the depth of expression trees are thus bounded
by the width of the text box, as subexpressions tend to be indented.
Some languages solve the bracket-terminator problem by parsing
whitespace in order to use indentation to express tree depth:
?:
&
47
52
While this is actually valid Hoon, it does not solve the width problem.
To address this problem, most Hoon `++twigs` have a short, fixed
fan-out. Thus, the parser does not need significant whitespace nor a
terminator to determine how many twigs follow a `?:`--it already knows
that the answer is three. A smart parser allows the Hoon programmer to
format her code using a [backstep pattern]() that allows her to descend
into a deep tree without losing right margin.
Lastly, but perhaps most significantly, code is meant to be seen, and
not read. Anyone who has even slight experience coding Hoon will tell
you that they can understand and connect with properly formatted Hoon
code on a deeper, more intuitive level that cannot be explained but must
be experienced. One doesn't read `++add`, she sees it.
Names and Categories
--------------------
While the second glyph in a rune means little or nothing, the first
defines a rough semantic category:
| bar Core construction
$ buc Tile construction
% cen Invocations
: col Tuple construction
. dot Nock operations
# hax Pretty printing
^ ket Type conversions
; sem Composers (and XML generators)
~ sig Hints
= tis Subject modifiers
? wut Conditionals, booleans, and tests
! zap Special operations
As shown above, each glyph has its own monosyllabic name, designed to be
pronounced quickly in combination with another glyph to form a rune
name. As languages are often read-aloud, this saves the programmer from
having to say "dollar sign, question mark"--"bucwut" is much more
compact.
Irregular pronuncations
-----------------------
To avoid a few tongue-twisters, some runes have irregular pronunciations
that should be noted:
-- hephep phep
+- lushep slep
++ luslus slus
== tistis stet
Note: these runes are not members of any of the categories above, but
are mostly used to....

View File

@ -0,0 +1,49 @@
<div class="short">
`buc $ %buc`
============
Tile construction
-----------------
The `$` runes construct [`++tile`]()s. [`++tile`]()s are one of our
primary building blocks in hoon, they define how we reduce our ASTs into
well typed nouns that nock can compute. You can think of a [`++tile`]()
sort of like a typeclass in Haskell.
</div>
#### Forks
##### [`++tile`]()s that can be one of multiple cases.
[`$?`]() Non-empty list of cases.
[`$|`]() Fork between atom and cell.
[`$&`]() Fork between cells whose head is a cell and cells whose head is
an atom.
<hr></hr>
#### Tuples
[`$:`]() Unlabelled arrays.
[`$=`]() Tuple with [`++face`]()s.
<hr> </hr>
#### Reductions
##### Important convenience methods for working with tiles, and are very broadly used.
[`$*`]() [bunt]()
[`$,`]() [clam]()
[`$@`]() [whip]()
<hr></hr>
<kids></kids>

View File

@ -0,0 +1,51 @@
<h1><a name="bcbr"><code>bucbar $| %bcbr</code></a></h1>
<div class="short">
Atom or cell
------------
`$|` is a tile rune that produces a [`%reed`](), a tile whose [icon]()
is a [fork]() between two nouns: an [atom]() of `tile` `p` and a cell of
`tile` `q`. `$|` is similar to [`$?`](), but is more strict in that in
only contains one atom tile and one cell tile.
</div>
<hr>
</hr>
### Produces
[`Tile`](): `[%reed p=tile q=tile]`
### Sample
`p` is a [`tile`]() `q` is a [`tile`]()
### Tall form
$| p
q
### Wide form
$|(p q)
### Irregular form
None
### Examples
~zod/try=> *$|(~ [~ u=@])
~
~zod/try=> :type; *$|(~ [~ u=@])
~
u(@)
++ list |* a=_,* :: null-terminated list
$|(~ [i=a t=(list a)]) ::
In `++list`, `$|` specifies that every element in a noun that can be
cast to a `++list` is either the atom `~` or the cell
`[i=a t=(list a)]`.

View File

@ -0,0 +1,43 @@
[buccab `$_` %bccb](#bccb)
==========================
Default value
`$_` produces a tile-by-example, called a `%weed`. A `%weed` contains
the twig used to make the example.
Produces
--------
Tile: `[%weed p=twig]`
Sample
------
`p` is a [tile]().
Tall form
---------
$_ p
Wide form
---------
$_(p)
Irregular form
--------------
_p
Examples
--------
~zod/try=> *_12
12
~zod/try=> :type; *_12
12
@ud
~zod/try=> ^-(_(add 2 2) 'a')
97

View File

@ -0,0 +1,44 @@
[buccol `$:` %bccl](#bccl)
==========================
Tile autocons
`$:` is a tile rune that constructs the tile of a tuple from a tuple of
tiles.
Produces
--------
[Tile](): `[p=tile q=tile]`
Sample
------
`p` is a [tile](). `q` is a [tile]().
Tall form
---------
$: p
q
==
Wide form
---------
$:(p q)
Irregular form
--------------
[p q]
Examples
--------
~zod/try=> *[1 2]
[%1 %2]
~zod/try=> (,[1 2] "ham")
[%1 %2]
~zod/try=> (,[@ 2] "ham")
[104 %2]

View File

@ -0,0 +1,61 @@
[buccom `$,` %bccm](#bccm)
==========================
Normalizing gate, `%clam`
`$,` is a synthetic rune that produces a `%leaf`, a normalizing gate or
[clam]() for `p`. `$,` is used to ensure an input value fits a certain
type: if it does match, the value is produced. If it doesn't, the
default value for the desired type is produced.
Produces
--------
[Twig](): `[%bccm p=tile]`
Sample
------
`p` is a [tile]()
Tall form
---------
$, p
Wide form
---------
None
Irregular form
--------------
,p
Examples
--------
++ cord ,@t :: text atom (UTF-8)
In `++cord`, `,` creates a gate that validates atoms of the odor
[`@t`]().
~zod/try=> (,[1 2] "ham")
[%1 %2]
~zod/try=> (,[@ 2] "ham")
[104 %2]
~zod/try=> (,~ %foo)
~
~zod/try=> (,~ [%ba %r])
~
~zod/try=> (,$%([%a @] [%b ^]) [%b 5])
[%b 0 0]
~zod/try=> (,$%([%a @] [%b ^]) [%a 5])
[%a 5]
~zod/try=> (,$%([%a @] [%b ^]) [%a 6 7])
[%a 0]
~zod/try=> (,$%([%a @] [%b ^]) [%b ~])
[%b 0 0]
~zod/try=> (,$%([%a @] [%b ^]) [%b "ame"])
[%b 97 [109 101 0]]

View File

@ -0,0 +1,64 @@
[buccen `$%` %bccn](#bccn)
==========================
Tagged union
`$%` is a tile rune that produces a [`%kelp`](), the tile of the
discriminated union. `$%` takes a list of lines which are labeled cases,
called fronds, closed by `==`. Commonly used for pattern matching.
Produces
--------
[Twig](): `[%kelp p=[i=line t=(list line)]]`
Sample
------
`p` is a [`++list`]() of [`++line`]()s.
Tall form
---------
$% p
q
==
Wide form
---------
None
Irregular form
--------------
None
Examples
--------
~zod/try=> $%([%& @p] [%| @t])
<1.dhe [* @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
~zod/try=> *$%([%& @p] [%| @t])
[%.y ~zod]
~zod/try=> :type; *$%([%& @p] [%| @t])
[%.y ~zod]
{[%.y @p] [%.n @t]}
~zod/try=> :type; *(each ,@p ,@t)
[%.y p=~zod]
{[%.y p=@p] [%.n p=@t]}
~zod/try=> $%(~ [%a 1])
~ <syntax error at [1 13]>
~zod/try=> $%([%~ ~] [%a 1])
<1.yck [* @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
~zod/try=> *$%([%~ ~] [%a 1])
[~ ~]
++ foot $% [%ash p=twig] :: dry, geometric
[%elm p=twig] :: wet, generic
[%oak ~] :: XX not used
[%yew p=(map term foot)] :: XX not used
==
In `++foot`, `$%` creates a list of possible cases. That is, a `++foot`
can be either `%ash`, `%elm`, `%oak` or `%yew`.

View File

@ -0,0 +1,49 @@
[bucket `$^` %bckt](#bckt)
==========================
Normalizing gate, `%herb`
`$^`, is a tile hoon that declares an [`%herb`](). An `%herb` is a gate,
accepting a sample of \* and normalizing it as you choose. If you use a
twig as a tile, it's treated as an herb.
Produces
--------
Tile: `[%herb p=twig]`
Sample
------
`p` is a [twig]().
Tall form
---------
$^ p
Wide form
---------
$^(p)
Irregular form
--------------
None
Examples
--------
~zod/try=> *$^(cord)
''
~zod/try=> *$^(|=(a=* ?^(a a [~ a])))
[~ 0]
~zod/try=> `$^(|=(a=* ?^(a a [~ a])))`1
! type-fail
! exit
~zod/try=> `$^(|=(a=* ?^(a a [~ a])))`[1 2]
[1 2]
~zod/try=> :type; *$^(|=(a=* ?^(a a [~ a])))
[~ 0]
{[%~ @] [* *]}

View File

@ -0,0 +1,62 @@
[buclus `$+` %bcls](#bcls)
==========================
Signature
`$+` a tile for a gate which accepts `p` and produces `q`. `$+` is
similar to a function signature. `$+(p q)` is a `%bark` of a `%weed`, or
`$_(|+(p _q))`.
Produces
--------
Tile: `$_(|+(p _q))`
Sample
------
`p` is a [tile]() `q` is a [tile]()
Tall form
---------
$+ p q
Wide form
---------
$+(p q)
Irregular form
--------------
None
Examples
--------
++ sort :: quicksort
~/ %sort
!:
|* [a=(list) b=$+([* *] ?)]
=> .(a ^.(homo a))
|- ^+ a
?~ a ~
%+ weld
$(a (skim t.a |=(c=_i.a (b c i.a))))
^+ t.a
[i.a $(a (skim t.a |=(c=_i.a !(b c i.a))))]
In ++sort, `$+` is a tile for a comparator gate, which takes two nouns
and produces a loobean.
~zod/try=> |=(a=@ (add 2 a))
<1.sgg [a=@ [[@da @ta] [@p @ta] *''] @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
~zod/try=> `$+(@ @)`|=(a=@ (add 2 a))
<1|crm [@ [[@da @ta] [@p @ta] *''] @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
~zod/try=> +<:|=(a=@ (add 2 a))
a=0
~zod/try=> +<:`$+(@ @)`|=(a=@ (add 2 a))
! -axis.6
! peek-park
! exit

View File

@ -0,0 +1,39 @@
[bucpam `$&` %bcpm](#bcpm)
==========================
Pair / tag
`$&` is a tile rune that produces a `%bush`. A `%bush` is a tile whose
[icon]() is a [fork]() between two different kinds of nouns: cells whose
head is a cell and cells whose head is an atom `(tile q)`. Its default
value is the value of `q`. One important use of `$&` is to implement
autocons in [`++twig`]() and [`++tile`]().
Produces
--------
[Tile](): `[%bush p=tile q=tile]`
Sample
------
`p` is a [tile]().
Tall form
---------
$& p
q
Wide form
---------
$&(p q)
Irregular form
--------------
None
Examples
--------

View File

@ -0,0 +1,37 @@
[bucpat `$@` %bcpt](#bcpt)
==========================
Wing to tile
`$@` is a natural rune that whips (normalizes) wing `p` into tile `q`.
Produces
--------
Tile: `[%bcpt p=wing q=tile]`
Sample
------
`p` is a [`++wing`](). `q` is a [tile]().
Tall form
---------
None
Wide form
---------
None
Irregular form
--------------
p@q
Examples
--------
~zod/try=> =+(a=97 a@cord)
'a'

View File

@ -0,0 +1,38 @@
[buctar `$*` %bctr](#bctr)
==========================
Default value
`$*`, is a synthetic rune that produces the [bunt]() (default value) of
a tile as a compile-time constant if possible. If it is not possible,
then it is produced dynamically.
Produces
--------
[Twig](): `[%bctr p=tile]`
Tall form
---------
$* p
Wide form
---------
$*(p)
Irregular form
--------------
*p
Examples
--------
~zod/try=> *@t
''
~zod/try=> *[@p @ux]
[~zod 0x0]
~zod/try=> *(list ,@)
~

View File

@ -0,0 +1,53 @@
[buctis `$=` %bcts](#bcts)
==========================
Face for tile
`$=` is a tile rune that produces a `%bark`. A `%bark` is a tile that
wraps a [face]() around another tile. Used primarily to add faces to
[nouns]().
Produces
--------
[Tile](): `[%bark p=term q=tile]`
Sample
------
`p` is a [term]().
`q` is a [tile]().
Tall form
---------
$= p
q
Wide form
---------
None
Irregular form
--------------
None
Examples
--------
`a=*` parses as `[%bark %a %noun]`.
~zod/try=> *$=(a @)
a=0
~zod/try=> :type; *$=(a @)
a=0
a=@
~zod/try=> :type; *a=@
a=0
a=@
~zod/try=> :type; *a=[1 2]
a=[%1 %2]
a=[%1 %2]

View File

@ -0,0 +1,48 @@
[bucwut `$?` %bcwt](#bcwt)
==========================
Fork
`$?` produces a fork, called a `%fern`. A `%fern` is a non-empty list of
cases.
Produces
--------
[Tile](): `[%fern p=[i=tile t=(list tile)]]`.
Sample
------
`p` is a [list]() of [tiles]().
Tall form
---------
$? p
q
==
Wide form
---------
None
Irregular form
--------------
?(p q)
Examples
--------
++ base ?([%atom p=odor] %noun %cell %bean %null) :: axils, @ * ^ ? ~
`++base`, `?` (the irregular form of `$?`) specifies a list of
orthoganal cases for the `%axil` tile.
~zod/try=> *?(%a %b %c)
%a
~zod/try=> :type; *?(%a %b %c)
%a
{%a %b %c}

View File

@ -0,0 +1,40 @@
[buczap `$!` %bczp](#bczp)
==========================
Axil bunt
`$!` is an synthetic internal twig that produces the [bunt]() (default
value) for `[%axil p]`.
Produces
--------
[Twig](): `[%bczp p=base]`
Sample
------
`p` is a [base]() [axil]() type.
Tall form
---------
None
Wide form
---------
None
Irregular form
--------------
None
Examples
--------
~zod/try=> (ream '~')
[%bczp p=%null]
~zod/try=> (make '~')
[%1 p=0]

View File

@ -0,0 +1,47 @@
<div class="short">
`bar | %bar`
============
Core construction
-----------------
The `|` runes construct [core]()s. In the broadest case you can think of
a core as similar to an object with named properties that can contain
either functions or data.
The `|` runes accept an associative array of names ([++term]()) to
([++foot]()), each pair of which are called an [++arm](), producing one
of the three basic categories of core.
</div>
#### The natural, generic core:
[`|%`]() Generic core, with [++arms] generally containing [++twig]()s
<hr></hr>
#### Doors, generic core with a sample:
##### Gates:
Cores with one arm [`$`], the empty name and which takes a sample
`p`. The closest thing in Hoon to a function.
[`|=`]() [`dry`]() gate, where the [sample]() is typechecked at compile
time. [`|*`]() [`wet`]() gate, where the sample is typechecked at
runtime against its product type.
##### Traps:
Traps reduce to a `|%` with one arm `$`, the empty name. A trap is just
some computation that has been put inside of a wrapper so that it may be
passed around.
[`|.`]() Generic trap. [`|-`]() Trap automatically [kick]ed (called)
after construction.
<hr></hr>
<kids></kids>

View File

@ -0,0 +1,118 @@
[barcab, `|_`, %brcb](#brcb)
============================
Door: core with sample
`|_` is a synthetic hoon that produces a [`%gold`]() [door]() with
sample `p` and [arms]() `q`. The list must be closed with a `--`.
`|_` is similar to `|%`, but defines a sample for the set of arms it
contains. Moreover, `|_` only accepts [dry or `%elm`]() arms. Put
simply, type checking on these arms is performed on the input before
computation. For more on variance, see the [glossary entry]() and the
examples below.
See also
--------
[barcen, `|%`, `%brcn`]() [barfas, `|/`, `%brfs`]()
Produces
--------
Twig: `[%brcb p=tile q=(map term foot)]`
Sample
------
`p` is a [tile](). `q` is a [`map`]() with [`++term`]() keys and
[`++foot`]() values.
Tall form
---------
|_ p
++ p.n.q
q.n.q
--
Wide form
---------
None
Irregular form
--------------
None
Examples
--------
/~zod/try=> =mol
|_ a=@ud
++ succ +(a)
++ prev (dec a)
--
/~zod/try=> ~(succ mol 1)
2
/~zod/try=> ~(succ mol ~(succ mol ~(prev mol 5)))
6
In this example we create a door `mol` that operates on a [`@ud`](),
`a`. We add two arms to our door, `++succ` and `++prev`, and invoke them
with the irregular form of [`%~`](). Doors are commonly invoked with
`%~`, irregular form `~(arm door sample)`, which replaces the door's
sample and pulls the specified arm.
/~zod/try=> =kom
|_ a=(list)
++ hed -.a
++ tal +.a
--
new var %kom
/~zod/try=> =kot
|/ a=(list)
+- hed -.a
+- tal +.a
--
new var %kot
/~zod/try=> ~(tal kom "abc")
t=~[98 99]
/~zod/try=> ~(tal kot "abc")
t="bc"
/~zod/try=> ~(tal kot [1 2 3 ~])
[2 3 ~]
/~zod/try=> ~(tal kom [1 2 3 ~])
t=~[2 3]
Here we're demonstrating the difference between `|_` and `|/`. We create
a nearly identical door using both runes, each with an arm that produces
the tail of the sample, `a`. You can see that our wet gates use the
sample as a tile to produce well-typed output.
++ ne
|_ tig=@
++ d (add tig '0')
++ x ?:((gte tig 10) (add tig 87) d)
++ v ?:((gte tig 10) (add tig 87) d)
++ w ?:(=(tig 63) '~' ?:(=(tig 62) '-' ?:((gte tig 36) (add tig 29) x)))
--
::
`++ne` is used to print a single digit in base 10, 16, 32, or 64 and is
a part of the hoon standard library. You can find it in `hoon.hoon`.
`|_` is very commonly used throughout our standard library for groups of
arms who all take the same sample.
~zod/try=> ~(x ne 12)
99
~zod/try=> `@t`~(x ne 12)
'c'
~zod/try=> `@ux`12
0xc
Here we put `++ne` to work a bit. Our first call renders 12 in base 16.
Since `99` is within the ASCII character range, we can cast it to a
[`@t`]() and get `'c'`. Conveniently, casting `12` to a [`@ux`]()
results in `0xc`.

Some files were not shown because too many files have changed in this diff Show More