mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-05 13:55:54 +03:00
Merge branch 'test' into memorable
Conflicts: Makefile gen164/watt.c
This commit is contained in:
commit
07cf59be1b
@ -225,7 +225,7 @@
|
||||
0w0 :: 54, ~wyd, Curtis Yarvin (sator)
|
||||
0w0 :: 55, ~tep, Curtis Yarvin (sator)
|
||||
0w0 :: 56, ~bes, Curtis Yarvin (sator)
|
||||
0w0 :: 57, ~dex, Curtis Yarvin (sator)
|
||||
0w0 :: 57, ~dex, Jared Hance (aestas)
|
||||
0w0 :: 58, ~sef, Curtis Yarvin (sator)
|
||||
0w0 :: 59, ~wyc, Curtis Yarvin (sator)
|
||||
0w0 :: 60, ~bur, Curtis Yarvin (sator)
|
||||
@ -240,7 +240,7 @@
|
||||
0w0 :: 69, ~pet, Curtis Yarvin (sator)
|
||||
0w0 :: 70, ~rul, Curtis Yarvin (sator)
|
||||
0w0 :: 71, ~syn, Curtis Yarvin (sator)
|
||||
0w0 :: 72, ~reg, Curtis Yarvin (sator)
|
||||
0w0 :: 72, ~reg, Henry Ault (aestas)
|
||||
0w0 :: 73, ~tyd, Curtis Yarvin (sator)
|
||||
0w0 :: 74, ~sup, Curtis Yarvin (sator)
|
||||
0w0 :: 75, ~sem, ~boswed-nibnyd (fidelis)
|
||||
@ -255,9 +255,9 @@
|
||||
0w2x.~ldho.Oo7kE.QqNSx.XteFh :: 84, ~web, Ar Vicco (donum)
|
||||
0w0 :: 85, ~sum, Curtis Yarvin (sator)
|
||||
0w0 :: 86, ~mut, Curtis Yarvin (sator)
|
||||
0w0 :: 87, ~nyx, urbit.org (civitas)
|
||||
0w0 :: 87, ~nyx, Curtis Yarvin (sator)
|
||||
0w30.UUr19.iBPlD.wfyJD.2CWPv :: 88, ~rex, Ben Davenport (angelus)
|
||||
0w0 :: 89, ~teb, urbit.org (civitas)
|
||||
0w0 :: 89, ~teb, Curtis Yarvin (sator)
|
||||
0w0 :: 90, ~fus, urbit.org (civitas)
|
||||
0w0 :: 91, ~hep, urbit.org (civitas)
|
||||
0w0 :: 92, ~ben, urbit.org (civitas)
|
||||
@ -277,7 +277,7 @@
|
||||
0w0 :: 106, ~bet, urbit.org (civitas)
|
||||
0w0 :: 107, ~bel, urbit.org (civitas)
|
||||
0w0 :: 108, ~tux, Chen Zheng (angelus)
|
||||
0w0 :: 109, ~tug, urbit.org (civitas)
|
||||
0w0 :: 109, ~tug, Philip Monk (aestas)
|
||||
0w0 :: 110, ~myr, urbit.org (civitas)
|
||||
0w0 :: 111, ~pel, urbit.org (civitas)
|
||||
0w0 :: 112, ~syp, urbit.org (civitas)
|
||||
@ -316,7 +316,7 @@
|
||||
0w0 :: 145, ~leb, ~nosryl-tarpem (fidelis)
|
||||
0w0 :: 146, ~dux, urbit.org (civitas)
|
||||
0w0 :: 147, ~ryn, urbit.org (civitas)
|
||||
0w0 :: 148, ~num, urbit.org (civitas)
|
||||
0w0 :: 148, ~num, Tlon (gleba)
|
||||
0w0 :: 149, ~pyx, ~racbes-solmun (fidelis)
|
||||
0w2g.gLmg4.MtrHQ.A5VmH.WPk6G :: 150, ~ryg, Dan Haffey (fortuna)
|
||||
0w0 :: 151, ~ryx, Tlon (gleba)
|
||||
@ -415,7 +415,7 @@
|
||||
0w0 :: 244, ~byr, Tlon (gleba)
|
||||
0w0 :: 245, ~sen, Tlon (gleba)
|
||||
0w0 :: 246, ~weg, Tlon (gleba)
|
||||
0w0 :: 247, ~fyr, Tlon (gleba)
|
||||
0wU.VWcJa.TR1rQ.ONSCN.Mi5TW :: 247, ~fyr, Anton Dyudin (aestas)
|
||||
0w0 :: 248, ~mur, Tlon (gleba)
|
||||
0w0 :: 249, ~tel, Tlon (gleba)
|
||||
0w0 :: 250, ~rep, Tlon (gleba)
|
||||
@ -439,7 +439,7 @@
|
||||
vix=(bex +((cut 0 [25 2] mag))) :: width of sender
|
||||
tay=(cut 0 [27 5] mag) :: message type
|
||||
==
|
||||
?> =(0 vez)
|
||||
?> =(7 vez)
|
||||
?> =(chk (end 0 20 (mug bod)))
|
||||
:+ [(end 3 wix bod) (cut 3 [wix vix] bod)]
|
||||
(kins tay)
|
||||
@ -459,7 +459,7 @@
|
||||
=+ tay=(ksin q.kec)
|
||||
%+ mix
|
||||
%+ can 0
|
||||
:~ [3 0]
|
||||
:~ [3 7]
|
||||
[20 (mug bod)]
|
||||
[2 yax]
|
||||
[2 qax]
|
||||
@ -1047,7 +1047,7 @@
|
||||
++ gnaw :: gnaw:am
|
||||
|= [kay=cape ryn=lane pac=rock] :: process packet
|
||||
^- [p=(list boon) q=fort]
|
||||
?. =(0 (end 0 3 pac)) [~ fox]
|
||||
?. =(7 (end 0 3 pac)) [~ fox]
|
||||
=+ kec=(bite pac)
|
||||
?: (goop p.p.kec) [~ fox]
|
||||
?. (~(has by urb.ton.fox) q.p.kec)
|
||||
@ -1342,7 +1342,7 @@
|
||||
+>(..la (tuck p.fud q.fud r.fud))
|
||||
::
|
||||
%buck
|
||||
=. +> ?.(=(%full aut) +> cock)
|
||||
=. +> ?.(=(%full aut) +> cock) :: finish key exch
|
||||
+>(..la (tock p.fud q.fud r.fud))
|
||||
::
|
||||
%bond
|
||||
@ -1819,7 +1819,7 @@
|
||||
:: ~& [%knap soq num pax]
|
||||
=+ ^= fuy
|
||||
=< zork =< zank
|
||||
%+ ~(rack am [now fox]) soq :- pax
|
||||
%^ ~(rack am [now fox]) soq pax
|
||||
?-(+<.sih %mean `p.+.sih, %nice ~)
|
||||
=> %_(. fox q.fuy)
|
||||
=| out=(list move)
|
||||
|
@ -2,7 +2,7 @@
|
||||
::
|
||||
|= pit=vase
|
||||
=> |%
|
||||
++ cult (map duct rave) :: subscriptions
|
||||
++ cult (map duct rove) :: subscriptions
|
||||
++ dojo ,[p=cult q=dome] :: domestic desk state
|
||||
++ gift :: out result <-$
|
||||
$% [%ergo p=@p q=@tas r=@ud] :: version update
|
||||
@ -20,6 +20,7 @@
|
||||
[%wart p=sock q=@tas r=path s=*] :: network request
|
||||
[%warp p=sock q=riff] :: file request
|
||||
== ::
|
||||
++ moot ,[p=case q=case r=path s=(map path lobe)] ::
|
||||
++ move ,[p=duct q=(mold note gift)] :: local move
|
||||
++ nako $: gar=(map ,@ud tako) :: new ids
|
||||
let=@ud :: next id
|
||||
@ -74,6 +75,7 @@
|
||||
hez=(unit duct) :: sync duch
|
||||
dos=(map desk dojo) :: native desk
|
||||
== ::
|
||||
++ rove (each mood moot) ::
|
||||
++ rung $: rus=(map desk rede) :: neighbor desks
|
||||
== ::
|
||||
-- =>
|
||||
@ -135,7 +137,7 @@
|
||||
+>(byn [[hen ~ [p.mun q.mun syd] r.mun dat] byn])
|
||||
::
|
||||
++ bleb :: ship sequence
|
||||
|= [hen=duct ins=@ud hip=nako]
|
||||
|= [hen=duct ins=@ud hip=*]
|
||||
^+ +>
|
||||
(blab hen [%w [%ud ins] ~] hip)
|
||||
::
|
||||
@ -147,13 +149,13 @@
|
||||
=+ xiq=(~(tap by qyx) ~)
|
||||
^- (unit ,@da)
|
||||
%+ roll xiq
|
||||
|= [xaq=[p=duct q=rave] nex=(unit ,@da)]
|
||||
|= [xaq=[p=duct q=rove] nex=(unit ,@da)]
|
||||
%+ hunt nex
|
||||
?- -.q.xaq
|
||||
& ?.(?=(%da -.q.p.q.xaq) ~ [~ p.q.p.q.xaq])
|
||||
::
|
||||
|
|
||||
=+ mot=`moat`p.q.xaq
|
||||
=+ mot=`moot`p.q.xaq
|
||||
%+ hunt
|
||||
?. ?=(%da -.p.mot) ~
|
||||
?.((lth now p.p.mot) ~ [~ p.p.mot])
|
||||
@ -162,14 +164,15 @@
|
||||
==
|
||||
::
|
||||
++ duce :: produce request
|
||||
|= [hen=duct rav=rave]
|
||||
|= [hen=duct rov=rove]
|
||||
^+ +>
|
||||
=. qyx (~(put by qyx) hen rav)
|
||||
?~ ref +>
|
||||
|- ^+ +>+.$
|
||||
=. qyx (~(put by qyx) hen rov)
|
||||
?~ ref +>.$
|
||||
|- ^+ +>+.$ :: XX why?
|
||||
=+ rav=(reve rov)
|
||||
=+ ^= vaw ^- rave
|
||||
?. ?=([%& %v *] rav) rav
|
||||
[%| [%ud let.dom] `case`q.p.rav]
|
||||
[%| [%ud let.dom] `case`q.p.rav r.p.rav]
|
||||
=+ inx=nix.u.ref
|
||||
%= +>+.$
|
||||
say [[hen [(scot %ud inx) ~] for [inx syd ~ vaw]] say]
|
||||
@ -211,18 +214,22 @@
|
||||
=+ nab=(~(aeon ze lim dom ran) p.p.rav)
|
||||
?~ nab
|
||||
?> =(~ (~(aeon ze lim dom ran) q.p.rav))
|
||||
(duce hen rav)
|
||||
~! [%um rav]
|
||||
(duce hen (rive rav))
|
||||
=+ huy=(~(aeon ze lim dom ran) q.p.rav)
|
||||
?: &(?=(^ huy) |((lth u.huy u.nab) &(=(0 u.huy) =(0 u.nab))))
|
||||
(blub hen)
|
||||
=+ top=?~(huy let.dom u.huy)
|
||||
=+ fud=(~(gack ze lim dom ran) u.nab let.dom)
|
||||
=. +>.$ (bleb hen u.nab fud)
|
||||
=+ sar=(~(apax ze lim dom ran) u.nab r.p.rav)
|
||||
=+ ear=(~(apax ze lim dom ran) top r.p.rav)
|
||||
=. +>.$ ?: =(sar ear) +>.$
|
||||
=+ fud=(~(gack ze lim dom ran) u.nab top)
|
||||
(bleb hen u.nab fud)
|
||||
?^ huy
|
||||
(blub hen)
|
||||
=+ ^= ptr ^- case
|
||||
[%ud +(let.dom)]
|
||||
(duce hen `rave`[%| ptr q.p.rav])
|
||||
(duce hen `rove`[%| ptr q.p.rav r.p.rav ear])
|
||||
==
|
||||
::
|
||||
++ echa :: announce raw
|
||||
@ -336,10 +343,21 @@
|
||||
haw.u.ref (~(del by haw.u.ref) nez)
|
||||
==
|
||||
::
|
||||
++ reve
|
||||
|= rov=rove
|
||||
^- rave
|
||||
?: ?=(%& -.rov) rov
|
||||
[%| p.p.rov q.p.rov r.p.rov]
|
||||
::
|
||||
++ rive
|
||||
|= rav=[%| p=moat]
|
||||
^- rove
|
||||
[%| p.p.rav q.p.rav r.p.rav ~]
|
||||
::
|
||||
++ wake :: update subscribers
|
||||
^+ .
|
||||
=+ xiq=(~(tap by qyx) ~)
|
||||
=| xaq=(list ,[p=duct q=rave])
|
||||
=| xaq=(list ,[p=duct q=rove])
|
||||
|- ^+ ..wake
|
||||
?~ xiq
|
||||
..wake(qyx (~(gas by *cult) xaq))
|
||||
@ -357,23 +375,28 @@
|
||||
$(xiq t.xiq, ..wake (balk p.i.xiq u.nao p.q.i.xiq))
|
||||
::
|
||||
|
|
||||
=+ mot=`moat`p.q.i.xiq
|
||||
=+ mot=`moot`p.q.i.xiq
|
||||
=+ nab=(~(aeon ze lim dom ran) p.mot)
|
||||
?~ nab
|
||||
$(xiq t.xiq, xaq [i.xiq xaq])
|
||||
=+ huy=(~(aeon ze lim dom ran) q.mot)
|
||||
?~ huy
|
||||
=+ ptr=[%ud +(let.dom)]
|
||||
=+ fud=`nako`(~(gack ze lim dom ran) u.nab let.dom)
|
||||
%= $
|
||||
xiq t.xiq
|
||||
xaq [[p.i.xiq [%| ptr q.mot]] xaq]
|
||||
..wake (bleb p.i.xiq let.dom fud)
|
||||
xaq [[p.i.xiq [%| ptr q.mot r.mot s.mot]] xaq]
|
||||
..wake =+ ear=(~(apax ze lim dom ran) let.dom r.p.q.i.xiq)
|
||||
?: =(s.p.q.i.xiq ear) ..wake
|
||||
=+ fud=(~(gack ze lim dom ran) u.nab let.dom)
|
||||
(bleb p.i.xiq let.dom ear)
|
||||
==
|
||||
=+ fud=(~(gack ze lim dom ran) u.nab u.huy)
|
||||
%= $
|
||||
xiq t.xiq
|
||||
..wake (blub:(bleb p.i.xiq +(u.nab) fud) p.i.xiq)
|
||||
..wake =- (blub:- p.i.xiq)
|
||||
=+ ear=(~(apax ze lim dom ran) u.huy r.p.q.i.xiq)
|
||||
?: =(s.p.q.i.xiq ear) ..wake
|
||||
=+ fud=(~(gack ze lim dom ran) u.nab u.huy)
|
||||
(bleb p.i.xiq +(u.nab) ear)
|
||||
==
|
||||
==
|
||||
--
|
||||
|
457
arvo/eyre.hoon
457
arvo/eyre.hoon
@ -139,8 +139,7 @@
|
||||
hen=duct :: event trace
|
||||
som=seam :: logical request
|
||||
pez=pest :: request state
|
||||
vaz=(list ,[p=cord q=tape]) :: variables
|
||||
sip=(list manx) :: scripts in result
|
||||
sip=marl :: injected scripts
|
||||
== ::
|
||||
++ rote :: remote server
|
||||
$: cnt=@ud :: number served
|
||||
@ -152,6 +151,7 @@
|
||||
[%aph p=ship q=@ud r=@ud s=json] :: app heartbeat
|
||||
[%apg p=term q=ship r=mark s=path] :: app get/start
|
||||
[%apm p=ship q=@ud r=@ud s=hasp t=json] :: message send
|
||||
[%app p=ship q=(unit ,@ud)] :: script by port
|
||||
[%aps p=ship q=@ud s=hasp t=path] :: subscribe
|
||||
[%apu p=ship q=@ud s=hasp t=path] :: unsubscribe
|
||||
[%cog p=@ud q=@ud] :: console get
|
||||
@ -226,7 +226,8 @@
|
||||
=+ ten=(~(get by q.moh) 'content-type')
|
||||
?~ ten ~
|
||||
?~ u.ten ~
|
||||
?. =('text/json' (end 3 9 i.u.ten)) ~
|
||||
?. =('text/json' (end 3 9 i.u.ten))
|
||||
~| %ecce-content-type ~
|
||||
?~ r.moh ~
|
||||
`(unit json)`(rush q.u.r.moh apex:poja)
|
||||
::
|
||||
@ -314,28 +315,6 @@
|
||||
=+ rep=:(welp p.hop scr q.q.hop)
|
||||
[%mid p.luv (tact rep)]
|
||||
==
|
||||
++ lofe :: variables in head
|
||||
|= [vaz=(list ,[p=cord q=tape]) luv=love]
|
||||
%- lofa
|
||||
:_ luv
|
||||
:_ ~
|
||||
^- manx
|
||||
:- [%script ~]
|
||||
:- :/ "window.urb = \{};\0a"
|
||||
(turn vaz |=([a=cord b=tape] :/("window.urb.{(trip a)}={b};\0a")))
|
||||
::
|
||||
++ lofi :: insert in body
|
||||
|= [mog=(list manx) luv=love]
|
||||
^- love
|
||||
?: =(~ mog) luv
|
||||
?+ -.luv luv
|
||||
%mid
|
||||
?. =(/text/html p.luv) luv
|
||||
=+ str=(trip q.q.luv)
|
||||
=+ scr=|-(^-(tape ?~(mog "</body>" (xmlt & i.mog $(mog t.mog)))))
|
||||
=+ rep=(need (repg "</body>" str scr))
|
||||
[%mid p.luv (tact rep)]
|
||||
==
|
||||
::
|
||||
++ loft :: love to response
|
||||
|= luv=love
|
||||
@ -390,9 +369,8 @@
|
||||
(slav %ud i.t.t.t.tea)
|
||||
?~ ouy
|
||||
+>.$
|
||||
:: ?: (lth ~m2 (sub now tim.bet.siq:beat:u.ouy))
|
||||
:: ~& %axon-heartbeat
|
||||
:: abet:work:amok:u.ouy
|
||||
?: (lth ~m2 (sub now tim.bet.siq:beat:u.ouy))
|
||||
abet:work:amok:u.ouy
|
||||
=* mab t.t.t.t.tea
|
||||
=+ woy=(yule:u.ouy ?+(i.mab !! %mess %meg, %show %sub))
|
||||
=< abet =< work =< abet
|
||||
@ -608,7 +586,7 @@
|
||||
=+ cyz=(need (~(get by wup.sef) ses))
|
||||
~(. ya [our ses] sef cyz)
|
||||
::
|
||||
++ galt
|
||||
++ galt ::
|
||||
|= [our=ship ses=hole num=@ud mez=(each bead (list tank))]
|
||||
^+ +>
|
||||
=+ suf=(~(get by own) our)
|
||||
@ -918,116 +896,115 @@
|
||||
|= [our=ship whu=(unit ship) rul=tape ruf=tape]
|
||||
^- manx
|
||||
=+ ^= sic ^- manx
|
||||
;script
|
||||
;
|
||||
; var seal = {
|
||||
; who: goal,
|
||||
; url: burl,
|
||||
; pas: null
|
||||
; }
|
||||
; var hist = []
|
||||
; var hind = 0
|
||||
; $(
|
||||
; function() {
|
||||
; $input = $('#input .line')
|
||||
; $prompt = $('#input .prompt')
|
||||
; $prompt.addClass('prefix')
|
||||
; $output = $('#output')
|
||||
; $input.focus()
|
||||
; $('body').click(function() { $input.focus() })
|
||||
; ctrl = false;
|
||||
;
|
||||
; start = function(ship) {
|
||||
; $prompt.text('vessel: ~')
|
||||
; $input.attr('placeholder', 'ship-name')
|
||||
; if(ship) {
|
||||
; $input.val(ship)
|
||||
; }
|
||||
; }
|
||||
;
|
||||
; ident = function() {
|
||||
; seal.who = $input.val()
|
||||
;
|
||||
; if( (seal.who.length != 13) &&
|
||||
; (seal.who.length != 6) &&
|
||||
; (seal.who.length != 3) )
|
||||
; {
|
||||
; $output.text('not a ship name - try again.');
|
||||
; return false;
|
||||
; }
|
||||
;
|
||||
; if(seal.who !== host) {
|
||||
; var foreign = {oth: host, ses: session};
|
||||
; var all = $.extend({}, seal, foreign);
|
||||
;
|
||||
; console.log('redirect')
|
||||
; window.location="http://"+seal.who+".urbit.org/gul"
|
||||
; + $.params(all);
|
||||
; return false;
|
||||
; }
|
||||
;
|
||||
; $output.text($prompt.text() + " " + seal.who)
|
||||
; $input.val('')
|
||||
; $input.attr('placeholder', 'ronber-bacnub-hanmev-labnyd')
|
||||
; $prompt.text('secret: ~')
|
||||
;
|
||||
; return true;
|
||||
; }
|
||||
;
|
||||
; login = function() {
|
||||
; seal.pas = $input.val()
|
||||
;
|
||||
; output = $output.html()
|
||||
; console.log($output.html())
|
||||
; $output.html(output.replace('sorry. please try again.<br>',''))
|
||||
;
|
||||
; $.post(form, seal, function(data,xhr,status) {
|
||||
; console.log(data);
|
||||
; if(data.ok == true) {
|
||||
; document.location = data.next;
|
||||
; } else {
|
||||
; $output.prepend('sorry. please try again.<br>')
|
||||
; }
|
||||
; })
|
||||
; }
|
||||
;
|
||||
; steps = [ident,login]
|
||||
; step = 0
|
||||
; start(seal.who)
|
||||
; if(seal.who) {
|
||||
; ident()
|
||||
; step++
|
||||
; }
|
||||
;
|
||||
; $input.on('keydown', function(e) {
|
||||
; if(e.keyCode == 17) {
|
||||
; ctrl = true
|
||||
; return;
|
||||
; }
|
||||
;
|
||||
; if(e.keyCode == 68 &&
|
||||
; ctrl == true &&
|
||||
; step == 1) {
|
||||
; $output.text('')
|
||||
; step = 0
|
||||
; start(null)
|
||||
; return;
|
||||
; }
|
||||
;
|
||||
; if(e.keyCode == 13) {
|
||||
; if(steps[step]() && step < steps.length-1)
|
||||
; step++
|
||||
; return;
|
||||
; }
|
||||
; });
|
||||
;
|
||||
; $input.on('keyup', function(e) {
|
||||
; if(e.keyCode == 17) {
|
||||
; ctrl = false
|
||||
; }
|
||||
; });
|
||||
; })
|
||||
==
|
||||
;script:'''
|
||||
var seal = {
|
||||
who: goal,
|
||||
url: burl,
|
||||
pas: null
|
||||
}
|
||||
var hist = []
|
||||
var hind = 0
|
||||
$(
|
||||
function() {
|
||||
$input = $('#input .line')
|
||||
$prompt = $('#input .prompt')
|
||||
$prompt.addClass('prefix')
|
||||
$output = $('#output')
|
||||
$input.focus()
|
||||
$('body').click(function() { $input.focus() })
|
||||
ctrl = false;
|
||||
|
||||
start = function(ship) {
|
||||
$prompt.text('vessel: ~')
|
||||
$input.attr('placeholder', 'ship-name')
|
||||
if(ship) {
|
||||
$input.val(ship)
|
||||
}
|
||||
}
|
||||
|
||||
ident = function() {
|
||||
seal.who = $input.val()
|
||||
|
||||
if( (seal.who.length != 13) &&
|
||||
(seal.who.length != 6) &&
|
||||
(seal.who.length != 3) )
|
||||
{
|
||||
$output.text('not a ship name - try again.');
|
||||
return false;
|
||||
}
|
||||
|
||||
if(seal.who !== host) {
|
||||
var foreign = {oth: host, ses: session};
|
||||
var all = $.extend({}, seal, foreign);
|
||||
|
||||
console.log('redirect')
|
||||
window.location="http://"+seal.who+".urbit.org/gul"
|
||||
+ $.params(all);
|
||||
return false;
|
||||
}
|
||||
|
||||
$output.text($prompt.text() + " " + seal.who)
|
||||
$input.val('')
|
||||
$input.attr('placeholder', 'ronber-bacnub-hanmev-labnyd')
|
||||
$prompt.text('secret: ~')
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
login = function() {
|
||||
seal.pas = $input.val()
|
||||
|
||||
output = $output.html()
|
||||
console.log($output.html())
|
||||
$output.html(output.replace('sorry. please try again.<br>',''))
|
||||
|
||||
$.post(form, seal, function(data,xhr,status) {
|
||||
console.log(data);
|
||||
if(data.ok == true) {
|
||||
document.location = data.next;
|
||||
} else {
|
||||
$output.prepend('sorry. please try again.<br>')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
steps = [ident,login]
|
||||
step = 0
|
||||
start(seal.who)
|
||||
if(seal.who) {
|
||||
ident()
|
||||
step++
|
||||
}
|
||||
|
||||
$input.on('keydown', function(e) {
|
||||
if(e.keyCode == 17) {
|
||||
ctrl = true
|
||||
return;
|
||||
}
|
||||
|
||||
if(e.keyCode == 68 &&
|
||||
ctrl == true &&
|
||||
step == 1) {
|
||||
$output.text('')
|
||||
step = 0
|
||||
start(null)
|
||||
return;
|
||||
}
|
||||
|
||||
if(e.keyCode == 13) {
|
||||
if(steps[step]() && step < steps.length-1)
|
||||
step++
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
$input.on('keyup', function(e) {
|
||||
if(e.keyCode == 17) {
|
||||
ctrl = false
|
||||
}
|
||||
});
|
||||
})
|
||||
'''
|
||||
=+ ^= cof
|
||||
;=
|
||||
; var host = '{(trip (rsh 3 1 (scot %p our)))}';
|
||||
@ -1041,32 +1018,32 @@
|
||||
;head
|
||||
;title: urbit login
|
||||
;script(type "text/javascript", src jqu);
|
||||
;style
|
||||
; body {
|
||||
; margin: 60px 120px;
|
||||
; font: normal 12px "Menlo" monospace;
|
||||
; background-color: #000;
|
||||
; color: #fff;
|
||||
; }
|
||||
;
|
||||
; #output {
|
||||
;
|
||||
; }
|
||||
;
|
||||
; #input .prompt {
|
||||
; display: inline-block;
|
||||
; margin-right: 12px;
|
||||
; }
|
||||
;
|
||||
; #input .line {
|
||||
; outline: none;
|
||||
; width: 80%;
|
||||
; border: 0;
|
||||
; background-color: transparent;
|
||||
; color: #fff;
|
||||
; font: normal 12px "Menlo" monospace;
|
||||
; }
|
||||
==
|
||||
;style:'''
|
||||
body {
|
||||
margin: 60px 120px;
|
||||
font: normal 12px "Menlo" monospace;
|
||||
background-color: #000;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#output {
|
||||
|
||||
}
|
||||
|
||||
#input .prompt {
|
||||
display: inline-block;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
#input .line {
|
||||
outline: none;
|
||||
width: 80%;
|
||||
border: 0;
|
||||
background-color: transparent;
|
||||
color: #fff;
|
||||
font: normal 12px "Menlo" monospace;
|
||||
}
|
||||
'''
|
||||
==
|
||||
=+ ^= bod ^- manx
|
||||
;body
|
||||
@ -1148,30 +1125,24 @@
|
||||
?> ?=(%way pez.u.pup)
|
||||
$(yov t.yov, q.rey (~(put by q.rey) i.yov u.pup(pez noz)))
|
||||
::
|
||||
++ duti :: heartbeat script
|
||||
;script:'''
|
||||
window.urb.seqn_h = 0
|
||||
window.urb.heartbeat = function() {
|
||||
this.poll({
|
||||
type:"heb",
|
||||
ship:this.ship,
|
||||
dely:30000,
|
||||
incs:function() {
|
||||
window.urb.seqn_h++
|
||||
}
|
||||
},function() {
|
||||
console.log('heartbeat.')
|
||||
})
|
||||
}
|
||||
// XX 404 bug
|
||||
// window.urb.heartbeat()
|
||||
++ duty |= [our=ship nap=@ud you=ship orx=oryx] :: interface script
|
||||
^- cord
|
||||
%^ cat 3
|
||||
%- crip
|
||||
=- "window.urb = {(pojo (jobe -))}\0a"
|
||||
:~
|
||||
[%ship (jape |1:<our>)]
|
||||
[%port (jone nap)]
|
||||
[%auto %b %&]
|
||||
[%user (jape |1:<you>)]
|
||||
[%oryx %s orx]
|
||||
==
|
||||
'''
|
||||
::
|
||||
++ duty
|
||||
;script:'''
|
||||
window.urb.seqn_u = 0
|
||||
window.urb.seqn_h = 0
|
||||
window.urb.dely = 0
|
||||
window.urb.puls = 0
|
||||
window.urb.cabs = {}
|
||||
window.urb.perms = {
|
||||
pol:"gie",
|
||||
sub:"tis",
|
||||
@ -1241,8 +1212,11 @@
|
||||
}
|
||||
|
||||
window.urb.gsig = function(params) {
|
||||
path = params.path
|
||||
if(!path)
|
||||
path = ""
|
||||
return params.appl+","+
|
||||
params.path.replace(/[^\x00-\x7F]/g, "")+","+
|
||||
path.replace(/[^\x00-\x7F]/g, "")+","+
|
||||
params.ship
|
||||
}
|
||||
|
||||
@ -1251,16 +1225,23 @@
|
||||
throw new Error("You must supply params to urb.poll.")
|
||||
|
||||
var method, perm, url, $this
|
||||
|
||||
method = "get"
|
||||
perm = params.type ? this.perms[params.type] : "gie"
|
||||
url = [perm,this.user,this.port,this.seqn_u]
|
||||
json = false
|
||||
if(perm[0] == "t") {
|
||||
method = "put"
|
||||
json = true
|
||||
}
|
||||
seqn = this.seqn_u
|
||||
if(params.seqn)
|
||||
seqn = params.seqn()
|
||||
url = [perm,this.user,this.port,seqn]
|
||||
url = "/"+url.join("/")
|
||||
|
||||
this.puls = 1
|
||||
|
||||
$this = this
|
||||
this.req(method,url,params,false,function(err,data) {
|
||||
this.req(method,url,params,json,function(err,data) {
|
||||
if (data.data.reload) {
|
||||
return document.location.reload()
|
||||
} else {
|
||||
@ -1297,6 +1278,23 @@
|
||||
}
|
||||
window.urb.poll(param)
|
||||
}
|
||||
|
||||
window.urb.heartbeat = function() {
|
||||
this.poll({
|
||||
type:"heb",
|
||||
ship:this.ship,
|
||||
dely:30000,
|
||||
seqn:function() {
|
||||
return window.urb.seqn_h
|
||||
},
|
||||
incs:function() {
|
||||
window.urb.seqn_h = window.urb.seqn_h+1
|
||||
}
|
||||
},function() {
|
||||
console.log('heartbeat.')
|
||||
})
|
||||
}
|
||||
window.urb.heartbeat()
|
||||
'''
|
||||
::
|
||||
++ fape :: dispatch %ape
|
||||
@ -1350,6 +1348,18 @@
|
||||
(need (eccu orx.ced moh))
|
||||
==
|
||||
::
|
||||
++ fapp
|
||||
|= [fur=(unit term) you=@p paw=path]
|
||||
?> ?=([~ %js] fur)
|
||||
?> ?=(?([%hart ~] [@ %hart ~]) paw)
|
||||
:- ~
|
||||
:* %app
|
||||
you
|
||||
?~ t.paw
|
||||
~
|
||||
(some (slav %ui (cat 3 '0i' i.paw)))
|
||||
==
|
||||
::
|
||||
++ faps :: dispatch %aps
|
||||
|= [fur=(unit term) you=@p paw=path moh=moth]
|
||||
^- (unit seam)
|
||||
@ -1455,8 +1465,9 @@
|
||||
==
|
||||
::
|
||||
++ foin :: version request
|
||||
|= [fur=(unit term) paw=(list ,@t) quy=quay]
|
||||
|= [fur=(unit term) you=@p paw=(list ,@t) quy=quay]
|
||||
^- (unit seam)
|
||||
=. aut.ced (~(put ju aut.ced) %$ (scot %p you)) :: XX backwards
|
||||
?. ?& ?=(~ fur)
|
||||
?=(~ quy)
|
||||
?=([@ @ ~] paw)
|
||||
@ -1470,17 +1481,18 @@
|
||||
~
|
||||
::
|
||||
[%$ ?(%da %ud %tas) @]
|
||||
[~ (case p.u.soy) (case p.u.soy)]
|
||||
[~ (case p.u.soy) (case p.u.soy) /]
|
||||
::
|
||||
[%many [%$ ?(%da %ud %tas) @] [%$ ?(%da %ud %tas) @] ~]
|
||||
[~ (case i.p.u.soy) (case i.t.p.u.soy)]
|
||||
[~ (case i.p.u.soy) (case i.t.p.u.soy) /]
|
||||
==
|
||||
|= mot=moat
|
||||
`seam`[%det i.t.paw mot]
|
||||
::
|
||||
++ funk :: functional request
|
||||
|= [nep=@tas fur=(unit term) paw=(list ,@t) quy=quay]
|
||||
|= [nep=@tas fur=(unit term) you=@p paw=(list ,@t) quy=quay]
|
||||
^- (unit seam)
|
||||
=. aut.ced (~(put ju aut.ced) %$ (scot %p you)) :: XX backwards
|
||||
=+ won==(%n (rsh 3 2 nep))
|
||||
%+ bind
|
||||
^- (unit ,[mark tube])
|
||||
@ -1508,11 +1520,15 @@
|
||||
toe(s (weld s.toe `path`[~(rent co (flux [nep ~] quy)) %web ~]))
|
||||
?. won ~
|
||||
:_ ~
|
||||
=- =+ pey=(cat 3 (end 3 2 nep) %v)
|
||||
=- =+ pey="{(scag 2 (trip nep))}v"
|
||||
=. pey %+ weld pey
|
||||
?. =(%i (snag 1 pey))
|
||||
""
|
||||
"/{(slag 1 (scow %p you))}"
|
||||
=+ ven=+((,@ (need (sky %cw p.toe q.toe r.toe ~))))
|
||||
=+ ^= cal :/
|
||||
"path='".
|
||||
"/{(trip pey)}".
|
||||
"/{pey}".
|
||||
"/{(scow %ud ven)}".
|
||||
"/{(trip q.toe)}';"
|
||||
[-.sac [cal +.sac]]
|
||||
@ -1591,6 +1607,7 @@
|
||||
%r :: app response
|
||||
%s :: app subscribe
|
||||
%h :: app heartbeat
|
||||
%p :: app script by port
|
||||
%n :: now
|
||||
%u :: app unsubscribe
|
||||
%z :: app version
|
||||
@ -1615,12 +1632,13 @@
|
||||
?+ one ~
|
||||
%g
|
||||
?+ tri ~
|
||||
?(%f %n) (funk nep p.q.pul paw r.pul)
|
||||
%v (foin p.q.pul paw r.pul)
|
||||
?(%f %n) (funk nep p.q.pul yun paw r.pul)
|
||||
%v (foin p.q.pul yun paw r.pul)
|
||||
%c (flub paw ~)
|
||||
%l (fool r.pul)
|
||||
%g (fapg p.q.pul yun paw)
|
||||
%e (fape p.q.pul yun paw)
|
||||
%p (fapp p.q.pul yun paw)
|
||||
==
|
||||
::
|
||||
%p
|
||||
@ -1706,7 +1724,6 @@
|
||||
*seam
|
||||
`pest`[%raw pul moh]
|
||||
~
|
||||
~
|
||||
==
|
||||
==
|
||||
::
|
||||
@ -1777,6 +1794,10 @@
|
||||
:: ~& [%wink-apm +.som.pip]
|
||||
:- [~ pip(pez %way)]
|
||||
(yokm num +.som.pip)
|
||||
::
|
||||
%app :: script by port
|
||||
:: ~& [%wink-app +.som.pip]
|
||||
(yokp num +.som.pip)
|
||||
::
|
||||
%aps :: subscribe
|
||||
:: ~& [%wink-aps +.som.pip]
|
||||
@ -1892,7 +1913,7 @@
|
||||
:+ 500
|
||||
~[content-type/'text/html']
|
||||
[~ (tact (xmlt | mad ~))]
|
||||
& [%fin (lofe vaz.pip (lofi mog (lopo q.p.p.pez.pip)))]
|
||||
& [%fin (lofa mog (lopo q.p.p.pez.pip))]
|
||||
==
|
||||
==
|
||||
::
|
||||
@ -1948,6 +1969,17 @@
|
||||
?~ yon (bust 204 num)
|
||||
abet:(post:u.yon cnt num hap jon)
|
||||
::
|
||||
++ yokp :: script by port
|
||||
|= [num=@ud you=ship nup=(unit ,@ud)]
|
||||
^- [(unit pimp) _+>]
|
||||
?~ nup
|
||||
$(nup [~ num], +> ~(harp yo num you *sink))
|
||||
=+ yon=(yolk u.nup)
|
||||
?~ yon
|
||||
=+ err=(bust 204 num)
|
||||
[`(need (~(get by q.rey.err) num)) err]
|
||||
[- abet:+]:(hark:u.yon num)
|
||||
::
|
||||
++ yoks :: subscribe
|
||||
|= [num=@ud you=ship nap=@ud hap=hasp pax=path]
|
||||
=+ yon=(yolk nap)
|
||||
@ -1991,7 +2023,7 @@
|
||||
(pass(hen hen.q.i.wuh) `p.i.wuh `note`[%g %nuke hap.q.i.wuh you])
|
||||
==
|
||||
::
|
||||
++ beat
|
||||
++ beat
|
||||
|= [cnt=@ud num=@ud jon=json]
|
||||
^- [(unit pimp) _+>]
|
||||
?. =(cnt num.bet.siq)
|
||||
@ -2001,6 +2033,18 @@
|
||||
=. +>.$ (hear:(yule %bet) ~ %& %json !>((joba %a-ok %b %&)))
|
||||
[`(need (~(get by q.rey) num)) +>.$]
|
||||
::
|
||||
++ hark
|
||||
|= num=@ud
|
||||
^- [(unit pimp) _+>]
|
||||
=. +>.$ abet:(busk:(yule %nil) num _@ ~ %& %js !>((duty our nap you orx.ced)))
|
||||
[`(need (~(get by q.rey) num)) +>.$]
|
||||
::
|
||||
++ harp
|
||||
%_ abet
|
||||
tim.bet.siq now
|
||||
num.sub.siq 1
|
||||
==
|
||||
::
|
||||
++ hoop :: request path
|
||||
|= can=(unit ,@ud)
|
||||
^- path
|
||||
@ -2096,22 +2140,17 @@
|
||||
==
|
||||
=+ pip=u.pup
|
||||
=+ ^= sip
|
||||
?. =(%apg -.som.pip) sip.pip
|
||||
[duti duty sip.pip]
|
||||
?. ?=(%apg -.som.pip) sip.pip
|
||||
=* his q.som.pip
|
||||
=+ mef=?:(=(our his) "gop" "gip/{|1:<his>}")
|
||||
[;script(src "/{mef}/{(pojo (jone nap))}/hart.js"); sip.pip]
|
||||
?~ huq +>.$(..yo (bust 404 num))
|
||||
%= +>.$
|
||||
q.rey
|
||||
%+ ~(put by q.rey) num
|
||||
^- pimp
|
||||
=+ quo=|=(a=cord :(weld "\"" (trip a) "\""))
|
||||
%= pip
|
||||
pez %new
|
||||
vaz :~ [%ship (quo (rsh 3 1 (scot %p our)))]
|
||||
[%port (trip (rsh 3 2 (scot %ui nap)))]
|
||||
[%auto "true"]
|
||||
[%oryx (quo orx.ced)]
|
||||
[%user (quo (rsh 3 1 (scot %p you)))]
|
||||
==
|
||||
sip sip
|
||||
som ^- seam
|
||||
:+ %sil
|
||||
|
@ -503,7 +503,7 @@
|
||||
(stag %hub ;~(pfix pat day:read))
|
||||
(stag %man ;~(pfix tar man:read))
|
||||
(stag %nap ;~(pfix cen day:read))
|
||||
(stag %now ;~(pfix fas day:read))
|
||||
(stag %now ;~(pfix pam day:read))
|
||||
(stag %saw ;~(pfix sem saw:read))
|
||||
(stag %see ;~(pfix col see:read))
|
||||
(stag %sic ;~(pfix ket sic:read))
|
||||
|
@ -332,22 +332,28 @@
|
||||
++ gasp :: %x take
|
||||
|= [hen=duct pax=path sih=sign]
|
||||
^- [(list move) _..^$]
|
||||
?: ?=(%a -.sih) [~ ..^$]
|
||||
?> ?=(%f -.sih)
|
||||
:_ ..^$
|
||||
:_ ~
|
||||
:- hen
|
||||
?- -.p.+.sih
|
||||
%|
|
||||
[%give %crud %gasp-crud p.p.+.sih]
|
||||
::
|
||||
%&
|
||||
=+ cay=`cage`q.p.p.+.sih
|
||||
?+ -.pax !!
|
||||
%d [%give (best %rush cay)]
|
||||
%f [%give (best %rust cay)]
|
||||
?+ -.sih !!
|
||||
%a
|
||||
?> ?=(%woot +<.sih)
|
||||
:_ ..^$ :_ ~
|
||||
?~ q.sih
|
||||
[hen %give %nice ~]
|
||||
[hen %give %mean u.q.sih]
|
||||
%f
|
||||
:_ ..^$
|
||||
:_ ~
|
||||
:- hen
|
||||
?- -.p.+.sih
|
||||
%|
|
||||
[%give %crud %gasp-crud p.p.+.sih]
|
||||
::
|
||||
%&
|
||||
=+ cay=`cage`q.p.p.+.sih
|
||||
?+ -.pax !!
|
||||
%d [%give (best %rush cay)]
|
||||
%f [%give (best %rust cay)]
|
||||
== ==
|
||||
==
|
||||
==
|
||||
::
|
||||
++ gave :: %r take
|
||||
|= [hen=duct pax=path sih=sign]
|
||||
@ -630,7 +636,7 @@
|
||||
:- hun.mat
|
||||
:^ %pass (away %w %drug (scot %p p.a) q.a ~) %c
|
||||
~& [%sync-subscribe our p.a q.a]
|
||||
[%warp [our p.a] q.a ~ %| [%da +(now)] [%da (add now ~d1000)]]
|
||||
[%warp [our p.a] q.a ~ %| [%da +(now)] [%da (add now ~d1000)] /]
|
||||
=+ ^= old ^- (list move)
|
||||
%+ turn
|
||||
%+ skip (~(tap in ped.sat) ~)
|
||||
@ -990,7 +996,7 @@
|
||||
?. (warm %pour)
|
||||
+>.$(qic.sat ~)
|
||||
?> ?=(^ huv.sat)
|
||||
=+ sam=(slop !>(p.kon) q.kon)
|
||||
=+ sam=:(slop [[%atom %ud] ost] !>(p.kon) q.kon)
|
||||
%+ ford /s/pour
|
||||
[%call (harm %pour (conf (core u.huv.sat))) (cove %$ sam)]
|
||||
==
|
||||
|
600
arvo/hoon.hoon
600
arvo/hoon.hoon
File diff suppressed because it is too large
Load Diff
163
arvo/test.hoon
163
arvo/test.hoon
@ -1,165 +1,24 @@
|
||||
!::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
:::::: :::::: Preface ::::::
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
?> ?=(@ .) :: atom subject
|
||||
%. . :: fun with subject
|
||||
|= cud=@ :: call it cud
|
||||
=- (mul:all 2 cud) :: multiply by 2
|
||||
^= all :: assemble engine
|
||||
=~ :: volume stack
|
||||
%164 :: version constant
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
:::::: :::::: volume 0, version stub ::::::
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
~% %k.164 ~ ~ ::
|
||||
|% ::
|
||||
++ stub 164 :: version stub
|
||||
-- ::
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
:::::: :::::: volume 1, Hoon models ::::::
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
~% %mood
|
||||
+
|
||||
~
|
||||
|% ::
|
||||
++ axis ,@ :: tree address
|
||||
-- ::
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
:::::: :::::: volume 2, Hoon libraries and compiler ::::::
|
||||
:::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
~% %hoon
|
||||
+
|
||||
==
|
||||
%dec dec
|
||||
==
|
||||
?> ?=([@ @] .)
|
||||
%. .
|
||||
|= [x=@ y=@]
|
||||
=- (add:all x y)
|
||||
^= all
|
||||
=> %164
|
||||
~% %k.164 ~ ~
|
||||
|%
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::: ::
|
||||
:::: chapter 2a, basic unsigned math ::::
|
||||
:: ::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
++ add :: add
|
||||
++ add
|
||||
~/ %add
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: =(0 a)
|
||||
b
|
||||
?: =(0 a) b
|
||||
$(a (dec a), b +(b))
|
||||
::
|
||||
++ cap :: tree head
|
||||
~/ %cap
|
||||
|= a=@
|
||||
^- ?(%2 %3)
|
||||
?- a
|
||||
%2 %2
|
||||
%3 %3
|
||||
?(%0 %1) !!
|
||||
* $(a (div a 2))
|
||||
==
|
||||
::
|
||||
++ dec :: decrement
|
||||
++ dec
|
||||
~/ %dec
|
||||
|= a=@
|
||||
?< =(0 a)
|
||||
=+ b=0
|
||||
|- ^- @
|
||||
?: =(a +(b))
|
||||
b
|
||||
?: =(a +(b)) b
|
||||
$(b +(b))
|
||||
::
|
||||
++ div :: divide
|
||||
~/ %div
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?< =(0 b)
|
||||
=+ c=0
|
||||
|-
|
||||
?: (lth a b)
|
||||
c
|
||||
$(a (sub a b), c +(c))
|
||||
::
|
||||
++ gte :: greater-equal
|
||||
~/ %gte
|
||||
|= [a=@ b=@]
|
||||
^- ?
|
||||
!(lth a b)
|
||||
::
|
||||
++ gth :: greater-than
|
||||
~/ %gth
|
||||
|= [a=@ b=@]
|
||||
^- ?
|
||||
!(lte a b)
|
||||
::
|
||||
++ lte :: less-equal
|
||||
~/ %lte
|
||||
|= [a=@ b=@]
|
||||
|(=(a b) (lth a b))
|
||||
::
|
||||
++ lth :: less-than
|
||||
~/ %lth
|
||||
|= [a=@ b=@]
|
||||
^- ?
|
||||
&(!=(a b) |-(|(=(0 a) &(!=(0 b) $(a (dec a), b (dec b))))))
|
||||
::
|
||||
++ mas :: tree body
|
||||
~/ %mas
|
||||
|= a=@
|
||||
^- @
|
||||
?- a
|
||||
1 !!
|
||||
2 1
|
||||
3 1
|
||||
* (add (mod a 2) (mul $(a (div a 2)) 2))
|
||||
==
|
||||
::
|
||||
++ max :: maximum
|
||||
~/ %max
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: (gth a b)
|
||||
a
|
||||
b
|
||||
::
|
||||
++ min :: minimum
|
||||
~/ %min
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: (lth a b)
|
||||
a
|
||||
b
|
||||
::
|
||||
++ mod :: remainder
|
||||
~/ %mod
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?< =(0 b)
|
||||
(sub a (mul b (div a b)))
|
||||
::
|
||||
++ mul :: multiply
|
||||
~/ %mul
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
=+ c=0
|
||||
|-
|
||||
?: =(0 a)
|
||||
c
|
||||
$(a (dec a), c (add b c))
|
||||
::
|
||||
++ 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))
|
||||
==
|
||||
::
|
||||
++ sub :: subtract
|
||||
~/ %sub
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: =(0 b)
|
||||
a
|
||||
$(a (dec a), b (dec b))
|
||||
--
|
||||
. ==
|
||||
|
@ -828,13 +828,13 @@
|
||||
=> .(+< [a b]=+<)
|
||||
(scan a (parsf b))
|
||||
++ parsf :: make parser from:
|
||||
|^ |* (pole ,_:/(*$&(_rule tape))) :: ;"chars{rule}chars"
|
||||
=> .(+< a=+<)
|
||||
|^ |* a=(pole ,_:/(*$&(_rule tape))) :: ;"chars{rule}chars"
|
||||
%- cook :_ (bill (norm a))
|
||||
|* (list)
|
||||
?~ +< ~
|
||||
?~ t i
|
||||
[i $(+< t)]
|
||||
::
|
||||
:: .= (norm [;"{n}, {n}"]:n=dim:ag) ~[[& dim] [| ", "] [& dim]]:ag
|
||||
++ norm
|
||||
|* (pole ,_:/(*$&(_rule tape)))
|
||||
@ -847,6 +847,7 @@
|
||||
?~ +.rul [%| p=rul]
|
||||
?@ &2.rul [%| p=;;(tape rul)]
|
||||
[%& p=rul]
|
||||
::
|
||||
:: .= (bill ~[[& dim] [| ", "] [& dim]]:ag)
|
||||
:: ;~(plug dim ;~(pfix com ace ;~(plug dim (easy)))):ag
|
||||
++ bill
|
||||
@ -1045,7 +1046,7 @@
|
||||
^- ankz
|
||||
^$(p ank)
|
||||
::
|
||||
++ ze !:
|
||||
++ ze
|
||||
|_ [lim=@da dome rang]
|
||||
++ zoal :: make yaki
|
||||
|= [p=(list tako) q=(map path lobe) t=@da]
|
||||
@ -1125,6 +1126,24 @@
|
||||
=+ zoq=(zaru voq)
|
||||
((diff (zump (zaal u.leb))) zeq zoq)
|
||||
::
|
||||
++ apax :: apax:ze
|
||||
|= [oan=@ud pax=path] :: data at path
|
||||
^- (map path lobe)
|
||||
?: =(0 oan) ~
|
||||
%- mo
|
||||
%+ skim
|
||||
%. ~
|
||||
%~ tap by
|
||||
=< q
|
||||
%- ~(got by hut)
|
||||
%- ~(got by hit)
|
||||
oan
|
||||
|= [p=path q=lobe]
|
||||
?| ?=(~ pax)
|
||||
?& !?=(~ p)
|
||||
=(-.pax -.p)
|
||||
$(p +.p, pax +.pax)
|
||||
== ==
|
||||
::
|
||||
++ aeon :: aeon:ze
|
||||
|= lok=case :: act count through
|
||||
@ -1220,7 +1239,7 @@
|
||||
|= lob=lobe
|
||||
(need (~(get by lat) lob))
|
||||
::
|
||||
++ gack !: :: gack a through b
|
||||
++ gack :: gack a through b
|
||||
|= [a=@ud b=@ud]
|
||||
^- [(map ,@ud tako) @ud (set yaki) (set blob)]
|
||||
:_ :- b
|
||||
@ -1250,7 +1269,7 @@
|
||||
^+ +>
|
||||
?: =(let oan) +>
|
||||
?: (gth oan let) !! :: don't have this version
|
||||
+>(ank (azel q:(need (~(get by hut) (need (~(get by hit) oan))))), let oan)
|
||||
+>(ank (azel q:(~(got by hut) (~(got by hit) oan))), let oan)
|
||||
::
|
||||
::::
|
||||
++ aqel :: aqel:ze
|
||||
@ -1309,8 +1328,9 @@
|
||||
|= [[pat=path bar=lobe] ank=ankh]
|
||||
^- ankh
|
||||
%- cosh
|
||||
=+ zar=(zaul bar)
|
||||
?~ pat [_cash [~ [(sham zar) zar]] `(map ,@ta ankh)`~]
|
||||
?~ pat
|
||||
=+ zar=(zaul bar)
|
||||
ank(q [~ (sham zar) zar])
|
||||
=+ nak=(~(get by r.ank) i.pat)
|
||||
%= ank
|
||||
r %+ ~(put by r.ank) i.pat
|
||||
@ -1355,7 +1375,7 @@
|
||||
$(gud (~(put in gud) tek), unk bun)
|
||||
$(unk bun)
|
||||
::
|
||||
++ zeas !: :: merge points fast
|
||||
++ zeas :: merge points fast
|
||||
|= [p=yaki q=yaki] :: (future zeal)
|
||||
^- (set yaki) :: zear still uses zule
|
||||
%- zear :: this is test-only
|
||||
@ -1373,13 +1393,13 @@
|
||||
(~(uni in u) (zeaz v))
|
||||
$(u (~(uni in u) (zeaz v)), s (zeat s.qez), t (zeat t.qez))
|
||||
::
|
||||
++ zeaz !:
|
||||
++ zeaz
|
||||
|= qez=(set tako)
|
||||
^- (set yaki)
|
||||
%- sa %+ turn (~(tap in qez) ~)
|
||||
|= tak=tako
|
||||
(~(got by hut) tak)
|
||||
++ zeat !: :: expand set
|
||||
++ zeat :: expand set
|
||||
|= qez=(set tako)
|
||||
^- (set tako)
|
||||
%+ roll (~(tap in qez) ~)
|
||||
@ -1839,7 +1859,7 @@
|
||||
+>(ank ank:(durn:(zu ank) nyp))
|
||||
--
|
||||
::
|
||||
++ zu !: :: filesystem
|
||||
++ zu :: filesystem
|
||||
|= ank=ankh :: filesystem state
|
||||
=| myz=(list ,[p=path q=miso]) :: changes in reverse
|
||||
=| ram=path :: reverse path into
|
||||
@ -3047,7 +3067,7 @@
|
||||
== ::
|
||||
++ mizu ,[p=@u q=(map ,@ud tako) r=rang] :: new state
|
||||
++ moar ,[p=@ud q=@ud] :: normal change range
|
||||
++ moat ,[p=case q=case] :: change range
|
||||
++ moat ,[p=case q=case r=path] :: change range
|
||||
++ mood ,[p=care q=case r=path] :: request in desk
|
||||
++ moth ,[p=meth q=math r=(unit octs)] :: http operation
|
||||
++ name ,[p=@t q=(unit ,@t) r=(unit ,@t) s=@t] :: first mid/nick last
|
||||
|
@ -87,7 +87,7 @@
|
||||
==
|
||||
==
|
||||
++ pour
|
||||
|= [way=path sih=sign]
|
||||
|= [ost=bone way=path sih=sign]
|
||||
^- [(list move) _+>]
|
||||
:_ +>.$
|
||||
%+ turn (~(tap in (~(get ju pus.hid) ~)))
|
||||
|
@ -130,7 +130,7 @@
|
||||
==
|
||||
::
|
||||
++ pour
|
||||
|= [pax=path sih=*]
|
||||
|= [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
=+ sih=((hard sign) sih)
|
||||
:: ~& [%chat-pour sih]
|
||||
|
73
main/app/test/app.js
Normal file
73
main/app/test/app.js
Normal file
@ -0,0 +1,73 @@
|
||||
$(function() {
|
||||
$tests = $("#tests")
|
||||
|
||||
runtest = function(name) {
|
||||
test = $(name)
|
||||
test.attr('disabled', true)
|
||||
test.addClass('disabled')
|
||||
|
||||
window.urb.send({
|
||||
appl:"test",
|
||||
data:{test:name}
|
||||
}, function(err,res) {
|
||||
test.attr('disabled', false)
|
||||
test.removeClass('disabled')
|
||||
|
||||
_test = {
|
||||
name: name,
|
||||
result: res.data
|
||||
}
|
||||
|
||||
console.log('set it')
|
||||
console.log(_test)
|
||||
|
||||
$tests.prepend(renderTest(_test))
|
||||
})
|
||||
}
|
||||
|
||||
renderTest = function(test) {
|
||||
css = "test"
|
||||
if(test.pending == true)
|
||||
css += " pending"
|
||||
$_test = $("<div class='"+css+"' id="+test.name+" onclick='runtest(\""+test.name+"\")'></div>")
|
||||
$_test.append("<div class='name'>"+test.name+"</div>")
|
||||
$_test.append("<div class='result'>"+JSON.stringify(test.result)+"</div>")
|
||||
return $_test
|
||||
}
|
||||
|
||||
renderTests = function(testlist) {
|
||||
console.log("renderTests: "+testlist)
|
||||
$tests.html("")
|
||||
for(i in testlist) {
|
||||
$tests.append(renderTest(testlist[i]))
|
||||
}
|
||||
}
|
||||
|
||||
renderError = function(error) {
|
||||
$tests.html("<div class='error'>Sorry! There was an error fetching from Test: "+error+"</div>")
|
||||
}
|
||||
|
||||
window.urb.subscribe({
|
||||
appl:"test",
|
||||
path:"/tests"
|
||||
}, function(err,res) {
|
||||
console.log('subscr')
|
||||
console.log(arguments)
|
||||
if (res.data.ok)
|
||||
return
|
||||
if(err)
|
||||
renderTests(err)
|
||||
else
|
||||
{
|
||||
if(res.data) {
|
||||
if(res.data) {
|
||||
renderTests(res.data)
|
||||
}
|
||||
else
|
||||
{
|
||||
renderTests("unknown error")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
237
main/app/test/core.hook
Normal file
237
main/app/test/core.hook
Normal file
@ -0,0 +1,237 @@
|
||||
:: Test suite
|
||||
::
|
||||
:: runnable from unix with command:
|
||||
:: curl http://localhost:8080/gog/test/all-tests
|
||||
::
|
||||
:::: /hook/core/test/app
|
||||
::
|
||||
/? 314 :: need urbit 314
|
||||
/= front /:/%%/front:/hymn/ :: load front page
|
||||
::
|
||||
:::: structures
|
||||
::
|
||||
|% :: structures
|
||||
++ axle ,[%0 tests=(map term test)] :: application state
|
||||
++ gilt :: subscription frame
|
||||
$% [%json p=json] :: json data
|
||||
[%html p=@t] :: html text
|
||||
[%hymn p=manx] :: html tree
|
||||
[%mime p=mite q=octs] :: mime data
|
||||
== ::
|
||||
++ gift :: output action
|
||||
$% [%rust gilt] :: total update
|
||||
[%mean p=ares] :: message failure
|
||||
[%nice ~] :: succeed
|
||||
== ::
|
||||
++ hasp ,[p=ship q=term] :: see %gall
|
||||
++ move ,[p=bone q=(mold note gift)] :: output operation
|
||||
++ result :: test result
|
||||
$% [%mean p=ares] :: failure
|
||||
[%nice ~] :: success
|
||||
== ::
|
||||
++ note :: system request
|
||||
$% $: %g :: to %ames
|
||||
$% [%mess p=hasp q=ship r=cage] ::
|
||||
== == == ::
|
||||
++ test :: test template
|
||||
$_ ^? |% ::
|
||||
++ poke |+([bone ship] [_(list move) +>]) :: start test
|
||||
++ pour |+([bone path *] [_(list move) +>]) :: system response
|
||||
-- ::
|
||||
-- ::
|
||||
!:
|
||||
:::: program
|
||||
::
|
||||
|_ $: hid=hide :: system state
|
||||
axle :: custom state
|
||||
==
|
||||
++ et :: tests
|
||||
|%
|
||||
++ tests-json
|
||||
%- jobe
|
||||
%+ turn (~(tap by tests))
|
||||
|= [nam=@t tes=test]
|
||||
:- nam
|
||||
%- jobe
|
||||
^- (list ,[@t json])
|
||||
~[[%name %s nam] [%result %s %untested]]
|
||||
++ succeed
|
||||
^- test
|
||||
|%
|
||||
++ poke
|
||||
|+ [ost=bone you=ship]
|
||||
^- [(list move) _+>]
|
||||
[[ost %give %nice ~]~ +>.$]
|
||||
++ pour
|
||||
|+ [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
!!
|
||||
--
|
||||
++ poke-local
|
||||
^- test
|
||||
=> |%
|
||||
++ sign ,[%g result]
|
||||
--
|
||||
|%
|
||||
++ poke
|
||||
|+ [ost=bone you=ship]
|
||||
^- [(list move) _+>]
|
||||
:_ +>.$ :_ ~
|
||||
:* ost %pass /poke-local %g
|
||||
%mess [our.hid %test] you %json
|
||||
!> (joba %test %s %bad-test-name)
|
||||
==
|
||||
++ pour
|
||||
|+ [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
:_ +>.$
|
||||
=+ sih=((soft sign) sih)
|
||||
:_ ~ :+ ost %give
|
||||
?~ sih [%mean ~ %poke-local-pour-bad-sign ~]
|
||||
?- +<.u.sih
|
||||
%nice [%mean ~ %poke-local-pour-unexpected-nice ~]
|
||||
%mean
|
||||
?: ?=([~ %bad-test ~] p.u.sih)
|
||||
[%nice ~]
|
||||
[%mean ~ %poke-local-pour-unexpected-mean ~]
|
||||
==
|
||||
--
|
||||
++ ze
|
||||
^- test
|
||||
|%
|
||||
++ poke
|
||||
|+ [ost=bone you=ship]
|
||||
^- [(list move) _+>]
|
||||
:_ +>.$ :_ ~
|
||||
=+ ^= zez
|
||||
%+ ~(axel ^ze lat.hid *dome *rang)
|
||||
lat.hid
|
||||
[%& [0v0 0v0] [/hello %ins 'hello, world']~]
|
||||
=+ `[l=@da d=dome r=rang]`+<.zez
|
||||
?: .= lat.r
|
||||
:_ [~ ~]
|
||||
[p=1.292.805.149 q=[%direct p=1.292.805.149 q='hello, world' r=%c]]
|
||||
[ost %give %nice ~]
|
||||
[ost %give %mean ~ %bad-rang ~[leaf/<d> leaf/<r>]]
|
||||
++ pour
|
||||
|+ [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
!!
|
||||
--
|
||||
++ all-tests
|
||||
^- test
|
||||
=> |%
|
||||
++ sign ,[%g result]
|
||||
++ sult
|
||||
$? result
|
||||
[%pending ~]
|
||||
==
|
||||
--
|
||||
=| results=(map ,@t sult)
|
||||
|%
|
||||
++ poke
|
||||
|+ [ost=bone you=ship]
|
||||
^- [(list move) _+>]
|
||||
=. results
|
||||
%- mo
|
||||
%+ turn (~(tap by tests))
|
||||
|= [nam=@t tes=test]
|
||||
[nam %pending ~]
|
||||
:_ +>.$
|
||||
%+ turn (~(tap by tests))
|
||||
|= [nam=@t tes=test]
|
||||
:* ost %pass /all-tests/[nam] %g
|
||||
%mess [our.hid %test] you %json
|
||||
!> (joba %test %s nam)
|
||||
==
|
||||
++ pour
|
||||
|+ [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
=+ sih=((hard sign) sih)
|
||||
?. ?=([@ ~] pax) ~& [%all-tests-strange-path pax] [~ +>.$]
|
||||
=. results (~(put by results) -.pax +.sih)
|
||||
:_ +>.$
|
||||
?: (~(any by results) |=([res=sult] ?=(%pending -.res)))
|
||||
~
|
||||
:_ ~
|
||||
?: (~(all by results) |=([res=sult] ?=(%nice -.res)))
|
||||
[ost %give %nice ~]
|
||||
:^ ost %give %mean
|
||||
:+ ~ %failed-tests
|
||||
%- zing
|
||||
%+ turn
|
||||
(skim (~(tap by results)) |=([nam=@t res=sult] ?=(%mean -.res)))
|
||||
|= [nam=@t res=sult]
|
||||
?> ?=(%mean -.res)
|
||||
^- (list tank)
|
||||
:_ ?~ p.res ~ q.u.p.res
|
||||
:- %leaf
|
||||
%+ weld "test %{(trip nam)} failed with "
|
||||
?~ p.res "no error message"
|
||||
%+ weld "error code %{(trip p.u.p.res)} and "
|
||||
?~ q.u.p.res "no error info"
|
||||
"the following error info:"
|
||||
--
|
||||
--
|
||||
++ spec-pour
|
||||
|= [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
=+ sih=((hard ,[%g result]) sih)
|
||||
:_ +>.$ :_ ~
|
||||
[ost %give %rust %mime /text/plain (taco (cat 3 (crip <sih>) 10))]
|
||||
++ prep
|
||||
|= old=(unit (unit axle))
|
||||
^- [(list move) _+>]
|
||||
:- ~
|
||||
%= +>.$
|
||||
tests
|
||||
?~ old
|
||||
~& %prep-sig tests
|
||||
?^ u.old
|
||||
~& %prep-no-sig tests.u.u.old
|
||||
=. tests
|
||||
%- mo
|
||||
^- (list ,[@t test])
|
||||
=> et
|
||||
:~ [%succeed succeed]
|
||||
[%ze ze]
|
||||
[%poke-local poke-local]
|
||||
==
|
||||
(~(put by tests) %all-tests all-tests:et)
|
||||
==
|
||||
++ peer :: accept subscriber
|
||||
|= [ost=bone you=ship pax=path]
|
||||
^- [(list move) _+>]
|
||||
?~ pax [[ost %give %rust %hymn front]~ +>.$]
|
||||
?: ?=(%tests -.pax)
|
||||
[[ost %give %rust %json tests-json:et]~ +>.$]
|
||||
:_ +>.$ :_ ~
|
||||
:* ost %pass /automagic %g
|
||||
%mess [our.hid %test] you %json
|
||||
!> (joba %test %s -.pax)
|
||||
==
|
||||
++ poke-json :: browser message
|
||||
|= [ost=bone you=ship jon=json]
|
||||
^- [(list move) _+>]
|
||||
=+ tes=((of [%test so] ~):jo jon)
|
||||
?~ tes [[ost %give %mean ~ %strange-json ~]~ +>.$]
|
||||
=+ tst=(~(get by tests) +.u.tes)
|
||||
?~ tst
|
||||
[[ost %give %mean ~ %bad-test ~]~ +>.$]
|
||||
~& [%running-test +.u.tes]
|
||||
=+ res=(poke:u.tst ost you)
|
||||
:- -.res
|
||||
+>.$(tests (~(put by tests) +.u.tes +.res))
|
||||
++ pour :: response
|
||||
|= [ost=bone pax=path sih=*]
|
||||
^- [(list move) _+>]
|
||||
?~ pax ~& %test-strange-path [~ +>.$]
|
||||
=+ tst=(~(get by tests) -.pax)
|
||||
?: ?=(%automagic -.pax)
|
||||
(spec-pour ost pax sih)
|
||||
?~ tst
|
||||
~& %test-bad-path [~ +>.$]
|
||||
=+ res=(pour:u.tst ost +.pax sih)
|
||||
:- -.res
|
||||
+>.$(tests (~(put by tests) -.pax +.res))
|
||||
--
|
30
main/app/test/front/hymn.hook
Normal file
30
main/app/test/front/hymn.hook
Normal file
@ -0,0 +1,30 @@
|
||||
:: Front page of the twitter app.
|
||||
::
|
||||
:::: /hook/hymn/front/twit/app
|
||||
::
|
||||
/? 314 :: need urbit 314
|
||||
/= urbit /:/===/lib/urb:/hymn/ :: urbit library (js)
|
||||
/= style /:/%%%/style:/hymn/ :: stylesheet (css)
|
||||
/= application /:/%%%/app:/hymn/ :: application (js)
|
||||
!:
|
||||
:::: content
|
||||
::
|
||||
^- manx
|
||||
;html
|
||||
;head
|
||||
;title: Tests
|
||||
;+ style
|
||||
;script
|
||||
=type "text/javascript"
|
||||
=src "//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.1/jquery.min.js"
|
||||
;
|
||||
==
|
||||
==
|
||||
;body
|
||||
;div#tests
|
||||
;p: Fetching tests...
|
||||
==
|
||||
;+ urbit
|
||||
;+ application
|
||||
==
|
||||
==
|
82
main/app/test/style.css
Normal file
82
main/app/test/style.css
Normal file
@ -0,0 +1,82 @@
|
||||
body,
|
||||
textarea,
|
||||
input {
|
||||
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
body {
|
||||
margin-top: 4rem;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
.test,
|
||||
.name,
|
||||
.result {
|
||||
width: 32rem;
|
||||
}
|
||||
|
||||
textarea {
|
||||
border: 0;
|
||||
height: 8rem;
|
||||
line-height: 1.5rem;
|
||||
margin-bottom: .3rem;
|
||||
resize: none;
|
||||
padding: 1rem 1px;
|
||||
background-color: #f7f7f7;
|
||||
}
|
||||
|
||||
.name {
|
||||
border: 0;
|
||||
color: #333;
|
||||
letter-spacing: 0.01rem;
|
||||
}
|
||||
|
||||
.name {
|
||||
background-color: transparent;
|
||||
border: 2px solid #5DE668;
|
||||
color: #5DE668;
|
||||
padding: .3rem 1rem;
|
||||
font-weight: 500;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.name {
|
||||
background-color: #5DE668;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.disabled {
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.text {
|
||||
word-wrap:break-word;
|
||||
margin-bottom: .3rem;
|
||||
line-height: 1.6rem;
|
||||
}
|
||||
|
||||
#twet {
|
||||
margin-bottom: 3rem;
|
||||
border-bottom: 2px solid #464646;
|
||||
padding-bottom: 2rem;
|
||||
}
|
||||
|
||||
#twet,
|
||||
.tweet {
|
||||
border-bottom: 1px solid #eee;
|
||||
}
|
||||
|
||||
.tweet {
|
||||
margin-bottom: 2rem;
|
||||
padding-bottom: 1rem;
|
||||
}
|
||||
|
||||
.pending {
|
||||
opacity: .3;
|
||||
}
|
||||
|
||||
.error {
|
||||
color: #FF5F5F;
|
||||
letter-spacing: .06rem;
|
||||
}
|
@ -100,7 +100,7 @@
|
||||
==
|
||||
::
|
||||
++ pour :: HTTP response
|
||||
|= [pax=path sih=sign]
|
||||
|= [ost=bone pax=path sih=sign]
|
||||
^- [(list move) _+>]
|
||||
:_ +>.$
|
||||
?+ -.pax !!
|
||||
|
@ -12,11 +12,14 @@
|
||||
?~ q.ark
|
||||
?- r.ark
|
||||
~
|
||||
~[(crip "No file {(spud pax)}")]
|
||||
~[(crip "~ {(spud pax)}")]
|
||||
[[@t ~] ~ ~]
|
||||
$(pax (welp pax /[p.n.r.ark]))
|
||||
*
|
||||
~[(crip "Multiple in {(spud pax)}")]
|
||||
:- (crip "* {(spud pax)}")
|
||||
%- sort :_ aor
|
||||
%- turn :_ |=([a=@t ~] a)
|
||||
(~(tap by `(map ,@t ,~)`r.ark))
|
||||
==
|
||||
:- (crip (spud pax))
|
||||
(lore ;;(,@t .^(%cx pax)))
|
||||
|
@ -15,7 +15,7 @@
|
||||
[%tower p=@p]
|
||||
[%s p=path]
|
||||
==
|
||||
=+ flags=*(list flag)
|
||||
=+ [flags=*(list flag) lat=&3:%]
|
||||
=> |%
|
||||
++ chat :: user action
|
||||
$% [%all p=mess] :: say
|
||||
@ -63,22 +63,19 @@
|
||||
==
|
||||
::
|
||||
++ dat
|
||||
%+ cook
|
||||
%+ sear
|
||||
|= p=coin
|
||||
?. ?=(~ -.p) [%ud 5]
|
||||
?+ p.p.p [%ud 5]
|
||||
%da [%da q.p.p]
|
||||
%dr [%dr q.p.p]
|
||||
%ud [%ud q.p.p]
|
||||
==
|
||||
;~(pfix (jest '\\\\ ') nuck:so)
|
||||
?. ?=([%$ ?(%da %dr %ud) @] p) ~
|
||||
(some +.p)
|
||||
;~(pfix bas bas (star ace) nuck:so)
|
||||
::
|
||||
++ expn
|
||||
%- sear
|
||||
:_ text
|
||||
|= a=@t
|
||||
^- (unit ,[p=@t q=tank])
|
||||
=+ hun=(rush a wide:vast)
|
||||
~! %
|
||||
=+ hun=(rush a wide:(vang | &1:% &2:% lat |3:%))
|
||||
?~ hun ~
|
||||
?~(a ~ [~ a (sell (slap !>(sed) u.hun))])
|
||||
::
|
||||
@ -273,7 +270,7 @@
|
||||
|= [now=@da txt=@t]
|
||||
^+ +>
|
||||
?: =(0 txt) +>
|
||||
=+ rey=(rush txt chat)
|
||||
=+ rey=(rush txt chat(lat (scot da/est)))
|
||||
?~ rey
|
||||
(show %leaf "invalid input")
|
||||
|-
|
||||
|
@ -10,5 +10,7 @@
|
||||
=- ?~ q.ark -
|
||||
[(crip (rend pax)) -]
|
||||
%- zing
|
||||
%+ turn (~(tap by r.ark))
|
||||
|=([a=@t ~] ^$(pax (weld pax `path`/[a])))
|
||||
%- turn :_ |=(a=@t ^$(pax (weld pax `path`/[a])))
|
||||
%- sort :_ aor
|
||||
%- turn :_ |=([a=@t ~] a)
|
||||
(~(tap by r.ark))
|
||||
|
@ -1,13 +1,13 @@
|
||||
window.urb.seqn_s = 0
|
||||
window.urb.cabs = {}
|
||||
|
||||
window.urb.send = function(params,cb) {
|
||||
if(!params)
|
||||
throw new Error("You must supply params to urb.send.")
|
||||
if(!params.appl)
|
||||
if(!params.appl) {
|
||||
if(!urb.appl)
|
||||
throw new Error("You must specify an appl for urb.send.")
|
||||
params.appl = urb.appl
|
||||
}
|
||||
if(!params.data) { params.data = {}; }
|
||||
|
||||
var method, perm, url, $this
|
||||
@ -35,10 +35,11 @@ window.urb.subscribe = function(params,cb) {
|
||||
throw new Error("You must supply a callback to urb.subscribe.")
|
||||
if(!params)
|
||||
throw new Error("You must supply params to urb.subscribe.")
|
||||
if(!params.appl)
|
||||
if(!params.appl) {
|
||||
if(!urb.appl)
|
||||
throw new Error("You must specify an appl for urb.subscribe.")
|
||||
params.appl = urb.appl
|
||||
}
|
||||
if(!params.path)
|
||||
throw new Error("You must specify a path for urb.subscribe.")
|
||||
params.ship = params.ship ? params.ship : this.ship
|
||||
@ -66,10 +67,11 @@ window.urb.subscribe = function(params,cb) {
|
||||
window.urb.unsubscribe = function(params,cb) {
|
||||
if(!params)
|
||||
throw new Error("You must supply params to urb.unsubscribe.")
|
||||
if(!params.appl)
|
||||
if(!urb.appl )
|
||||
if(!params.appl) {
|
||||
if(!urb.appl)
|
||||
throw new Error("You must specify an appl for urb.unsubscribe.")
|
||||
params.appl = urb.appl
|
||||
}
|
||||
if(!params.path)
|
||||
throw new Error("You must specify a path for urb.unsubscribe.")
|
||||
params.ship = params.ship ? params.ship : this.ship
|
||||
|
@ -10,8 +10,7 @@
|
||||
++ grab :: convert from
|
||||
|%
|
||||
++ md :: convert from %md
|
||||
|= src=@t
|
||||
=< (mark (trip src))
|
||||
=< |=(src=@t (mark (trip src)))
|
||||
|%
|
||||
++ mark
|
||||
|= p=tape
|
||||
@ -23,7 +22,7 @@
|
||||
=+ sep=(sepa tub)
|
||||
?~ q.sep [p.sep ~]
|
||||
:- p.sep
|
||||
%- some :_ [p.sep ~]
|
||||
%- some :_ [p.sep ~]
|
||||
(turn p.u.q.sep |=(a=tape (scan a blos)))
|
||||
::
|
||||
++ base %+ stag %par
|
||||
@ -39,7 +38,7 @@
|
||||
code codf html para base
|
||||
==
|
||||
::
|
||||
++ brek (stag %cut (cold ~ ;~(plug fas fas))) :: line break
|
||||
++ brek (stag %cut (cold ~ ;~(plug fas fas))) :: line break
|
||||
++ chrd ;~(pose escp prn (cold ' ' eol)) :: shin character data
|
||||
++ code :: code block
|
||||
%+ stag %pre
|
||||
@ -61,7 +60,7 @@
|
||||
%- plus
|
||||
;~ pose
|
||||
%+ cook welp
|
||||
;~(plug (plus prn) (cold "\0a" eol))
|
||||
;~(plug (star prn) (cold "\0a" eol))
|
||||
(full (plus ;~(less ;~(plug tec tec tec) prn)))
|
||||
==
|
||||
::
|
||||
@ -83,7 +82,7 @@
|
||||
==
|
||||
++ spas :: all shin elements
|
||||
|* res=_rule
|
||||
%- plus
|
||||
%- plus
|
||||
;~ pose emph stri link
|
||||
brek cods (text res)
|
||||
==
|
||||
@ -106,19 +105,7 @@
|
||||
(ifix [cab cab] (stag %bent inn))
|
||||
==
|
||||
::
|
||||
++ escp :: escapable chars
|
||||
;~ pose
|
||||
(cold '`' (jest '\\`'))
|
||||
(cold '*' (jest '\\*'))
|
||||
(cold '#' (jest '\\#'))
|
||||
(cold '-' (jest '\\-'))
|
||||
(cold '.' (jest '\\.'))
|
||||
(cold '{' (jest '\\{'))
|
||||
(cold '}' (jest '\\}'))
|
||||
(cold '[' (jest '\\['))
|
||||
(cold ']' (jest '\\]'))
|
||||
(cold '\\' (jest '\\\\'))
|
||||
==
|
||||
++ escp ;~(pfix bas (mask (trip '`*#-.{}[]\\'))) :: escapable chars
|
||||
::
|
||||
++ head :: header
|
||||
%+ stag %had
|
||||
@ -160,7 +147,7 @@
|
||||
;~(plug (stun [0 3] ace) cab wits cab wits cab (star ;~(pose cab ace)))
|
||||
==
|
||||
::
|
||||
++ html (stag %hem apex:xmlp) :: html barb
|
||||
++ html (stag %hem apex:xmlp) :: html barb
|
||||
++ lasd :: top level list
|
||||
%+ stag %lit
|
||||
%- full
|
||||
@ -212,7 +199,7 @@
|
||||
==
|
||||
==
|
||||
::
|
||||
++ para (stag %par (full (spas fail))) :: paragraph
|
||||
++ para (stag %par (full (spas fail))) :: paragraph
|
||||
++ quot :: blockquotes
|
||||
%+ stag %quo
|
||||
%- full
|
||||
@ -234,16 +221,28 @@
|
||||
++ sepa :: separate barbs
|
||||
%+ knee *wall |. ~+
|
||||
=+ lin=;~(plug eol wits eol)
|
||||
%- full
|
||||
%+ ifix [(star whit) (star whit)]
|
||||
%+ more ;~(plug eol wits (more wits eol))
|
||||
;~ pose
|
||||
sepc
|
||||
(sepl (cold "-" hep))
|
||||
(sepl (cold "*" tar))
|
||||
(sepl (cold "+" lus))
|
||||
(sepl (cook welp ;~(plug (star nud) (cold "." dot))))
|
||||
(plus ;~(less lin ;~(pose prn ;~(simu ;~(plug eol prn) eol))))
|
||||
(plus ;~(pose prn ;~(less lin eol)))
|
||||
==
|
||||
::
|
||||
++ sepc :: separate code block
|
||||
=+ tecs=(cold "```" (jest '```'))
|
||||
%+ cook |=(wall `tape`(zing +<))
|
||||
;~ plug
|
||||
tecs
|
||||
(cook zing (star ;~(plug eol ;~(less tecs (star prn)))))
|
||||
(cold "\0a" eol)
|
||||
tecs
|
||||
(easy ~)
|
||||
==
|
||||
++ sepl :: separate list
|
||||
|* bus=_rule
|
||||
%+ cook zing
|
||||
@ -285,14 +284,14 @@
|
||||
::
|
||||
++ grow :: convert into
|
||||
=< |%
|
||||
++ hymn :: convert to %hymn
|
||||
++ hymn :: convert to %hymn
|
||||
;html
|
||||
;head:title:"Untitled"
|
||||
;body
|
||||
;* (apex don)
|
||||
==
|
||||
==
|
||||
++ psal :: convert to %psal
|
||||
++ psal :: convert to %psal
|
||||
;div
|
||||
;* (apex don)
|
||||
==
|
||||
|
@ -6,7 +6,8 @@
|
||||
::
|
||||
++ grow :: convert to
|
||||
|%
|
||||
++ html (crip (xmlt | own ~)) :: convert to %html
|
||||
++ hymn ;html(head:title:"Untitled" body:"+{own}") :: convert to %hymn
|
||||
++ html (crip (xmlt | hymn ~)) :: convert to %html
|
||||
++ mime [/text/html (taco html)] :: convert to %mime
|
||||
--
|
||||
--
|
||||
|
41
main/pub/fab/dirs/hymn.hook
Normal file
41
main/pub/fab/dirs/hymn.hook
Normal file
@ -0,0 +1,41 @@
|
||||
:: %clay browser
|
||||
::
|
||||
:::: /hook/hymn/dirs/fab/pub
|
||||
::
|
||||
/= gas /$ fuel
|
||||
/= rut /$ |= [a=beam path] ^- [p=path q=path]
|
||||
[(tope a(s ~)) (flop (slag 1 s.a))]
|
||||
!:
|
||||
:::: ~pittyp-pittyp
|
||||
::
|
||||
=+ pax=`path`(flop but.gas)
|
||||
=+ cot=(trip ;;(,@ (fall (file (welp p.rut pax)) '')))
|
||||
=+ js="""
|
||||
window.location = "/gen/main{<q.rut>}/" + pax.value
|
||||
"""
|
||||
;html
|
||||
;head:title:"{<pax>}"
|
||||
;body
|
||||
;input#pax(onchange js, value (slag 1 <pax>));
|
||||
;+ =+ ups="%"
|
||||
|-
|
||||
?: =(~ pax) ;div:a/"/gen/main{<q.rut>}":"/==="
|
||||
=: ups "%{ups}"
|
||||
pax (scag (dec (lent pax)) pax)
|
||||
==
|
||||
=+ sul=;;(arch .^(%cy (welp p.rut pax)))
|
||||
?: (gte 2 ~(wyt by r.sul)) $
|
||||
;div:a/"/gen/main{<q.rut>}{<pax>}":"{ups}"
|
||||
::
|
||||
;* =+ sub=;;(arch .^(%cy (welp p.rut pax)))
|
||||
=| don=tape
|
||||
%+ turn (~(tap by r.sub)) |= [a=span ~]
|
||||
=: don "{don}/{(trip a)}"
|
||||
pax (welp pax /[a])
|
||||
==
|
||||
=+ sus=;;(arch .^(%cy (welp p.rut pax)))
|
||||
?: =(2 ~(wyt by r.sus)) $(a p.n.-.r.sus)
|
||||
;div:a/"/gen/main{<q.rut>}{<pax>}":"{(slag 1 don)}"
|
||||
;pre:"{cot}"
|
||||
==
|
||||
==
|
114
main/pub/fab/next-site/hymn.hook
Normal file
114
main/pub/fab/next-site/hymn.hook
Normal file
@ -0,0 +1,114 @@
|
||||
:: Documentation website generator.
|
||||
::
|
||||
:::: /hook/hymn/next-site/fab/fub
|
||||
::
|
||||
/= bod /^ manx /: /===/pub/src/doc/say/intro /psal/
|
||||
/= sty /^ @t /: /===/pub/fab/site/styles /css/
|
||||
/= say /^ (map ,@ (list ,[@u manx]))
|
||||
/: /===/pub/src/doc/say
|
||||
/% /@ /hymn/
|
||||
/= ref /: /===/pub/src/doc/ref
|
||||
/. /= vol /; |= vol=(map ,@ manx)
|
||||
%+ sort (~(tap by vol)) |= [[a=term *] [b=term *]]
|
||||
=+ [pax=(trip a) paf=(trip b)]
|
||||
|-
|
||||
?~ pax & ?~ paf |
|
||||
?: =(i.pax i.paf) $(pax t.pax, paf t.paf)
|
||||
(lth i.pax i.paf)
|
||||
/, vol /% /psal/
|
||||
:: /= hon /, hoon /% /psal/
|
||||
==
|
||||
/= gas /$ fuel
|
||||
::
|
||||
:::: ~tomsyt-balsen, ~pittyp-pittyp
|
||||
::
|
||||
|%
|
||||
++ tuts
|
||||
|= tut=(list ,[term tape]) ^- manx
|
||||
:- /ol
|
||||
%+ turn tut |= [a=term b=tape]
|
||||
;li:p:a/"/gen/main/pub/fab/next-site/tut/{(trip a)}":"{b}"
|
||||
++ refs
|
||||
|= ref=(list ,[term tape tape]) ^- marl
|
||||
%+ turn ref |= [a=term b=tape c=tape]
|
||||
;p:a/"/gen/main/pub/fab/next-site/ref/{(trip a)}":";{strong "{b}"}: {c}"
|
||||
--
|
||||
!:
|
||||
::::
|
||||
::
|
||||
;html
|
||||
;head
|
||||
;title: Urbit: Personal Cloud Computing
|
||||
;link/"/gen/main/pub/fab/site/styles.css"(rel "stylesheet");
|
||||
==
|
||||
;body
|
||||
;div(class "content container")
|
||||
;+
|
||||
=. but.gas (flop but.gas)
|
||||
=+ ^= pag ^- marl
|
||||
?. ?=([@ @ *] but.gas) ~
|
||||
=+ ^- paf=(unit ,[nom=@t num=@u])
|
||||
%+ rush i.t.but.gas :: XX numbers in path
|
||||
;~(plug (cook crip (star alf)) dem)
|
||||
?~ paf ~
|
||||
?+ i.but.gas ~
|
||||
%tut
|
||||
=+ dir=(fall (~(get by say) nom.u.paf) ~)
|
||||
=+ mir=(~(get by (mo dir)) num.u.paf)
|
||||
?^ mir [u.mir]~
|
||||
(turn dir |=([@ a=manx] a))
|
||||
%ref
|
||||
?+ nom.u.paf ~ :: XX foreword, preface
|
||||
%vol
|
||||
%+ murn vol.ref |= [a=term b=manx]
|
||||
?. =((end 3 1 a) (scot ud/num.u.paf)) ~
|
||||
(some b)
|
||||
==
|
||||
==
|
||||
?^ pag
|
||||
;div.subpage
|
||||
;* pag
|
||||
==
|
||||
;div(class "page documentation")
|
||||
;+ bod
|
||||
;h1(class "page-title"): Documentation
|
||||
;p ; This documentation is a work in progress. Feedback and corrections
|
||||
; are welcome. Pull requests are encouraged. The repo for this site
|
||||
; lives ;{a(href "https://github.com/urbit/urbit.github.io") "here"}.
|
||||
==
|
||||
;ul
|
||||
;li
|
||||
;p:(h2:"Tutorial")
|
||||
;p:(a/"/gen/main/pub/fab/site/tut/setup":"Setup")
|
||||
;strong: Nock
|
||||
;+ %- tuts :~
|
||||
nock1/"Intro to Nock" nock2/"Nock is Easy" nock3/"Using Nock"
|
||||
==
|
||||
;strong: Hoon
|
||||
;+ %- tuts :~
|
||||
hoon1/"Intro to Hoon" hoon2/"Types" hoon3/"Hoon Computes"
|
||||
hoon4/"Gates" hoon5/"Tiles" hoon6/"Type Inference"
|
||||
hoon7/"Odds, Ends, Quirks"
|
||||
==
|
||||
;strong: Arvo
|
||||
;+ %- tuts :~
|
||||
arvo1/"Basic Arvo" arvo2/"More Basic Arvo" arvo3/"Apps"
|
||||
arvo4/"Functional Publishing I" arvo5/"Functional Publishing II"
|
||||
==
|
||||
==
|
||||
;li
|
||||
;p:(h2:"Reference")
|
||||
;* %- refs :~
|
||||
foreword/["Foreword" "Nock"] preface/["Preface" "Hoon Abstract"]
|
||||
vol0/["Volume 0" "Version Stub"]
|
||||
vol1/["Volume 1" "Hoon Structures"]
|
||||
vol2/["Volume 2" "Hoon Compiler"]
|
||||
vol3/["Volume 3" "Arvo Core"]
|
||||
vol4/["Volume 4" "Arvo Vanes"]
|
||||
==
|
||||
==
|
||||
==
|
||||
==
|
||||
==
|
||||
==
|
||||
==
|
@ -139,7 +139,7 @@ pre, .codeblock {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem;
|
||||
font-size: .9rem;
|
||||
font-size: .8rem;
|
||||
line-height: 1.4;
|
||||
white-space: pre;
|
||||
white-space: pre-wrap;
|
||||
|
@ -13,7 +13,7 @@ other:
|
||||
= show ships in current station
|
||||
\\ 5 show recent backlog (last n messages)
|
||||
\\ ~m5 show recent backlog (using @dr syntax)
|
||||
\\ ~2014.07.04 show recent backlog (using @da syntax)
|
||||
\\ ~2014.7.4 show recent backlog (using @da syntax)
|
||||
|
||||
command-line parameters:
|
||||
[%tower ~hoclur-bicrel] select haus server (default: ticketing ship)
|
||||
|
3
main/pub/src/doc/ref/hoon/LexiconToDo.txt
Normal file
3
main/pub/src/doc/ref/hoon/LexiconToDo.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Lexicon:
|
||||
|
||||
Links between common runes and their inverts.
|
553
main/pub/src/doc/ref/hoon/lex-noun.md
Normal file
553
main/pub/src/doc/ref/hoon/lex-noun.md
Normal file
@ -0,0 +1,553 @@
|
||||
Lexicon: Nouns
|
||||
=======
|
||||
|
||||
Atom Syntax
|
||||
----------
|
||||
|
||||
|
||||
###Canonical Atom Odors
|
||||
|
||||
An odor is an atom format that specifies an atomic subtype.
|
||||
|
||||
```
|
||||
@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
|
||||
```
|
||||
|
||||
###Unsigned decimal, @ud
|
||||
|
||||
Hoon's unsigned decimal format is the normal Continental syntax. It differs
|
||||
from the Anglo-American only in the use of periods, rather than commas, between
|
||||
groups of 3:
|
||||
|
||||
~zod/try=> 19
|
||||
19
|
||||
~zod/try=> 1.024
|
||||
1.024
|
||||
|
||||
An unsigned decimal not broken into groups is a syntax error. Also, whitespace
|
||||
or even linebreaks can appear between the dot and the next group.
|
||||
|
||||
~zod/try=> 65. 536
|
||||
65.536
|
||||
|
||||
###Unsigned hexadecimal, @ux
|
||||
|
||||
@ux has the same syntax as @ud, except that it's prefixed by 0x and uses groups
|
||||
of four. Hex digits are lowercase only.
|
||||
|
||||
~zod/try=> 0x0
|
||||
0x0
|
||||
~zod/try=> `@ud`0x17
|
||||
23
|
||||
|
||||
###Unsigned base64 and base32, @uv, @uw
|
||||
|
||||
The prefix is 0w for base64 and 0v for base32. The digits for @uw are, in
|
||||
order: 0-9, a-z, A-Z, -, ~:
|
||||
|
||||
~zod/try=> `@ud`0w-
|
||||
62
|
||||
|
||||
For @uv, the digits are 0-9, a-v.
|
||||
|
||||
Signed integers, @sd, @sx, @sw, @sv, @sb
|
||||
|
||||
Obviously, without finite-sized integers, the sign extension trick 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 sign bit is the low
|
||||
bit:
|
||||
|
||||
~zod/try=> -1
|
||||
-1
|
||||
~zod/try=> --1
|
||||
--1
|
||||
~zod/try=> `@ud`-1
|
||||
1
|
||||
~zod/try=> `@ud`--1
|
||||
2
|
||||
~zod/try=> `@ud`-2
|
||||
3
|
||||
~zod/try=> `@ud`--2
|
||||
4
|
||||
~zod/try=> `@ux`-0x10
|
||||
0x1f
|
||||
~zod/try=> `@ux`--0x10
|
||||
0x20
|
||||
~zod/try=> `@ud`--0w-
|
||||
124
|
||||
~zod/try=> `@sw`124
|
||||
--0w-
|
||||
|
||||
###Absolute date, @da
|
||||
|
||||
Urbit dates represent 128-bit chronological time, with 2^64 seconds from the
|
||||
start of the universe to the end. 2^127 is 3:30:08 PM on December 5, AD 226,
|
||||
for reasons not clear or relevant:
|
||||
|
||||
~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
|
||||
|
||||
The time of day and/or second fragment is optional:
|
||||
|
||||
~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
|
||||
|
||||
We also do BC:
|
||||
|
||||
~zod/try=> `@ux`~226-.12.5
|
||||
0x7fff.fffc.afb1.b800.0000.0000.0000.0000
|
||||
|
||||
The semantics of the time system are that UGT (Urbit Galactic Time) is GMT/UTC
|
||||
as of leap second 25. UGT is chronological and will never add leap seconds,
|
||||
even if UTC continues this mistake. If a gap appears, it must be resolved in
|
||||
the presentation layer, with timezones and other human curiosities.
|
||||
|
||||
See section 2cH of the source for more details.
|
||||
|
||||
###Relative date, @dr
|
||||
|
||||
It's also nice to have a syntax for basic time intervals:
|
||||
|
||||
~zod/try=> `@ux`~s1
|
||||
0x1.0000.0000.0000.0000
|
||||
|
||||
~zod/try=> `@ux`~m1
|
||||
0x3c.0000.0000.0000.0000
|
||||
|
||||
~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
|
||||
|
||||
There are no @dr intervals under a second or over a day. Since the resolution
|
||||
is so high, though, (div ~s1 1.000.000) produces a pretty accurate microsecond.
|
||||
|
||||
###Loobean, @f
|
||||
|
||||
A loobean, or just bean, is 0 or 1. 0 is yes, 1 is no:
|
||||
|
||||
~zod/try=> `@ud`.y
|
||||
0
|
||||
~zod/try=> `@ud`.n
|
||||
1
|
||||
|
||||
###Nil, @n
|
||||
|
||||
Nil indicates an absence of information, as in a list terminator. The only
|
||||
value is ~, 0.
|
||||
|
||||
~zod/try=> `@ud`~
|
||||
0
|
||||
|
||||
###Unicode text, @t
|
||||
|
||||
@t is a sequence of UTF-8 bytes, LSB first - sometimes called a cord. For
|
||||
lowercase numbers and letters, the canonical syntax is ~~text:
|
||||
|
||||
~zod/try=> ~~foo
|
||||
'foo'
|
||||
|
||||
Note that the prettyprinter makes an unprincipled exception and prints the text
|
||||
in a noncanonical format:
|
||||
|
||||
~zod/try=> `@ux`~~foo
|
||||
0x6f.6f66
|
||||
|
||||
We want to be able to encode an arbitrary Unicode string as a single URL-safe
|
||||
token, using no punctuation but .~-, in @t. Space is ., . is ~., ~ is ~~, - is
|
||||
-:
|
||||
|
||||
~zod/try=> ~~foo.bar
|
||||
'foo bar'
|
||||
~zod/try=> ~~foo.bar~.baz~~moo-hoo
|
||||
'foo bar.baz~moo-hoo'
|
||||
|
||||
For all other ASCII/Unicode characters, insert the Unicode codepoint in
|
||||
lower-case hexadecimal, followed by .. For example, for U+2605 "BLACK STAR",
|
||||
write:
|
||||
|
||||
~zod/try=> ~~foo~2605.bar
|
||||
'foo★bar'
|
||||
|
||||
This UTF-32 codepoint is of course converted to UTF-8:
|
||||
|
||||
~zod/try=> `@ux`~~foo~2605.bar
|
||||
0x72.6162.8598.e26f.6f66
|
||||
|
||||
###URL-safe ASCII text, @ta
|
||||
|
||||
@ta encodes the ASCII subset that all canonical atom syntaxes restrict
|
||||
themselves to. The prefix is ~.. There are no escape sequences except ~~, which
|
||||
means ~, and ~-, which means \_. - and . encode themselves. No other characters
|
||||
besides numbers and lowercase letters need apply.
|
||||
|
||||
~zod/try=> `@t`~.foo
|
||||
'foo'
|
||||
~zod/try=> `@t`~.foo.bar
|
||||
'foo.bar'
|
||||
~zod/try=> `@t`~.foo~~bar
|
||||
'foo~bar'
|
||||
~zod/try=> `@t`~.foo~-bar
|
||||
'foo_bar'
|
||||
~zod/try=> `@t`~.foo-bar
|
||||
'foo-bar'
|
||||
|
||||
A @ta atom is called a span.
|
||||
|
||||
###Codepoint, @c
|
||||
|
||||
Normally when we build atoms of Unicode text, we use a UTF-8 bytestream, LSB
|
||||
first. But sometimes it's useful to build atoms of one or more UTF-32 words.
|
||||
|
||||
The codepoint syntax is the same as @t, except with a ~- prefix. Let's repeat
|
||||
our examples, with hex display:
|
||||
|
||||
~zod/try=> `@ux`~-foo
|
||||
0x6f.0000.006f.0000.0066
|
||||
|
||||
~zod/try=> `@ux`~-foo.bar
|
||||
0x72.0000.0061.0000.0062.0000.0020.0000.006f.0000.006f.0000.0066
|
||||
|
||||
###Phonemic, @p
|
||||
|
||||
We've seen @p used for ships, of course. But it's not just for ships - it's for
|
||||
any short number optimized for memorability, not for arithmetic. @p is great
|
||||
for checksums, for instance.
|
||||
|
||||
That said, @p is subtly customized for the sociopolitical design of Urbit as a
|
||||
digital republic. For example, one feature we don't want is the ability to see
|
||||
at a glance which carrier and cruiser issued a destroyer. Consider the carrier
|
||||
0x21:
|
||||
|
||||
~zod/try=> `@p`0x21
|
||||
~mep
|
||||
|
||||
It issues 255 cruisers, including 0x4321:
|
||||
|
||||
~zod/try=> `@p`0x4321
|
||||
~pasnut
|
||||
|
||||
Which issues 65.535 destroyers, including 0x8765.4321 and several successors:
|
||||
|
||||
~zod/try=> `@p`0x8765.4321
|
||||
~famsyr-dirwes
|
||||
~zod/try=> `@p`0x8766.4321
|
||||
~lidlug-maprec
|
||||
~zod/try=> `@p`0x8767.4321
|
||||
~tidlus-roplen
|
||||
~zod/try=> `@p`0x8768.4321
|
||||
~lisnel-lonbet
|
||||
|
||||
Of course, anyone who can juggle bits can see that ~famsyr-dirwes is a close
|
||||
cousin of ~lidlug-maprec. But she actually has to juggle bits to do it.
|
||||
Obfuscation does not prevent calculated associations, just automatic ones.
|
||||
|
||||
But at the yacht level, we actually want to see a uniform 32-bit space of
|
||||
yachts directly associated with the destroyer:
|
||||
|
||||
~zod/try=> `@p`0x9.8765.4321
|
||||
~talfes-sibzod-famsyr-dirwes
|
||||
~zod/try=> `@p`0xba9.8765.4321
|
||||
~tacbep-ronreg-famsyr-dirwes
|
||||
~zod/try=> `@p`0xd.cba9.8765.4321
|
||||
~bicsub-ritbyt-famsyr-dirwes
|
||||
~zod/try=> `@p`0xfed.cba9.8765.4321
|
||||
~sivrep-hadfeb-famsyr-dirwes
|
||||
|
||||
###IPv4 and IPv6 addresses, @if, @is
|
||||
|
||||
Urbit lives atop IP and would be very foolish to not support a syntax for the
|
||||
large atoms that are IPv4 and IPv6 addresses.
|
||||
|
||||
@if is the standard IPv4 syntax, prefixed with .:
|
||||
|
||||
~zod/try=> `@ux`.127.0.0.1
|
||||
0x7f00.0001
|
||||
|
||||
@is is the same as @if, but with 8 groups of 4 hex digits:
|
||||
|
||||
~zod/try=> `@ux`.dead.beef.0.cafe.42.babe.dead.beef
|
||||
0xdead.beef.0000.cafe.0042.babe.dead.beef
|
||||
|
||||
|
||||
###Floating Point, @rs, @rd, @rq, @rh
|
||||
|
||||
The syntax for a single-precision float is the normal English syntax, with a . prefix:
|
||||
|
||||
.6.2832 :: τ as @rs
|
||||
.-6.2832 :: -τ as @rs
|
||||
.~6.2832 :: τ as @rd
|
||||
.~-6.2832 :: -τ as @rd
|
||||
.~~6.2832 :: τ as @rh
|
||||
.~~~6.2832 :: τ as @rq
|
||||
|
||||
(Hoon is a Tauist language and promotes International Tau Day.)
|
||||
|
||||
###Transparent cell syntax
|
||||
|
||||
By adding _, we can encode arbitrary nouns in our safe subset. The prefix to a
|
||||
canonical cell is ._; the separator is _; the terminator is __. Thus:
|
||||
|
||||
~zod/try=> ._3_4__
|
||||
[3 4]
|
||||
|
||||
~zod/try=> :type; ._.127.0.0.1_._0x12_19___~tasfyn-partyv__
|
||||
[.127.0.0.1 [0x12 19] ~tasfyn-partyv]
|
||||
[@if [@ux @ud] @p]
|
||||
|
||||
Those who don't see utility in this strange feature have perhaps never needed
|
||||
to jam a data structure into a URL.
|
||||
|
||||
###Opaque noun syntax
|
||||
|
||||
Speaking of jam, sometimes we really don't care what's inside our noun. Then,
|
||||
the syntax to use is a variant of @uw prefixed by ~, which incorporates the
|
||||
built-in jam and cue marshallers:
|
||||
|
||||
~zod/try=> (jam [3 4])
|
||||
78.241
|
||||
~zod/try=> `@uw`(jam [3 4])
|
||||
0wj6x
|
||||
~zod/try=> (cue 0wj6x)
|
||||
[3 4]
|
||||
~zod/try=> ~0wj6x
|
||||
[3 4]
|
||||
|
||||
Noncanonical Syntax
|
||||
--------------------
|
||||
|
||||
These are syntaxes for constants which don't fit the canonical character-set
|
||||
constraints.
|
||||
|
||||
###Cubes, @tas
|
||||
|
||||
@tas, a term, is our most exclusive odor. The only characters permitted are
|
||||
lowercase ASCII, - except as the first or last character, and 0-9 except as the
|
||||
first character.
|
||||
|
||||
The syntax for @tas is the text itself, always preceded by %. This means a term
|
||||
is always cubical. You can cast it to @tas if you like, but we just about
|
||||
always want the cube:
|
||||
|
||||
~zod/try=> %dead-fish9
|
||||
%dead-fish9
|
||||
|
||||
~zod/try=> -:!>(%dead-fish9)
|
||||
[%cube p=271.101.667.197.767.630.546.276 q=[%atom p=%tas]]
|
||||
|
||||
The empty @tas has a special syntax, $:
|
||||
|
||||
~zod/try=> %$
|
||||
%$
|
||||
|
||||
A term without % is not a constant, but a name:
|
||||
|
||||
~zod/try=> dead-fish9
|
||||
! -find-limb.dead-fish9
|
||||
! find-none
|
||||
! exit
|
||||
|
||||
A common structure in Hoon is a noun with a cubical head and an arbitrary tail:
|
||||
|
||||
~zod/try=> [%foo 'bar']
|
||||
[%foo 'bar']
|
||||
|
||||
This structure may be generated with the following irregular syntax:
|
||||
|
||||
~zod/try=> a/'bar'
|
||||
[%a 'bar']
|
||||
|
||||
###Loobeans, @f
|
||||
|
||||
.y is a little cumbersome, so we can say & and |. The % prefix cubes as usual.
|
||||
|
||||
~zod/try=> `@ud`&
|
||||
0
|
||||
~zod/try=> `@ud`|
|
||||
1
|
||||
|
||||
###Cords, @t
|
||||
|
||||
The canonical ~~ syntax for @t, while it has its place, is intolerable in a
|
||||
number of ways - especially when it comes to escaping capitals. So @t is both
|
||||
printed and parsed in a conventional-looking single-quote syntax:
|
||||
|
||||
~zod/try=> 'foo bar'
|
||||
'foo bar'
|
||||
~zod/try=> `@ux`'foo bar'
|
||||
0x72.6162.206f.6f66
|
||||
Escape ' with \:
|
||||
|
||||
~zod/try=> 'Foo \'bar'
|
||||
'Foo \'bar'
|
||||
~zod/try=> `@ux`'\''
|
||||
0x27
|
||||
|
||||
###Strings
|
||||
|
||||
Text in Hoon is generally manipulated in two ways, depending on what you're
|
||||
doing: as an atomic cord/span/term, or as a tape which is a list of bytes (not
|
||||
codepoints).
|
||||
|
||||
To generate a tape, use double quotes:
|
||||
|
||||
~zod/try=> "foo"
|
||||
"foo"
|
||||
~zod/try=> `*`"foo"
|
||||
[102 111 111 0]
|
||||
|
||||
We're getting off the constant reservation, but strings also interpolate with curly-braces:
|
||||
|
||||
~zod/try=> "hello {(weld "wor" "ld")} is a fun thing to say"
|
||||
"hello world is a fun thing to say"
|
||||
|
||||
And they can be joined across space or lines with a .:
|
||||
|
||||
~zod/try=> "hello"."world"
|
||||
"helloworld"
|
||||
~zod/try=> "hello". "world"
|
||||
"helloworld"
|
||||
|
||||
Lists
|
||||
-----
|
||||
|
||||
A list in Hoon is a null-terminated tuple. See section 2bB for Hoon's List library.
|
||||
|
||||
~zod/try=> :type; `(list)`[3 4 ~]
|
||||
~[3 4]
|
||||
it(*)
|
||||
|
||||
The list type can be further specified by a subtype:
|
||||
|
||||
~zod/try=> :type; `(list ,@ud)`[3 4 ~]
|
||||
~[3 4]
|
||||
it(@ud)
|
||||
|
||||
The above example is a list of @ud, meaning the all values in the list must be of type @ud.
|
||||
|
||||
Polymorphic lists can be specified by constructing a more complex type:
|
||||
|
||||
~zod/try=> :type; `(list ?(@ud @ux))`[3 0xf ~]
|
||||
~[3 15]
|
||||
it({@ud @ux})
|
||||
|
||||
Not specifing a more complex type defaults to a list of raw nouns:
|
||||
|
||||
~zod/try=> :type; `(list)`[3 0xf ~]
|
||||
~[3 15]
|
||||
it(*)
|
||||
|
||||
Null-terminated tuples may be generated with the following syntax:
|
||||
|
||||
~zod/try=> ~[3 0xf]
|
||||
[3 0xf ~]
|
||||
|
||||
~zod/try=> :type; ~[3 0xf]
|
||||
[3 0xf ~]
|
||||
[@ud @ux %~]
|
||||
|
||||
Note that this syntax is not automatically typed as a list, but may be cast as such:
|
||||
|
||||
~zod/try=> :type; `(list ?(@ux @ud))`~[3 0xf]
|
||||
~[0x3 0xf]
|
||||
it({@ux @ud})
|
||||
|
||||
Furthermore, a different syntax may be used to group the entire noun in the
|
||||
head of a null terminated tuple:
|
||||
|
||||
|
||||
~zod/try=> [3 0xf]~
|
||||
[[3 0xf] ~]
|
||||
|
||||
This is often used to easily generate a list from a single noun.
|
||||
|
||||
~zod/try=> :type; `(list ,[@ud @ux])`[3 0xf]~
|
||||
~[[3 0xf]]
|
||||
it([@ud @ux])
|
||||
|
||||
The above is typed as a list of decimal hexadecimal pairs.
|
||||
|
||||
Units
|
||||
-----
|
||||
|
||||
A Unit is Hoon's "maybe" type. As in, either some value or null. See section 2bA for Hoon's Unit library. Units are represented by a cell whose head is null and whose tail is some noun:
|
||||
|
||||
~zod/try=> `(unit ,@ud)`[~ 3]
|
||||
[~ 3]
|
||||
|
||||
The unit type can be further specified by a subtype. The above example is a unit of @ud, meaning the optional value must be of type @ud.
|
||||
|
||||
~zod/try=> `(unit ,@ud)`[~ [3 3]]
|
||||
! type-fail
|
||||
! exit
|
||||
|
||||
~zod/try=> `(unit ,^)`[~ [3 3]]
|
||||
[~ [3 3]]
|
||||
|
||||
For convenience, a null-headed noun may be specified with the following irregular syntax:
|
||||
|
||||
~zod/try=> `3
|
||||
[~ 3]
|
||||
|
||||
~zod/try=> :type; `3
|
||||
[~ 3]
|
||||
[%~ @ud]
|
||||
|
||||
Note that this syntax is not automatically typed as a Unit, but may be cast as such:
|
||||
|
||||
~zod/try=> :type; `(unit)``3
|
||||
[~ 3]
|
||||
u(*)
|
||||
|
||||
|
||||
|
||||
|
2521
main/pub/src/doc/ref/hoon/lex-rune.md
Normal file
2521
main/pub/src/doc/ref/hoon/lex-rune.md
Normal file
File diff suppressed because it is too large
Load Diff
2612
main/pub/src/doc/ref/hoon/lex-tile.md
Normal file
2612
main/pub/src/doc/ref/hoon/lex-tile.md
Normal file
File diff suppressed because it is too large
Load Diff
2612
main/pub/src/doc/ref/hoon/lex-twig.md
Normal file
2612
main/pub/src/doc/ref/hoon/lex-twig.md
Normal file
File diff suppressed because it is too large
Load Diff
2546
main/pub/src/doc/ref/hoon/lexicon.md
Normal file
2546
main/pub/src/doc/ref/hoon/lexicon.md
Normal file
File diff suppressed because it is too large
Load Diff
228
main/pub/src/doc/ref/hoon/morphology.md
Normal file
228
main/pub/src/doc/ref/hoon/morphology.md
Normal file
@ -0,0 +1,228 @@
|
||||
Morphology
|
||||
==========
|
||||
|
||||
Hoon is a statically typed language that compiles to Nock.
|
||||
|
||||
Types
|
||||
-----
|
||||
|
||||
Types are nouns the compiler keeps around as it turns your Hoon into Nock.
|
||||
|
||||
A type serve two purposes:
|
||||
|
||||
1. It defines a set of nouns. Any finite noun is either in this set, or not in
|
||||
it.
|
||||
|
||||
2. it ascribes semantics to all nouns in this set. For example, a Hoon type
|
||||
exports a semantic namespace.
|
||||
|
||||
|
||||
These are defined in Hoon as one of the ten kinds of type found in `++type`.
|
||||
|
||||
At its most general, the `noun` type contains all Hoon nouns. Everything in
|
||||
Hoon is a noun. The `%void` type contains no values at all. The `%atom` type
|
||||
contains only atoms. The `%cube` type is parameterized by a value, and it
|
||||
contains only that single value. The other types are defined in the lexicon.
|
||||
|
||||
Type inference in Hoon works well enough that there is no direct
|
||||
syntax for defining or declaring a type. There is only a syntax for
|
||||
constructing twigs. Types are always produced by inference.
|
||||
|
||||
|
||||
When resolving a face, for example, the axis that
|
||||
ends up in the nock formula depends on the where the face is in the subject.
|
||||
We only know this because faces are in the subject type. Thus, in `=> [p=42
|
||||
q=1.337] p`, the `p` twig compiles to nock `[0 2]` while in `=> [q=42 p=1.337]
|
||||
p`, the `p` twig compiles to nock `[0 3]`. This is true even though the actual
|
||||
nock produced by `[p=42 q=1.337]` is the same as that produced by `[q=42
|
||||
p=1.337]`. Thus, the nock formula may depend on the subject type. It is for
|
||||
this reason that we say that a type defines not only a set of values, but also
|
||||
the semantics for operating on those values.
|
||||
|
||||
|
||||
Tiles
|
||||
-----
|
||||
|
||||
What are the usual things we want to do with types?
|
||||
|
||||
- Test if a noun is of a particular type.
|
||||
|
||||
- Create a blank default example of a type
|
||||
|
||||
- Coerce a noun into a type
|
||||
|
||||
It is possible to generate twigs for each of the above use cases from two
|
||||
pieces of information: (1) a tile describing a type and (2) a reference to
|
||||
which case we want to generate.
|
||||
|
||||
Tiles are not types.
|
||||
|
||||
Every tile has a unique associated type, or "icon".
|
||||
|
||||
A tile is not a type, but every tile corresponds to some type.
|
||||
|
||||
Formalizing the operations on a tile, there are exactly four.
|
||||
|
||||
Bunting a tile is simply creating a blank default example of the tile's icon.
|
||||
This may seem to have limited usefulness, but this is actually the most common
|
||||
use of tiles. This is due to the the way in which we create, for example,
|
||||
gates. The sample of a gate is usually defined in terms of a tile, as in `|=
|
||||
[p=@ q=@] (add p q)`. The `|=` rune takes a tile (in this case `[p=@ q=@]`
|
||||
and bunts it to create a default sample of `[0 0]` with the type of a cell of
|
||||
two atoms. Note that this is different from `|= [p=%0 q=%0] (add p q)`,
|
||||
which still bunts to create a default sample of `[0 0]`, but whose type is a
|
||||
cell of two constant `0`s. In the first case, when we call our gate, the type
|
||||
checker will make sure that we are only ever replacing the sample with a cell
|
||||
of two atoms, while in the second case the type checker will enforce that we
|
||||
are only ever replacing the sample with a cell of two `0`s.
|
||||
|
||||
Clamming a tile is creating a gate whose sample is a noun and whose product is
|
||||
a member of the icon. This allows us to coerce any noun into any type. If the
|
||||
noun is not a member of that type, then we produce some member of the type that
|
||||
is either in some sense "similar" to the given noun or else we simply give a
|
||||
default value, usually the bunt of this tile.
|
||||
|
||||
Fishing a tile is testing whether a particular value is of that type. This
|
||||
returns a loobean. This obviously has many uses.
|
||||
|
||||
Whipping a tile is something you'll never have to do directly. Whipping is
|
||||
never directly used in any Hoon source code. Whipping is used internally by
|
||||
clamming.
|
||||
|
||||
In summary, a tile is simply a convenient syntax for creating well-typed nouns.
|
||||
|
||||
A tile is not a twig, but tiles always are reduced statically in one
|
||||
of four ways to a twig.
|
||||
|
||||
|
||||
Type Inference
|
||||
--------------
|
||||
|
||||
Hoon is a higher-order typed functional language. Most languages in this class,
|
||||
Haskell and ML being prominent examples, use something called the
|
||||
Hindley-Milner unification algorithm. Hoon uses its own special sauce instead.
|
||||
|
||||
Hoon's philosophy is that a language is a UI for programmers, and the basic
|
||||
test of a UI is its predictability. It is impossible (for most programmers)
|
||||
to learn a language properly unless they know what the compiler is doing, which
|
||||
in practice means mentally stepping through the algorithms it uses (with the
|
||||
exception of semantically neutral optimizations). Haskell is a hard language to
|
||||
learn (for most programmers) because it's hard (for most programmers) to follow
|
||||
what the Haskell compiler is thinking.
|
||||
|
||||
|
||||
Broadly speaking, type inference in Hoon has three general limitations as
|
||||
compared to Hindley-Milner inference.
|
||||
|
||||
1. Hoon does not think backwards. For instance, it cannot infer a function's
|
||||
argument type (or rather, a gate's sample type) from its body.
|
||||
|
||||
2. Hoon can infer through tail recursion, but not head recursion. It can check
|
||||
head recursion, however, given an annotation.
|
||||
|
||||
3. The compiler catches most but not all divergent inference problems - i.e.
|
||||
you can put the compiler into an infinite loop or exponential equivalent.
|
||||
An interrupt will still show you your error location.
|
||||
|
||||
Although an inference algorithm that reasons only forward must and does require
|
||||
a few more annotations from the programmer, the small extra burden on her
|
||||
fingers is more than offset by the lighter load on her hippocampus.
|
||||
Furthermore, programs also exist to be read. Some of these annotations (which a
|
||||
smarter algorithm might infer by steam) may annoy the actual author of the code
|
||||
but be a lifesaver for her replacement.
|
||||
|
||||
Our experience is that these limitations are minor annoyances at worst and
|
||||
prudent restrictions at best. Your mileage may vary.
|
||||
|
||||
Type inference is a frightening problem, especially if you've been exposed to
|
||||
a wall of math. Your only real problem in learning Hoon is to learn not to
|
||||
fear it. Once you work past this reasonable but entirely unfounded fear of
|
||||
inference, your Hoon experience will be simple, refreshing and delightful. So
|
||||
first, let's talk through a few reassuring facts:
|
||||
|
||||
1. Type inference in Hoon never sees a tile. It operates exclusively on twigs.
|
||||
All tiles and synthetic twigs are reduced to natural twigs for the inference
|
||||
engine's benefit.
|
||||
|
||||
2. The semantics of Hoon are in ++ut in hoon.hoon, and nowhere else.
|
||||
|
||||
3. Within ++ut, all the semantics of Hoon are in the call graph of one arm: ++mint.
|
||||
++mint has a case for every natural hoon. So do ++play and ++mull,
|
||||
but their semantics are redundant with ++mint.
|
||||
|
||||
4. One leg in the sample of ++mint - gol - which looks for all the world like a
|
||||
mechanism for backward inference, is not. It is semantically irrelevant and
|
||||
only exists to get better localization on error reports.
|
||||
|
||||
5. ++mint is the gate that maps [type twig] to [type nock]:
|
||||
|
||||
[subject-type twig] => [product-type nock-formula]
|
||||
|
||||
When we have a type that describes the subject for the formula we're trying to
|
||||
generate, as we generate that formula we want to also generate a type for the
|
||||
product of that formula on that subject. As long as subject-type is a
|
||||
correct description of some subject, you can take any twig and compile it
|
||||
against subject-type, producing a formula such that *(subject formula) is a
|
||||
product correctly described by product-type.
|
||||
|
||||
|
||||
Compilation
|
||||
------------
|
||||
|
||||
`++make` is a top-level function that turns text into nock.
|
||||
|
||||
~hoclur-bicrel/try=> `*`(make '|= [@ @ud] +<')
|
||||
[8 [1 0 0] [1 0 6] 0 1]
|
||||
|
||||
Another way to do this is with `!=`.
|
||||
|
||||
~hoclur-bicrel/try=> !=(|=([@ @ud] +<))
|
||||
[8 [1 0 0] [1 0 6] 0 1]
|
||||
|
||||
`++make` is more general, in that it can be called on programmatically
|
||||
generated text, but `!=` is convenient for learning and debugging.
|
||||
|
||||
The compilation process is as follows:
|
||||
|
||||
First, a runic expression is parsed into an abstact syntax tree, called a
|
||||
`twig`:
|
||||
|
||||
text => twig
|
||||
|
||||
Parsing code into a `twig` can be done with `++ream`:
|
||||
|
||||
~hoclur-bicrel/try=> (ream '|= [@ @ud] +<')
|
||||
[ %brts
|
||||
p=[p=[%axil p=[%atom p=~.]] q=[%axil p=[%atom p=~.ud]]]
|
||||
q=[%cnts p=~[[%.y p=6]] q=~]
|
||||
]
|
||||
|
||||
Refer to the Syntax section for more detail on parsing.
|
||||
|
||||
The compiler proper, is `++mint` in `++ut`.
|
||||
|
||||
++mint takes a twig and a subject type and produces a product type and a nock formula.
|
||||
|
||||
[subject-type twig] => [product-type nock-formula]
|
||||
|
||||
For example, we can call `++mint` on the twig we produced earlier with a
|
||||
subject type of any noun:
|
||||
|
||||
~hoclur-bicrel/try=>
|
||||
(~(mint ut %noun) %noun [%brts [[%axil [%atom ~.]] [%axil [%atom ~.ud]]] [%cnts ~[[%.y 6]] ~]])
|
||||
|
||||
[ p
|
||||
[ %core
|
||||
p=[%cell p=[%cell p=[%atom p=%$] q=[%atom p=%ud]] q=%noun]
|
||||
q
|
||||
[ p=%gold
|
||||
q=[%cell p=[%cell p=[%atom p=%$] q=[%atom p=%ud]] q=%noun]
|
||||
r=[p=[0 6] q={[p=%$ q=[%ash p=[%cnts p=~[[%.y p=6]] q=~]]]}]
|
||||
]
|
||||
]
|
||||
q=[%8 p=[%1 p=[0 0]] q=[p=[%1 p=[0 6]] q=[%0 p=1]]]
|
||||
]
|
||||
|
||||
Note that the head of the above is a type, which in this case is a gold core
|
||||
with an ash gate. The second part, though, is (with a few labels, or faces added) the nock that was
|
||||
produced by `++make`.
|
176
main/pub/src/doc/ref/hoon/orthography.md
Normal file
176
main/pub/src/doc/ref/hoon/orthography.md
Normal file
@ -0,0 +1,176 @@
|
||||
Orthography: Consensus Aesthetic
|
||||
==========
|
||||
|
||||
The Hoon compiler enforces the syntactical correctness of the language, it does
|
||||
not, with some exceptions, enforce aesthetic standards. Many different styles
|
||||
of Hoon are possible. However, given Hoon's runic syntax, it is remarkably easy
|
||||
for the novice programmer to generate idiosyncratic illegible code. Many other
|
||||
languages that make heavy use of ASCII have a similar problem. Furthermore,
|
||||
collaborative programming is made vastly easier by using a standard style
|
||||
convention.
|
||||
|
||||
The Urbit source is written in a style of Hoon called the Consensus Aesthetic.
|
||||
No patches to the Urbit source will be accepted unless they follow the ConsensusAesthetic.
|
||||
|
||||
The general rules of the Consensus Aesthetic are the following:
|
||||
|
||||
Character Restriction
|
||||
---------------------
|
||||
|
||||
The horizontal tab character, \ht, ASCII 0x9, must never occur. This is
|
||||
enforced by the compiler.
|
||||
|
||||
Line and Comments
|
||||
-----------------
|
||||
|
||||
Lines must not exceed 80 columns in width and should not exceed 55 columns.
|
||||
|
||||
Blank lines (lines consisting entirely of whitespace) should not occur. For
|
||||
visual separation of code, use empty comments.
|
||||
|
||||
Comments may appear on column 0, column 57 or inline at the same level of
|
||||
indentation as the code.
|
||||
|
||||
Indentation
|
||||
-----------
|
||||
|
||||
Aesthetically, the act of programming is the act of formatting a big wall of
|
||||
text. This canvas has a curious but essential property - it is indefinitely
|
||||
tall, but finitely wide. The programmer's task as a visual designer is to
|
||||
persuade code to flow down, not across.
|
||||
|
||||
The first law of Hoon indentation style is that all tall form indentation is in
|
||||
two-space increments. Single spaces are for wide form only.
|
||||
|
||||
The second law of Hoon indentation is that everything in the kernel is good
|
||||
indentation style. Or at least if it's not, it needs to be changed.
|
||||
|
||||
The third and most important law of Hoon indentation is that large twigs should
|
||||
flow down and not across. The Aesthetic prescribes a backstep pattern, which
|
||||
preserves indentation level in the common case:
|
||||
|
||||
|
||||
```
|
||||
?: |
|
||||
47
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
```
|
||||
|
||||
|
||||
Notice that the first child is placed the furthest horizontal distance away
|
||||
from its parent rune. Each of the subsequent children is outdented, such
|
||||
that the last child (a similarly formatted twig) is vertically aligned with its parent.
|
||||
|
||||
However, this convention does not always prevent horizontal drift. For example,
|
||||
there are many cases when the last twig is not the heaviest:
|
||||
|
||||
```
|
||||
?: &
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
47
|
||||
```
|
||||
|
||||
To handle cases like this, there exist several (synthetic runes)[lexicon/#rune_types]
|
||||
that invert the argument order of common runes to ensure the last twig is the
|
||||
heaviest. For example, where `?:` is _if-then_, `?.` is _unless_:
|
||||
|
||||
```
|
||||
?. &
|
||||
47
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
```
|
||||
|
||||
###N-ary runes###
|
||||
For runes that take an arbitrary number of children, the children are indented,
|
||||
with the closing `==` aligned with the rune:
|
||||
|
||||
```
|
||||
;~ plug
|
||||
ace
|
||||
ace
|
||||
==
|
||||
```
|
||||
|
||||
For runes operating on associative lists, there exist two indentation conventions:
|
||||
Kingside, where the key-value pairs are (or at least start) on the same line:
|
||||
|
||||
```
|
||||
%= res
|
||||
key1 val
|
||||
key2 val2
|
||||
==
|
||||
```
|
||||
|
||||
And Queenside, where the keys lie indented on the line above their respective
|
||||
values:
|
||||
|
||||
```
|
||||
%= res
|
||||
key
|
||||
twig-producing-val
|
||||
key2
|
||||
=+ a=2
|
||||
[a 3]
|
||||
==
|
||||
```
|
||||
|
||||
While both of these techniques are used to preserve the right margin, the
|
||||
latter is used when the keys and/or values are especially heavy.
|
||||
|
||||
|
||||
Naming Convention
|
||||
-----------------
|
||||
|
||||
Names must follow one of the following naming conventions: Austere, Lapidary,
|
||||
or Freehand.
|
||||
|
||||
In Austere Hoon, variables and arguments are named alphabetically with one
|
||||
letter, a, b, c etc, in strict order of appearance in the text. This scheme is
|
||||
only useful in the case of extremely regular and straightforward namespaces:
|
||||
very short functions, for instance.
|
||||
|
||||
Austere arms must be gates or trays. Gate arms are three letters and try to
|
||||
carry some mnemonic significance - for instance, ++dec. Tray arms are two
|
||||
letters and try to resemble pronouns - for instance, ++by.
|
||||
|
||||
Austere structures must be short tuples, no wider than 5. The legs are named p,
|
||||
q, r, s and/or t.
|
||||
|
||||
Conventional recursive structures use other standard names. The head of a list
|
||||
is always i, the tail is always t. In a binary tree of nodes, the node is n,
|
||||
the children l and r.
|
||||
|
||||
When in doubt, do not use Austere Hoon. In an ordinary context - not least
|
||||
because Austere gates are easily mistaken for Lapidary variables - there should
|
||||
be as few Austere arms as possible. And always remind yourself that Austere
|
||||
Hoon makes it as hard as possible to refactor your code.
|
||||
|
||||
Lapidary Hoon is the ordinary style of most of Hoon and Arvo. In lapidary mode,
|
||||
variables, arguments, attributes, etc, are three-letter strings, usually
|
||||
consonant-vowel-consonant, generally meaningless. If the same string is used
|
||||
more than once in the same file, it should be used for the same concept in some
|
||||
sense, as often happens spontaneously in cutting and pasting. It would be nice
|
||||
to have an editor with a macro that generated random unique TLV strings
|
||||
automatically.
|
||||
|
||||
Lapidary arms are always four letters. They may or may not be English words,
|
||||
which may or may not mean anything relevant.
|
||||
|
||||
In Freehand Hoon, do whatever you want. Note that while uppercase is not
|
||||
permitted in a symbol, - is, suggesting a generally Lisp-like state of gross
|
||||
hyphenated disorder. F-mode is best used for top-layer software which nothing
|
||||
else is based on; prototyping and casual coding; etc. Freehand Hoon is not an acceptable style for any code in the Urbit source proper, and is discouraged for production applications.
|
||||
|
||||
|
85
main/pub/src/doc/ref/hoon/philosophy.md
Normal file
85
main/pub/src/doc/ref/hoon/philosophy.md
Normal file
@ -0,0 +1,85 @@
|
||||
Philosophy
|
||||
==========
|
||||
|
||||
Hoon is a higher-order typed functional language that it compiles itself to
|
||||
Nock in 3400 lines of Hoon. If this number is accurate (it is), Hoon is very
|
||||
expressive, or very simple, or both. (It's both.) The bad news is that it
|
||||
really has nothing at all in common, either syntactically or semantically, with
|
||||
anything you've used before.
|
||||
|
||||
By understanding Nock tutorial, you've actually come closer than you realize to
|
||||
knowing Hoon. Hoon is actually not much more than a fancy wrapper around Nock.
|
||||
People who know C can think of Hoon as the C to Urbit's Nock - just a
|
||||
sprinkling of syntax, wrapped around machine code and memory.
|
||||
|
||||
For instance, it's easy to imagine how instead of calculating tree axes by
|
||||
hand, we could actually assign names to different parts of the tree - and those
|
||||
names would stay the same as we pushed more data on the subject.
|
||||
|
||||
The way we're going to do this is by associating something called a type with
|
||||
the subject. You may have heard of types before. Technically, Hoon is a
|
||||
statically typed language, which just means that the type isn't a part of your
|
||||
program: it's just a piece of data the compiler keeps around as it turns your
|
||||
Hoon into Nock.
|
||||
|
||||
A lot of other languages use dynamic types, in which the type of a value is
|
||||
carried along with the data as you use it. Even languages like Lisp, which are
|
||||
nominally typeless, look rather typed from the Hoon perspective. For example, a
|
||||
Lisp atom knows dynamically whether it's a symbol or an integer. A Hoon atom is
|
||||
just a Nock atom, which is just a number. So without a static type, Hoon
|
||||
doesn't even know how to print an atom properly.
|
||||
|
||||
Most higher-order typed languages, Haskell and ML being prominent examples, use
|
||||
something called the Hindley-Milner unification algorithm. Hoon uses its own
|
||||
special sauce instead.
|
||||
|
||||
Why? There are two obvious problems with Hindley-Milner as a functional type
|
||||
system, the main one being the wall of heavy mathematics that greets you
|
||||
instantly when you google it. We have heard some claims that Hindley-Milner is
|
||||
actually quite simple. We urge all such claimants to hie themselves to its
|
||||
Wikipedia page, which they'll surely be able to relieve of its present alarming
|
||||
resemblance to some string-theory paper in Physics Review D.
|
||||
|
||||
Nor is this in any way an an anti-academic stance. Quite the contrary.
|
||||
Frankly, OS guys really quite seldom find themselves in the math-department
|
||||
lounge, cadging stray grants by shamelessly misrepresenting the CAP theorem as
|
||||
a result in mathematics. It doesn't seem too much to expect the mathematicians
|
||||
to reciprocate this basic academic courtesy.
|
||||
|
||||
Furthermore, besides the drawback that Hindley-Milner reeks of math and
|
||||
programmers who love math are about as common as cats who love a bath - a
|
||||
problem, but really only a marketing problem - Hindley-Milner has a genuine
|
||||
product problem as well. It's too powerful.
|
||||
|
||||
Specifically, Hindley-Milner reasons both forward with evaluation, and backward
|
||||
from constraints. Pretty unavoidable in any sort of unification algorithm,
|
||||
obviously. But since the compiler has to think both forward and backward, and
|
||||
the programmer has to predict what the compiler will do, the programmer has to
|
||||
think backward as well.
|
||||
|
||||
Hoon's philosophy is that a language is a UI for programmers, and the basic
|
||||
test of a UI is to be easy to use. It is impossible (for most programmers) to
|
||||
learn a language properly unless they know what the compiler is doing, which in
|
||||
practice means mentally stepping through the algorithms it uses (with the
|
||||
exception of semantically neutral optimizations). Haskell is a hard language to
|
||||
learn (for most programmers) because it's hard (for most programmers) to follow
|
||||
what the Haskell compiler is thinking.
|
||||
|
||||
It's true that some programmers have an effective mathematical intuition that
|
||||
let them "see" algorithms without working through them step by step. But this
|
||||
is a rare talent, we feel. And even those who have a talent don't always enjoy
|
||||
exercising it.
|
||||
|
||||
If a thorough understanding of any language demands high-grade mathematical
|
||||
intuition in its programmers, the language as a UI is like a doorway that makes
|
||||
you duck if you're over 6 feet tall. The only reason to build such a doorway in
|
||||
your castle is if you and all your friends are short, and only your enemies are
|
||||
tall. Is this really the case here?
|
||||
|
||||
Although an inference algorithm that reasons only forward must and does require
|
||||
a few more annotations from the programmer, the small extra burden on her
|
||||
fingers is more than offset by the lighter load on her hippocampus.
|
||||
Furthermore, programs also exist to be read. The modern code monkey is above
|
||||
all things a replaceable part, and some of these annotations (which a smarter
|
||||
algorithm might infer by steam) may annoy the actual author of the code but be
|
||||
a lifesaver for her replacement.
|
226
main/pub/src/doc/ref/hoon/phonology.md
Normal file
226
main/pub/src/doc/ref/hoon/phonology.md
Normal file
@ -0,0 +1,226 @@
|
||||
Phonology
|
||||
=========
|
||||
|
||||
Glyphs
|
||||
------
|
||||
|
||||
Hoon is a keyword-free language - any alphanumeric text in the program is part
|
||||
of the program. Where other languages have reserved words, Hoon syntax uses
|
||||
ASCII symbols, or glyphs. In normal English, many of these glyphs have
|
||||
cumbersome multisyllabic names. As Hoon uses these glyphs heavily, it has its
|
||||
own, more concise, naming scheme for them:
|
||||
|
||||
ace space gal < per )
|
||||
bar | gar > sel [
|
||||
bas \ hax # sem ;
|
||||
buc $ hep - ser ]
|
||||
cab _ kel { sig ~
|
||||
cen % ker } soq '
|
||||
col : ket ^ tar *
|
||||
com , lus + tec `
|
||||
doq " pam & tis =
|
||||
dot . pat @ wut ?
|
||||
fas / pel ( zap !
|
||||
|
||||
|
||||
A language is meant to be spoken. Even a programming language. Studies have
|
||||
shown that even when we read silently, we activate the motor cortex that
|
||||
controls our vocal cords. Even if we never speak these symbols, they're easier
|
||||
to think if bound to simple sounds.
|
||||
|
||||
Mnemonic aids for memorizing the above glyphs can be found in the comments of section 2eF of the Urbit Source, which is reprinted here:
|
||||
|
||||
```
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
:: section 2eF, parsing (ascii) ::
|
||||
::
|
||||
++ ace (just ' ') :: spACE
|
||||
++ bar (just '|') :: vertical BAR
|
||||
++ bas (just '\\') :: Back Slash (escaped)
|
||||
++ buc (just '$') :: dollars BUCks
|
||||
++ cab (just '_') :: CABoose
|
||||
++ cen (just '%') :: perCENt
|
||||
++ col (just ':') :: COLon
|
||||
++ com (just ',') :: COMma
|
||||
++ doq (just '"') :: Double Quote
|
||||
++ dot (just '.') :: dot dot dot ...
|
||||
++ fas (just '/') :: Forward Slash
|
||||
++ gal (just '<') :: Greater Left
|
||||
++ gar (just '>') :: Greater Right
|
||||
++ hax (just '#') :: Hash
|
||||
++ kel (just '{') :: Curly Left
|
||||
++ ker (just '}') :: Curly Right
|
||||
++ ket (just '^') :: CareT
|
||||
++ lus (just '+') :: pLUS
|
||||
++ hep (just '-') :: HyPhen
|
||||
++ pel (just '(') :: Paren Left
|
||||
++ pam (just '&') :: AMPersand pampersand
|
||||
++ per (just ')') :: Paren Right
|
||||
++ pat (just '@') :: AT pat
|
||||
++ sel (just '[') :: Square Left
|
||||
++ sem (just ';') :: SEMicolon
|
||||
++ ser (just ']') :: Square Right
|
||||
++ sig (just '~') :: SIGnature squiggle
|
||||
++ soq (just '\'') :: Single Quote
|
||||
++ tar (just '*') :: sTAR
|
||||
++ tec (just '`') :: backTiCk
|
||||
++ tis (just '=') :: 'tis tis, it is
|
||||
++ wut (just '?') :: wut, what?
|
||||
++ zap (just '!') :: zap! bang! crash!!
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
```
|
||||
|
||||
Digraph Glyphs: Runes
|
||||
--------------------
|
||||
|
||||
The fundamental building block of Hoon is the digraph glyph or rune. TThe choice of glyph is not random. The first defines a semantic category. That is, all runes whose first glyph is `|` or `bar` are conceptually related. See Morphology for details.
|
||||
|
||||
To pronounce a rune, concatenate the glyph names, stressing the first syllable
|
||||
and softening the second vowel into a "schwa." Hence, to say `~&`, say
|
||||
"sigpam." To say `|=`, say "bartis."
|
||||
|
||||
Punctuation Runes
|
||||
----------------
|
||||
|
||||
The following runes are used as punctuation in Tall Form Hoon (See Syntax for details) and have mandatory special pronunciation:
|
||||
|
||||
-- hephep phep
|
||||
+- lushep slep
|
||||
++ luslus slus
|
||||
== tistis stet
|
||||
|
||||
Wing Runes
|
||||
---------
|
||||
|
||||
The following runes are used to access specific axes or wings in a noun. See Morphology. They have optional alternate phonology.
|
||||
|
||||
+< lusgal glus
|
||||
+> lusgar gras
|
||||
-< hepgal gelp
|
||||
-> hepgar garp
|
||||
|
||||
Tile Runes
|
||||
---------
|
||||
|
||||
The following runes comprise the set of "Tile Runes" and are used to generate
|
||||
complex types (See Morphology for details). They have an optional alternate
|
||||
phonology, which describes the tile they generate:
|
||||
|
||||
$% buccen kelp
|
||||
$^ bucket herb
|
||||
$: buccol tile
|
||||
$= buctis bark
|
||||
$& bucpam bush
|
||||
$? bucwut fern
|
||||
$| bucbar reed
|
||||
|
||||
The following glyphs are not runes, but are commonly used with tile runes to specify basic types. (See Morphology for details). In context, they have an optional alternate phonology:
|
||||
|
||||
@ "atom"
|
||||
^ "cell"
|
||||
* "noun"
|
||||
? "bean"
|
||||
~ "null"
|
||||
|
||||
Irregular Runes
|
||||
--------------
|
||||
|
||||
The following glyphs have optional special pronunciation when they appear as
|
||||
the irregular form as certain digraph runes. It is perfectly acceptable to
|
||||
pronounce the characters, but some may find the alternate phonology useful,
|
||||
especially in cases where multiple irregular forms occur in sequence.
|
||||
|
||||
Irregular Regular Pronunciation
|
||||
|
||||
,p $,(p) "clam p"
|
||||
_p $_(p) "bunt p"
|
||||
p@q $@(p q) "whip p into q"
|
||||
!p ?!(p) "NOT p"
|
||||
&(p q) ?&(p q) "AND p q
|
||||
|(p q) ?|(p q) "OR p q"
|
||||
?(p q) $?(p q) "fern p q"
|
||||
`p`q ^-(p q) "cast p q"
|
||||
p=q ^=(p q) "p is q"
|
||||
~[p q] :~(a b) "list p q"
|
||||
`[p] [~ p] "unit p"
|
||||
p^q [p q] "cell p q"
|
||||
[p q] :*(p) "cell p q"
|
||||
+(p) .+(p) "bump p"
|
||||
=(p q) .=(p q) "equals p q"
|
||||
p:q =<(p q) "p of q"
|
||||
p(q r) %=(p q r) "toss p q r"
|
||||
(p q) %-(p q) "slam p q"
|
||||
~(p q r) %~(p q r) "slug p q r"
|
||||
|
||||
Nouns
|
||||
-----
|
||||
|
||||
Some nouns also have an alternate phonology:
|
||||
|
||||
|
||||
& "yes"
|
||||
%& "yes"
|
||||
%.y "yes"
|
||||
|
||||
| "no"
|
||||
%| "no"
|
||||
%.n "no"
|
||||
|
||||
42 "forty-two"
|
||||
0i42 "dec four two"
|
||||
0x2e "hex two e"
|
||||
0b10 "bin one zero"
|
||||
0v3t "base thirty two three t"
|
||||
0wA4 "base sixty-four big a four"
|
||||
|
||||
'foo' "cord foo"
|
||||
"foo" "tape foo"
|
||||
|
||||
|
||||
Example
|
||||
-------
|
||||
|
||||
Take the following snippet of Hoon:
|
||||
|
||||
++ dec :: decrement
|
||||
~/ %dec
|
||||
|= a=@
|
||||
~| %decrement-underflow
|
||||
?< =(0 a)
|
||||
=+ b=0
|
||||
|- ^- @
|
||||
?: =(a +(b))
|
||||
b
|
||||
$(b +(b))
|
||||
|
||||
Omitting the spaces and comments (which only a real purist would include), the
|
||||
above is pronounced:
|
||||
|
||||
slus dec
|
||||
sigfas cen-dec
|
||||
bartis A tis pat
|
||||
sigbar cen-decrement-underflow
|
||||
wutgal tis zero A
|
||||
tislus B tis zero
|
||||
barhep kethep pat
|
||||
wutcol tis A lus B
|
||||
B
|
||||
buc B lus B
|
||||
|
||||
Or using the alternate phonology:
|
||||
|
||||
slus dec
|
||||
sigfas cen-dec
|
||||
bartis A is atom
|
||||
sigbar cen-decrement-underflow
|
||||
wutgal equals zero A
|
||||
tislus B is zero
|
||||
barhep kethep atom
|
||||
wutcol equals A lus B
|
||||
B
|
||||
buc B lus B
|
||||
|
||||
Which is very similar. The alternate phonology exists as a result of common
|
||||
speech patterns observed amongst Hoon programmers in the wild. In any language
|
||||
actually spoken by actual humans, laziness soon rounds off any rough edges.
|
||||
|
483
main/pub/src/doc/ref/hoon/syntax.md
Normal file
483
main/pub/src/doc/ref/hoon/syntax.md
Normal file
@ -0,0 +1,483 @@
|
||||
Syntax
|
||||
======
|
||||
|
||||
Runes
|
||||
-----
|
||||
|
||||
Everything in hoon is parsed into an abstract syntax tree (AST), called a `twig`.
|
||||
A `twig` is a (frond)[lexicon/#fronds] composed of a (cubic)[lexicon/#cubes]
|
||||
rune and one or more children:
|
||||
|
||||
```
|
||||
~zod/try=> :-(1 2)
|
||||
[1 2]
|
||||
~zod/try=> (ream ':-(1 2)')
|
||||
[%clhp p=[%dtzy p=%ud q=1] q=[%dtzy p=%ud q=2]]
|
||||
```
|
||||
|
||||
As the expression above begins with `:-`, it is parsed into the twig
|
||||
`[%clhp p=twig q=twig]`, which accepts two twigs with which it produces a
|
||||
tuple. In this case, both elements are atom literals and are parsed into the twig
|
||||
`[%dtzy p=term q=@]`, which produces atomic constants.
|
||||
|
||||
There are several valid twig syntaxes in hoon, which are covered below.
|
||||
|
||||
###Tall Form
|
||||
|
||||
For all multiline expressions, Tall form is used. To avoid the visual problems
|
||||
that deep expression trees cause in other functional languages (namely excessive
|
||||
parentheses and the tendencey for code to drift horizontally off the right side
|
||||
of the screen), hoon employs neither multiline braces nor significant
|
||||
indentation. Instead, when a twig, such as the `[%clhp p=twig q=twig]` from
|
||||
above is parsed, the parser then knows that exactly two twigs are to follow. In
|
||||
Tall Form, twigs are separated by at least two spaces (a newline is equivalent
|
||||
to two spaces).
|
||||
|
||||
These rules do not prevent the aforementioned problem horizontal drift:
|
||||
|
||||
```
|
||||
?: |
|
||||
47
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
```
|
||||
|
||||
**Note:** `?:` initiaties an _if-then_else_ twig. `|` is the loobean false.
|
||||
|
||||
To avoid this problem, the official convention prescribes a backstep pattern, which
|
||||
preserves indentation level in the common case:
|
||||
|
||||
|
||||
```
|
||||
?: |
|
||||
47
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
```
|
||||
|
||||
|
||||
Notice that the first child is placed the furthest horizontal distance away
|
||||
from its parent rune. Each of the subsequent children is outdented, such
|
||||
that the last child (a similarly formatted twig) is vertically aligned with its parent.
|
||||
|
||||
However, this convention does not always prevent horizontal drift. For example,
|
||||
there are many cases when the last twig is not the heaviest:
|
||||
|
||||
```
|
||||
?: &
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
47
|
||||
```
|
||||
|
||||
To handle cases like this, there exist several (synthetic runes)[lexicon/#rune_types]
|
||||
that invert the argument order of common runes. For example, where `?:` is _if-then_, `?.` is _unless_:
|
||||
|
||||
```
|
||||
?. &
|
||||
47
|
||||
?: |
|
||||
52
|
||||
?: |
|
||||
7
|
||||
20
|
||||
```
|
||||
|
||||
####Closing Unbounded Twigs####
|
||||
|
||||
Some runes accept a list of an arbitrary number of children,
|
||||
which is closed by a `==` (pronounced "stet"). By convention, the children
|
||||
appear in an indented block, and for most runes, the `==` is aligned vertically with
|
||||
its parent.
|
||||
|
||||
```
|
||||
:*
|
||||
1
|
||||
2
|
||||
3
|
||||
==
|
||||
:: [1 2 3]
|
||||
```
|
||||
|
||||
Some runes, such as `;~`, [%smsg p=twig q=tusk]`, have both `twig` and `tusk`
|
||||
(list of twigs) children:
|
||||
|
||||
```
|
||||
;~ plug
|
||||
ace
|
||||
ace
|
||||
==
|
||||
```
|
||||
|
||||
####Kingside and Queenside####
|
||||
|
||||
Runes such as %= accept associative lists. There exist two conventions:
|
||||
Kingside, where the key-value pairs are (or at least start) on the same line:
|
||||
|
||||
```
|
||||
%= res
|
||||
key1 val
|
||||
key2 val2
|
||||
==
|
||||
```
|
||||
|
||||
And queenside, where the keys lie indented on the line above their respective
|
||||
values:
|
||||
|
||||
```
|
||||
%= res
|
||||
key
|
||||
twig-producing-val
|
||||
key2
|
||||
=+ a=2
|
||||
[a 3]
|
||||
==
|
||||
```
|
||||
|
||||
The latter is useful when the keys and/or values are heavy.
|
||||
|
||||
####Reference[#tall-reference]
|
||||
|
||||
For specific rune syntaxes, see the [lexicon]().
|
||||
The regular form parser, `++norm:vast`, can also be helpful: for example, %dtls
|
||||
(increment) is parsed by
|
||||
|
||||
```
|
||||
++ norm :: rune regular form
|
||||
|= tol=?
|
||||
=< %- stew
|
||||
^. stet ^. limo
|
||||
:~ :- '|'
|
||||
:: ......code skipped.......
|
||||
```
|
||||
|
||||
```
|
||||
:- '.'
|
||||
;~ pfix dot
|
||||
%- stew
|
||||
^. stet ^. limo
|
||||
:~ ['+' (rune lus %dtls expa)]
|
||||
```
|
||||
|
||||
```
|
||||
++ expa |.(loaf) :: one twig
|
||||
```
|
||||
|
||||
```
|
||||
++ loaf ?:(tol tall wide) :: hoon, current width
|
||||
```
|
||||
|
||||
###Wide
|
||||
|
||||
Wide form is a more compact and visually structured twig syntax, where an
|
||||
expression can be no longer than one line. Notably, children are enclosed by
|
||||
parentheses, and twigs are separated by single spaces:
|
||||
|
||||
```
|
||||
?:((gth 1 2) %abort-abort %correct)
|
||||
```
|
||||
|
||||
While Tall Form expressions can contain wide form expressions, the converse is
|
||||
invalid hoon:
|
||||
|
||||
```
|
||||
?: .=(a b)
|
||||
0
|
||||
1
|
||||
:: succeeds
|
||||
?:(.= a
|
||||
b 0 1)
|
||||
:: fails
|
||||
```
|
||||
|
||||
There are two other notable differences from Tall Form: `==` is no longer used,
|
||||
having been made redundant by closing parentheses; and, the syntax for
|
||||
associative lists gains a `','` between pairs:
|
||||
|
||||
```
|
||||
?-(a 0 %even, 1 %odd)
|
||||
:: vs.
|
||||
?- a
|
||||
0 %even
|
||||
1 %odd
|
||||
==
|
||||
```
|
||||
|
||||
####Reference
|
||||
|
||||
For specific rune syntaxes, see the [lexicon]().
|
||||
The regular form parser, `++norm:vast`, can also be [helpful.](#tall-reference).
|
||||
|
||||
###Irregular
|
||||
|
||||
For many common runes, there exist special wide forms. For example,
|
||||
the rune `:*`, which was used as an example in the tall section[linkToExample](),
|
||||
is more frequently employed in its irregular form, a list of twigs surrounded
|
||||
by brackets:
|
||||
|
||||
```
|
||||
~zod/try=> [1 2]
|
||||
[1 2]
|
||||
~zod/try=> (ream '[1 2]')
|
||||
[%cltr p=~[[%dtzy p=%ud q=1] [%dtzy p=%ud q=2]]]
|
||||
```
|
||||
|
||||
A comprehensive list of all of these irregular forms can be found in the
|
||||
[lexicon](lexicon/irregular-section)i, and the irregular form parser
|
||||
`++scat:vast`.
|
||||
|
||||
###Tile
|
||||
|
||||
Some runes accept [tiles](lexicon) instead of/in addition to twigs as children.
|
||||
|
||||
These runes switch us into tile syntax:
|
||||
|
||||
Tiles have a similar syntax to twigs when:
|
||||
|
||||
Examples
|
||||
|
||||
|
||||
And different
|
||||
|
||||
1.The irregular forms for `^=` and `:*`, infix `=` and surrounding `[]`
|
||||
repsectively, now denote `$=` and `$:`
|
||||
|
||||
2.Primitive types `'@'`, `'^'`, and `'*'` represent their tiles.
|
||||
|
||||
3.Number literals represent their cubes, and are along with actual cubes
|
||||
interpreted as their associated clams.
|
||||
|
||||
|
||||
Tile syntax defaults to parsing a twig, and using the result as a
|
||||
[clam](lexicon).
|
||||
|
||||
|
||||
|
||||
```
|
||||
~zod/try=> *a=@ud
|
||||
a=0
|
||||
```
|
||||
|
||||
|
||||
`a=@ud` is a `tile`, representing a face _a_ wrapped around an atom of [odor]()
|
||||
_unsigned-decimal_.
|
||||
|
||||
Tile syntax is similar to that of twigs, except that `'@'`, `'^'`, and `'*'`
|
||||
represent the [clams](lexicon) for the `atom`, `cell`, and `noun` primitive types,
|
||||
and numeric literals become cubed. When a twig is encountered, its product is
|
||||
used as a clam directly:
|
||||
|
||||
```
|
||||
|= a=(list char)
|
||||
[' ' a]
|
||||
```
|
||||
|
||||
See [lexicon tiles[, parser `++noil:vast`
|
||||
|
||||
Wings
|
||||
-----
|
||||
|
||||
Items in the subject are accesed with wings
|
||||
|
||||
```
|
||||
> =<(a.b.+.c c=[4 [b=[a=1 2] b=[a=6 7]])
|
||||
6
|
||||
```
|
||||
|
||||
Limbs and axes, separated by dots, inner to outer.
|
||||
|
||||
Limbs are terms, axes (have a few syntaces)[lexicon axis syntax]
|
||||
|
||||
See:**
|
||||
|
||||
Nouns
|
||||
-----
|
||||
|
||||
Most common rune is the virtual %dtzy, atomic nock 1
|
||||
|
||||
```
|
||||
>(ream '42')
|
||||
[%dtzy p=%ud q=42]
|
||||
```
|
||||
|
||||
Its counterpart %dtzz does cubes
|
||||
|
||||
```
|
||||
>(ream '%42')
|
||||
[%dtzz p=%ud q=42]
|
||||
```
|
||||
|
||||
See [lexicon atoms]
|
||||
|
||||
Tapes
|
||||
|
||||
###Interpolation
|
||||
|
||||
```
|
||||
"This is an {(weld "inter" (trip %polate))}d string"
|
||||
|
||||
|
||||
Dependencies (%ford)
|
||||
--------------------
|
||||
|
||||
While !^ provides rudimentary %clay includes...
|
||||
|
||||
|
||||
See: ford.hoon
|
||||
|
||||
Templating (++sail)
|
||||
-------------------
|
||||
|
||||
Start with `;term`
|
||||
|
||||
```
|
||||
;html
|
||||
;head:title:"Hello"
|
||||
;body
|
||||
;p
|
||||
; Text with some ;{b "bolded"}
|
||||
; and some -{(weld "inter" "polate"}d
|
||||
==
|
||||
==
|
||||
==
|
||||
```
|
||||
|
||||
See:
|
||||
|
||||
Generates `manx`, xml nouns.
|
||||
[lexicon template lang], parser `++sail:vast`.
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.= ~[1 2 3 4 5 6]
|
||||
:~ 1
|
||||
2
|
||||
3
|
||||
4
|
||||
5
|
||||
6
|
||||
==
|
||||
|
||||
:* 1 3 4 ==
|
||||
:- 1 :- 3 4
|
||||
1^3^4
|
||||
[1 3 4]
|
||||
|
||||
|
||||
|
||||
':-' is constructing a tuple of two elements, constants...
|
||||
|
||||
```
|
||||
~zod/try=>(mul 4 (add 2 3))
|
||||
20
|
||||
~zod/try=> (ream '(mul 4 (add 2 3))')
|
||||
[ %cnhp
|
||||
p=[%cnzz p=~[%mul]]
|
||||
q
|
||||
~[
|
||||
[%dtzy p=%ud q=4]
|
||||
[%cnhp p=[%cnzz p=~[%add]] q=~[[%dtzy p=%ud q=2] [%dtzy p=%ud q=3]]]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
A twig is a (frond)[lexicon frond] composed of a rune and one or
|
||||
more children; here, we see `%cnhp %cnzz %dtzy`, which are defined
|
||||
in `++twig` as:
|
||||
|
||||
```
|
||||
++ twig $& [p=twig q=twig] ::
|
||||
$%
|
||||
[%cnhp p=twig q=tusk] :: slam p w/ sample q
|
||||
[%cnzz p=wing] :: pulls p
|
||||
==
|
||||
|
||||
++ tusk (list twig) ::
|
||||
```
|
||||
|
||||
Skipping the particulars, '%-' (slams gates)[lexicon gates], %cnzz is a virtual
|
||||
rune that (pulls arms)[lexicon cores], and %dtzy is a virtual rune that
|
||||
<makes constants>; the resulting twig representing fetching `add` and `mul`,
|
||||
and applying them to 2, 3, and 4.
|
||||
|
||||
```
|
||||
++ twig $% ::
|
||||
[%$ p=axis] :: simple leg
|
||||
:: ::
|
||||
[%bccb p=tile] :: bunt a tile
|
||||
:: etc.
|
||||
==
|
||||
```
|
1958
main/pub/src/doc/ref/vol/4a.md
Normal file
1958
main/pub/src/doc/ref/vol/4a.md
Normal file
File diff suppressed because it is too large
Load Diff
1550
main/pub/src/doc/ref/vol/4c.md
Normal file
1550
main/pub/src/doc/ref/vol/4c.md
Normal file
File diff suppressed because it is too large
Load Diff
@ -18,8 +18,6 @@
|
||||
|
||||
- chapter 2c, simple noun surgery
|
||||
|
||||
### Chapters 2a through 2eZ refactoring and second-pass.
|
||||
### Dulin and Henry.
|
||||
|
||||
- section 2cA, bit surgery
|
||||
- section 2cB, bit logic
|
||||
@ -40,8 +38,6 @@
|
||||
|
||||
- chapter 2e, miscellaneous libs
|
||||
|
||||
### Anton - virtualization
|
||||
|
||||
- section 2eA, packing
|
||||
- section 2eB, parsing (tracing)
|
||||
- section 2eC, parsing (custom rules)
|
||||
@ -63,7 +59,6 @@
|
||||
- section 2eY, SHA-2564 (move me)
|
||||
- section 2eZ, OLD rendering (kill me)
|
||||
|
||||
### Chapter 2f is Philip.
|
||||
|
||||
- chapter 2f, Hoon proper
|
||||
|
||||
@ -78,20 +73,18 @@
|
||||
|
||||
- chapter 3b, Arvo libraries, zuse
|
||||
|
||||
### Anton - All of Chapter 3b except 3bE and 3bG.
|
||||
|
||||
- section 3bA, lite number theory
|
||||
- section 3bB, cryptosuites
|
||||
- section 3bC, UTC
|
||||
- section 3bD, JSON and XML
|
||||
- section 3bE, tree sync
|
||||
- section 3bF, names etc
|
||||
- section 3bG, Arvo models
|
||||
- section 3bF!, filesystem interface
|
||||
- section 3bG!, URL handling
|
||||
- section 3bH!, names etc
|
||||
- section 3bI!, Arvo models
|
||||
|
||||
- Volume 4, Arvo vanes
|
||||
|
||||
### Chapter 4a, %ames, is Philip. Possibly %ford nad %gall as well.
|
||||
|
||||
- chapter 4a, ames, networking
|
||||
|
||||
- section 4aA, structures
|
||||
@ -114,8 +107,6 @@
|
||||
- section 4cB, filesystem logic
|
||||
- section 4cC, filesystem vane
|
||||
|
||||
### Anton Chapter 4d
|
||||
|
||||
- chapter 4d, dill: terminal handling
|
||||
|
||||
- chapter 4e, eyre: http servant
|
@ -1,481 +0,0 @@
|
||||
Ames
|
||||
====
|
||||
|
||||
Ames is our networking protocol.
|
||||
|
||||
data models
|
||||
-----------
|
||||
|
||||
###`++fort`, formal state
|
||||
|
||||
```
|
||||
++ fort :: formal state
|
||||
$: %0 :: version
|
||||
gad=duct :: client interface
|
||||
hop=@da :: network boot date
|
||||
ton=town :: security
|
||||
zac=(map ship corn) :: flows by server
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the state of our vane. Anything that must be remembered between
|
||||
calls to ames must be stored in this state.
|
||||
|
||||
`%0` is the version of the ames state model itself. If the data model `++fort`
|
||||
changes, then this number needs to be incremented, and an adapter must be
|
||||
written to upgrade the old state into the new state. Note that this is the
|
||||
version number of the model itself, not the contents. When the data changes,
|
||||
there is of course no need to change this.
|
||||
|
||||
`gad` is a `duct` over which we send `%send` cards to unix. This card is
|
||||
initialized when unix sends a `%barn` card as vere starts up. Vere treats this
|
||||
duct specially -- don't send anything weird over it.
|
||||
|
||||
`hop` is the network boot date. This is set when the `%kick` card is sent by
|
||||
vere on start up.
|
||||
|
||||
`ton` is a `++town`, where we store all of our security/encryption state. Note
|
||||
that this is shared across all ships on a pier.
|
||||
|
||||
`zac` is a map of ships to `++corn`. This stores all the per-ship state. The
|
||||
keys to this map are the ships on the current pier.
|
||||
|
||||
###`++town`, all security state
|
||||
|
||||
```
|
||||
++ town :: all security state
|
||||
$: lit=@ud :: imperial modulus
|
||||
any=@ :: entropy
|
||||
urb=(map ship sufi) :: all keys and routes
|
||||
fak=? ::
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the security state of our pier.
|
||||
|
||||
`lit` is unused.
|
||||
|
||||
`any` is 256 bits of entropy. This entropy is used and updated in exactly two
|
||||
places: when we send a `%junk` card, and when we generate a new symmetric key
|
||||
in `++griz:lax:as:go`. When it is updated, it is updated by a SHA-256 hash of
|
||||
the current time and the old value of the entropy.
|
||||
|
||||
`urb` is a map of ships to `++sufi`. This is where we store all the per-ship
|
||||
state for the pier. The keys to this map are the ships on the current pier.
|
||||
|
||||
`fak` is true if we are on a fake network. This disables certain security
|
||||
checks so that anyone may run a fake `~zod`. This is used only for development.
|
||||
To use, run vere with the `-F` option (and the `-I ~zod` option for a fake
|
||||
`~zod`).
|
||||
|
||||
###`++sufi`, domestic host
|
||||
|
||||
```
|
||||
++ sufi :: domestic host
|
||||
$: hoy=(list ship) :: hierarchy
|
||||
val=wund :: private keys
|
||||
law=will :: server will
|
||||
seh=(map hand ,[p=ship q=@da]) :: key cache
|
||||
hoc=(map ship dore) :: neighborhood
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the security state of a domestic server.
|
||||
|
||||
`hoy` is a list of the ships directly above us in the hierarchy of ships. For
|
||||
example, for `~hoclur-bicrel`, this would be `~tasruc` and `~tug`. See
|
||||
`++sein`.
|
||||
|
||||
`val` is a list of our private keys.
|
||||
|
||||
`law` is our certificate, which is a list of the XXX
|
||||
|
||||
`seh`
|
||||
|
||||
`hoc` is a map of ships to `++dore`. The stores all the security informatoin
|
||||
about foreign ships. The keys to this map are the neighbors (ships we have
|
||||
been in contact with) of this domestic server.
|
||||
|
||||
###`++wund`, private keys
|
||||
|
||||
```
|
||||
++ wund (list ,[p=life q=ring r=acru]) :: mace in action
|
||||
```
|
||||
|
||||
This is a list of our own private keys, indexed by life. The key itself is
|
||||
the `++ring`, and the `++acru` is the encryption engine. We generate the
|
||||
`++acru` from the private key by calling `++weur`. Thus, we can at any time
|
||||
regenerate our `++wund` from a `++mace`. The current crypto is at the head of
|
||||
the list and can be accessed with
|
||||
`++sen:as:go`.
|
||||
|
||||
###`++ring`, private key
|
||||
|
||||
```
|
||||
++ ring ,@ :: private key
|
||||
```
|
||||
|
||||
This is a private key. The first byte is reserved to identify the type of
|
||||
cryptography. Lower-case means public key, upper-case means public key, and
|
||||
the letter identifies which `++acru` to use.
|
||||
|
||||
###`++pass`, public key
|
||||
|
||||
```
|
||||
++ pass ,@ :: public key
|
||||
```
|
||||
|
||||
This is a public key. The first byte is reserved to identify the type of
|
||||
cryptography. Lower-case means public key, upper-case means public key, and
|
||||
the letter identifies which `++acru` to use.
|
||||
|
||||
###`++mace`, private secrets
|
||||
|
||||
```
|
||||
++ mace (list ,[p=life q=ring]) :: private secrets
|
||||
```
|
||||
|
||||
This is a list of the our private keys, indexed by life. From this we can
|
||||
generate a `++wund` for actual use.
|
||||
|
||||
###`++skin`, encoding stem
|
||||
|
||||
```
|
||||
++ skin ?(%none %open %fast %full) :: encoding stem
|
||||
```
|
||||
|
||||
This defines the type of encryption used for each message. `%none` refers
|
||||
to messages sent in the clear, `%open` refers to signed messages, `%full`
|
||||
refers to sealed messages, and `%fast` refers to symmetrically encrypted
|
||||
messages. See `++acru` for details.
|
||||
|
||||
###`++acru`, asymmetric cryptosuite
|
||||
|
||||
```
|
||||
++ acru :: asym cryptosuite
|
||||
$_ ^? |% :: opaque object
|
||||
++ as ^? :: asym ops
|
||||
|% ++ seal |=([a=pass b=@ c=@] _@) :: encrypt to a
|
||||
++ sign |=([a=@ b=@] _@) :: certify as us
|
||||
++ sure |=([a=@ b=@] *(unit ,@)) :: authenticate from us
|
||||
++ tear |= [a=pass b=@] :: accept from a
|
||||
*(unit ,[p=@ q=@]) ::
|
||||
-- ::
|
||||
++ de |+([a=@ b=@] *(unit ,@)) :: symmetric de, soft
|
||||
++ dy |+([a=@ b=@] _@) :: symmetric de, hard
|
||||
++ en |+([a=@ b=@] _@) :: symmetric en
|
||||
++ ex ^? :: export
|
||||
|% ++ fig _@uvH :: fingerprint
|
||||
++ pac _@uvG :: default passcode
|
||||
++ pub *pass :: public key
|
||||
++ sec *ring :: private key
|
||||
--
|
||||
++ nu ^? :: reconstructors
|
||||
|% ++ pit |=([a=@ b=@] ^?(..nu)) :: from [width seed]
|
||||
++ nol |=(a=@ ^?(..nu)) :: from naked ring
|
||||
++ com |=(a=@ ^?(..nu)) :: from naked pass
|
||||
--
|
||||
--
|
||||
```
|
||||
|
||||
This is an opaque interface for a general asymmetric cryptosuite. Any form
|
||||
of asymmetric cryptography can be dropped in to be used instead of the default.
|
||||
Right now, there are two cryptosuites, `++crua`, which is your standard RSA,
|
||||
and `++crub`, which is elliptic curve crypto but is mostly stubbed out at the
|
||||
moment.
|
||||
|
||||
####`++as:acru`, asymmetric operations
|
||||
|
||||
```
|
||||
++ as ^? :: asym ops
|
||||
|% ++ seal |=([a=pass b=@ c=@] _@) :: encrypt to a
|
||||
++ sign |=([a=@ b=@] _@) :: certify as us
|
||||
++ sure |=([a=@ b=@] *(unit ,@)) :: authenticate from us
|
||||
++ tear |= [a=pass b=@] :: accept from a
|
||||
*(unit ,[p=@ q=@]) ::
|
||||
-- ::
|
||||
```
|
||||
|
||||
This is the core that defines the standard asymmetric cryptography
|
||||
operations.
|
||||
|
||||
`++seal:as:acru` allows us to send a message encrypted with someone's public
|
||||
key so that only they may read it. If Alice seals a message with Bob's public
|
||||
key, then she can be sure that Bob is the only one who can read it. This is
|
||||
associated with the `++skin` `%full`.
|
||||
|
||||
`++sign:as:acru` allows us to sign a message with our private key so that
|
||||
others can verify that we sent the message. If Alice signs a message with her
|
||||
private key, then Bob can verify with her public key that it was indeed Alice
|
||||
who sent it. This is associated with the `++skin` `%open`.
|
||||
|
||||
`++sure:as:acru` is the dual to `++sign:as:acru`. It allows us to verify that
|
||||
a message we have received is indeed from the claimed sender. If Alice sends a
|
||||
message with her private key, then Bob can use this arm to verify that it was
|
||||
indeed Alice who sent it. This is associated with the `++skin` `%open`.
|
||||
|
||||
`++tear:as:acru` is the dual to `++seal:as:acru`. It allows us to read a
|
||||
message that we can be sure is only read by us. If Alice seals a message with
|
||||
Bob's public key, then Bob can use this arm to read it. This is associated
|
||||
with the `++skin` `%full`.
|
||||
|
||||
####`++de:acru`, `++dy:acru`, and `++en:acru`, symmetric encryption/decryption
|
||||
|
||||
```
|
||||
++ de |+([a=@ b=@] *(unit ,@)) :: symmetric de, soft
|
||||
++ dy |+([a=@ b=@] _@) :: symmetric de, hard
|
||||
++ en |+([a=@ b=@] _@) :: symmetric en
|
||||
```
|
||||
|
||||
Symmetric encryption is associated with the `++skin` `%fast`.
|
||||
|
||||
`++de:acru` decrypts a message with a symmetric key, returning `~` on failure
|
||||
and `[~ u=data]` on success.
|
||||
|
||||
`++dy:acru` decrypts a message with a symmetric key, crashing on failure. This
|
||||
should almost always be defined as, and should always be semantically
|
||||
equivalent to, `(need (de a b))`.
|
||||
|
||||
`++en:acru` encrypts a message with a symmetric key.
|
||||
|
||||
####`++ex:acru`, exporting data
|
||||
|
||||
```
|
||||
++ ex ^? :: export
|
||||
|% ++ fig _@uvH :: fingerprint
|
||||
++ pac _@uvG :: default passcode
|
||||
++ pub *pass :: public key
|
||||
++ sec *ring :: private key
|
||||
--
|
||||
```
|
||||
|
||||
`++fig:ex:acru` is our fingerprint, usually a hash of our public key. This is
|
||||
used, for example, in `++zeno`, where every carrier owner's fingerprint is
|
||||
stored so that we can ensure that carriers are indeed owned by their owners
|
||||
|
||||
`++pac:ex:acru` is our default passcode, which is unused at present.
|
||||
|
||||
`++pub:ex:acru` is the `++pass` form of our public key.
|
||||
|
||||
`++sec:ex:acru` is the `++ring` form of our private key.
|
||||
|
||||
####`++nu:acru`, reconstructors
|
||||
|
||||
```
|
||||
++ nu ^? :: reconstructors
|
||||
|% ++ pit |=([a=@ b=@] ^?(..nu)) :: from [width seed]
|
||||
++ nol |=(a=@ ^?(..nu)) :: from naked ring
|
||||
++ com |=(a=@ ^?(..nu)) :: from naked pass
|
||||
--
|
||||
```
|
||||
|
||||
These arms allow us to reconstruct a `++acru` from basic data.
|
||||
|
||||
`++pit:nu:acru` constructs a `++acru` from the width of our intended key and
|
||||
seed entropy. This is usually used in the initial construction of the
|
||||
`++acru`.
|
||||
|
||||
`++nol:nu:acru` constructs a `++acru` from a "naked ring", meaning a `++ring`
|
||||
without the initial byte identifying the type of crypto. There is often a
|
||||
helper arm that that wraps this; see `++weur` for `++crua` and `++wear` for
|
||||
`++crub`.
|
||||
|
||||
`++com:nu:acru` constructs a `++acru` from a "naked pass", meaning a `++ring`
|
||||
without the initial byte identifying the type of crypto. There is often a
|
||||
helper arm that that wraps this; see `++haul` for `++crua` and `++hail` for
|
||||
`++crub`.
|
||||
|
||||
###`++will`, certificate
|
||||
|
||||
```
|
||||
++ will (list deed) :: certificate
|
||||
```
|
||||
|
||||
This is a list of deeds associated with the current ship. There should be
|
||||
an item in this list for every ship from this point up in the hierarchy times
|
||||
the number of lives that each ship has had. For example, ~hoclur-bicrel may
|
||||
have a will with three items: one for itself, one for ~tasruc (who issued
|
||||
~hoclur-bicrel's deed) and one for ~tug (who issued ~tasruc's deed).
|
||||
|
||||
###`++deed`, identity
|
||||
|
||||
```
|
||||
++ deed ,[p=@ q=step r=?] :: sig, stage, fake?
|
||||
```
|
||||
|
||||
`p` is the signature of a particular deed, which is a signed copy of `q`.
|
||||
|
||||
`q` is the stage in the identity.
|
||||
|
||||
`r` is true if we're working on a fake network, where we don't check that the
|
||||
carrier fingerprints are correct. This allows us to create fake networks for
|
||||
development without interfering with the real network.
|
||||
|
||||
###`++step`, identity stage
|
||||
|
||||
```
|
||||
++ step ,[p=bray q=gens r=pass] :: identity stage
|
||||
```
|
||||
|
||||
This is a single stage in our identity. Thus, this is specific to a single
|
||||
life in a single ship. Everything in here may change between lives.
|
||||
|
||||
`p`
|
||||
|
||||
`q`
|
||||
|
||||
`r` is the public key for this stage in the identity.
|
||||
|
||||
###`++bray`
|
||||
|
||||
```
|
||||
++ bray ,[p=life q=(unit life) r=ship s=@da] :: our parent us now
|
||||
```
|
||||
|
||||
XXX
|
||||
|
||||
###`++gens`, general identity
|
||||
|
||||
```
|
||||
++ gens ,[p=lang q=gcos] :: general identity
|
||||
```
|
||||
|
||||
`p` is the IETF language code for the preferred language of this identity.
|
||||
This is unused at the moment, but in the future text should be localized based
|
||||
on this.
|
||||
|
||||
`q` is the description of the ship.
|
||||
|
||||
###`++gcos`, identity description
|
||||
|
||||
```
|
||||
++ gcos :: id description
|
||||
$% [%czar ~] :: 8-bit ship
|
||||
[%duke p=what] :: 32-bit ship
|
||||
[%earl p=@t] :: 64-bit ship
|
||||
[%king p=@t] :: 16-bit ship
|
||||
[%pawn p=(unit ,@t)] :: 128-bit ship
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the description of the identity of a ship. Most types of identity have
|
||||
a `@t` field, which is their human-readable name. The identity of a `%duke` is
|
||||
more involved.
|
||||
|
||||
A `%czar`, a carrier, is a ship with an 8-bit address. Thus, there are only
|
||||
256 carriers. These are at the top of the namespace hierarchy, and the
|
||||
fingerprint of each carrier is stored in `++zeno`. These are the "senators" of
|
||||
Urbit.
|
||||
|
||||
A `%king`, a cruiser, is a ship with a 16-bit address. Thus, there are 65,536
|
||||
cruisers. Each carrier may issue 256 cruisers. These are the infrastructure
|
||||
of Urbit.
|
||||
|
||||
A `%duke`, a destroyer, is a ship with a 32-bit address. Thus, there are
|
||||
4,294,967,296 destroyers. Each cruiser may issue 65,536 cruisers. These are
|
||||
the individuals of Urbit.
|
||||
|
||||
A `%earl`, a yacht, is a ship with a 64-bit address. Thus, there are
|
||||
18,446,744,073,709,551,616 yachts. Each destroyer may issue 4,294,967,296
|
||||
yachts. These are the devices of Urbit.
|
||||
|
||||
A `%pawn`, a submarine, is a ship with a 128-bit address. Thus, there are a
|
||||
lot of submarines. The chance of random name collision is negligible, so
|
||||
submarines are not issued by any ship. They must simply assert their presence,
|
||||
and they are all considered children of ~zod. This is the underworld of Urbit,
|
||||
where anonymity reigns supreme.
|
||||
|
||||
###`++what`, logical destroyer identity
|
||||
|
||||
```
|
||||
++ what :: logical identity
|
||||
$% [%anon ~] :: anonymous
|
||||
[%lady p=whom] :: female person ()
|
||||
[%lord p=whom] :: male person []
|
||||
[%punk p=sect q=@t] :: opaque handle ""
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the logical identity of a destroyer.
|
||||
|
||||
A `%anon` is a completely anonymous destroyer. The difference between this and
|
||||
a submarine is that a submarine is ephemeral while a `%anon` destroyer is not.
|
||||
Thus, we may not know who ~hoclur-bicrel is, but we do know that it's always
|
||||
the same person.
|
||||
|
||||
A `%lady` is a female person. The name used here should be a real name.
|
||||
|
||||
A `%lord` is a male person. The name used here should be a real name.
|
||||
|
||||
A `%punk` is a person who is identified only by a handle.
|
||||
|
||||
###`++whom`, real person
|
||||
|
||||
```
|
||||
++ whom ,[p=@ud q=govt r=sect s=name] :: year/govt/id
|
||||
```
|
||||
|
||||
Ths is the information associated with a real person. It is mostly information
|
||||
that could be observed with the briefest of interactions.
|
||||
|
||||
`p` is the birth year.
|
||||
|
||||
`q` is the location of a user, usually of the form "country/zip".
|
||||
|
||||
`r` is the sect of the user.
|
||||
|
||||
`s` is the real name of the person.
|
||||
|
||||
|
||||
###`++govt`
|
||||
|
||||
```
|
||||
++ govt path :: country/postcode
|
||||
```
|
||||
|
||||
This is the location of the user, usually of the form "country/zip".
|
||||
|
||||
###`++sect`
|
||||
|
||||
```
|
||||
++ sect ?(%black %blue %red %orange %white) :: banner
|
||||
```
|
||||
|
||||
XXX
|
||||
|
||||
###`++name`
|
||||
|
||||
```
|
||||
++ name ,[p=@t q=(unit ,@t) r=(unit ,@t) s=@t] :: first mid/nick last
|
||||
```
|
||||
|
||||
This is the given name, possible middle name/initial, possible nickname, and
|
||||
surname of a user.
|
||||
|
||||
packet format
|
||||
-------------
|
||||
|
||||
`++go`, PKI engine
|
||||
------------------
|
||||
|
||||
###`++as`, per server
|
||||
|
||||
####`++born`, register user
|
||||
|
||||
#####`++lax`, per client
|
||||
|
||||
`++pu`, packet pump
|
||||
-------------------
|
||||
|
||||
`++am`, protocol engine
|
||||
-----------------------
|
||||
|
||||
###`++um`, per server
|
||||
|
||||
####`++ho`, per friend
|
||||
|
||||
#####`++la`, per packet
|
||||
|
||||
protocol vane
|
||||
-------------
|
||||
|
@ -1,484 +0,0 @@
|
||||
Clay
|
||||
====
|
||||
|
||||
Clay is our filesystem.
|
||||
|
||||
data models
|
||||
-----------
|
||||
|
||||
###`++raft`, formal state
|
||||
|
||||
```
|
||||
++ raft :: filesystem
|
||||
$: fat=(map ship room) :: domestic
|
||||
hoy=(map ship rung) :: foreign
|
||||
ran=rang :: hashes
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the state of our vane. Anything that must be remembered between calls
|
||||
to clay must be stored in this state.
|
||||
|
||||
`fat` is the set of domestic servers. This stores all the information that is
|
||||
specfic to a particular ship on this pier. The keys to this map are the ships
|
||||
on the current pier.
|
||||
|
||||
`hoy` is the set of foreign servers that we know anything about. This stores
|
||||
all the information that is specific to a particular foreign ship. The keys to
|
||||
this map are all the ships whose filesystems we have attempted to access
|
||||
through clay.
|
||||
|
||||
`ran` is the store of all commits and deltas, keyed by hash. The is where all
|
||||
the "real" data we know is stored; the rest is "just bookkeeping".
|
||||
|
||||
###`++room`, filesystem per domestic ship
|
||||
|
||||
```
|
||||
++ room :: fs per ship
|
||||
$: hun=duct :: terminal duct
|
||||
hez=(unit duct) :: sync duch
|
||||
dos=(map desk dojo) :: native desk
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the representation of the filesystem of a ship on our pier.
|
||||
|
||||
`hun` is the duct that we use to send messages to dill to display notifications
|
||||
of filesystem changes. Only `%note` gifts should be produced along this duct.
|
||||
This is set by the `%init` kiss.
|
||||
|
||||
`hez`, if present, is the duct we use to send sync messages to unix so that
|
||||
they end up in the pier unix directory. Only `%ergo` gifts should be producd
|
||||
along this duct. This is set by `%into` and `%invo` gifts.
|
||||
|
||||
`dos` is a well-known operating system released in 1981. It is also the set of
|
||||
desks on this ship, mapped to their data.
|
||||
|
||||
###`++desk`, filesystem branch
|
||||
|
||||
```
|
||||
++ desk ,@tas :: ship desk case spur
|
||||
```
|
||||
|
||||
This is the name of a branch of the filesystem. The default desks are "arvo",
|
||||
"main", and "try". More may be created by simply referencing them. Desks have
|
||||
independent histories and states, and they may be merged into each other.
|
||||
|
||||
###`++dojo`, domestic desk state
|
||||
|
||||
```
|
||||
++ dojo ,[p=cult q=dome] :: domestic desk state
|
||||
```
|
||||
|
||||
This is the all the data that is specific to a particular desk on a domestic
|
||||
ship. `p` is the set of subscribers to this desk and `q` is the data in the
|
||||
desk.
|
||||
|
||||
###`++cult`, subscriptions
|
||||
|
||||
```
|
||||
++ cult (map duct rave) :: subscriptions
|
||||
```
|
||||
|
||||
This is the set of subscriptions to a particular desk. The keys are the ducts
|
||||
from where the subscriptions requests came. The results will be produced along
|
||||
these ducts. The values are a description of the requested information.
|
||||
|
||||
###`++rave`, general subscription request
|
||||
|
||||
```
|
||||
++ rave :: general request
|
||||
$% [& p=mood] :: single request
|
||||
[| p=moat] :: change range
|
||||
== ::
|
||||
```
|
||||
|
||||
This represents a subscription request for a desk. The request can be for
|
||||
either a single item in the desk or else for a range of changes on the desk.
|
||||
|
||||
###`++mood`, single subscription request
|
||||
|
||||
```
|
||||
++ mood ,[p=care q=case r=path] :: request in desk
|
||||
```
|
||||
|
||||
This represents a request for the state of the desk at a particular commit,
|
||||
specfied by `q`. `p` specifies what kind of information is desired, and `r`
|
||||
specifies the path we are requesting.
|
||||
|
||||
###`++moat`, range subscription request
|
||||
|
||||
```
|
||||
++ moat ,[p=case q=case] :: change range
|
||||
```
|
||||
|
||||
This represents a request for all changes between `p` and `q`. Note that there
|
||||
is currently no way to request to be notified only on changes to particular
|
||||
paths in the filesystem. You must subscribe to the entire desk.
|
||||
|
||||
###`++care`, clay submode
|
||||
|
||||
```
|
||||
++ care ?(%u %v %w %x %y %z) :: clay submode
|
||||
```
|
||||
|
||||
This specifies what type of information is requested in a subscription or a
|
||||
scry.
|
||||
|
||||
`%u` requests the `++rang` at the current moment. Because this information is
|
||||
not stored for any moment other than the present, we crash if the `++case` is
|
||||
not a `%da` for now.
|
||||
|
||||
`%v` requests the `++dome` at the specified commit.
|
||||
|
||||
`%w` requests the current revsion number of the desk.
|
||||
|
||||
`%x` requests the file at a specified path at the specified commit. If there
|
||||
is no node at that path or if the node has no contents (that is, if `q:ankh` is
|
||||
null), then this produces null.
|
||||
|
||||
`%y` requests a `++arch` of the specfied commit at the specified path.
|
||||
|
||||
`%z` requests the `++ankh` of the specified commit at the specfied path.
|
||||
|
||||
###`++arch`, shallow filesystem node
|
||||
|
||||
```
|
||||
++ arch ,[p=@uvI q=(unit ,@uvI) r=(map ,@ta ,~)] :: fundamental node
|
||||
```
|
||||
|
||||
This is analogous to `++ankh` except that the we have neither our contents nor
|
||||
the ankhs of our children. The other fields are exactly the same, so `p` is a
|
||||
hash of the associated ankh, `u.q`, if it exists, is a hash of the contents of
|
||||
this node, and the keys of `r` are the names of our children. `r` is a map to
|
||||
null rather than a set so that the ordering of the map will be equivalent to
|
||||
that of `r:ankh`, allowing efficient conversion.
|
||||
|
||||
###`++case`, specifying a commit
|
||||
|
||||
```
|
||||
++ case :: ship desk case spur
|
||||
$% [%da p=@da] :: date
|
||||
[%tas p=@tas] :: label
|
||||
[%ud p=@ud] :: number
|
||||
== ::
|
||||
```
|
||||
|
||||
A commit can be referred to in three ways: `%da` refers to the commit that was
|
||||
at the head on date `p`, `%tas` refers to the commit labeled `p`, and `%ud`
|
||||
refers to the commit numbered `p`. Note that since these all can be reduced
|
||||
down to a `%ud`, only numbered commits may be referenced with a `++case`.
|
||||
|
||||
###`++dome`, desk data
|
||||
|
||||
```
|
||||
++ dome :: project state
|
||||
$: ang=agon :: pedigree
|
||||
ank=ankh :: state
|
||||
let=@ud :: top id
|
||||
hit=(map ,@ud tako) :: changes by id
|
||||
lab=(map ,@tas ,@ud) :: labels
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the data that is actually stored in a desk.
|
||||
|
||||
`ang` is unused and should be removed.
|
||||
|
||||
`ank` is the current state of the desk. Thus, it is the state of the
|
||||
filesystem at revison `let`. The head of a desk is always a numbered commit.
|
||||
|
||||
`let` is the number of the most recently numbered commit. This is also the
|
||||
total number of numbered commits.
|
||||
|
||||
`hit` is a map of numerical ids to hashes of commits. These hashes are mapped
|
||||
into their associated commits in `hut:rang`. In general, the keys of this map
|
||||
are exactly the numbers from 1 to `let`, with no gaps. Of course, when there
|
||||
are no numbered commits, `let` is 0, so `hit` is null. Additionally, each of
|
||||
the commits is an ancestor of every commit numbered greater than this one.
|
||||
Thus, each is a descendant of every commit numbered less than this one. Since
|
||||
it is true that the date in each commit (`t:yaki`) is no earlier than that of
|
||||
each of its parents, the numbered commits are totally ordered in the same way
|
||||
by both pedigree and date. Of course, not every commit is numbered. If that
|
||||
sounds too complicated to you, don't worry about it. It basically behaves
|
||||
exactly as you would expect.
|
||||
|
||||
`lab` is a map of textual labels to numbered commits. Note that labels can
|
||||
only be applied to numbered commits. Labels must be unique across a desk.
|
||||
|
||||
###`++ankh`, filesystem node
|
||||
|
||||
```
|
||||
++ ankh :: fs node (new)
|
||||
$: p=cash :: recursive hash
|
||||
q=(unit ,[p=cash q=*]) :: file
|
||||
r=(map ,@ta ankh) :: folders
|
||||
== ::
|
||||
```
|
||||
|
||||
This is a single node in the filesystem. This may be file or a directory or
|
||||
both. In earth filesystems, a node is a file xor a directory. On mars, we're
|
||||
inclusive, so a node is a file ior a directory.
|
||||
|
||||
`p` is a recursive hash that depends on the contents of the this file or
|
||||
directory and on any children.
|
||||
|
||||
`q` is the contents of this file, if any. `p.q` is a hash of the contents
|
||||
while `q.q` is the data itself.
|
||||
|
||||
`r` is the set of children of this node. In the case of a pure file, this is
|
||||
empty. The keys are the names of the children and the values are, recursively,
|
||||
the nodes themselves.
|
||||
|
||||
###`++cash`, ankh hash
|
||||
|
||||
```
|
||||
++ cash ,@uvH :: ankh hash
|
||||
```
|
||||
|
||||
This is a 128-bit hash of an ankh. These are mostly stored within ankhs
|
||||
themselves, and they are used to check for changes in possibly-deep
|
||||
hierarchies.
|
||||
|
||||
###`++rung`, filesystem per neighbor ship
|
||||
|
||||
```
|
||||
++ rung $: rus=(map desk rede) :: neighbor desks
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the filesystem of a neighbor ship. The keys to this map are all the
|
||||
desks we know about on their ship.
|
||||
|
||||
###`++rede`, desk state
|
||||
|
||||
```
|
||||
++ rede :: universal project
|
||||
$: lim=@da :: complete to
|
||||
qyx=cult :: subscribers
|
||||
ref=(unit rind) :: outgoing requests
|
||||
dom=dome :: revision state
|
||||
== ::
|
||||
```
|
||||
|
||||
This is our knowledge of the state of a desk, either foreign or domestic.
|
||||
|
||||
`lim` is the date of the last full update. We only respond to requests for
|
||||
stuff before this time.
|
||||
|
||||
`qyx` is the list of subscribers to this desk. For domestic desks, this is
|
||||
simply `p:dojo`, all subscribers to the desk, while in foreign desks this is
|
||||
all the subscribers from our ship to the foreign desk.
|
||||
|
||||
`ref` is the request manager for the desk.
|
||||
|
||||
`dom` is the actual data in the desk.
|
||||
|
||||
###`++rind`, request manager
|
||||
|
||||
```
|
||||
++ rind :: request manager
|
||||
$: nix=@ud :: request index
|
||||
bom=(map ,@ud ,[p=duct q=rave]) :: outstanding
|
||||
fod=(map duct ,@ud) :: current requests
|
||||
haw=(map mood (unit)) :: simple cache
|
||||
== ::
|
||||
```
|
||||
|
||||
This is the request manager for a desk.
|
||||
|
||||
`nix` is one more than the index of the most recent request. Thus, it is the
|
||||
next available request number.
|
||||
|
||||
`bom` is the set of outstanding requests. The keys of this map are some subset
|
||||
of the numbers between 0 and one less than `nix`. The members of the map are
|
||||
exactly those requests that have not yet been fully satisfied.
|
||||
|
||||
`fod` is the same set as `bom`, but from a different perspective. In
|
||||
particular, the values of `fod` are the same as the values of `bom`, and the
|
||||
`p` out of the values of `bom` are the same as the keys of `fod`. Thus, we can
|
||||
map ducts to their associated request number and `++rave`, and we can map
|
||||
numbers to their associated duct and `++rave`.
|
||||
|
||||
`haw` is a map from simple requests to their values. This acts as a cache for
|
||||
requests that have already been made. Thus, the second request for a
|
||||
particular `++mood` is nearly instantaneous.
|
||||
|
||||
###`++rang`, data store
|
||||
|
||||
```
|
||||
++ rang $: hut=(map tako yaki) ::
|
||||
lat=(map lobe blob) ::
|
||||
== ::
|
||||
```
|
||||
|
||||
This is a set of data keyed by hash. Thus, this is where the "real" data is
|
||||
stored, but it is only meaningful if we know the hash of what we're looking
|
||||
for.
|
||||
|
||||
`hut` is a map from hashes to commits. We often get the hashes from
|
||||
`hit:dome`, which keys them by logical id. Not every commit has an id.
|
||||
|
||||
`lat` is a map from hashes to the actual data. We often get the hashes from a
|
||||
`++yaki`, a commit, which references this map to get the data. There is no
|
||||
`++blob` in any `++yaki`. They are only accessible through this map.
|
||||
|
||||
###`++tako`, commit reference
|
||||
|
||||
```
|
||||
++ tako ,@ :: yaki ref
|
||||
```
|
||||
|
||||
This is a hash of a `++yaki`, a commit. These are most notably used as the
|
||||
keys in `hut:rang`, where they are associated with the actual `++yaki`, and as
|
||||
the values in `hit:dome`, where sequential ids are associated with these.
|
||||
|
||||
###`++yaki`, commit
|
||||
|
||||
```
|
||||
++ yaki ,[p=(list tako) q=(map path lobe) r=tako t=@da] :: commit
|
||||
```
|
||||
|
||||
This is a single commit.
|
||||
|
||||
`p` is a list of the hashes of the parents of this commit. In most cases, this
|
||||
will be a single commit, but in a merge there may be more parents. In theory,
|
||||
there may be an arbitrary number of parents, but in practice merges have
|
||||
exactly two parents. This may change in the future. For commit 1, there is no
|
||||
parent.
|
||||
|
||||
`q` is a map of the paths on a desk to the data at that location. If you
|
||||
understand what a `++lobe` and a `++blob` is, then the type signature here
|
||||
tells the whole story.
|
||||
|
||||
`r` is the hash associated with this commit.
|
||||
|
||||
`t` is the date at which this commit was made.
|
||||
|
||||
###`++lobe`, data reference
|
||||
|
||||
```
|
||||
++ lobe ,@ :: blob ref
|
||||
```
|
||||
|
||||
This is a hash of a `++blob`. These are most notably used in `lat:rang`, where
|
||||
they are associated with the actual `++blob`, and as the values in `q:yaki`,
|
||||
where paths are associated with their data in a commit.
|
||||
|
||||
###`++blob`, data
|
||||
|
||||
```
|
||||
++ blob $% [%delta p=lobe q=lobe r=udon] :: delta on q
|
||||
[%direct p=lobe q=* r=umph] ::
|
||||
[%indirect p=lobe q=* r=udon s=lobe] ::
|
||||
== ::
|
||||
```
|
||||
|
||||
This is a node of data. In every case, `p` is the hash of the blob.
|
||||
|
||||
`%delta` is the case where we define the data by a delta on other data. In
|
||||
practice, the other data is always the previous commit, but nothing depends on
|
||||
this. `q` is the hash of the parent blob, and `r` is the delta.
|
||||
|
||||
`%direct` is the case where we simply have the data directly. `q` is the data
|
||||
itself, and `r` is any preprocessing instructions. These almost always come
|
||||
from the creation of a file.
|
||||
|
||||
`%indirect` is both of the preceding cases at once. `q` is the direct data,
|
||||
`r` is the delta, and `s` is the parent blob. It should always be the case
|
||||
that applying `r` to `s` gives the same data as `q` directly (with the
|
||||
prepreprocessor instructions in `p.r`). This exists purely for performance
|
||||
reasons. This is unused, at the moment, but in general these should be created
|
||||
when there are a long line of changes so that we do not have to traverse the
|
||||
delta chain back to the creation of the file.
|
||||
|
||||
###`++udon`, abstract delta
|
||||
|
||||
```
|
||||
++ udon :: abstract delta
|
||||
$: p=umph :: preprocessor
|
||||
$= q :: patch
|
||||
$% [%a p=* q=*] :: trivial replace
|
||||
[%b p=udal] :: atomic indel
|
||||
[%c p=(urge)] :: list indel
|
||||
[%d p=upas q=upas] :: tree edit
|
||||
== ::
|
||||
== ::
|
||||
```
|
||||
|
||||
This is an abstract change to a file. This is a superset of what would
|
||||
normally be called diffs. Diffs usually refer to changes in lines of text
|
||||
while we have the ability to do more interesting deltas on arbitrary data
|
||||
structures.
|
||||
|
||||
`p` is any preprocessor instructions.
|
||||
|
||||
`%a` refers to the trival delta of a complete replace of old data with new
|
||||
data.
|
||||
|
||||
`%b` refers to changes in an opaque atom on the block level. This has very
|
||||
limited usefulness, and is not used at the moment.
|
||||
|
||||
`%c` refers to changes in a list of data. This is often lines of text, which
|
||||
is your classic diff. We, however, will work on any list of data.
|
||||
|
||||
`%d` refers to changes in a tree of data. This is general enough to describe
|
||||
changes to any hoon noun, but often more special-purpose delta should be
|
||||
created for different content types. This is not used at the moment, and may
|
||||
in fact be unimplemented.
|
||||
|
||||
###`++urge`, list change
|
||||
|
||||
```
|
||||
++ urge |*(a=_,* (list (unce a))) :: list change
|
||||
```
|
||||
|
||||
This is a parametrized type for list changes. For example, `(urge ,@t)` is a
|
||||
list change for lines of text.
|
||||
|
||||
###`++unce`, change part of a list.
|
||||
|
||||
```
|
||||
++ unce |* a=_,* :: change part
|
||||
$% [%& p=@ud] :: skip[copy]
|
||||
[%| p=(list a) q=(list a)] :: p -> q[chunk]
|
||||
== ::
|
||||
```
|
||||
|
||||
This is a single change in a list of elements of type `a`. For example, `(unce ,@t)` is
|
||||
a single change in a lines of text.
|
||||
|
||||
`%&` means the next `p` lines are unchanged.
|
||||
|
||||
`%|` means the lines `p` have changed to `q`.
|
||||
|
||||
###`++umph`, preprocessing information
|
||||
|
||||
```
|
||||
++ umph :: change filter
|
||||
$| $? %a :: no filter
|
||||
%b :: jamfile
|
||||
%c :: LF text
|
||||
== ::
|
||||
$% [%d p=@ud] :: blocklist
|
||||
== ::
|
||||
```
|
||||
|
||||
This space intentionally left undocumented. This stuff will change once we get
|
||||
a well-typed clay.
|
||||
|
||||
|
||||
###`++upas`, tree change
|
||||
|
||||
```
|
||||
++ upas :: tree change (%d)
|
||||
$& [p=upas q=upas] :: cell
|
||||
$% [%0 p=axis] :: copy old
|
||||
[%1 p=*] :: insert new
|
||||
[%2 p=axis q=udon] :: mutate!
|
||||
== ::
|
||||
```
|
||||
|
||||
This space intentionally left undocumented. This stuff is not known to work,
|
||||
and will likely change when we get a well-typed clay. Also, this is not a
|
||||
complicated type; it is not difficult to work out the meaning.
|
472
main/pub/src/doc/sail-moveme.md
Normal file
472
main/pub/src/doc/sail-moveme.md
Normal file
@ -0,0 +1,472 @@
|
||||
Structures
|
||||
==========
|
||||
|
||||
The fundamental hoon structure used to generate XML is a manx. A manx is
|
||||
composed of a `marx` and a `marl`, representing an XML node:
|
||||
|
||||
|
||||
```
|
||||
++ manx ,[g=marx c=marl] :: XML node
|
||||
++ marx ,[n=mane a=mart] :: XML tag
|
||||
++ mane $|(@tas [@tas @tas]) :: XML name/space
|
||||
```
|
||||
|
||||
Names, manes
|
||||
------------
|
||||
|
||||
The most basic `manx` consists of an XML node name, called a `mane`, an empty
|
||||
`marl`, and an empty `mart`:
|
||||
|
||||
```
|
||||
~zod/try=> ;div
|
||||
[[%div ~] ~]
|
||||
~zod/try=> ;namespaced_div;
|
||||
[[[%namespaced %div] ~] ~]
|
||||
```
|
||||
|
||||
This represents an XML node, an opening and a closing tag with no attributes
|
||||
nor children:
|
||||
|
||||
```
|
||||
~zod/try=> (xmlt | ;div; "")
|
||||
"<div></div>"
|
||||
~zod/try=> (xmlt | ;namespaced_div; ~)
|
||||
"<namespaced:div></namespaced:div>"
|
||||
```
|
||||
|
||||
**Note**: `++xmlt` takes three arguments: a loobean determening whether text should be
|
||||
xml-escaped, the `manx` to be rendered, and a tape onto which to append the
|
||||
results. `<script>` and `<style>` tags are unescaped by default. For more
|
||||
information, see the XML documentation in Volume 3, section 3bD.
|
||||
|
||||
However, `%gall` applications operate on nouns of the type `[%hymn manx]`,
|
||||
making direct calls to `++xmlt` rare.
|
||||
|
||||
Attributes and child nodes
|
||||
--------------------------
|
||||
|
||||
To represent XML nodes with children and/or attributes, `marl` and `mart` are
|
||||
used respectively:
|
||||
|
||||
```
|
||||
++ marl (list manx) :: XML node list
|
||||
++ mart (list ,[n=mane v=tape]) :: XML attributes
|
||||
```
|
||||
|
||||
Each child node is simply another manx, and attributes are pairs of key `mane`
|
||||
to value `tape`. `marl` and `mart` are lists of these respective values.
|
||||
|
||||
Wide Form
|
||||
=========
|
||||
|
||||
Children
|
||||
--------
|
||||
|
||||
The XML templating syntax begins with a `';'` followed by a `term`.
|
||||
In wide form, a child node is appended with a `':'`:
|
||||
|
||||
```
|
||||
~zod/try=> ;div:p;
|
||||
[[%div ~] [[%p ~] ~] ~]
|
||||
~zod/try=> :poxo ;div:p;
|
||||
<div><p></p></div>
|
||||
```
|
||||
|
||||
**Note:**`/~zod/try/1/bin/poxo/hoon` is a shell script that applies `(curr (cury xmlt |) ~)`
|
||||
to a `manx`, rendering it as a `tape`.
|
||||
|
||||
Multiple nodes can be represented inside of parentheses, separated by single spaces:
|
||||
|
||||
```
|
||||
~zod/try=> ;div:(p ul:(li li))
|
||||
[[%div ~] [[%p ~] ~] [[%ul ~] [[%li ~] ~] [[%li ~] ~] ~] ~]
|
||||
~zod/try=> :poxo ;div:(p ul:(li li))
|
||||
<div><p></p><ul><li></li><li></li></ul></div>
|
||||
```
|
||||
|
||||
Tags must always be closed. In wide form, this is done either with a `';'` if the
|
||||
node contains no children, or with a `':'`, followed by one or more children.
|
||||
|
||||
In wide form, terminating `';'`s are implied: `;div:(p p p)` is equivalent to
|
||||
`;div:(p; p; p;)`.
|
||||
However, in instances where there are a chain of nodes where each node
|
||||
contains only one child, as with `;div:p;`, it is good practice to include the
|
||||
final `';'` to avoid confusion with an unclosed single tag.
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
Attributes are included as `','`-separated pairs of `mane` and and a `tape` producing twig. These
|
||||
pairs are contained within parentheses, which immediately follow a `mane`:
|
||||
|
||||
```
|
||||
~zod/try=> ;div(id "me", class "elem");
|
||||
[[%div [%id "me"] [%class "elem"] ~] ~]
|
||||
~zod/try=> :poxo ;div(class "elem", id "me"); ~))
|
||||
<div class="elem" id="me"></div>
|
||||
```
|
||||
|
||||
The characters `'.'`, `'#'`, and `'/'` are short forms of the attributes `class`,
|
||||
`id`, and `href` respectively:
|
||||
|
||||
```
|
||||
~zod/try=> ;div.elem#me;
|
||||
[[%div [%id "me"] [%class "elem"] ~] ~]
|
||||
~zod/try=> ;a/"//google.com";
|
||||
[[%a [%href "//google.com"] ~] ~]
|
||||
```
|
||||
|
||||
As demonstrated above, the short forms of both `class` and `id` accept unquoted
|
||||
terms instead of tapes.
|
||||
The resulting XML is, of course, identical:
|
||||
|
||||
```
|
||||
~zod/try=> :poxo ;div.elem#me;
|
||||
<div id="me" class="elem"></div>
|
||||
```
|
||||
|
||||
Character data
|
||||
--------------
|
||||
|
||||
Nodes can also contain text:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"contents of paragraph"
|
||||
[[%p ~] [[%~. [%~. "contents of paragraph"] ~] ~] ~]
|
||||
~zod/try=> :poxo ;p:"contents of paragraph"
|
||||
<p>contents of paragraph</p>
|
||||
```
|
||||
|
||||
Text is stored as a `mars` (a cdata node):
|
||||
|
||||
```
|
||||
++ mars ,[t=[n=%$ a=[i=[n=%$ v=tape] t=~]] c=~] :: XML cdata
|
||||
```
|
||||
|
||||
Techincally, a `mars` is a `manx` with an empty `mane`, one empty-named attribute
|
||||
containing the text, and no children. Equivalently, it is a `_:/(*tape)`.
|
||||
|
||||
To insert text with newlines, it is surrounded in triple quotes:
|
||||
|
||||
```
|
||||
;code:"""
|
||||
block
|
||||
with newlines
|
||||
"""
|
||||
```
|
||||
|
||||
This is rendered as:
|
||||
|
||||
```
|
||||
<code>block
|
||||
with newlines</code>
|
||||
```
|
||||
|
||||
Interpolation
|
||||
-------------
|
||||
|
||||
Similar to the syntax for `tape` interpolation,
|
||||
|
||||
```
|
||||
~zod/try=> "Tape with {(weld "inter" (trip %polate))}d text"
|
||||
"Tape with interpolated text"
|
||||
```
|
||||
|
||||
there exists a `manx` syntax to insert XML produced by twigs. The simplest form
|
||||
is that of embedded nodes:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"Text text ;{b "bolded text"} more text"
|
||||
[ [%p ~]
|
||||
[[%~. [%~. "Text text "] ~] ~]
|
||||
[[%b ~] [[%~. [%~. "bolded text"] ~] ~] ~]
|
||||
[[%~. [%~. " more text"] ~] ~]
|
||||
~
|
||||
]
|
||||
~zod/try=> :poxo ;p:"Text text ;{b "bolded text"} more text"
|
||||
<p>Text text <b>bolded text</b> more text</p>
|
||||
```
|
||||
|
||||
Notice that the syntax calls for a `marx`, followed by zero or more wide-form children
|
||||
`manx`, placed within `';{}'`.
|
||||
|
||||
Dynamic data can also be interpolated. This is done by prefixing the `{}` wrapped twig with one of the following glyphs: `-, +, *, or %`.
|
||||
|
||||
A `{}` prefixed by a `'-'` accepts a `tape`:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"Paragraph with -{(weld "inter" (trip %polate))}d text"
|
||||
[ [%p ~]
|
||||
[[%~. [%~. "Paragraph with "] ~] ~]
|
||||
[[%~. [%~. ~[~~i ~~n ~~t ~~e ~~r ~~p ~~o ~~l ~~a ~~t ~~e]] ~] ~]
|
||||
[[%~. [%~. "d text"] ~] ~]
|
||||
~
|
||||
]
|
||||
```
|
||||
|
||||
If no glyph prefix is present, a`'-'` is assumed:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"Paragraph with {(weld "inter" (trip %polate))}d text"
|
||||
[ [%p ~]
|
||||
[[%~. [%~. "Paragraph with "] ~] ~]
|
||||
[[%~. [%~. ~[~~i ~~n ~~t ~~e ~~r ~~p ~~o ~~l ~~a ~~t ~~e]] ~] ~]
|
||||
[[%~. [%~. "d text"] ~] ~]
|
||||
~
|
||||
]
|
||||
~zod/try=> :poxo ;p:"Paragraph with {(weld "inter" (trip %polate))}d text"
|
||||
<p>Paragraph with interpolated text</p>
|
||||
```
|
||||
|
||||
A prefix of `'+'` accepts a `manx`:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"This text +{?:((gth 2 1) ;b:"be bold" ;i:"be scared")}"
|
||||
[[%p ~] [[%~. [%~. "This text "] ~] ~] [[%b ~] [[%~. [%~. "be bold"] ~] ~] ~] ~]
|
||||
~zod/try=> :poxo ;p:"This text +{?:((gth 2 1) ;b:"be bold" ;i:"be scared")}"
|
||||
<p>This text <b>be bold</b></p>
|
||||
```
|
||||
|
||||
A prefix of `'*'` accepts a `marl`:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"Today *{(turn `wain`~[%live %love] |=(a=@tas ;span:"we {(trip a)}, "))}"
|
||||
[ [%p ~]
|
||||
[[%~. [%~. "Today "] ~] ~]
|
||||
[ i=[[%span ~] [[%~. [%~. "we "] ~] ~] [[%~. [%~. "live"] ~] ~] [[%~. [%~. ", "] ~] ~] ~]
|
||||
t
|
||||
[ i=[[%span ~] [[%~. [%~. "we "] ~] ~] [[%~. [%~. "love"] ~] ~] [[%~. [%~. ", "] ~] ~] ~]
|
||||
t=~
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/try=> :poxo ;p:"Today *{(turn `wain`~[%live %love] |=(a=@tas ;span:"we {(trip a)}, "))}"
|
||||
<p>Today <span>we live, </span><span>we love, </span></p>
|
||||
```
|
||||
|
||||
A prefix of `'%'` accepts `$+(marl marl)`, a gate with both a sample and product of `marl`. The gate is then slammed by the nodes that follow it:
|
||||
|
||||
```
|
||||
~zod/try=> ;p:"%{|=(a=marl (weld a a))}dup"
|
||||
[ [%p ~]
|
||||
~[[g=[n=%$ a=~[[n=%$ v="dup"]]] c=~] [g=[n=%$ a=~[[n=%$ v="dup"]]] c=~]]
|
||||
]
|
||||
~zod/try=> :poxo ;p:"%{|=(a=marl (weld a a))}dup"
|
||||
<p>dupdup</p>
|
||||
```
|
||||
|
||||
Interpolation can be disabled by replacing double quotes with single quotes.
|
||||
For example, `;unescaped:'Kel {}'` becomes `<unescaped>Kel {}</unescaped>`,
|
||||
and:
|
||||
|
||||
```
|
||||
;script:'''
|
||||
function(){
|
||||
console.log(42)
|
||||
}
|
||||
'''
|
||||
```
|
||||
|
||||
when rendered, is:
|
||||
|
||||
```
|
||||
<script>function(){
|
||||
console.log(42)
|
||||
}</script>
|
||||
```
|
||||
|
||||
Tall form
|
||||
==========
|
||||
|
||||
Most development is done in tall form:
|
||||
|
||||
```
|
||||
;html
|
||||
;head
|
||||
;title
|
||||
; Hi
|
||||
==
|
||||
==
|
||||
;body
|
||||
;p
|
||||
; Hello world
|
||||
==
|
||||
==
|
||||
==
|
||||
```
|
||||
|
||||
This produces the `manx`:
|
||||
|
||||
```
|
||||
g=[n=%html a=~]
|
||||
c
|
||||
~[
|
||||
[ g=[n=%head a=~]
|
||||
c=~[[g=[n=%title a=~] c=~[[g=[n=%$ a=~[[n=%$ v="Hi
|
||||
"]]] c=~]]]]
|
||||
]
|
||||
[ g=[n=%body a=~]
|
||||
c=~[[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="Hello world
|
||||
"]]] c=~]]]]
|
||||
]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
When the `manx` is rendered, it produces:
|
||||
|
||||
```
|
||||
<html><head><title>Hi
|
||||
</title></head><body><p>Hello world
|
||||
</p></body></html>
|
||||
```
|
||||
|
||||
As previously mentioned, a tag must always be closed. In tall form, this is accomplished by a `'=='`, which should align directly beneath it; any node in between the two is a subnnode.
|
||||
|
||||
As demonstrated in the example above, the tall form for character data
|
||||
is opened by `'; '` (note the space). Unlike wide form, the text that follows
|
||||
the `'; '` is not wrapped in quotes, but is instead terminated with a new
|
||||
line. The syntax for interpolation remains the same.
|
||||
|
||||
The final way in which a tag may be closed is with `': '`, which is equivalent
|
||||
to a `manx` with a single child declared by `'; '`. As with `'; '`, the text
|
||||
declared by the `': '` is terminated by a new line:
|
||||
|
||||
```
|
||||
;p: par contents
|
||||
:: <p>par contents</p>
|
||||
```
|
||||
|
||||
Another syntax that is unique to tall form is`';='`, which describes a `marl`
|
||||
with no tag:
|
||||
|
||||
```
|
||||
!:
|
||||
=- [- (xmll | - ~)]
|
||||
;=
|
||||
;p: node
|
||||
;node(with "attribute");
|
||||
==
|
||||
```
|
||||
|
||||
This produces the `marl`:
|
||||
|
||||
```
|
||||
[[[%p ~] [[%~. [%~. "node"] ~] ~] ~] [[%node [%with "attribute"] ~] ~] ~]
|
||||
```
|
||||
|
||||
|
||||
Notice how this renders two XML nodes without an outer tag:
|
||||
|
||||
```
|
||||
"<p>node</p><node with="attribute"></node>"
|
||||
```
|
||||
|
||||
Tall interpolation
|
||||
------------------
|
||||
|
||||
A ';' followed by an interpolation glyph(`-, +, *, or %`) and two or more spaces,
|
||||
accepts a twig and interpolates it into the surrounding structure:
|
||||
|
||||
```
|
||||
;div#demo
|
||||
;- "foo"
|
||||
;+ ;p:"bar"
|
||||
;* :- ;p:"baz"
|
||||
?: &
|
||||
~
|
||||
~[;hi;]
|
||||
;% |= a=marl
|
||||
(weld a a)
|
||||
; dup
|
||||
==
|
||||
```
|
||||
|
||||
This produces the `manx`:
|
||||
|
||||
```
|
||||
[ g=[n=%div a=~[[n=%id v="demo"]]]
|
||||
c
|
||||
~[
|
||||
[g=[n=%$ a=~[[n=%$ v="foo"]]] c=~]
|
||||
[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="bar"]]] c=~]]]
|
||||
[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="baz"]]] c=~]]]
|
||||
[g=[n=%$ a=~[[n=%$ v="dup
|
||||
"]]] c=~]
|
||||
[g=[n=%$ a=~[[n=%$ v="dup
|
||||
"]]] c=~]
|
||||
]
|
||||
]
|
||||
```
|
||||
|
||||
When the `manx` is rendered, it produces:
|
||||
|
||||
```
|
||||
<div id="demo">foo<p>bar</p><p>baz</p>dup
|
||||
dup
|
||||
</div>
|
||||
```
|
||||
|
||||
Attributes
|
||||
----------
|
||||
|
||||
The tall form syntax for attributes is `'='` followed by a `mane` (the key), two
|
||||
or more spaces, and a tall twig that produces a tape:
|
||||
|
||||
```
|
||||
;div
|
||||
=id "foo"
|
||||
=class "bar"
|
||||
;p: baz`
|
||||
==
|
||||
```
|
||||
|
||||
This produces the `manx`:
|
||||
|
||||
```
|
||||
[ g=[n=%div a=~[[n=%id v="foo"] [n=%class v="bar"]]]
|
||||
c=~[[g=[n=%p a=~] c=~[[g=[n=%$ a=~[[n=%$ v="baz"]]] c=~]]]]
|
||||
]
|
||||
```
|
||||
|
||||
When rendered, this `manx` produces:
|
||||
|
||||
```
|
||||
<div id="foo" class="bar"><p>baz</p></div>
|
||||
```
|
||||
|
||||
The tall-form syntax can be combined with the wide-form attribute syntax (and all of its short forms):
|
||||
|
||||
```
|
||||
;html
|
||||
;div#foo(tag "bar")
|
||||
=attr "exceedingly value in here"
|
||||
; tall form
|
||||
;p: contents
|
||||
==
|
||||
==
|
||||
```
|
||||
|
||||
This produces the `manx`:
|
||||
|
||||
```
|
||||
[ [%html ~]
|
||||
[ [%div [%id "foo"] [%tag "bar"] [%attr "hella long value in here"] ~]
|
||||
[[%~. [%~. "tall form
|
||||
"] ~] ~]
|
||||
[[%p ~] [[%~. [%~. "contents"] ~] ~] ~]
|
||||
~
|
||||
]
|
||||
~
|
||||
]
|
||||
```
|
||||
|
||||
When rendered, this `manx` produces:
|
||||
|
||||
```
|
||||
"<html><div id="foo" tag="bar" attr="hella long value in here">tall form
|
||||
<p>contents</p></div></html>"
|
||||
```
|
||||
|
||||
|
||||
|
@ -238,7 +238,7 @@ we put:
|
||||
:::: /hoon/three/mad/fab/pub
|
||||
::
|
||||
/= hello /: /===/pub/fab/mad/res/hello /hymn/
|
||||
:
|
||||
::
|
||||
:::: ~tasfyn-partyv
|
||||
::
|
||||
::
|
@ -319,7 +319,7 @@ example, it'll be obvious what it is.
|
||||
<<33r:: *[a 7 b c] *[*[a b] c]>>
|
||||
|
||||
*[*[a c] 2 [0 1] 0 b]]
|
||||
|
||||
|
||||
<<27 :: *[a 2 b c] *[*[a b] *[a c]]>>
|
||||
|
||||
*[*[*[a c] [0 1]] *[*[a c] 0 b]]
|
||||
|
@ -1,4 +1,4 @@
|
||||
|= ^
|
||||
|= [a=manx ~]
|
||||
=- ~[$/!>(-)]~
|
||||
(xmlt | a "")
|
||||
=- ~[te/[-]~]~
|
||||
(crip (xmlt | a ""))
|
||||
|
Loading…
Reference in New Issue
Block a user