diff --git a/bin/solid.pill b/bin/solid.pill index 8e981d024e..33fcaf9c5d 100644 --- a/bin/solid.pill +++ b/bin/solid.pill @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:771c5a1b15985f4c793f5c2e0786ddf73b0326272fdf781715d4b63f8be7a017 -size 11635326 +oid sha256:7293a04c2de520a04f1a1afb49e497a5465b39a5863bee39d02e5b3ba491193a +size 13618239 diff --git a/pkg/arvo/sur/hood.hoon b/pkg/arvo/sur/hood.hoon index a2e6439260..6130b03240 100644 --- a/pkg/arvo/sur/hood.hoon +++ b/pkg/arvo/sur/hood.hoon @@ -45,9 +45,8 @@ (snoc - leaf/"pending: {}") ^- tang =/ meb (mergebase-hashes our desk now arak) - =/ len (lent meb) :~ leaf/"/sys/kelvin: {<[lal num]:weft>}" - leaf/"base hash: {?.(=(len 1) <(head meb)>)}" + leaf/"base hash: {?.(=(1 (lent meb)) <(head meb)>)}" leaf/"%cz hash: {}" leaf/"remote aeon: {}" leaf/"force on: {?:(=(~ add.rein.arak) "~" )}" diff --git a/pkg/base-dev/desk.bill b/pkg/base-dev/desk.bill new file mode 100644 index 0000000000..7f45256db2 --- /dev/null +++ b/pkg/base-dev/desk.bill @@ -0,0 +1,5 @@ +:~ :- %apes + ~ + :- %fish + ~ +== diff --git a/pkg/base-dev/lib/agentio.hoon b/pkg/base-dev/lib/agentio.hoon new file mode 100644 index 0000000000..bd09905f72 --- /dev/null +++ b/pkg/base-dev/lib/agentio.hoon @@ -0,0 +1,125 @@ +=> + |% + ++ card card:agent:gall + -- +:: +|_ =bowl:gall +++ scry + |= [desk=@tas =path] + %+ weld + /(scot %p our.bowl)/[desk]/(scot %da now.bowl) + path +:: +++ pass + |_ =wire + ++ poke + |= [=dock =cage] + [%pass wire %agent dock %poke cage] + :: + ++ poke-our + |= [app=term =cage] + ^- card + (poke [our.bowl app] cage) + :: + ++ poke-self + |= =cage + ^- card + (poke-our dap.bowl cage) + :: + ++ arvo + |= =note-arvo + ^- card + [%pass wire %arvo note-arvo] + :: + ++ watch + |= [=dock =path] + [%pass (watch-wire path) %agent dock %watch path] + :: + ++ watch-our + |= [app=term =path] + (watch [our.bowl app] path) + :: + ++ watch-wire + |= =path + ^+ wire + ?. ?=(~ wire) + wire + agentio-watch+path + :: + ++ leave + |= =dock + [%pass wire %agent dock %leave ~] + :: + ++ leave-our + |= app=term + (leave our.bowl app) + :: + ++ leave-path + |= [=dock =path] + =. wire + (watch-wire path) + (leave dock) + :: + ++ wait + |= p=@da + (arvo %b %wait p) + :: + ++ rest + |= p=@da + (arvo %b %wait p) + :: + ++ warp + |= [wer=ship =riff:clay] + (arvo %c %warp wer riff) + :: + ++ warp-our + |= =riff:clay + (warp our.bowl riff) + :: + :: right here, right now + ++ warp-slim + |= [genre=?(%sing %next) =care:clay =path] + =/ =mood:clay + [care r.byk.bowl path] + =/ =rave:clay + ?:(?=(%sing genre) [genre mood] [genre mood]) + (warp-our q.byk.bowl `rave) + -- +:: +++ fact-curry + |* [=mark =mold] + |= [paths=(list path) fac=mold] + (fact mark^!>(fac) paths) +:: +++ fact-kick + |= [=path =cage] + ^- (list card) + :~ (fact cage ~[path]) + (kick ~[path]) + == +:: +++ fact-init + |= =cage + ^- card + [%give %fact ~ cage] +:: +++ fact-init-kick + |= =cage + ^- (list card) + :~ (fact cage ~) + (kick ~) + == +:: +++ fact + |= [=cage paths=(list path)] + ^- card + [%give %fact paths cage] +:: +++ kick + |= paths=(list path) + [%give %kick paths ~] +:: +++ kick-only + |= [=ship paths=(list path)] + [%give %kick paths `ship] +-- diff --git a/pkg/base-dev/lib/azimuth.hoon b/pkg/base-dev/lib/azimuth.hoon new file mode 100644 index 0000000000..0d42991ad2 --- /dev/null +++ b/pkg/base-dev/lib/azimuth.hoon @@ -0,0 +1,454 @@ +:: azimuth: constants and utilities +:: +/+ ethereum +:: +=> => [azimuth-types ethereum-types .] + |% + +$ complete-ship + $: state=point + history=(list diff-point) ::TODO maybe block/event nr? :: newest first + keys=(map life pass) + == + :: + ++ fleet (map @p complete-ship) + :: + ++ eth-type + |% + ++ point + :~ [%bytes-n 32] :: encryptionKey + [%bytes-n 32] :: authenticationKey + %bool :: hasSponsor + %bool :: active + %bool :: escapeRequested + %uint :: sponsor + %uint :: escapeRequestedTo + %uint :: cryptoSuiteVersion + %uint :: keyRevisionNumber + %uint :: continuityNumber + == + ++ deed + :~ %address :: owner + %address :: managementProxy + %address :: spawnProxy + %address :: votingProxy + %address :: transferProxy + == + -- + :: + ++ eth-noun + |% + +$ point + $: encryption-key=octs + authentication-key=octs + has-sponsor=? + active=? + escape-requested=? + sponsor=@ud + escape-to=@ud + crypto-suite=@ud + key-revision=@ud + continuity-number=@ud + == + +$ deed + $: owner=address + management-proxy=address + spawn-proxy=address + voting-proxy=address + transfer-proxy=address + == + -- + :: + ++ function + |% + ++ azimuth + $% [%points who=@p] + [%rights who=@p] + [%get-spawned who=@p] + [%dns-domains ind=@ud] + == + -- + :: + :: # diffs + :: + ++ update + $% [%full ships=(map ship point) dns=dnses heard=events] + [%difs dis=(list (pair event-id diff-azimuth))] + == + :: + :: # constants + :: + :: contract addresses + ++ contracts mainnet-contracts + ++ mainnet-contracts + |% + :: azimuth: data contract + :: + ++ azimuth + 0x223c.067f.8cf2.8ae1.73ee.5caf.ea60.ca44.c335.fecb + :: + ++ ecliptic + 0x6ac0.7b7c.4601.b5ce.11de.8dfe.6335.b871.c7c4.dd4d + :: + ++ linear-star-release + 0x86cd.9cd0.992f.0423.1751.e376.1de4.5cec.ea5d.1801 + :: + ++ conditional-star-release + 0x8c24.1098.c3d3.498f.e126.1421.633f.d579.86d7.4aea + :: + ++ delegated-sending + 0xf790.8ab1.f1e3.52f8.3c5e.bc75.051c.0565.aeae.a5fb + :: + :: launch: block number of azimuth deploy + :: + ++ launch 6.784.800 + :: + :: public: block number of azimuth becoming independent + :: + ++ public 7.033.765 + -- + :: + :: Testnet contract addresses + :: + ++ ropsten-contracts + |% + ++ azimuth + 0x308a.b6a6.024c.f198.b57e.008d.0ac9.ad02.1988.6579 + :: + ++ ecliptic + 0x8b9f.86a2.8921.d9c7.05b3.113a.755f.b979.e1bd.1bce + :: + ++ linear-star-release + 0x1f8e.dd03.1ee4.1474.0aed.b39b.84fb.8f2f.66ca.422f + :: + ++ conditional-star-release + 0x0 + :: + ++ delegated-sending + 0x3e8c.a510.354b.c2fd.bbd6.1502.52d9.3105.c9c2.7bbe + :: + ++ launch 4.601.630 + ++ public launch + -- + :: + :: Local contract addresses + :: + :: These addresses are only reproducible if you use the deploy + :: script in bridge + :: + ++ local-contracts + |% + ++ ecliptic + 0x56db.68f2.9203.ff44.a803.faa2.404a.44ec.bb7a.7480 + ++ azimuth + 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 + ++ delegated-sending + 0xb71c.0b6c.ee1b.cae5.6dfe.95cd.9d3e.41dd.d7ea.fc43 + ++ linear-star-release + 0x3c3.dc12.be65.8158.d1d7.f9e6.6e08.ec40.99c5.68e4 + ++ conditional-star-release + 0x35eb.3b10.2d9c.1b69.ac14.69c1.b1fe.1799.850c.d3eb + ++ launch 0 + ++ public 0 + -- + :: + :: ++ azimuth 0x863d.9c2e.5c4c.1335.96cf.ac29.d552.55f0.d0f8.6381 :: local bridge + :: hashes of ship event signatures + ++ azimuth-events + |% + :: + :: OwnerChanged(uint32,address) + ++ owner-changed + 0x16d0.f539.d49c.6cad.822b.767a.9445.bfb1. + cf7e.a6f2.a6c2.b120.a7ea.4cc7.660d.8fda + :: + :: Activated(uint32) + ++ activated + 0xe74c.0380.9d07.69e1.b1f7.06cc.8414.258c. + d1f3.b6fe.020c.d15d.0165.c210.ba50.3a0f + :: + :: Spawned(uint32,uint32) + ++ spawned + 0xb2d3.a6e7.a339.f5c8.ff96.265e.2f03.a010. + a854.1070.f374.4a24.7090.9644.1508.1546 + :: + :: EscapeRequested(uint32,uint32) + ++ escape-requested + 0xb4d4.850b.8f21.8218.141c.5665.cba3.79e5. + 3e9b.b015.b51e.8d93.4be7.0210.aead.874a + :: + :: EscapeCanceled(uint32,uint32) + ++ escape-canceled + 0xd653.bb0e.0bb7.ce83.93e6.24d9.8fbf.17cd. + a590.2c83.28ed.0cd0.9988.f368.90d9.932a + :: + :: EscapeAccepted(uint32,uint32) + ++ escape-accepted + 0x7e44.7c9b.1bda.4b17.4b07.96e1.00bf.7f34. + ebf3.6dbb.7fe6.6549.0b1b.fce6.246a.9da5 + :: + :: LostSponsor(uint32,uint32) + ++ lost-sponsor + 0xd770.4f9a.2519.3dbd.0b0c.b4a8.09fe.ffff. + a7f1.9d1a.ae88.17a7.1346.c194.4482.10d5 + :: + :: ChangedKeys(uint32,bytes32,bytes32,uint32,uint32) + ++ changed-keys + 0xaa10.e7a0.117d.4323.f1d9.9d63.0ec1.69be. + bb3a.988e.8957.70e3.5198.7e01.ff54.23d5 + :: + :: BrokeContinuity(uint32,uint32) + ++ broke-continuity + 0x2929.4799.f1c2.1a37.ef83.8e15.f79d.d91b. + cee2.df99.d63c.d1c1.8ac9.68b1.2951.4e6e + :: + :: ChangedSpawnProxy(uint32,address) + ++ changed-spawn-proxy + 0x9027.36af.7b3c.efe1.0d9e.840a.ed0d.687e. + 35c8.4095.122b.2505.1a20.ead8.866f.006d + :: + :: ChangedTransferProxy(uint32,address) + ++ changed-transfer-proxy + 0xcfe3.69b7.197e.7f0c.f067.93ae.2472.a9b1. + 3583.fecb.ed2f.78df.a14d.1f10.796b.847c + :: + :: ChangedManagementProxy(uint32,address) + ++ changed-management-proxy + 0xab9c.9327.cffd.2acc.168f.afed.be06.139f. + 5f55.cb84.c761.df05.e051.1c25.1e2e.e9bf + :: + :: ChangedVotingProxy(uint32,address) + ++ changed-voting-proxy + 0xcbd6.269e.c714.57f2.c7b1.a227.74f2.46f6. + c5a2.eae3.795e.d730.0db5.1768.0c61.c805 + :: + :: ChangedDns(string,string,string) + ++ changed-dns + 0xfafd.04ad.e1da.ae2e.1fdb.0fc1.cc6a.899f. + d424.063e.d5c9.2120.e67e.0730.53b9.4898 + -- + -- +:: +:: logic +:: +|% +++ pass-from-eth + |= [enc=octs aut=octs sut=@ud] + ^- pass + %^ cat 3 'b' + ?. &(=(1 sut) =(p.enc 32) =(p.aut 32)) + (cat 8 0 0) + (cat 8 q.aut q.enc) +:: +++ point-from-eth + |= [who=@p point:eth-noun deed:eth-noun] + ^- point + :: + :: ownership + :: + :+ :* owner + management-proxy + voting-proxy + transfer-proxy + == + :: + :: network state + :: + ?. active ~ + :- ~ + :* key-revision + :: + (pass-from-eth encryption-key authentication-key crypto-suite) + :: + continuity-number + :: + [has-sponsor `@p`sponsor] + :: + ?. escape-requested ~ + ``@p`escape-to + == + :: + :: spawn state + :: + ?. ?=(?(%czar %king) (clan:title who)) ~ + :- ~ + :* spawn-proxy + ~ ::TODO call getSpawned to fill this + == +:: +++ event-log-to-point-diff + =, azimuth-events + =, abi:ethereum + |= log=event-log:rpc:ethereum + ^- (unit (pair ship diff-point)) + ~? ?=(~ mined.log) %processing-unmined-event + :: + ?: =(i.topics.log owner-changed) + =/ [who=@ wer=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %owner wer] + :: + ?: =(i.topics.log activated) + =/ who=@ + (decode-topics t.topics.log ~[%uint]) + `[who %activated who] + :: + ?: =(i.topics.log spawned) + =/ [pre=@ who=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[pre %spawned who] + :: + ?: =(i.topics.log escape-requested) + =/ [who=@ wer=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[who %escape `wer] + :: + ?: =(i.topics.log escape-canceled) + =/ who=@ (decode-topics t.topics.log ~[%uint]) + `[who %escape ~] + :: + ?: =(i.topics.log escape-accepted) + =/ [who=@ wer=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[who %sponsor & wer] + :: + ?: =(i.topics.log lost-sponsor) + =/ [who=@ pos=@] + (decode-topics t.topics.log ~[%uint %uint]) + `[who %sponsor | pos] + :: + ?: =(i.topics.log changed-keys) + =/ who=@ (decode-topics t.topics.log ~[%uint]) + =/ [enc=octs aut=octs sut=@ud rev=@ud] + %+ decode-results data.log + ~[[%bytes-n 32] [%bytes-n 32] %uint %uint] + `[who %keys rev (pass-from-eth enc aut sut)] + :: + ?: =(i.topics.log broke-continuity) + =/ who=@ (decode-topics t.topics.log ~[%uint]) + =/ num=@ (decode-results data.log ~[%uint]) + `[who %continuity num] + :: + ?: =(i.topics.log changed-management-proxy) + =/ [who=@ sox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %management-proxy sox] + :: + ?: =(i.topics.log changed-voting-proxy) + =/ [who=@ tox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %voting-proxy tox] + :: + ?: =(i.topics.log changed-spawn-proxy) + =/ [who=@ sox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %spawn-proxy sox] + :: + ?: =(i.topics.log changed-transfer-proxy) + =/ [who=@ tox=address] + (decode-topics t.topics.log ~[%uint %address]) + `[who %transfer-proxy tox] + :: + :: warn about unimplemented events, but ignore + :: the ones we know are harmless. + ~? ?! .= i.topics.log + :: OwnershipTransferred(address,address) + 0x8be0.079c.5316.5914.1344.cd1f.d0a4.f284. + 1949.7f97.22a3.daaf.e3b4.186f.6b64.57e0 + [%unimplemented-event i.topics.log] + ~ +:: +++ apply-point-diff + |= [pot=point dif=diff-point] + ^- point + ?- -.dif + %full new.dif + :: + %activated + %_ pot + net `[0 0 0 &^(^sein:title who.dif) ~] + kid ?. ?=(?(%czar %king) (clan:title who.dif)) ~ + `[0x0 ~] + == + :: + :: ownership + :: + %owner pot(owner.own new.dif) + %transfer-proxy pot(transfer-proxy.own new.dif) + %management-proxy pot(management-proxy.own new.dif) + %voting-proxy pot(voting-proxy.own new.dif) + :: + :: networking + :: + ?(%keys %continuity %sponsor %escape) + ?> ?=(^ net.pot) + ?- -.dif + %keys + pot(life.u.net life.dif, pass.u.net pass.dif) + :: + %sponsor + %= pot + sponsor.u.net new.dif + escape.u.net ?:(has.new.dif ~ escape.u.net.pot) + == + :: + %continuity pot(continuity-number.u.net new.dif) + %escape pot(escape.u.net new.dif) + == + :: + :: spawning + :: + ?(%spawned %spawn-proxy) + ?> ?=(^ kid.pot) + ?- -.dif + %spawned + =- pot(spawned.u.kid -) + (~(put in spawned.u.kid.pot) who.dif) + :: + %spawn-proxy pot(spawn-proxy.u.kid new.dif) + == + == +:: +++ parse-id + |= id=@t + ^- azimuth:function + |^ + ~| id + %+ rash id + ;~ pose + (function %points 'points' shipname) + (function %get-spawned 'getSpawned' shipname) + (function %dns-domains 'dnsDomains' dem:ag) + == + :: + ++ function + |* [tag=@tas fun=@t rul=rule] + ;~(plug (cold tag (jest fun)) (ifix [pal par] rul)) + :: + ++ shipname + ;~(pfix sig fed:ag) + -- +:: +++ function-to-call + |% + ++ azimuth + |= cal=azimuth:function + ^- [id=@t dat=call-data:rpc:ethereum] + ?- -.cal + %points + :- (crip "points({(scow %p who.cal)})") + ['points(uint32)' ~[uint+`@`who.cal]] + :: + %rights + :- (crip "rights({(scow %p who.cal)})") + ['rights(uint32)' ~[uint+`@`who.cal]] + :: + %get-spawned + :- (crip "getSpawned({(scow %p who.cal)})") + ['getSpawned(uint32)' ~[uint+`@`who.cal]] + :: + %dns-domains + :- (crip "dnsDomains({(scow %ud ind.cal)})") + ['dnsDomains(uint256)' ~[uint+ind.cal]] + == + -- +-- diff --git a/pkg/base-dev/lib/azimuthio.hoon b/pkg/base-dev/lib/azimuthio.hoon new file mode 100644 index 0000000000..979c347049 --- /dev/null +++ b/pkg/base-dev/lib/azimuthio.hoon @@ -0,0 +1,146 @@ +/- rpc=json-rpc +/+ ethereum, azimuth, strandio +=, strand=strand:strandio +=, jael +|% +++ tract azimuth:contracts:azimuth +++ fetch-point + |= [url=@ta who=ship] + =/ m (strand ,point:azimuth) + ^- form:m + =/ =request:rpc:ethereum + :+ %eth-call + =- [from=~ to=tract gas=~ price=~ value=~ data=-] + (encode-call:rpc:ethereum 'points(uint32)' [%uint `@`who]~) + [%label %latest] + ;< jon=json bind:m (request-rpc url `'point' request) + =/ res=cord (so:dejs:format jon) + =/ =point:eth-noun:azimuth + (decode-results:abi:ethereum res point:eth-type:azimuth) + :: + =/ =request:rpc:ethereum + :+ %eth-call + =- [from=~ to=tract gas=~ price=~ value=~ data=-] + (encode-call:rpc:ethereum 'rights(uint32)' [%uint `@`who]~) + [%label %latest] + ;< jon=json bind:m (request-rpc url `'deed' request) + =/ res=cord (so:dejs:format jon) + =/ =deed:eth-noun:azimuth + (decode-results:abi:ethereum res deed:eth-type:azimuth) + :: + (pure:m (point-from-eth:azimuth who point deed)) +:: +++ request-rpc + |= [url=@ta id=(unit @t) req=request:rpc:ethereum] + =/ m (strand ,json) + ^- form:m + %+ (retry json) `10 + =/ m (strand ,(unit json)) + ^- form:m + |^ + =/ =request:http + :* method=%'POST' + url=url + header-list=['Content-Type'^'application/json' ~] + ^= body + %- some %- as-octt:mimes:html + %- en-json:html + (request-to-json:rpc:ethereum id req) + == + ;< ~ bind:m (send-request:strandio request) + ;< rep=(unit client-response:iris) bind:m + take-maybe-response:strandio + ?~ rep + (pure:m ~) + (parse-response u.rep) + :: + ++ parse-response + |= =client-response:iris + =/ m (strand ,(unit json)) + ^- form:m + ?> ?=(%finished -.client-response) + ?~ full-file.client-response + (pure:m ~) + =/ body=@t q.data.u.full-file.client-response + =/ jon=(unit json) (de-json:html body) + ?~ jon + (pure:m ~) + =, dejs-soft:format + =/ array=(unit (list response:rpc)) + ((ar parse-one-response) u.jon) + ?~ array + =/ res=(unit response:rpc) (parse-one-response u.jon) + ?~ res + (strand-fail:strandio %request-rpc-parse-error >id< ~) + ?: ?=(%error -.u.res) + (strand-fail:strandio %request-rpc-error >id< >+.res< ~) + ?. ?=(%result -.u.res) + (strand-fail:strandio %request-rpc-fail >u.res< ~) + (pure:m `res.u.res) + (strand-fail:strandio %request-rpc-batch >%not-implemented< ~) + :: (pure:m `[%batch u.array]) + :: + ++ parse-one-response + |= =json + ^- (unit response:rpc) + =/ res=(unit [@t ^json]) + %. json + =, dejs-soft:format + (ot id+so result+some ~) + ?^ res `[%result u.res] + ~| parse-one-response=json + :+ ~ %error %- need + %. json + =, dejs-soft:format + (ot id+so error+(ot code+no message+so ~) ~) + -- +:: +++ retry + |* result=mold + |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))] + =/ m (strand ,result) + =| try=@ud + |- ^- form:m + =* loop $ + ?: =(crash-after `try) + (strand-fail:strandio %retry-too-many ~) + ;< ~ bind:m (backoff:strandio try ~m1) + ;< res=(unit result) bind:m computation + ?^ res + (pure:m u.res) + loop(try +(try)) +:: +++ get-latest-block + |= url=@ta + =/ m (strand ,block) + ^- form:m + ;< =json bind:m (request-rpc url `'block number' %eth-block-number ~) + (get-block-by-number url (parse-eth-block-number:rpc:ethereum json)) +:: +++ get-block-by-number + |= [url=@ta =number:block] + =/ m (strand ,block) + ^- form:m + |^ + ;< =json bind:m + (request-rpc url `'block by number' %eth-get-block-by-number number |) + =/ =block (parse-block json) + ?. =(number number.id.block) + (strand-fail:strandio %reorg-detected >number< >block< ~) + (pure:m block) + :: + ++ parse-block + |= =json + ^- block + =< [[&1 &2] |2] + ^- [@ @ @] + ~| json + %. json + =, dejs:format + %- ot + :~ hash+parse-hex-result:rpc:ethereum + number+parse-hex-result:rpc:ethereum + 'parentHash'^parse-hex-result:rpc:ethereum + == + -- +-- diff --git a/pkg/base-dev/lib/bip/b158.hoon b/pkg/base-dev/lib/bip/b158.hoon new file mode 100644 index 0000000000..eb0eb7f0f8 --- /dev/null +++ b/pkg/base-dev/lib/bip/b158.hoon @@ -0,0 +1,249 @@ +/- bc=bitcoin +/+ bcu=bitcoin-utils +|% +++ params + |% + ++ p 19 + ++ m 784.931 + -- +:: +++ siphash + |= [k=byts m=byts] + ^- byts + |^ + ?> =(wid.k 16) + ?> (lte (met 3 dat.k) wid.k) + ?> (lte (met 3 dat.m) wid.m) + =. k (flim:sha k) + =. m (flim:sha m) + (flim:sha (fin (comp m (init dat.k)))) + :: Initialise internal state + :: + ++ init + |= k=@ + ^- [@ @ @ @] + =/ k0=@ (end [6 1] k) + =/ k1=@ (cut 6 [1 1] k) + :^ (mix k0 0x736f.6d65.7073.6575) + (mix k1 0x646f.7261.6e64.6f6d) + (mix k0 0x6c79.6765.6e65.7261) + (mix k1 0x7465.6462.7974.6573) + :: + :: Compression rounds + ++ comp + |= [m=byts v=[v0=@ v1=@ v2=@ v3=@]] + ^- [@ @ @ @] + =/ len=@ud (div wid.m 8) + =/ last=@ (lsh [3 7] (mod wid.m 256)) + =| i=@ud + =| w=@ + |- + =. w (cut 6 [i 1] dat.m) + ?: =(i len) + =. v3.v (mix v3.v (mix last w)) + =. v (rnd (rnd v)) + =. v0.v (mix v0.v (mix last w)) + v + %= $ + v =. v3.v (mix v3.v w) + =. v (rnd (rnd v)) + =. v0.v (mix v0.v w) + v + i (add i 1) + == + :: + :: Finalisation rounds + ++ fin + |= v=[v0=@ v1=@ v2=@ v3=@] + ^- byts + =. v2.v (mix v2.v 0xff) + =. v (rnd (rnd (rnd (rnd v)))) + :- 8 + :(mix v0.v v1.v v2.v v3.v) + :: + :: Sipround + ++ rnd + |= [v0=@ v1=@ v2=@ v3=@] + ^- [@ @ @ @] + =. v0 (~(sum fe 6) v0 v1) + =. v2 (~(sum fe 6) v2 v3) + =. v1 (~(rol fe 6) 0 13 v1) + =. v3 (~(rol fe 6) 0 16 v3) + =. v1 (mix v1 v0) + =. v3 (mix v3 v2) + =. v0 (~(rol fe 6) 0 32 v0) + =. v2 (~(sum fe 6) v2 v1) + =. v0 (~(sum fe 6) v0 v3) + =. v1 (~(rol fe 6) 0 17 v1) + =. v3 (~(rol fe 6) 0 21 v3) + =. v1 (mix v1 v2) + =. v3 (mix v3 v0) + =. v2 (~(rol fe 6) 0 32 v2) + [v0 v1 v2 v3] + -- +:: +str: bit streams +:: read is from the front +:: write appends to the back +:: +++ str + |% + ++ read-bit + |= s=bits:bc + ^- [bit=@ub rest=bits:bc] + ?> (gth wid.s 0) + :* ?:((gth wid.s (met 0 dat.s)) 0b0 0b1) + [(dec wid.s) (end [0 (dec wid.s)] dat.s)] + == + :: + ++ read-bits + |= [n=@ s=bits:bc] + ^- [bits:bc rest=bits:bc] + =| bs=bits:bc + |- + ?: =(n 0) [bs s] + =^ b s (read-bit s) + $(n (dec n), bs (write-bits bs [1 b])) + :: + ++ write-bits + |= [s1=bits:bc s2=bits:bc] + ^- bits:bc + [(add wid.s1 wid.s2) (can 0 ~[s2 s1])] + -- +:: +gol: Golomb-Rice encoding/decoding +:: +++ gol + |% + :: +en: encode x and append to end of s + :: - s: bits stream + :: - x: number to add to the stream + :: - p: golomb-rice p param + :: + ++ en + |= [s=bits:bc x=@ p=@] + ^- bits:bc + =+ q=(rsh [0 p] x) + =+ unary=[+(q) (lsh [0 1] (dec (bex q)))] + =+ r=[p (end [0 p] x)] + %+ write-bits:str s + (write-bits:str unary r) + :: + ++ de + |= [s=bits:bc p=@] + ^- [delta=@ rest=bits:bc] + |^ ?> (gth wid.s 0) + =^ q s (get-q s) + =^ r s (read-bits:str p s) + [(add dat.r (lsh [0 p] q)) s] + :: + ++ get-q + |= s=bits:bc + =| q=@ + =^ first-bit s (read-bit:str s) + |- + ?: =(0 first-bit) [q s] + =^ b s (read-bit:str s) + $(first-bit b, q +(q)) + -- + -- +:: +hsh +:: +++ hsh + |% + :: +to-range + :: - item: scriptpubkey to hash + :: - f: N*M + :: - k: key for siphash (end of blockhash, reversed) + :: + ++ to-range + |= [item=byts f=@ k=byts] + ^- @ + (rsh [0 64] (mul f (swp 3 dat:(siphash k item)))) + :: +set-construct: return sorted hashes of scriptpubkeys + :: + ++ set-construct + |= [items=(list byts) k=byts f=@] + ^- (list @) + %+ sort + %+ turn items + |= item=byts + (to-range item f k) + lth + -- +:: +++ parse-filter + |= filter=hexb:bc + ^- [n=@ux gcs-set=bits:bc] + =/ n n:(de:csiz:bcu filter) + =/ lead=@ ?:(=(1 wid.n) 1 +(wid.n)) + :- dat.n + [(mul 8 (sub wid.filter lead)) `@ub`dat:(drop:byt:bcu lead filter)] +:: +to-key: blockhash (little endian) to key for siphash +:: +++ to-key + |= blockhash=tape + ^- byts + %+ take:byt:bcu 16 + %- flip:byt:bcu + (from-cord:hxb:bcu (crip blockhash)) +:: +match: whether block filter matches *any* target scriptpubkeys +:: - filter: full block filter, with leading N +:: - k: key for siphash (end of blockhash, reversed) +:: - targets: scriptpubkeys to match +:: +++ match + |= [filter=hexb:bc k=byts targets=(list byts)] + ^- ? + =/ [p=@ m=@] [p:params m:params] + =/ [n=@ux gcs-set=bits:bc] (parse-filter filter) + =+ target-hs=(set-construct:hsh targets k (mul n m)) + =+ last-val=0 + |- + ?~ target-hs %.n + ?: =(last-val i.target-hs) + %.y + ?: (gth last-val i.target-hs) + $(target-hs t.target-hs) + :: last-val is less than target: check next val in GCS, if any + :: + ?: (lth wid.gcs-set p) %.n + =^ delta gcs-set + (de:gol gcs-set p) + $(last-val (add delta last-val)) +:: +all-match: returns all target byts that match +:: - filter: full block filter, with leading N +:: - targets: scriptpubkeys to match +:: +++ all-match + |= [filter=hexb:bc blockhash=hexb:bc targets=(list [address:bc byts])] + ^- (set [address:bc hexb:bc]) + =/ k (to-key (trip (to-cord:hxb:bcu blockhash))) + %- ~(gas in *(set [address:bc hexb:bc])) + =/ [p=@ m=@] [p:params m:params] + =/ [n=@ux gcs-set=bits:bc] (parse-filter filter) + =/ target-map=(map @ [address:bc hexb:bc]) + %- ~(gas by *(map @ [address:bc hexb:bc])) + %+ turn targets + |= [a=address:bc t=hexb:bc] + [(to-range:hsh t (mul n m) k) a t] + =+ target-hs=(sort ~(tap in ~(key by target-map)) lth) + =+ last-val=0 + =| matches=(list @) + |- + ?~ target-hs + (murn matches ~(get by target-map)) + ?: =(last-val i.target-hs) + %= $ + target-hs t.target-hs + matches [last-val matches] + == + ?: (gth last-val i.target-hs) + $(target-hs t.target-hs) + :: last-val is less than target: get next val in GCS, if any + :: + ?: (lth wid.gcs-set p) + (murn matches ~(get by target-map)) + =^ delta gcs-set + (de:gol gcs-set p) + $(last-val (add delta last-val)) +:: +-- diff --git a/pkg/base-dev/lib/bip/b173.hoon b/pkg/base-dev/lib/bip/b173.hoon new file mode 100644 index 0000000000..e2c46db1ac --- /dev/null +++ b/pkg/base-dev/lib/bip/b173.hoon @@ -0,0 +1,144 @@ +:: BIP173: Bech32 Addresses +:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +:: +:: Heavily copies: +:: https://github.com/bitcoinjs/bech32/blob/master/index.js +:: +/- sur=bitcoin +/+ bcu=bitcoin-utils +=, sur +=, bcu +|% +++ prefixes + ^- (map network tape) + (my [[%main "bc"] [%testnet "tb"] ~]) +++ charset "qpzry9x8gf2tvdw0s3jn54khce6mua7l" ++$ raw-decoded [hrp=tape data=(list @) checksum=(list @)] +:: below is a port of: https://github.com/bitcoinjs/bech32/blob/master/index.js +:: +++ polymod + |= values=(list @) + |^ ^- @ + =/ gen=(list @ux) + ~[0x3b6a.57b2 0x2650.8e6d 0x1ea1.19fa 0x3d42.33dd 0x2a14.62b3] + =/ chk=@ 1 + |- ?~ values chk + =/ top (rsh [0 25] chk) + =. chk + (mix i.values (lsh [0 5] (dis chk 0x1ff.ffff))) + $(values t.values, chk (update-chk chk top gen)) +:: + ++ update-chk + |= [chk=@ top=@ gen=(list @ux)] + =/ is (gulf 0 4) + |- ?~ is chk + ?: =(1 (dis 1 (rsh [0 i.is] top))) + $(is t.is, chk (mix chk (snag i.is gen))) + $(is t.is) + -- +:: +++ expand-hrp + |= hrp=tape + ^- (list @) + =/ front (turn hrp |=(p=@tD (rsh [0 5] p))) + =/ back (turn hrp |=(p=@tD (dis 31 p))) + (zing ~[front ~[0] back]) +:: +++ verify-checksum + |= [hrp=tape data-and-checksum=(list @)] + ^- ? + %- |=(a=@ =(1 a)) + %- polymod + (weld (expand-hrp hrp) data-and-checksum) +:: +++ checksum + |= [hrp=tape data=(list @)] + ^- (list @) + :: xor 1 with the polymod + :: + =/ pmod=@ + %+ mix 1 + %- polymod + (zing ~[(expand-hrp hrp) data (reap 6 0)]) + %+ turn (gulf 0 5) + |=(i=@ (dis 31 (rsh [0 (mul 5 (sub 5 i))] pmod))) +:: +++ charset-to-value + |= c=@tD + ^- (unit @) + (find ~[c] charset) +++ value-to-charset + |= value=@ + ^- (unit @tD) + ?: (gth value 31) ~ + `(snag value charset) +:: +++ is-valid + |= [bech=tape last-1-pos=@] ^- ? + ?& ?|(=((cass bech) bech) =((cuss bech) bech)) :: to upper or to lower is same as bech + (gte last-1-pos 1) + (lte (add last-1-pos 7) (lent bech)) + (lte (lent bech) 90) + (levy bech |=(c=@tD (gte c 33))) + (levy bech |=(c=@tD (lte c 126))) + == +:: data should be 5bit words +:: +++ encode-raw + |= [hrp=tape data=(list @)] + ^- cord + =/ combined=(list @) + (weld data (checksum hrp data)) + %- crip + (zing ~[hrp "1" (tape (murn combined value-to-charset))]) +++ decode-raw + |= body=cord + ^- (unit raw-decoded) + =/ bech (cass (trip body)) :: to lowercase + =/ pos (flop (fand "1" bech)) + ?~ pos ~ + =/ last-1=@ i.pos + ?. (is-valid bech last-1) :: check bech32 validity (not segwit validity or checksum) + ~ + =/ hrp (scag last-1 bech) + =/ encoded-data-and-checksum=(list @) + (slag +(last-1) bech) + =/ data-and-checksum=(list @) + %+ murn encoded-data-and-checksum + charset-to-value + ?. =((lent encoded-data-and-checksum) (lent data-and-checksum)) :: ensure all were in CHARSET + ~ + ?. (verify-checksum hrp data-and-checksum) + ~ + =/ checksum-pos (sub (lent data-and-checksum) 6) + `[hrp (scag checksum-pos data-and-checksum) (slag checksum-pos data-and-checksum)] +:: +from-address: BIP173 bech32 address encoding to hex +:: https://github.com/bitcoin/bips/blob/master/bip-0173.mediawiki +:: expects to drop a leading 5-bit 0 (the witness version) +:: +++ from-address + |= body=cord + ^- hexb + ~| "Invalid bech32 address" + =/ d=(unit raw-decoded) (decode-raw body) + ?> ?=(^ d) + =/ bs=bits (from-atoms:bit 5 data.u.d) + =/ byt-len=@ (div (sub wid.bs 5) 8) + ?> =(5^0b0 (take:bit 5 bs)) + ?> ?| =(20 byt-len) + =(32 byt-len) + == + [byt-len `@ux`dat:(take:bit (mul 8 byt-len) (drop:bit 5 bs))] +:: pubkey is the 33 byte ECC compressed public key +:: +++ encode-pubkey + |= [=network pubkey=byts] + ^- (unit cord) + ?. =(33 wid.pubkey) + ~|('pubkey must be a 33 byte ECC compressed public key' !!) + =/ prefix (~(get by prefixes) network) + ?~ prefix ~ + :- ~ + %+ encode-raw u.prefix + [0v0 (to-atoms:bit 5 [160 `@ub`dat:(hash-160 pubkey)])] +-- diff --git a/pkg/base-dev/lib/bip/b174.hoon b/pkg/base-dev/lib/bip/b174.hoon new file mode 100644 index 0000000000..3bae71d929 --- /dev/null +++ b/pkg/base-dev/lib/bip/b174.hoon @@ -0,0 +1,182 @@ +:: BIP174: PSBTs +:: https://github.com/bitcoin/bips/blob/master/bip-0174.mediawiki +:: +/- sur=bitcoin +/+ bcu=bitcoin-utils +=, sur +=, bcu +|% +++ en + |% + ++ globals + |= rawtx=hexb + ^- map:psbt + :~ [[1 0x0] rawtx] + == + :: + ++ input + |= [only-witness=? i=in:psbt] + ^- map:psbt + %+ weld + ?: only-witness ~ + ~[[1^0x0 rawtx.i]] + :~ (witness-tx i) + (hdkey %input hdkey.i) + == + :: + ++ output + |= =out:psbt + ^- map:psbt + ?~ hk.out ~ + :~ (hdkey %output u.hk.out) + == + :: + ++ witness-tx + |= i=in:psbt + ^- keyval:psbt + :- [1 0x1] + %- cat:byt + :~ (flip:byt 8^value.utxo.i) + 1^0x16 + 2^0x14 + (hash-160 pubkey.hdkey.i) + == + :: + ++ hdkey + |= [=target:psbt h=^hdkey] + ^- keyval:psbt + =/ typ=@ux + ?- target + %input 0x6 + %output 0x2 + == + =/ coin-type=hexb + ?- network.h + %main + 1^0x0 + %testnet + 1^0x1 + == + :- (cat:byt ~[1^typ pubkey.h]) + %- cat:byt + :~ fprint.h + 1^`@ux`bipt.h 3^0x80 + coin-type 3^0x80 + 4^0x80 + 1^`@ux`chyg.h 3^0x0 + (flip:byt 4^idx.h) + == + :: + ++ keyval-byts + |= kv=keyval:psbt + ^- hexb + %- cat:byt + :~ 1^wid.key.kv + key.kv + 1^wid.val.kv + val.kv + == + :: + ++ map-byts + |= m=map:psbt + ^- (unit hexb) + ?~ m ~ + :- ~ + %- cat:byt + (turn m keyval-byts) + -- + ++ base64 + |= b=hexb + ^- base64:psbt + %- en:base64:mimes:html + (flip:byt b) +:: +encode: make base64 cord of PSBT +:: - only-witness: don't include non-witness UTXO +:: +++ encode + |= $: only-witness=? + rawtx=hexb + txid=hexb + inputs=(list in:psbt) + outputs=(list out:psbt) + == + ^- base64:psbt + =/ sep=(unit hexb) `1^0x0 + =/ final=(list (unit hexb)) + %+ join sep + %+ turn + %- zing + :~ ~[(globals:en rawtx)] + (turn inputs (cury input:en only-witness)) + (turn outputs output:en) + == + map-byts:en + %- base64:en + ^- byts + %- cat:byt + %+ weld ~[[5 0x70.7362.74ff]] + (murn (snoc final sep) same) +:: +++ parse + |= psbt-base64=cord + ^- (list map:psbt) + =/ todo=hexb + (drop:byt 5 (to-byts psbt-base64)) + =| acc=(list map:psbt) + =| m=map:psbt + |- + ?: =(wid.todo 0) + (snoc acc m) + :: 0x0: map separator + :: + ?: =(1^0x0 (take:byt 1 todo)) + $(acc (snoc acc m), m *map:psbt, todo (drop:byt 1 todo)) + =^ kv todo (next-keyval todo) + $(m (snoc m kv)) +:: +get-txid: extract txid from a valid PSBT +:: +++ get-txid + |= psbt-base64=cord + ^- hexb + =/ tx=hexb + %- raw-tx + %+ drop:byt 5 + (to-byts psbt-base64) + %- flip:byt + (dsha256 tx) +:: +raw-tx: extract hex transaction +:: looks for key 0x0 in global map +:: crashes if tx not in hex +:: +++ raw-tx + |= b=hexb + ^- hexb + |- + ?: =(wid.b 0) !! + ?: =(1^0x0 (take:byt 1 b)) !! + =/ nk (next-keyval b) + ?: =(0x0 dat.key.kv.nk) + val.kv.nk + $(b rest.nk) +:: +next-keyval: returns next key-val in a PSBT map +:: input first byte must be a map key length +:: +++ next-keyval + |= b=hexb + ^- [kv=keyval:psbt rest=hexb] + =/ klen dat:(take:byt 1 b) + =/ k (take:byt klen (drop:byt 1 b)) + =/ vlen dat:(take:byt 1 (drop:byt (add 1 klen) b)) + =/ v (take:byt vlen (drop:byt (add 2 klen) b)) + ?> ?&((gth wid.k 0) (gth wid.v 0)) + :- [k v] + (drop:byt ;:(add 2 klen vlen) b) +:: +++ to-byts + |= psbt-base64=cord + ^- hexb + ~| "Invalid PSBT" + =+ p=(de:base64:mimes:html psbt-base64) + ?~ p !! + (flip:byt u.p) +-- diff --git a/pkg/base-dev/lib/bip32.hoon b/pkg/base-dev/lib/bip32.hoon new file mode 100644 index 0000000000..02187ad877 --- /dev/null +++ b/pkg/base-dev/lib/bip32.hoon @@ -0,0 +1,243 @@ +:: bip32 implementation in hoon +:: +:: to use, call one of the core initialization arms. +:: using the produced core, derive as needed and take out the data you want. +:: +::NOTE tested to be correct against +:: https://en.bitcoin.it/wiki/BIP_0032_TestVectors +:: +=, hmac:crypto +=, secp:crypto +=+ ecc=secp256k1 +:: +:: prv: private key +:: pub: public key +:: cad: chain code +:: dep: depth in chain +:: ind: index at depth +:: pif: parent fingerprint (4 bytes) +|_ [prv=@ pub=point.ecc cad=@ dep=@ud ind=@ud pif=@] +:: ++$ keyc [key=@ cai=@] :: prv/pub key + chain code +:: +:: elliptic curve operations and values +:: +++ point priv-to-pub.ecc +:: +++ ser-p compress-point.ecc +:: +++ n n:t.ecc +:: +:: core initialization +:: +++ from-seed + |= byts + ^+ +> + =+ der=(hmac-sha512l [12 'dees nioctiB'] [wid dat]) + =+ pri=(cut 3 [32 32] der) + +>.$(prv pri, pub (point pri), cad (cut 3 [0 32] der)) +:: +++ from-private + |= keyc + +>(prv key, pub (point key), cad cai) +:: +++ from-public + |= keyc + +>(pub (decompress-point.ecc key), cad cai) +:: +++ from-public-point + |= [pon=point.ecc cai=@] + +>(pub pon, cad cai) +:: +++ from-extended + |= t=tape + =+ x=(de-base58check 4 t) + => |% + ++ take + |= b=@ud + ^- [v=@ x=@] + :- (end [3 b] x) + (rsh [3 b] x) + -- + =^ k x (take 33) + =^ c x (take 32) + =^ i x (take 4) + =^ p x (take 4) + =^ d x (take 1) + ?> =(0 x) :: sanity check + %. [d i p] + =< set-metadata + =+ v=(swag [1 3] t) + ?: =("prv" v) (from-private k c) + ?: =("pub" v) (from-public k c) + !! +:: +++ set-metadata + |= [d=@ud i=@ud p=@] + +>(dep d, ind i, pif p) +:: +:: derivation +:: +++ derivation-path + ;~ pfix + ;~(pose (jest 'm/') (easy ~)) + %+ most fas + ;~ pose + %+ cook + |=(i=@ (add i (bex 31))) + ;~(sfix dem soq) + :: + dem + == == +:: +++ derive-path + |= t=tape + %- derive-sequence + (scan t derivation-path) +:: +++ derive-sequence + |= j=(list @u) + ?~ j +> + =. +> (derive i.j) + $(j t.j) +:: +++ derive + ?: =(0 prv) + derive-public + derive-private +:: +++ derive-private + |= i=@u + ^+ +> + :: we must have a private key to derive the next one + ?: =(0 prv) + ~| %know-no-private-key + !! + :: derive child at i + =/ [left=@ right=@] + =- [(cut 3 [32 32] -) (cut 3 [0 32] -)] + %+ hmac-sha512l [32 cad] + :- 37 + ?: (gte i (bex 31)) + :: hardened child + (can 3 ~[4^i 32^prv 1^0]) + :: normal child + (can 3 ~[4^i 33^(ser-p (point prv))]) + =+ key=(mod (add left prv) n) + :: rare exception, invalid key, go to the next one + ?: |(=(0 key) (gte left n)) $(i +(i)) + %_ +>.$ + prv key + pub (point key) + cad right + dep +(dep) + ind i + pif fingerprint + == +:: +++ derive-public + |= i=@u + ^+ +> + :: public keys can't be hardened + ?: (gte i (bex 31)) + ~| %cant-derive-hardened-public-key + !! + :: derive child at i + =/ [left=@ right=@] + =- [(cut 3 [32 32] -) (cut 3 [0 32] -)] + %+ hmac-sha512l [32 cad] + 37^(can 3 ~[4^i 33^(ser-p pub)]) + :: rare exception, invalid key, go to the next one + ?: (gte left n) $(i +(i)) ::TODO or child key is "point at infinity" + %_ +>.$ + pub (add-points.ecc (point left) pub) + cad right + dep +(dep) + ind i + pif fingerprint + == +:: +:: rendering +:: +++ private-key ?.(=(0 prv) prv ~|(%know-no-private-key !!)) +++ public-key (ser-p pub) +++ chain-code cad +++ private-chain [private-key cad] +++ public-chain [public-key cad] +:: +++ identity (hash160 public-key) +++ fingerprint (cut 3 [16 4] identity) +:: +++ address + |= network=?(%main %regtest %testnet) + ^- @uc + :: removes checksum + :: + %+ rsh [3 4] + %+ en-base58check + [4 (version-bytes network %pub %.n)] + [20 identity] +:: +++ prv-extended + |= network=?(%main %regtest %testnet) + %+ en-b58c-bip32 (version-bytes network %prv %.y) + (build-extended private-key) +:: +++ pub-extended + |= network=?(%main %regtest %testnet) + %+ en-b58c-bip32 (version-bytes network %pub %.y) + (build-extended public-key) +:: +++ build-extended + |= key=@ + %+ can 3 + :~ 33^key + 32^cad + 4^ind + 4^pif + 1^dep + == +:: +++ en-b58c-bip32 + |= [v=@ k=@] + %- en-base58:mimes:html + (en-base58check [4 v] [74 k]) +:: +:: base58check +:: +++ en-base58check + :: v: version bytes + :: d: data + |= [v=byts d=byts] + =+ p=[(add wid.v wid.d) (can 3 ~[d v])] + =- (can 3 ~[4^- p]) + %+ rsh [3 28] + (sha-256l:sha 32 (sha-256l:sha p)) +:: +++ de-base58check + :: vw: amount of version bytes + |= [vw=@u t=tape] + =+ x=(de-base58:mimes:html t) + =+ hash=(sha-256l:sha 32 (sha-256:sha (rsh [3 4] x))) + ?> =((end [3 4] x) (rsh [3 28] hash)) + (cut 3 [vw (sub (met 3 x) (add 4 vw))] x) +:: +++ hash160 + |= d=@ + (ripemd-160:ripemd:crypto 32 (sha-256:sha d)) +:: +++ version-bytes + |= [network=?(%main %regtest %testnet) type=?(%pub %prv) bip32=?] + ^- @ux + |^ + ?- type + %pub ?:(bip32 xpub-key pay-to-pubkey) + %prv ?:(bip32 xprv-key private-key) + == + :: + ++ pay-to-pubkey ?:(=(network %main) 0x0 0x6f) + ++ private-key ?:(=(network %main) 0x80 0xef) + ++ xpub-key ?:(=(network %main) 0x488.b21e 0x435.87cf) + ++ xprv-key ?:(=(network %main) 0x488.ade4 0x435.8394) + -- +-- diff --git a/pkg/base-dev/lib/bip39.hoon b/pkg/base-dev/lib/bip39.hoon new file mode 100644 index 0000000000..cc33fe479f --- /dev/null +++ b/pkg/base-dev/lib/bip39.hoon @@ -0,0 +1,46 @@ +:: bip39 implementation in hoon +:: +/+ bip39-english +:: +|% +++ from-entropy + |= byts + ^- tape + =. wid (mul wid 8) + ~| [%unsupported-entropy-bit-length wid] + ?> &((gte wid 128) (lte wid 256)) + :: + =+ cs=(div wid 32) + =/ check=@ + %+ rsh [0 (sub 256 cs)] + (sha-256l:sha (div wid 8) dat) + =/ bits=byts + :- (add wid cs) + %+ can 0 + :~ cs^check + wid^dat + == + :: + =/ pieces + |- ^- (list @) + :- (end [0 11] dat.bits) + ?: (lte wid.bits 11) ~ + $(bits [(sub wid.bits 11) (rsh [0 11] dat.bits)]) + :: + =/ words=(list tape) + %+ turn pieces + |= ind=@ud + (snag ind `(list tape)`bip39-english) + :: + %+ roll (flop words) + |= [nex=tape all=tape] + ?~ all nex + :(weld all " " nex) +:: +::NOTE always produces a 512-bit result +++ to-seed + |= [mnem=tape pass=tape] + ^- @ + %- hmac-sha512t:pbkdf:crypto + [(crip mnem) (crip (weld "mnemonic" pass)) 2.048 64] +-- diff --git a/pkg/base-dev/lib/bip39/english.hoon b/pkg/base-dev/lib/bip39/english.hoon new file mode 100644 index 0000000000..60de893177 --- /dev/null +++ b/pkg/base-dev/lib/bip39/english.hoon @@ -0,0 +1,2052 @@ +:: english wordlist for use in bip39 +^- (list tape) +:~ + "abandon" + "ability" + "able" + "about" + "above" + "absent" + "absorb" + "abstract" + "absurd" + "abuse" + "access" + "accident" + "account" + "accuse" + "achieve" + "acid" + "acoustic" + "acquire" + "across" + "act" + "action" + "actor" + "actress" + "actual" + "adapt" + "add" + "addict" + "address" + "adjust" + "admit" + "adult" + "advance" + "advice" + "aerobic" + "affair" + "afford" + "afraid" + "again" + "age" + "agent" + "agree" + "ahead" + "aim" + "air" + "airport" + "aisle" + "alarm" + "album" + "alcohol" + "alert" + "alien" + "all" + "alley" + "allow" + "almost" + "alone" + "alpha" + "already" + "also" + "alter" + "always" + "amateur" + "amazing" + "among" + "amount" + "amused" + "analyst" + "anchor" + "ancient" + "anger" + "angle" + "angry" + "animal" + "ankle" + "announce" + "annual" + "another" + "answer" + "antenna" + "antique" + "anxiety" + "any" + "apart" + "apology" + "appear" + "apple" + "approve" + "april" + "arch" + "arctic" + "area" + "arena" + "argue" + "arm" + "armed" + "armor" + "army" + "around" + "arrange" + "arrest" + "arrive" + "arrow" + "art" + "artefact" + "artist" + "artwork" + "ask" + "aspect" + "assault" + "asset" + "assist" + "assume" + "asthma" + "athlete" + "atom" + "attack" + "attend" + "attitude" + "attract" + "auction" + "audit" + "august" + "aunt" + "author" + "auto" + "autumn" + "average" + "avocado" + "avoid" + "awake" + "aware" + "away" + "awesome" + "awful" + "awkward" + "axis" + "baby" + "bachelor" + "bacon" + "badge" + "bag" + "balance" + "balcony" + "ball" + "bamboo" + "banana" + "banner" + "bar" + "barely" + "bargain" + "barrel" + "base" + "basic" + "basket" + "battle" + "beach" + "bean" + "beauty" + "because" + "become" + "beef" + "before" + "begin" + "behave" + "behind" + "believe" + "below" + "belt" + "bench" + "benefit" + "best" + "betray" + "better" + "between" + "beyond" + "bicycle" + "bid" + "bike" + "bind" + "biology" + "bird" + "birth" + "bitter" + "black" + "blade" + "blame" + "blanket" + "blast" + "bleak" + "bless" + "blind" + "blood" + "blossom" + "blouse" + "blue" + "blur" + "blush" + "board" + "boat" + "body" + "boil" + "bomb" + "bone" + "bonus" + "book" + "boost" + "border" + "boring" + "borrow" + "boss" + "bottom" + "bounce" + "box" + "boy" + "bracket" + "brain" + "brand" + "brass" + "brave" + "bread" + "breeze" + "brick" + "bridge" + "brief" + "bright" + "bring" + "brisk" + "broccoli" + "broken" + "bronze" + "broom" + "brother" + "brown" + "brush" + "bubble" + "buddy" + "budget" + "buffalo" + "build" + "bulb" + "bulk" + "bullet" + "bundle" + "bunker" + "burden" + "burger" + "burst" + "bus" + "business" + "busy" + "butter" + "buyer" + "buzz" + "cabbage" + "cabin" + "cable" + "cactus" + "cage" + "cake" + "call" + "calm" + "camera" + "camp" + "can" + "canal" + "cancel" + "candy" + "cannon" + "canoe" + "canvas" + "canyon" + "capable" + "capital" + "captain" + "car" + "carbon" + "card" + "cargo" + "carpet" + "carry" + "cart" + "case" + "cash" + "casino" + "castle" + "casual" + "cat" + "catalog" + "catch" + "category" + "cattle" + "caught" + "cause" + "caution" + "cave" + "ceiling" + "celery" + "cement" + "census" + "century" + "cereal" + "certain" + "chair" + "chalk" + "champion" + "change" + "chaos" + "chapter" + "charge" + "chase" + "chat" + "cheap" + "check" + "cheese" + "chef" + "cherry" + "chest" + "chicken" + "chief" + "child" + "chimney" + "choice" + "choose" + "chronic" + "chuckle" + "chunk" + "churn" + "cigar" + "cinnamon" + "circle" + "citizen" + "city" + "civil" + "claim" + "clap" + "clarify" + "claw" + "clay" + "clean" + "clerk" + "clever" + "click" + "client" + "cliff" + "climb" + "clinic" + "clip" + "clock" + "clog" + "close" + "cloth" + "cloud" + "clown" + "club" + "clump" + "cluster" + "clutch" + "coach" + "coast" + "coconut" + "code" + "coffee" + "coil" + "coin" + "collect" + "color" + "column" + "combine" + "come" + "comfort" + "comic" + "common" + "company" + "concert" + "conduct" + "confirm" + "congress" + "connect" + "consider" + "control" + "convince" + "cook" + "cool" + "copper" + "copy" + "coral" + "core" + "corn" + "correct" + "cost" + "cotton" + "couch" + "country" + "couple" + "course" + "cousin" + "cover" + "coyote" + "crack" + "cradle" + "craft" + "cram" + "crane" + "crash" + "crater" + "crawl" + "crazy" + "cream" + "credit" + "creek" + "crew" + "cricket" + "crime" + "crisp" + "critic" + "crop" + "cross" + "crouch" + "crowd" + "crucial" + "cruel" + "cruise" + "crumble" + "crunch" + "crush" + "cry" + "crystal" + "cube" + "culture" + "cup" + "cupboard" + "curious" + "current" + "curtain" + "curve" + "cushion" + "custom" + "cute" + "cycle" + "dad" + "damage" + "damp" + "dance" + "danger" + "daring" + "dash" + "daughter" + "dawn" + "day" + "deal" + "debate" + "debris" + "decade" + "december" + "decide" + "decline" + "decorate" + "decrease" + "deer" + "defense" + "define" + "defy" + "degree" + "delay" + "deliver" + "demand" + "demise" + "denial" + "dentist" + "deny" + "depart" + "depend" + "deposit" + "depth" + "deputy" + "derive" + "describe" + "desert" + "design" + "desk" + "despair" + "destroy" + "detail" + "detect" + "develop" + "device" + "devote" + "diagram" + "dial" + "diamond" + "diary" + "dice" + "diesel" + "diet" + "differ" + "digital" + "dignity" + "dilemma" + "dinner" + "dinosaur" + "direct" + "dirt" + "disagree" + "discover" + "disease" + "dish" + "dismiss" + "disorder" + "display" + "distance" + "divert" + "divide" + "divorce" + "dizzy" + "doctor" + "document" + "dog" + "doll" + "dolphin" + "domain" + "donate" + "donkey" + "donor" + "door" + "dose" + "double" + "dove" + "draft" + "dragon" + "drama" + "drastic" + "draw" + "dream" + "dress" + "drift" + "drill" + "drink" + "drip" + "drive" + "drop" + "drum" + "dry" + "duck" + "dumb" + "dune" + "during" + "dust" + "dutch" + "duty" + "dwarf" + "dynamic" + "eager" + "eagle" + "early" + "earn" + "earth" + "easily" + "east" + "easy" + "echo" + "ecology" + "economy" + "edge" + "edit" + "educate" + "effort" + "egg" + "eight" + "either" + "elbow" + "elder" + "electric" + "elegant" + "element" + "elephant" + "elevator" + "elite" + "else" + "embark" + "embody" + "embrace" + "emerge" + "emotion" + "employ" + "empower" + "empty" + "enable" + "enact" + "end" + "endless" + "endorse" + "enemy" + "energy" + "enforce" + "engage" + "engine" + "enhance" + "enjoy" + "enlist" + "enough" + "enrich" + "enroll" + "ensure" + "enter" + "entire" + "entry" + "envelope" + "episode" + "equal" + "equip" + "era" + "erase" + "erode" + "erosion" + "error" + "erupt" + "escape" + "essay" + "essence" + "estate" + "eternal" + "ethics" + "evidence" + "evil" + "evoke" + "evolve" + "exact" + "example" + "excess" + "exchange" + "excite" + "exclude" + "excuse" + "execute" + "exercise" + "exhaust" + "exhibit" + "exile" + "exist" + "exit" + "exotic" + "expand" + "expect" + "expire" + "explain" + "expose" + "express" + "extend" + "extra" + "eye" + "eyebrow" + "fabric" + "face" + "faculty" + "fade" + "faint" + "faith" + "fall" + "false" + "fame" + "family" + "famous" + "fan" + "fancy" + "fantasy" + "farm" + "fashion" + "fat" + "fatal" + "father" + "fatigue" + "fault" + "favorite" + "feature" + "february" + "federal" + "fee" + "feed" + "feel" + "female" + "fence" + "festival" + "fetch" + "fever" + "few" + "fiber" + "fiction" + "field" + "figure" + "file" + "film" + "filter" + "final" + "find" + "fine" + "finger" + "finish" + "fire" + "firm" + "first" + "fiscal" + "fish" + "fit" + "fitness" + "fix" + "flag" + "flame" + "flash" + "flat" + "flavor" + "flee" + "flight" + "flip" + "float" + "flock" + "floor" + "flower" + "fluid" + "flush" + "fly" + "foam" + "focus" + "fog" + "foil" + "fold" + "follow" + "food" + "foot" + "force" + "forest" + "forget" + "fork" + "fortune" + "forum" + "forward" + "fossil" + "foster" + "found" + "fox" + "fragile" + "frame" + "frequent" + "fresh" + "friend" + "fringe" + "frog" + "front" + "frost" + "frown" + "frozen" + "fruit" + "fuel" + "fun" + "funny" + "furnace" + "fury" + "future" + "gadget" + "gain" + "galaxy" + "gallery" + "game" + "gap" + "garage" + "garbage" + "garden" + "garlic" + "garment" + "gas" + "gasp" + "gate" + "gather" + "gauge" + "gaze" + "general" + "genius" + "genre" + "gentle" + "genuine" + "gesture" + "ghost" + "giant" + "gift" + "giggle" + "ginger" + "giraffe" + "girl" + "give" + "glad" + "glance" + "glare" + "glass" + "glide" + "glimpse" + "globe" + "gloom" + "glory" + "glove" + "glow" + "glue" + "goat" + "goddess" + "gold" + "good" + "goose" + "gorilla" + "gospel" + "gossip" + "govern" + "gown" + "grab" + "grace" + "grain" + "grant" + "grape" + "grass" + "gravity" + "great" + "green" + "grid" + "grief" + "grit" + "grocery" + "group" + "grow" + "grunt" + "guard" + "guess" + "guide" + "guilt" + "guitar" + "gun" + "gym" + "habit" + "hair" + "half" + "hammer" + "hamster" + "hand" + "happy" + "harbor" + "hard" + "harsh" + "harvest" + "hat" + "have" + "hawk" + "hazard" + "head" + "health" + "heart" + "heavy" + "hedgehog" + "height" + "hello" + "helmet" + "help" + "hen" + "hero" + "hidden" + "high" + "hill" + "hint" + "hip" + "hire" + "history" + "hobby" + "hockey" + "hold" + "hole" + "holiday" + "hollow" + "home" + "honey" + "hood" + "hope" + "horn" + "horror" + "horse" + "hospital" + "host" + "hotel" + "hour" + "hover" + "hub" + "huge" + "human" + "humble" + "humor" + "hundred" + "hungry" + "hunt" + "hurdle" + "hurry" + "hurt" + "husband" + "hybrid" + "ice" + "icon" + "idea" + "identify" + "idle" + "ignore" + "ill" + "illegal" + "illness" + "image" + "imitate" + "immense" + "immune" + "impact" + "impose" + "improve" + "impulse" + "inch" + "include" + "income" + "increase" + "index" + "indicate" + "indoor" + "industry" + "infant" + "inflict" + "inform" + "inhale" + "inherit" + "initial" + "inject" + "injury" + "inmate" + "inner" + "innocent" + "input" + "inquiry" + "insane" + "insect" + "inside" + "inspire" + "install" + "intact" + "interest" + "into" + "invest" + "invite" + "involve" + "iron" + "island" + "isolate" + "issue" + "item" + "ivory" + "jacket" + "jaguar" + "jar" + "jazz" + "jealous" + "jeans" + "jelly" + "jewel" + "job" + "join" + "joke" + "journey" + "joy" + "judge" + "juice" + "jump" + "jungle" + "junior" + "junk" + "just" + "kangaroo" + "keen" + "keep" + "ketchup" + "key" + "kick" + "kid" + "kidney" + "kind" + "kingdom" + "kiss" + "kit" + "kitchen" + "kite" + "kitten" + "kiwi" + "knee" + "knife" + "knock" + "know" + "lab" + "label" + "labor" + "ladder" + "lady" + "lake" + "lamp" + "language" + "laptop" + "large" + "later" + "latin" + "laugh" + "laundry" + "lava" + "law" + "lawn" + "lawsuit" + "layer" + "lazy" + "leader" + "leaf" + "learn" + "leave" + "lecture" + "left" + "leg" + "legal" + "legend" + "leisure" + "lemon" + "lend" + "length" + "lens" + "leopard" + "lesson" + "letter" + "level" + "liar" + "liberty" + "library" + "license" + "life" + "lift" + "light" + "like" + "limb" + "limit" + "link" + "lion" + "liquid" + "list" + "little" + "live" + "lizard" + "load" + "loan" + "lobster" + "local" + "lock" + "logic" + "lonely" + "long" + "loop" + "lottery" + "loud" + "lounge" + "love" + "loyal" + "lucky" + "luggage" + "lumber" + "lunar" + "lunch" + "luxury" + "lyrics" + "machine" + "mad" + "magic" + "magnet" + "maid" + "mail" + "main" + "major" + "make" + "mammal" + "man" + "manage" + "mandate" + "mango" + "mansion" + "manual" + "maple" + "marble" + "march" + "margin" + "marine" + "market" + "marriage" + "mask" + "mass" + "master" + "match" + "material" + "math" + "matrix" + "matter" + "maximum" + "maze" + "meadow" + "mean" + "measure" + "meat" + "mechanic" + "medal" + "media" + "melody" + "melt" + "member" + "memory" + "mention" + "menu" + "mercy" + "merge" + "merit" + "merry" + "mesh" + "message" + "metal" + "method" + "middle" + "midnight" + "milk" + "million" + "mimic" + "mind" + "minimum" + "minor" + "minute" + "miracle" + "mirror" + "misery" + "miss" + "mistake" + "mix" + "mixed" + "mixture" + "mobile" + "model" + "modify" + "mom" + "moment" + "monitor" + "monkey" + "monster" + "month" + "moon" + "moral" + "more" + "morning" + "mosquito" + "mother" + "motion" + "motor" + "mountain" + "mouse" + "move" + "movie" + "much" + "muffin" + "mule" + "multiply" + "muscle" + "museum" + "mushroom" + "music" + "must" + "mutual" + "myself" + "mystery" + "myth" + "naive" + "name" + "napkin" + "narrow" + "nasty" + "nation" + "nature" + "near" + "neck" + "need" + "negative" + "neglect" + "neither" + "nephew" + "nerve" + "nest" + "net" + "network" + "neutral" + "never" + "news" + "next" + "nice" + "night" + "noble" + "noise" + "nominee" + "noodle" + "normal" + "north" + "nose" + "notable" + "note" + "nothing" + "notice" + "novel" + "now" + "nuclear" + "number" + "nurse" + "nut" + "oak" + "obey" + "object" + "oblige" + "obscure" + "observe" + "obtain" + "obvious" + "occur" + "ocean" + "october" + "odor" + "off" + "offer" + "office" + "often" + "oil" + "okay" + "old" + "olive" + "olympic" + "omit" + "once" + "one" + "onion" + "online" + "only" + "open" + "opera" + "opinion" + "oppose" + "option" + "orange" + "orbit" + "orchard" + "order" + "ordinary" + "organ" + "orient" + "original" + "orphan" + "ostrich" + "other" + "outdoor" + "outer" + "output" + "outside" + "oval" + "oven" + "over" + "own" + "owner" + "oxygen" + "oyster" + "ozone" + "pact" + "paddle" + "page" + "pair" + "palace" + "palm" + "panda" + "panel" + "panic" + "panther" + "paper" + "parade" + "parent" + "park" + "parrot" + "party" + "pass" + "patch" + "path" + "patient" + "patrol" + "pattern" + "pause" + "pave" + "payment" + "peace" + "peanut" + "pear" + "peasant" + "pelican" + "pen" + "penalty" + "pencil" + "people" + "pepper" + "perfect" + "permit" + "person" + "pet" + "phone" + "photo" + "phrase" + "physical" + "piano" + "picnic" + "picture" + "piece" + "pig" + "pigeon" + "pill" + "pilot" + "pink" + "pioneer" + "pipe" + "pistol" + "pitch" + "pizza" + "place" + "planet" + "plastic" + "plate" + "play" + "please" + "pledge" + "pluck" + "plug" + "plunge" + "poem" + "poet" + "point" + "polar" + "pole" + "police" + "pond" + "pony" + "pool" + "popular" + "portion" + "position" + "possible" + "post" + "potato" + "pottery" + "poverty" + "powder" + "power" + "practice" + "praise" + "predict" + "prefer" + "prepare" + "present" + "pretty" + "prevent" + "price" + "pride" + "primary" + "print" + "priority" + "prison" + "private" + "prize" + "problem" + "process" + "produce" + "profit" + "program" + "project" + "promote" + "proof" + "property" + "prosper" + "protect" + "proud" + "provide" + "public" + "pudding" + "pull" + "pulp" + "pulse" + "pumpkin" + "punch" + "pupil" + "puppy" + "purchase" + "purity" + "purpose" + "purse" + "push" + "put" + "puzzle" + "pyramid" + "quality" + "quantum" + "quarter" + "question" + "quick" + "quit" + "quiz" + "quote" + "rabbit" + "raccoon" + "race" + "rack" + "radar" + "radio" + "rail" + "rain" + "raise" + "rally" + "ramp" + "ranch" + "random" + "range" + "rapid" + "rare" + "rate" + "rather" + "raven" + "raw" + "razor" + "ready" + "real" + "reason" + "rebel" + "rebuild" + "recall" + "receive" + "recipe" + "record" + "recycle" + "reduce" + "reflect" + "reform" + "refuse" + "region" + "regret" + "regular" + "reject" + "relax" + "release" + "relief" + "rely" + "remain" + "remember" + "remind" + "remove" + "render" + "renew" + "rent" + "reopen" + "repair" + "repeat" + "replace" + "report" + "require" + "rescue" + "resemble" + "resist" + "resource" + "response" + "result" + "retire" + "retreat" + "return" + "reunion" + "reveal" + "review" + "reward" + "rhythm" + "rib" + "ribbon" + "rice" + "rich" + "ride" + "ridge" + "rifle" + "right" + "rigid" + "ring" + "riot" + "ripple" + "risk" + "ritual" + "rival" + "river" + "road" + "roast" + "robot" + "robust" + "rocket" + "romance" + "roof" + "rookie" + "room" + "rose" + "rotate" + "rough" + "round" + "route" + "royal" + "rubber" + "rude" + "rug" + "rule" + "run" + "runway" + "rural" + "sad" + "saddle" + "sadness" + "safe" + "sail" + "salad" + "salmon" + "salon" + "salt" + "salute" + "same" + "sample" + "sand" + "satisfy" + "satoshi" + "sauce" + "sausage" + "save" + "say" + "scale" + "scan" + "scare" + "scatter" + "scene" + "scheme" + "school" + "science" + "scissors" + "scorpion" + "scout" + "scrap" + "screen" + "script" + "scrub" + "sea" + "search" + "season" + "seat" + "second" + "secret" + "section" + "security" + "seed" + "seek" + "segment" + "select" + "sell" + "seminar" + "senior" + "sense" + "sentence" + "series" + "service" + "session" + "settle" + "setup" + "seven" + "shadow" + "shaft" + "shallow" + "share" + "shed" + "shell" + "sheriff" + "shield" + "shift" + "shine" + "ship" + "shiver" + "shock" + "shoe" + "shoot" + "shop" + "short" + "shoulder" + "shove" + "shrimp" + "shrug" + "shuffle" + "shy" + "sibling" + "sick" + "side" + "siege" + "sight" + "sign" + "silent" + "silk" + "silly" + "silver" + "similar" + "simple" + "since" + "sing" + "siren" + "sister" + "situate" + "six" + "size" + "skate" + "sketch" + "ski" + "skill" + "skin" + "skirt" + "skull" + "slab" + "slam" + "sleep" + "slender" + "slice" + "slide" + "slight" + "slim" + "slogan" + "slot" + "slow" + "slush" + "small" + "smart" + "smile" + "smoke" + "smooth" + "snack" + "snake" + "snap" + "sniff" + "snow" + "soap" + "soccer" + "social" + "sock" + "soda" + "soft" + "solar" + "soldier" + "solid" + "solution" + "solve" + "someone" + "song" + "soon" + "sorry" + "sort" + "soul" + "sound" + "soup" + "source" + "south" + "space" + "spare" + "spatial" + "spawn" + "speak" + "special" + "speed" + "spell" + "spend" + "sphere" + "spice" + "spider" + "spike" + "spin" + "spirit" + "split" + "spoil" + "sponsor" + "spoon" + "sport" + "spot" + "spray" + "spread" + "spring" + "spy" + "square" + "squeeze" + "squirrel" + "stable" + "stadium" + "staff" + "stage" + "stairs" + "stamp" + "stand" + "start" + "state" + "stay" + "steak" + "steel" + "stem" + "step" + "stereo" + "stick" + "still" + "sting" + "stock" + "stomach" + "stone" + "stool" + "story" + "stove" + "strategy" + "street" + "strike" + "strong" + "struggle" + "student" + "stuff" + "stumble" + "style" + "subject" + "submit" + "subway" + "success" + "such" + "sudden" + "suffer" + "sugar" + "suggest" + "suit" + "summer" + "sun" + "sunny" + "sunset" + "super" + "supply" + "supreme" + "sure" + "surface" + "surge" + "surprise" + "surround" + "survey" + "suspect" + "sustain" + "swallow" + "swamp" + "swap" + "swarm" + "swear" + "sweet" + "swift" + "swim" + "swing" + "switch" + "sword" + "symbol" + "symptom" + "syrup" + "system" + "table" + "tackle" + "tag" + "tail" + "talent" + "talk" + "tank" + "tape" + "target" + "task" + "taste" + "tattoo" + "taxi" + "teach" + "team" + "tell" + "ten" + "tenant" + "tennis" + "tent" + "term" + "test" + "text" + "thank" + "that" + "theme" + "then" + "theory" + "there" + "they" + "thing" + "this" + "thought" + "three" + "thrive" + "throw" + "thumb" + "thunder" + "ticket" + "tide" + "tiger" + "tilt" + "timber" + "time" + "tiny" + "tip" + "tired" + "tissue" + "title" + "toast" + "tobacco" + "today" + "toddler" + "toe" + "together" + "toilet" + "token" + "tomato" + "tomorrow" + "tone" + "tongue" + "tonight" + "tool" + "tooth" + "top" + "topic" + "topple" + "torch" + "tornado" + "tortoise" + "toss" + "total" + "tourist" + "toward" + "tower" + "town" + "toy" + "track" + "trade" + "traffic" + "tragic" + "train" + "transfer" + "trap" + "trash" + "travel" + "tray" + "treat" + "tree" + "trend" + "trial" + "tribe" + "trick" + "trigger" + "trim" + "trip" + "trophy" + "trouble" + "truck" + "true" + "truly" + "trumpet" + "trust" + "truth" + "try" + "tube" + "tuition" + "tumble" + "tuna" + "tunnel" + "turkey" + "turn" + "turtle" + "twelve" + "twenty" + "twice" + "twin" + "twist" + "two" + "type" + "typical" + "ugly" + "umbrella" + "unable" + "unaware" + "uncle" + "uncover" + "under" + "undo" + "unfair" + "unfold" + "unhappy" + "uniform" + "unique" + "unit" + "universe" + "unknown" + "unlock" + "until" + "unusual" + "unveil" + "update" + "upgrade" + "uphold" + "upon" + "upper" + "upset" + "urban" + "urge" + "usage" + "use" + "used" + "useful" + "useless" + "usual" + "utility" + "vacant" + "vacuum" + "vague" + "valid" + "valley" + "valve" + "van" + "vanish" + "vapor" + "various" + "vast" + "vault" + "vehicle" + "velvet" + "vendor" + "venture" + "venue" + "verb" + "verify" + "version" + "very" + "vessel" + "veteran" + "viable" + "vibrant" + "vicious" + "victory" + "video" + "view" + "village" + "vintage" + "violin" + "virtual" + "virus" + "visa" + "visit" + "visual" + "vital" + "vivid" + "vocal" + "voice" + "void" + "volcano" + "volume" + "vote" + "voyage" + "wage" + "wagon" + "wait" + "walk" + "wall" + "walnut" + "want" + "warfare" + "warm" + "warrior" + "wash" + "wasp" + "waste" + "water" + "wave" + "way" + "wealth" + "weapon" + "wear" + "weasel" + "weather" + "web" + "wedding" + "weekend" + "weird" + "welcome" + "west" + "wet" + "whale" + "what" + "wheat" + "wheel" + "when" + "where" + "whip" + "whisper" + "wide" + "width" + "wife" + "wild" + "will" + "win" + "window" + "wine" + "wing" + "wink" + "winner" + "winter" + "wire" + "wisdom" + "wise" + "wish" + "witness" + "wolf" + "woman" + "wonder" + "wood" + "wool" + "word" + "work" + "world" + "worry" + "worth" + "wrap" + "wreck" + "wrestle" + "wrist" + "write" + "wrong" + "yard" + "year" + "yellow" + "you" + "young" + "youth" + "zebra" + "zero" + "zone" + "zoo" +== diff --git a/pkg/base-dev/lib/dbug.hoon b/pkg/base-dev/lib/dbug.hoon new file mode 100644 index 0000000000..ce98619e85 --- /dev/null +++ b/pkg/base-dev/lib/dbug.hoon @@ -0,0 +1,155 @@ +:: dbug: agent wrapper for generic debugging tools +:: +:: usage: %-(agent:dbug your-agent) +:: +|% ++$ poke + $% [%bowl ~] + [%state grab=cord] + [%incoming =about] + [%outgoing =about] + == +:: ++$ about + $@ ~ + $% [%ship =ship] + [%path =path] + [%wire =wire] + [%term =term] + == +:: +++ agent + |= =agent:gall + ^- agent:gall + !. + |_ =bowl:gall + +* this . + ag ~(. agent bowl) + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card:agent:gall agent:gall) + ?. ?=(%dbug mark) + =^ cards agent (on-poke:ag mark vase) + [cards this] + =/ dbug + !<(poke vase) + =; =tang + ((%*(. slog pri 1) tang) [~ this]) + ?- -.dbug + %bowl [(sell !>(bowl))]~ + :: + %state + =? grab.dbug =('' grab.dbug) '-' + =; product=^vase + [(sell product)]~ + =/ state=^vase + :: if the underlying app has implemented a /dbug/state scry endpoint, + :: use that vase in place of +on-save's. + :: + =/ result=(each ^vase tang) + (mule |.(q:(need (need (on-peek:ag /x/dbug/state))))) + ?:(?=(%& -.result) p.result on-save:ag) + %+ slap + (slop state !>([bowl=bowl ..zuse])) + (ream grab.dbug) + :: + %incoming + =; =tang + ?^ tang tang + [%leaf "no matching subscriptions"]~ + %+ murn + %+ sort ~(tap by sup.bowl) + |= [[* a=[=ship =path]] [* b=[=ship =path]]] + (aor [path ship]:a [path ship]:b) + |= [=duct [=ship =path]] + ^- (unit tank) + =; relevant=? + ?. relevant ~ + `>[path=path from=ship duct=duct]< + ?: ?=(~ about.dbug) & + ?- -.about.dbug + %ship =(ship ship.about.dbug) + %path ?=(^ (find path.about.dbug path)) + %wire %+ lien duct + |=(=wire ?=(^ (find wire.about.dbug wire))) + %term !! + == + :: + %outgoing + =; =tang + ?^ tang tang + [%leaf "no matching subscriptions"]~ + %+ murn + %+ sort ~(tap by wex.bowl) + |= [[[a=wire *] *] [[b=wire *] *]] + (aor a b) + |= [[=wire =ship =term] [acked=? =path]] + ^- (unit tank) + =; relevant=? + ?. relevant ~ + `>[wire=wire agnt=[ship term] path=path ackd=acked]< + ?: ?=(~ about.dbug) & + ?- -.about.dbug + %ship =(ship ship.about.dbug) + %path ?=(^ (find path.about.dbug path)) + %wire ?=(^ (find wire.about.dbug wire)) + %term =(term term.about.dbug) + == + == + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. ?=([@ %dbug *] path) + (on-peek:ag path) + ?+ path [~ ~] + [%u %dbug ~] ``noun+!>(&) + [%x %dbug %state ~] ``noun+!>(on-save:ag) + [%x %dbug %subscriptions ~] ``noun+!>([wex sup]:bowl) + == + :: + ++ on-init + ^- (quip card:agent:gall agent:gall) + =^ cards agent on-init:ag + [cards this] + :: + ++ on-save on-save:ag + :: + ++ on-load + |= old-state=vase + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-load:ag old-state) + [cards this] + :: + ++ on-watch + |= =path + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-watch:ag path) + [cards this] + :: + ++ on-leave + |= =path + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-leave:ag path) + [cards this] + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-agent:ag wire sign) + [cards this] + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-arvo:ag wire sign-arvo) + [cards this] + :: + ++ on-fail + |= [=term =tang] + ^- (quip card:agent:gall agent:gall) + =^ cards agent (on-fail:ag term tang) + [cards this] + -- +-- diff --git a/pkg/base-dev/lib/default-agent.hoon b/pkg/base-dev/lib/default-agent.hoon new file mode 100644 index 0000000000..319bf95245 --- /dev/null +++ b/pkg/base-dev/lib/default-agent.hoon @@ -0,0 +1,69 @@ +/+ skeleton +|* [agent=* help=*] +?: ?=(%& help) + ~| %default-agent-helpfully-crashing + skeleton +|_ =bowl:gall +++ on-init + `agent +:: +++ on-save + !>(~) +:: +++ on-load + |= old-state=vase + `agent +:: +++ on-poke + |= =cage + ~| "unexpected poke to {} with mark {}" + !! +:: +++ on-watch + |= =path + ~| "unexpected subscription to {} on path {}" + !! +:: +++ on-leave + |= path + `agent +:: +++ on-peek + |= =path + ~| "unexpected scry into {} on path {}" + !! +:: +++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall _agent) + ?- -.sign + %poke-ack + ?~ p.sign + `agent + %- (slog leaf+"poke failed from {} on wire {}" u.p.sign) + `agent + :: + %watch-ack + ?~ p.sign + `agent + =/ =tank leaf+"subscribe failed from {} on wire {}" + %- (slog tank u.p.sign) + `agent + :: + %kick `agent + %fact + ~| "unexpected subscription update to {} on wire {}" + ~| "with mark {}" + !! + == +:: +++ on-arvo + |= [=wire =sign-arvo] + ~| "unexpected system response {<-.sign-arvo>} to {} on wire {}" + !! +:: +++ on-fail + |= [=term =tang] + %- (slog leaf+"error in {}" >term< tang) + `agent +-- diff --git a/pkg/base-dev/lib/ethio.hoon b/pkg/base-dev/lib/ethio.hoon new file mode 100644 index 0000000000..a377290e3a --- /dev/null +++ b/pkg/base-dev/lib/ethio.hoon @@ -0,0 +1,257 @@ +:: ethio: Asynchronous Ethereum input/output functions. +:: +/- rpc=json-rpc +/+ ethereum, strandio +=, ethereum-types +=, jael +:: +=> |% + +$ topics (list ?(@ux (list @ux))) + -- +|% +:: +request-rpc: send rpc request, with retry +:: +++ request-rpc + |= [url=@ta id=(unit @t) req=request:rpc:ethereum] + =/ m (strand:strandio ,json) + ^- form:m + ;< res=(list [id=@t =json]) bind:m + (request-batch-rpc-strict url [id req]~) + ?: ?=([* ~] res) + (pure:m json.i.res) + %+ strand-fail:strandio + %unexpected-multiple-results + [>(lent res)< ~] +:: +request-batch-rpc-strict: send rpc requests, with retry +:: +:: sends a batch request. produces results for all requests in the batch, +:: but only if all of them are successful. +:: +++ request-batch-rpc-strict + |= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])] + |^ %+ (retry:strandio results) + `10 + attempt-request + :: + +$ results (list [id=@t =json]) + :: + ++ attempt-request + =/ m (strand:strandio ,(unit results)) + ^- form:m + ;< responses=(list response:rpc) bind:m + (request-batch-rpc-loose url reqs) + =- ?~ err + (pure:m `res) + (pure:m ~) + %+ roll responses + |= $: rpc=response:rpc + [res=results err=(list [id=@t code=@t message=@t])] + == + ?: ?=(%error -.rpc) + [res [+.rpc err]] + ?. ?=(%result -.rpc) + [res [['' 'ethio-rpc-fail' (crip )] err]] + [[+.rpc res] err] + -- +:: +request-batch-rpc-loose: send rpc requests, with retry +:: +:: sends a batch request. produces results for all requests in the batch, +:: including the ones that are unsuccessful. +:: +++ request-batch-rpc-loose + |= [url=@ta reqs=(list [id=(unit @t) req=request:rpc:ethereum])] + |^ %+ (retry:strandio results) + `10 + attempt-request + :: + +$ result response:rpc + +$ results (list response:rpc) + :: + ++ attempt-request + =/ m (strand:strandio ,(unit results)) + ^- form:m + =/ =request:http + :* method=%'POST' + url=url + header-list=['Content-Type'^'application/json' ~] + :: + ^= body + %- some %- as-octt:mimes:html + %- en-json:html + a+(turn reqs request-to-json:rpc:ethereum) + == + ;< ~ bind:m + (send-request:strandio request) + ;< rep=(unit client-response:iris) bind:m + take-maybe-response:strandio + ?~ rep + (pure:m ~) + (parse-responses u.rep) + :: + ++ parse-responses + |= =client-response:iris + =/ m (strand:strandio ,(unit results)) + ^- form:m + ?> ?=(%finished -.client-response) + ?~ full-file.client-response + (pure:m ~) + =/ body=@t q.data.u.full-file.client-response + =/ jon=(unit json) (de-json:html body) + ?~ jon + (pure:m ~) + =/ array=(unit (list response:rpc)) + ((ar:dejs-soft:format parse-one-response) u.jon) + ?~ array + (strand-fail:strandio %rpc-result-incomplete-batch >u.jon< ~) + (pure:m array) + :: + ++ parse-one-response + |= =json + ^- (unit response:rpc) + =/ res=(unit [@t ^json]) + %. json + =, dejs-soft:format + (ot id+so result+some ~) + ?^ res `[%result u.res] + ~| parse-one-response=json + :+ ~ %error %- need + %. json + =, dejs-soft:format + (ot id+so error+(ot code+no message+so ~) ~) + -- +:: +:: +read-contract: calls a read function on a contract, produces result hex +:: +++ read-contract + |= [url=@t req=proto-read-request:rpc:ethereum] + =/ m (strand:strandio ,@t) + ;< res=(list [id=@t res=@t]) bind:m + (batch-read-contract-strict url [req]~) + ?: ?=([* ~] res) + (pure:m res.i.res) + %+ strand-fail:strandio + %unexpected-multiple-results + [>(lent res)< ~] +:: +batch-read-contract-strict: calls read functions on contracts +:: +:: sends a batch request. produces results for all requests in the batch, +:: but only if all of them are successful. +:: +++ batch-read-contract-strict + |= [url=@t reqs=(list proto-read-request:rpc:ethereum)] + |^ =/ m (strand:strandio ,results) + ^- form:m + ;< res=(list [id=@t =json]) bind:m + %+ request-batch-rpc-strict url + (turn reqs proto-to-rpc) + =+ ^- [=results =failures] + (roll res response-to-result) + ?~ failures (pure:m results) + (strand-fail:strandio %batch-read-failed-for >failures< ~) + :: + +$ results (list [id=@t res=@t]) + +$ failures (list [id=@t =json]) + :: + ++ proto-to-rpc + |= proto-read-request:rpc:ethereum + ^- [(unit @t) request:rpc:ethereum] + :- id + :+ %eth-call + ^- call:rpc:ethereum + [~ to ~ ~ ~ `tape`(encode-call:rpc:ethereum function arguments)] + [%label %latest] + :: + ++ response-to-result + |= [[id=@t =json] =results =failures] + ^+ [results failures] + ?: ?=(%s -.json) + [[id^p.json results] failures] + [results [id^json failures]] + -- +:: +:: +++ get-latest-block + |= url=@ta + =/ m (strand:strandio ,block) + ^- form:m + ;< =json bind:m + (request-rpc url `'block number' %eth-block-number ~) + (get-block-by-number url (parse-eth-block-number:rpc:ethereum json)) +:: +++ get-block-by-number + |= [url=@ta =number:block] + =/ m (strand:strandio ,block) + ^- form:m + |^ + %+ (retry:strandio ,block) `10 + =/ m (strand:strandio ,(unit block)) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :- `'block by number' + [%eth-get-block-by-number number |] + (pure:m (parse-block json)) + :: + ++ parse-block + |= =json + ^- (unit block) + =< ?~(. ~ `[[&1 &2] |2]:u) + ^- (unit [@ @ @]) + ~| json + %. json + =, dejs-soft:format + %- ot + :~ hash+parse-hex + number+parse-hex + 'parentHash'^parse-hex + == + :: + ++ parse-hex |=(=json `(unit @)`(some (parse-hex-result:rpc:ethereum json))) + -- +:: +++ get-logs-by-hash + |= [url=@ta =hash:block contracts=(list address) =topics] + =/ m (strand:strandio (list event-log:rpc:ethereum)) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :* `'logs by hash' + %eth-get-logs-by-hash + hash + contracts + topics + == + %- pure:m + (parse-event-logs:rpc:ethereum json) +:: +++ get-logs-by-range + |= $: url=@ta + contracts=(list address) + =topics + =from=number:block + =to=number:block + == + =/ m (strand:strandio (list event-log:rpc:ethereum)) + ^- form:m + ;< =json bind:m + %+ request-rpc url + :* `'logs by range' + %eth-get-logs + `number+from-number + `number+to-number + contracts + topics + == + %- pure:m + (parse-event-logs:rpc:ethereum json) +:: +++ get-next-nonce + |= [url=@ta =address] + =/ m (strand:strandio ,@ud) + ^- form:m + ;< =json bind:m + %^ request-rpc url `'nonce' + [%eth-get-transaction-count address [%label %latest]] + %- pure:m + (parse-eth-get-transaction-count:rpc:ethereum json) +-- diff --git a/pkg/base-dev/lib/language-server/build.hoon b/pkg/base-dev/lib/language-server/build.hoon new file mode 100644 index 0000000000..015f37b889 --- /dev/null +++ b/pkg/base-dev/lib/language-server/build.hoon @@ -0,0 +1,61 @@ +/- *language-server +:: +|% +++ parse-error + |= =tape + ^- (unit [=path =range]) + =/ parse-pair + %+ cook + |=([row=@ud col=@ud] [(dec row) col]) + (ifix [sel ser] ;~((glue ace) dem dem)) + =/ parse-path + %+ cook + |=(p=path (slag 3 p)) + (ifix [fas (jest '::')] (more fas urs:ab)) + =/ parse-full + ;~(plug parse-path ;~(sfix ;~((glue dot) parse-pair parse-pair) gar)) + (rust tape parse-full) +:: +++ get-errors-from-tang + |= [uri=@t =tang] + ^- (list range) + =/ =path + (uri-to-path uri) + %+ murn tang + |= =tank + ^- (unit range) + ?. ?=([%leaf *] tank) + ~ + =/ error + (parse-error p.tank) + ?~ error + ~ + ?: =(path path.u.error) + `range.u.error + ~ +:: +++ uri-to-path + |= uri=@t + ^- path + =/ pier-root=(set cord) + %- sy + ['app' 'gen' 'lib' 'mar' 'ren' 'sur' 'sys' 'test' ~] + =/ path=(list cord) + (parse-uri uri) + |- + ?< ?=(~ path) + ?: (~(has in pier-root) i.path) + `^path`path + $(path t.path) +:: +++ parse-uri + |= uri=@t + =- (fall - /fail) + %+ rush uri + %+ more + ;~(pose (plus fas) dot) + %+ cook + crip + (star ;~(pose col hep alf)) +:: +-- diff --git a/pkg/base-dev/lib/language-server/complete.hoon b/pkg/base-dev/lib/language-server/complete.hoon new file mode 100644 index 0000000000..56b3ca498e --- /dev/null +++ b/pkg/base-dev/lib/language-server/complete.hoon @@ -0,0 +1,386 @@ +/+ language-server-parser +:: Autocomplete for hoon. +:: +=/ debug | +|% ++* option [item] + [term=cord detail=item] +:: +:: Like +rose except also produces line number +:: +++ lily + |* [los=tape sab=rule] + =+ vex=(sab [[1 1] los]) + ?~ q.vex + [%| p=p.vex(q (dec q.p.vex))] + ?. =(~ q.q.u.q.vex) + [%| p=p.vex(q (dec q.p.vex))] + [%& p=p.u.q.vex] +:: +:: Get all the identifiers accessible if this type is your subject. +:: +++ get-identifiers + |= ty=type + %- flop + |- ^- (list (option type)) + ?- ty + %noun ~ + %void ~ + [%atom *] ~ + [%cell *] + %+ weld + $(ty p.ty) + $(ty q.ty) + :: + [%core *] + %- weld + :_ ?. ?=(%gold r.p.q.ty) + ~ + $(ty p.ty) + ^- (list (option type)) + %- zing + %+ turn ~(tap by q.r.q.ty) + |= [term =tome] + %+ turn + ~(tap by q.tome) + |= [name=term =hoon] + ^- (pair term type) + ~| term=term + [name ~(play ~(et ut ty) ~[name] ~)] + :: + [%face *] + ?^ p.ty + ~ + [p.ty q.ty]~ + :: + [%fork *] + %= $ + ty + =/ tines ~(tap in p.ty) + ?~ tines + %void + |- ^- type + ?~ t.tines + i.tines + (~(fuse ut $(tines t.tines)) i.tines) + == + :: + [%hint *] $(ty q.ty) + [%hold *] $(ty ~(repo ut ty)) + == +:: +++ search-exact + |* [sid=term options=(list (option))] + =/ match + %+ skim options + |= [id=cord *] + =(sid id) + ?~ match + ~ + [~ i.match] +:: +:: Get all the identifiers that start with sid. +:: +++ search-prefix + |* [sid=cord ids=(list (option))] + ^+ ids + %+ skim ids + |= [id=cord *] + ^- ?(%.y %.n) + =(sid (end [3 (met 3 sid)] id)) +:: +:: Get the longest prefix of a list of identifiers. +:: +++ longest-match + |= matches=(list (option)) + ^- cord + ?~ matches + '' + =/ n 1 + =/ last (met 3 term.i.matches) + |- ^- term + ?: (gth n last) + term.i.matches + =/ prefix (end [3 n] term.i.matches) + ?: |- ^- ? + ?| ?=(~ t.matches) + ?& =(prefix (end [3 n] term.i.t.matches)) + $(t.matches t.t.matches) + == == + $(n +(n)) + (end [3 (dec n)] term.i.matches) +:: +:: Run +find-type safely, printing the first line of the stack trace on +:: error. +:: +++ find-type-mule + |= [sut=type gen=hoon] + ^- (unit [term type]) + =/ res (mule |.((find-type sut gen))) + ?- -.res + %& p.res + %| ((slog (flop (scag 10 p.res))) ~) + == +:: +:: Get the subject type of the wing where you've put the "magic-spoon". +:: +++ find-type + |= [sut=type gen=hoon] + =* loop $ + |^ + ^- (unit [term type]) + ?- gen + [%cnts [%magic-spoon ~] *] `['' sut] + [%cnts [%magic-spoon @ ~] *] `[i.t.p.gen sut] + [%cnts [%magic-spoon @ *] *] + %= $ + sut (~(play ut sut) wing+t.t.p.gen) + t.p.gen t.p.gen(t ~) + == + :: + [%cnts [%magic-fork @ ~] *] + `['' (~(play ut sut) wing+t.p.gen)] + :: + [^ *] (both p.gen q.gen) + [%brcn *] (grow q.gen) + [%brpt *] (grow q.gen) + [%cnts *] + |- ^- (unit [term type]) + =* inner-loop $ + ?~ q.gen + ~ + %+ replace + loop(gen q.i.q.gen) + |. inner-loop(q.gen t.q.gen) + :: + [%dtkt *] (spec-and-hoon p.gen q.gen) + [%dtls *] loop(gen p.gen) + [%rock *] ~ + [%sand *] ~ + [%tune *] ~ + [%dttr *] (both p.gen q.gen) + [%dtts *] (both p.gen q.gen) + [%dtwt *] loop(gen p.gen) + [%hand *] ~ + [%ktbr *] loop(gen p.gen) + [%ktls *] (both p.gen q.gen) + [%ktpm *] loop(gen p.gen) + [%ktsg *] loop(gen p.gen) + [%ktwt *] loop(gen p.gen) + [%note *] loop(gen q.gen) + [%sgzp *] (both p.gen q.gen) + [%sggr *] loop(gen q.gen) :: should check for hoon in p.gen + [%tsgr *] (change p.gen q.gen) + [%tscm *] + %+ replace + loop(gen p.gen) + |.(loop(gen q.gen, sut (~(busk ut sut) p.gen))) + :: + [%wtcl *] (bell p.gen q.gen r.gen) + [%fits *] (both p.gen wing+q.gen) + [%wthx *] loop(gen wing+q.gen) + [%dbug *] loop(gen q.gen) + [%zpcm *] (both p.gen q.gen) + [%lost *] loop(gen p.gen) + [%zpmc *] (both p.gen q.gen) + [%zpts *] loop(gen p.gen) + [%zppt *] (both q.gen r.gen) + [%zpgl *] (spec-and-hoon p.gen q.gen) + [%zpzp *] ~ + * + =+ doz=~(open ap gen) + ?: =(doz gen) + ~_ (show [%c 'hoon'] [%q gen]) + ~> %mean.'play-open' + !! + loop(gen doz) + == + :: + ++ replace + |= [a=(unit [term type]) b=(trap (unit [term type]))] + ^- (unit [term type]) + ?~(a $:b a) + :: + ++ both + |= [a=hoon b=hoon] + (replace loop(gen a) |.(loop(gen b))) + :: + ++ bell + |= [a=hoon b=hoon c=hoon] + %+ replace loop(gen a) + |. %+ replace loop(gen b, sut (~(gain ut sut) a)) + |. loop(gen c, sut (~(lose ut sut) a)) + :: + ++ spec-and-hoon + |= [a=spec b=hoon] + (replace (find-type-in-spec sut a) |.(loop(gen b))) + :: + ++ change + |= [a=hoon b=hoon] + (replace loop(gen a) |.(loop(gen b, sut (~(play ut sut) a)))) + :: + ++ grow + |= m=(map term tome) + =/ tomes ~(tap by m) + |- ^- (unit [term type]) + =* outer-loop $ + ?~ tomes + ~ + =/ arms ~(tap by q.q.i.tomes) + |- ^- (unit [term type]) + =* inner-loop $ + ?~ arms + outer-loop(tomes t.tomes) + %+ replace + loop(gen q.i.arms, sut (~(play ut sut) gen)) + |. inner-loop(arms t.arms) + -- +:: +:: Not implemented yet. I wonder whether we should modify types found +:: in spec mode such that if it's a mold that produces a type, it +:: should just display the type and not that it's technically a +:: function. +:: +++ find-type-in-spec + |= [sut=type pec=spec] + ^- (unit [term type]) + ~ +:: +++ get-id-sym + |= [pos=@ud =tape] + %^ get-id pos tape + ^- $-(nail (like (unit @t))) + ;~(sfix (punt sym) (star ;~(pose prn (just `@`10)))) +:: +++ get-id-cord + |= [pos=@ud =tape] + %^ get-id pos tape + ^- $-(nail (like (unit @t))) + ;~(sfix (punt (cook crip (star prn))) (star ;~(pose prn (just `@`10)))) +:: +++ get-id + |= [pos=@ud txt=tape seek=$-(nail (like (unit @t)))] + ^- [forward=(unit @t) backward=(unit @t) id=(unit @t)] + =/ forward=(unit @t) + (scan (slag pos txt) seek) + =/ backward=(unit @t) + %- (lift |=(t=@t (swp 3 t))) + (scan (flop (scag pos txt)) seek) + =/ id=(unit @t) + ?~ forward + ?~ backward + ~ + `u.backward + ?~ backward + `u.forward + `(cat 3 u.backward u.forward) + [forward backward id] +:: +:: Insert magic marker in hoon source at the given position. +:: +++ insert-magic + |= [pos=@ud txt=tape] + ^- [back-pos=@ud fore-pos=@ud txt=tape] + :: Find beg-pos by searching backward to where the current term + :: begins + =+ (get-id-sym pos txt) + =/ back-pos + ?~ backward + pos + (sub pos (met 3 u.backward)) + =/ fore-pos + ?~ forward + pos + (add pos (met 3 u.forward)) + :+ back-pos fore-pos + :: Insert "magic-spoon" marker so +find-type can identify where to + :: stop. + :: + ;: weld + (scag back-pos txt) + ?: &(?=(~ id) ?=([%'.' *] (slag pos txt))) + "magic-fork" + "magic-spoon" + ?~ id + "" + "." + (slag back-pos txt) + "\0a" + == +:: +:: Produce the longest possible advance without choosing between +:: matches. +:: +:: Takes a +hoon which has already has a magic-spoon marker. Useful if +:: you want to handle your own parsing. +:: +++ advance-hoon + |= [sut=type gen=hoon] + %+ bind (find-type-mule sut gen) + |= [id=term typ=type] + =/ matches=(list (option type)) + (search-prefix id (get-identifiers typ)) + (longest-match matches) +:: +:: Same as +advance-hoon, but takes a position and text directly. +:: +++ advance-tape + |= [sut=type pos=@ud code=tape] + (advance-hoon sut (scan txt:(insert-magic pos code) vest)) +:: +:: Produce a list of matches. +:: +:: Takes a +hoon which has already has a magic-spoon marker. Useful if +:: you want to handle your own parsing. +:: +++ tab-list-hoon + |= [sut=type gen=hoon] + ^- (unit (list (option type))) + %+ bind (find-type-mule sut gen) + |= [id=term typ=type] + (search-prefix id (get-identifiers typ)) +:: +:: Same as +advance-hoon, but takes a position and text directly. +:: +++ tab-list-tape + |= [sut=type pos=@ud code=tape] + ^- (each (unit (list (option type))) [row=@ col=@]) + ~? > debug %start-magick + =/ magicked txt:(insert-magic pos code) + ~? > debug %start-parsing + =/ res (lily magicked (language-server-parser *path)) + ?: ?=(%| -.res) + ~? > debug [%parsing-error p.res] + [%| p.res] + :- %& + ~? > debug %parsed-good + ((cury tab-list-hoon sut) hoon:`pile:clay`p.res) +:: +:: Generators +++ tab-generators + |= [pfix=path app=(unit term) gens=(list term)] + ^- (list (option tank)) + %+ turn gens + |= gen=term + ^- (option tank) + =/ pax=path + (weld pfix ~[gen %hoon]) + =/ file + .^(@t %cx pax) + :_ (render-help file) + ?~ app + (cat 3 '+' gen) + ?: =(%hood u.app) + (cat 3 '|' gen) + :((cury cat 3) ':' u.app '|' gen) +:: Stolen from +help +++ render-help + |= a=@t + ^- tank + :- %leaf + =/ c (to-wain:format a) + ?~ c "~" + ?. =(':: ' (end [3 4] i.c)) + "" + (trip i.c) +-- diff --git a/pkg/base-dev/lib/language-server/easy-print.hoon b/pkg/base-dev/lib/language-server/easy-print.hoon new file mode 100644 index 0000000000..12558c8a5f --- /dev/null +++ b/pkg/base-dev/lib/language-server/easy-print.hoon @@ -0,0 +1,484 @@ +:: Fast type printing that's easy on the eyes or your money back +:: +=> |% + +$ cape [p=(map @ud wine) q=wine] + +$ wine + $@ $? %noun + %path + %type + %void + %wall + %wool + %yarn + == + $% [%mato p=term] + [%gate p=hoon q=type r=wine] + [%core p=(list @ta) q=wine] + [%face p=term q=wine] + [%list p=term q=wine] + [%pear p=term q=@] + [%bcwt p=(list wine)] + [%plot p=(list wine)] + [%stop p=@ud] + [%tree p=term q=wine] + [%unit p=term q=wine] + == + -- +|_ sut=type +++ dash + |= [mil=tape lim=char lam=tape] + ^- tape + =/ esc (~(gas in *(set @tD)) lam) + :- lim + |- ^- tape + ?~ mil [lim ~] + ?: ?| =(lim i.mil) + =('\\' i.mil) + (~(has in esc) i.mil) + == + ['\\' i.mil $(mil t.mil)] + ?: (lte ' ' i.mil) + [i.mil $(mil t.mil)] + ['\\' ~(x ne (rsh 2 i.mil)) ~(x ne (end 2 i.mil)) $(mil t.mil)] +:: +++ deal |=(lum=* (dish dole lum)) +++ dial + |= ham=cape + =+ gid=*(set @ud) + =| top-level=? :: don't need circumfix punctuation + =< `tank`-:$ + |% + ++ many + |= haz=(list wine) + ^- [(list tank) (set @ud)] + ?~ haz [~ gid] + =^ mor gid $(haz t.haz) + =^ dis gid ^$(q.ham i.haz) + [[dis mor] gid] + :: + ++ $ + ^- [tank (set @ud)] + ?- q.ham + %noun :_(gid [%leaf '*' ~]) + %path :_(gid [%leaf '/' ~]) + %type :_(gid [%leaf '#' 't' ~]) + %void :_(gid [%leaf '#' '!' ~]) + %wool :_(gid [%leaf '*' '"' '"' ~]) + %wall :_(gid [%leaf '*' '\'' '\'' ~]) + %yarn :_(gid [%leaf '"' '"' ~]) + [%mato *] :_(gid [%leaf '@' (trip p.q.ham)]) + [%gate *] + =^ sam gid + ?. ?=([%plot * * *] r.q.ham) + ?: ?=(%plot -.r.q.ham) + %- (slog -:$(q.ham r.q.ham) ~) + `gid + `gid + [`u=- +]:$(q.ham i.p.r.q.ham, top-level |) + :_ gid + :+ %rose + :- ?> ?=(%core -.q.q.ham) + ?: ?=(%dry q.p.q.q.q.ham) + " -> " + " ~> " + ?: top-level + ["" ""] + ["(" ")"] + :+ ?~(sam leaf+"_" u.sam) + =/ res (mule |.((~(play ut q.q.ham) p.q.ham))) + ?- -.res + %& duck(sut p.res) + %| leaf+"###" + == + ~ + :: + [%core *] + =^ sam gid + ?. ?=([%plot * * ~] q.q.ham) + `gid + [`u=- +]:$(q.ham i.p.q.q.ham) + :_ gid + ?~ sam + :+ %rose + [[' ' ~] ['<' ~] ['>' ~]] + |- ^- (list tank) + ?~ p.q.ham ~ + [[%leaf (rip 3 i.p.q.ham)] $(p.q.ham t.p.q.ham)] + :+ %rose + [" -> " "" ""] + :+ u.sam + :+ %rose + [[' ' ~] ['<' ~] ['>' ~]] + |- ^- (list tank) + ?~ p.q.ham ~ + [[%leaf (rip 3 i.p.q.ham)] $(p.q.ham t.p.q.ham)] + ~ + :: + [%face *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%palm [['=' ~] ~ ~ ~] [%leaf (trip p.q.ham)] cox ~]) + :: + [%list *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) + :: + [%bcwt *] + =^ coz gid (many p.q.ham) + :_(gid [%rose [[' ' ~] ['?' '(' ~] [')' ~]] coz]) + :: + [%plot *] + =^ coz gid (many p.q.ham) + :_(gid [%rose [[' ' ~] ['[' ~] [']' ~]] coz]) + :: + [%pear *] + :_(gid [%leaf '$' ~(rend co [%$ p.q.ham q.q.ham])]) + :: + [%stop *] + =+ num=~(rend co [%$ %ud p.q.ham]) + ?: (~(has in gid) p.q.ham) + :_(gid [%leaf '#' num]) + =^ cox gid + %= $ + gid (~(put in gid) p.q.ham) + q.ham (~(got by p.ham) p.q.ham) + == + :_(gid [%palm [['.' ~] ~ ~ ~] [%leaf ['^' '#' num]] cox ~]) + :: + [%tree *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) + :: + [%unit *] + =^ cox gid $(q.ham q.q.ham) + :_(gid [%rose [" " (weld (trip p.q.ham) "(") ")"] cox ~]) + == + -- +:: +++ dish !: + |= [ham=cape lum=*] ^- tank + ~| [%dish-h ?@(q.ham q.ham -.q.ham)] + ~| [%lump lum] + ~| [%ham ham] + %- need + =| gil=(set [@ud *]) + |- ^- (unit tank) + ?- q.ham + %noun + %= $ + q.ham + ?: ?=(@ lum) + [%mato %$] + :- %plot + |- ^- (list wine) + [%noun ?:(?=(@ +.lum) [[%mato %$] ~] $(lum +.lum))] + == + :: + %path + :- ~ + :+ %rose + [['/' ~] ['/' ~] ~] + |- ^- (list tank) + ?~ lum ~ + ?@ lum !! + ?> ?=(@ -.lum) + [[%leaf (rip 3 -.lum)] $(lum +.lum)] + :: + %type + =+ tyr=|.((dial dole)) + =+ vol=tyr(sut lum) + =+ cis=;;(tank .*(vol [%9 2 %0 1])) + :^ ~ %palm + [~ ~ ~ ~] + [[%leaf '#' 't' '/' ~] cis ~] + :: + %wall + :- ~ + :+ %rose + [[' ' ~] ['<' '|' ~] ['|' '>' ~]] + |- ^- (list tank) + ?~ lum ~ + ?@ lum !! + [[%leaf (trip ;;(@ -.lum))] $(lum +.lum)] + :: + %wool + :- ~ + :+ %rose + [[' ' ~] ['<' '<' ~] ['>' '>' ~]] + |- ^- (list tank) + ?~ lum ~ + ?@ lum !! + [(need ^$(q.ham %yarn, lum -.lum)) $(lum +.lum)] + :: + %yarn + [~ %leaf (dash (tape lum) '"' "\{")] + :: + %void + ~ + :: + [%mato *] + ?. ?=(@ lum) + ~ + :+ ~ + %leaf + ?+ (rash p.q.ham ;~(sfix (cook crip (star low)) (star hig))) + ~(rend co [%$ p.q.ham lum]) + %$ ~(rend co [%$ %ud lum]) + %t (dash (rip 3 lum) '\'' ~) + %tas ['%' ?.(=(0 lum) (rip 3 lum) ['$' ~])] + == + :: + [%gate *] + !! + :: + [%core *] + :: XX needs rethinking for core metal + :: ?. ?=(^ lum) ~ + :: => .(lum `*`lum) + :: =- ?~(tok ~ [~ %rose [[' ' ~] ['<' ~] ['>' ~]] u.tok]) + :: ^= tok + :: |- ^- (unit (list tank)) + :: ?~ p.q.ham + :: =+ den=^$(q.ham q.q.ham) + :: ?~(den ~ [~ u.den ~]) + :: =+ mur=$(p.q.ham t.p.q.ham, lum +.lum) + :: ?~(mur ~ [~ [[%leaf (rip 3 i.p.q.ham)] u.mur]]) + [~ (dial ham)] + :: + [%face *] + =+ wal=$(q.ham q.q.ham) + ?~ wal + ~ + [~ %palm [['=' ~] ~ ~ ~] [%leaf (trip p.q.ham)] u.wal ~] + :: + [%list *] + ?: =(~ lum) + [~ %leaf '~' ~] + =- ?~ tok + ~ + [~ %rose [[' ' ~] ['~' '[' ~] [']' ~]] u.tok] + ^= tok + |- ^- (unit (list tank)) + ?: ?=(@ lum) + ?.(=(~ lum) ~ [~ ~]) + =+ [for=^$(q.ham q.q.ham, lum -.lum) aft=$(lum +.lum)] + ?. &(?=(^ for) ?=(^ aft)) + ~ + [~ u.for u.aft] + :: + [%bcwt *] + |- ^- (unit tank) + ?~ p.q.ham + ~ + =+ wal=^$(q.ham i.p.q.ham) + ?~ wal + $(p.q.ham t.p.q.ham) + wal + :: + [%plot *] + =- ?~ tok + ~ + [~ %rose [[' ' ~] ['[' ~] [']' ~]] u.tok] + ^= tok + |- ^- (unit (list tank)) + ?~ p.q.ham + ~ + ?: ?=([* ~] p.q.ham) + =+ wal=^$(q.ham i.p.q.ham) + ?~(wal ~ [~ [u.wal ~]]) + ?@ lum + ~ + =+ gim=^$(q.ham i.p.q.ham, lum -.lum) + ?~ gim + ~ + =+ myd=$(p.q.ham t.p.q.ham, lum +.lum) + ?~ myd + ~ + [~ u.gim u.myd] + :: + [%pear *] + ?. =(lum q.q.ham) + ~ + =. p.q.ham + (rash p.q.ham ;~(sfix (cook crip (star low)) (star hig))) + =+ fox=$(q.ham [%mato p.q.ham]) + ?> ?=([~ %leaf ^] fox) + ?: ?=(?(%n %tas) p.q.ham) + fox + [~ %leaf '%' p.u.fox] + :: + [%stop *] + ?: (~(has in gil) [p.q.ham lum]) ~ + =+ kep=(~(get by p.ham) p.q.ham) + ?~ kep + ~|([%stop-loss p.q.ham] !!) + $(gil (~(put in gil) [p.q.ham lum]), q.ham u.kep) + :: + [%tree *] + =- ?~ tok + ~ + [~ %rose [[' ' ~] ['{' ~] ['}' ~]] u.tok] + ^= tok + =+ tuk=*(list tank) + |- ^- (unit (list tank)) + ?: =(~ lum) + [~ tuk] + ?. ?=([n=* l=* r=*] lum) + ~ + =+ rol=$(lum r.lum) + ?~ rol + ~ + =+ tim=^$(q.ham q.q.ham, lum n.lum) + ?~ tim + ~ + $(lum l.lum, tuk [u.tim u.rol]) + :: + [%unit *] + ?@ lum + ?.(=(~ lum) ~ [~ %leaf '~' ~]) + ?. =(~ -.lum) + ~ + =+ wal=$(q.ham q.q.ham, lum +.lum) + ?~ wal + ~ + [~ %rose [[' ' ~] ['[' ~] [']' ~]] [%leaf '~' ~] u.wal ~] + == +:: +++ doge + |= ham=cape + =- ?+ woz woz + [%list * [%mato %'ta']] %path + [%list * [%mato %'t']] %wall + [%list * [%mato %'tD']] %yarn + [%list * %yarn] %wool + == + ^= woz + ^- wine + ?. ?=([%stop *] q.ham) + ?: ?& ?= [%bcwt [%pear %n %0] [%plot [%pear %n %0] [%face *] ~] ~] + q.ham + =(1 (met 3 p.i.t.p.i.t.p.q.ham)) + == + [%unit =<([p q] i.t.p.i.t.p.q.ham)] + q.ham + =+ may=(~(get by p.ham) p.q.ham) + ?~ may + q.ham + =+ nul=[%pear %n 0] + ?. ?& ?=([%bcwt *] u.may) + ?=([* * ~] p.u.may) + |(=(nul i.p.u.may) =(nul i.t.p.u.may)) + == + q.ham + =+ din=?:(=(nul i.p.u.may) i.t.p.u.may i.p.u.may) + ?: ?& ?=([%plot [%face *] [%face * %stop *] ~] din) + =(p.q.ham p.q.i.t.p.din) + =(1 (met 3 p.i.p.din)) + =(1 (met 3 p.i.t.p.din)) + == + :+ %list + (cat 3 p.i.p.din p.i.t.p.din) + q.i.p.din + ?: ?& ?= $: %plot + [%face *] + [%face * %stop *] + [[%face * %stop *] ~] + == + din + =(p.q.ham p.q.i.t.p.din) + =(p.q.ham p.q.i.t.t.p.din) + =(1 (met 3 p.i.p.din)) + =(1 (met 3 p.i.t.p.din)) + =(1 (met 3 p.i.t.t.p.din)) + == + :+ %tree + %^ cat + 3 + p.i.p.din + (cat 3 p.i.t.p.din p.i.t.t.p.din) + q.i.p.din + q.ham +:: +++ dole + ^- cape + =+ gil=*(set type) + =+ dex=[p=*(map type @) q=*(map @ wine)] + =< [q.p q] + |- ^- [p=[p=(map type @) q=(map @ wine)] q=wine] + =- [p.tez (doge q.p.tez q.tez)] + ^= tez + ^- [p=[p=(map type @) q=(map @ wine)] q=wine] + ?: (~(meet ut sut) -:!>(*type)) + [dex %type] + ?- sut + %noun [dex sut] + %void [dex sut] + [%atom *] [dex ?~(q.sut [%mato p.sut] [%pear p.sut u.q.sut])] + [%cell *] + =+ hin=$(sut p.sut) + =+ yon=$(dex p.hin, sut q.sut) + :- p.yon + :- %plot + ?:(?=([%plot *] q.yon) [q.hin p.q.yon] [q.hin q.yon ~]) + :: + [%core *] + ?: ?=([[%$ * [[%$ @ *] ~ ~]] ~ ~] q.r.q.sut) + =/ dad $(sut p.sut) + :- p.dad + ~! q.r.q.sut + [%gate q.n.q.q.n.q.r.q.sut sut(r.p.q %gold) q.dad] + =+ yad=$(sut p.sut) + :- p.yad + =+ ^= doy ^- [p=(list @ta) q=wine] + ?: ?=([%core *] q.yad) + [p.q.yad q.q.yad] + [~ q.yad] + :- %core + :_ q.doy + :_ p.doy + %^ cat 3 + %~ rent co + :+ %$ %ud + %- ~(rep by (~(run by q.r.q.sut) |=(tome ~(wyt by q.+<)))) + |=([[@ a=@u] b=@u] (add a b)) + %^ cat 3 + ?-(r.p.q.sut %gold '.', %iron '|', %lead '?', %zinc '&') + =+ gum=(mug q.r.q.sut) + %+ can 3 + :~ [1 (add 'a' (mod gum 26))] + [1 (add 'a' (mod (div gum 26) 26))] + [1 (add 'a' (mod (div gum 676) 26))] + == + :: + [%hint *] + $(sut q.sut) + :: + [%face *] + =+ yad=$(sut q.sut) + ?^(p.sut yad [p.yad [%face p.sut q.yad]]) + :: + [%fork *] + =+ yed=(sort ~(tap in p.sut) aor) + =- [p [%bcwt q]] + |- ^- [p=[p=(map type @) q=(map @ wine)] q=(list wine)] + ?~ yed + [dex ~] + =+ mor=$(yed t.yed) + =+ dis=^$(dex p.mor, sut i.yed) + [p.dis q.dis q.mor] + :: + [%hold *] + =+ hey=(~(get by p.dex) sut) + ?^ hey + [dex [%stop u.hey]] + ?: (~(has in gil) sut) + =+ dyr=+(~(wyt by p.dex)) + [[(~(put by p.dex) sut dyr) q.dex] [%stop dyr]] + =+ rom=$(gil (~(put in gil) sut), sut ~(repo ut sut)) + =+ rey=(~(get by p.p.rom) sut) + ?~ rey + rom + [[p.p.rom (~(put by q.p.rom) u.rey q.rom)] [%stop u.rey]] + == +:: +++ duck (dial dole) +-- diff --git a/pkg/base-dev/lib/language-server/json.hoon b/pkg/base-dev/lib/language-server/json.hoon new file mode 100644 index 0000000000..a817766dfa --- /dev/null +++ b/pkg/base-dev/lib/language-server/json.hoon @@ -0,0 +1,301 @@ +/- lsp=language-server +|% +:: +++ util + |% + ++ get-json-string + |= [jon=(map @t json) key=@t] + ^- (unit cord) + =/ cord-jon=(unit json) + (~(get by jon) key) + ?~ cord-jon + ~ + ?> ?=([%s *] u.cord-jon) + `p.u.cord-jon + -- +:: +:: +++ dejs + =, dejs:format + |% + ++ request + |= jon=json + ?> ?=([%o *] jon) + =/ method=cord + %- method + (trip (need (get-json-string:util p.jon 'method'))) + =/ id=cord + (need (get-json-string:util p.jon 'id')) + =/ params=json + (~(got by p.jon) 'params') + ^- all:request:lsp + |^ + ?+ method [%unknown jon] + %text-document--hover (text-document--hover params id) + %text-document--completion (text-document--completion params id) + == + :: + ++ text-document--hover + |= [params=json id=cord] + ^- text-document--hover:request:lsp + :+ %text-document--hover + id + %. params + %: ot + position+position + 'textDocument'^text-document-id + ~ + == + :: + ++ text-document--completion + |= [params=json id=cord] + :+ %text-document--completion id + %. params + %: ot + position+position + 'textDocument'^text-document-id + ~ + == + -- + :: + ++ notification + |= jon=json + ?> ?=([%o *] jon) + =/ method=cord + %- method + (trip (need (get-json-string:util p.jon 'method'))) + =/ params=json + (~(got by p.jon) 'params') + ^- all:notification:lsp + |^ + ?+ method [%unknown jon] + %text-document--did-change + (text-document--did-change params) + %text-document--did-open + (text-document--did-open params) + %text-document--did-save + (text-document--did-save params) + %text-document--did-close + (text-document--did-close params) + == + :: + ++ text-document--did-save + |= jon=json + ^- text-document--did-save:notification:lsp + ?> ?=([%o *] jon) + =/ doc-id + (~(got by p.jon) 'textDocument') + :- %text-document--did-save + (text-document-id doc-id) + :: + ++ text-document--did-close + |= jon=json + ^- text-document--did-close:notification:lsp + ?> ?=([%o *] jon) + =/ doc-id + (~(got by p.jon) 'textDocument') + :- %text-document--did-close + (text-document-id doc-id) + :: + ++ text-document--did-change + |= jon=json + ^- text-document--did-change:notification:lsp + :- %text-document--did-change + %. jon + %: ot + 'textDocument'^text-document-id + 'contentChanges'^text-document-changes + ~ + == + :: + ++ text-document--did-open + |= jon=json + ^- text-document--did-open:notification:lsp + ?> ?=([%o *] jon) + :- %text-document--did-open + (text-document-item (~(got by p.jon) 'textDocument')) + -- + :: Utilities + :: + ++ text-document-item + |= jon=json + ^- text-document-item:lsp + %. jon + %: ot + uri+so + version+(mu ni) + text+so + ~ + == + :: + ++ text-document-id + %: ou + uri+(un so) + version+(uf ~ (pe ~ ni)) + ~ + == + :: + ++ text-document-changes + %- ar + %: ou + range+(uf ~ (pe ~ range)) + 'rangeLength'^(uf ~ (pe ~ ni)) + text+(un so) + ~ + == + :: + ++ method + |= =tape + ^- cord + %- crip %- zing + %+ join "--" + ^- (list ^tape) + %+ turn + ^- (list (list ^tape)) + %+ scan + tape + %+ more + fas + ;~ plug + (star low) + (star ;~(plug (cook |=(a=@ (add a 32)) hig) (star low))) + == + |= words=(list ^tape) + ^- ^tape + (zing (join "-" words)) + :: + ++ range + %: ot + start+position + end+position + ~ + == + :: + ++ position + %: ot + line+ni + character+ni + ~ + == + -- +:: +++ enjs + =, enjs:format + |% + ++ text-document--publish-diagnostics + |= pub=text-document--publish-diagnostics:notification:lsp + ^- json + %: pairs + uri+s+uri.pub + diagnostics+a+(turn diagnostics.pub diagnostic) + ~ + == + ++ notification + |= notification=all:notification:lsp + ^- json + =/ params=json + ?+ -.notification !! + %text-document--publish-diagnostics + (text-document--publish-diagnostics notification) + == + ~! -.notification + =/ method=cord (crip (unparse-method -.notification)) + %: pairs + method+s+method + params+params + ~ + == + :: + ++ response + |= res=all:response:lsp + ^- json + |^ + ?- -.res + %text-document--hover (text-document--hover res) + %text-document--completion (text-document--completion res) + == + :: + ++ wrap-in-id + |= [id=cord res=json] + %: pairs + id+s+id + result+res + ~ + == + ++ text-document--hover + |= hov=text-document--hover:response:lsp + %+ wrap-in-id id.hov + %+ frond 'contents' + ?~ contents.hov + ~ + s+u.contents.hov + :: + ++ text-document--completion + |= com=text-document--completion:response:lsp + %+ wrap-in-id id.com + [%a (turn completion.com completion-item)] + -- + ++ unparse-method + |= =cord + ^- ^tape + %+ rash cord + %+ cook |=(l=(list ^tape) (zing (join "/" l))) + %+ more (jest '--') + %+ cook + |= tapes=(list ^tape) + ^- ^tape + ?~ tapes ~ + %- zing + :- i.tapes + %+ turn t.tapes + |= t=^tape + ^- ^tape + ?~ t ~ + [`@tD`(sub i.t 32) t.t] + %+ more + ;~(less (jest '--') hep) + (star alf) + :: + ++ completion-item + |= com=completion-item:lsp + ^- json + %: pairs + label+s+label.com + detail+s+detail.com + kind+(numb kind.com) + 'documentation'^s+doc.com + 'insertText'^s+insert-text.com + 'insertTextFormat'^(numb insert-text-format.com) + ~ + == + :: + ++ position + |= =position:lsp + ^- json + %: pairs + line+(numb row.position) + character+(numb col.position) + ~ + == + :: + ++ range + |= =range:lsp + ^- json + %: pairs + start+(position start.range) + end+(position end.range) + ~ + == + :: + ++ diagnostic + |= diag=diagnostic:lsp + ^- json + %: pairs + range+(range range.diag) + severity+(numb severity.diag) + message+s+message.diag + ~ + == + :: + -- +-- diff --git a/pkg/base-dev/lib/language-server/parser.hoon b/pkg/base-dev/lib/language-server/parser.hoon new file mode 100644 index 0000000000..cf57790926 --- /dev/null +++ b/pkg/base-dev/lib/language-server/parser.hoon @@ -0,0 +1,72 @@ +:: lifted directly from ford, should probably be in zuse +=, clay +=< pile-rule +|% +++ pile-rule + |= pax=path + %- full + %+ ifix + :_ gay + :: parse optional /? and ignore + :: + ;~(plug gay (punt ;~(plug fas wut gap dem gap))) + |^ + ;~ plug + %+ cook (bake zing (list (list taut))) + %+ rune hep + (most ;~(plug com gaw) taut-rule) + :: + %+ cook (bake zing (list (list taut))) + %+ rune lus + (most ;~(plug com gaw) taut-rule) + :: + %+ rune tis + ;~(plug sym ;~(pfix gap stap)) + :: + %+ rune sig + ;~((glue gap) sym wyde:vast stap) + :: + %+ rune cen + ;~(plug sym ;~(pfix gap ;~(pfix cen sym))) + :: + %+ rune buc + ;~ (glue gap) + sym + ;~(pfix cen sym) + ;~(pfix cen sym) + == + :: + %+ rune tar + ;~ (glue gap) + sym + ;~(pfix cen sym) + stap + == + :: + %+ stag %tssg + (most gap tall:(vang & pax)) + == + :: + ++ pant + |* fel=^rule + ;~(pose fel (easy ~)) + :: + ++ mast + |* [bus=^rule fel=^rule] + ;~(sfix (more bus fel) bus) + :: + ++ rune + |* [bus=^rule fel=^rule] + %- pant + %+ mast gap + ;~(pfix fas bus gap fel) + -- +:: +++ taut-rule + %+ cook |=(taut +<) + ;~ pose + (stag ~ ;~(pfix tar sym)) + ;~(plug (stag ~ sym) ;~(pfix tis sym)) + (cook |=(a=term [`a a]) sym) + == +-- diff --git a/pkg/base-dev/lib/language-server/rune-snippet.hoon b/pkg/base-dev/lib/language-server/rune-snippet.hoon new file mode 100644 index 0000000000..b25e306bea --- /dev/null +++ b/pkg/base-dev/lib/language-server/rune-snippet.hoon @@ -0,0 +1,532 @@ +/- lsp-sur=language-server +/+ auto=language-server-complete +=> +|% +++ snippet + |= [rune=tape text=tape] + ^- json + =, enjs:format + %- pairs + :~ 'label'^(tape rune) + 'insertTextFormat'^(numb 2) + 'insertText'^(tape text) + == +:: +++ runes + ^- (list (option:auto tape)) + :~ :- '|$' + """ + $\{1:sample} + $\{2:body} + """ + :- '|_' + """ + $\{1:sample} + ++ $\{2:arm} + $\{3:body} + -- + """ + :- '|:' + """ + $\{1:sample} + $\{2:body} + """ + :- '|%' + """ + + ++ $\{1:arm} + $\{2:body} + -- + """ + :- '|.' + """ + $\{1:body} + """ + :- '|^' + """ + + $\{1:body} + :: + ++ $\{2:arm} + $\{3:body} + -- + """ + :- '|-' + """ + $\{1:body} + """ + :- '|~' + """ + $\{1:sample} + $\{2:body} + """ + :- '|*' + """ + $\{1:sample} + $\{2:body} + """ + :- '|=' + """ + $\{1:sample} + $\{2:body} + """ + :- '|@' + """ + ++ $\{1:arm} + $\{2:body} + -- + """ + :- '|?' + """ + $\{1:sample} + """ + :: + :- ':_' + """ + $\{1:tail} + $\{2:head} + """ + :- ':^' + """ + $\{1:car} + $\{2:cadr} + $\{3:caddr} + $\{4:cddr} + """ + :- ':-' + """ + $\{1:tail} + $\{2:head} + """ + :- ':+' + """ + $\{1:car} + $\{2:cadr} + $\{3:cddr} + """ + :- ':~' + """ + $\{1:item} + == + """ + :- ':*' + """ + $\{1:item} + == + """ + :: + :- '%_' + """ + $\{1:target} + $\{2:wing} $\{3:new-value} + == + """ + :- '%.' + """ + $\{1:arg} + $\{2:gate} + """ + :- '%-' + """ + $\{1:gate} + $\{2:arg} + """ + :- '%:' + """ + $\{1:gate} + $\{2:args} + == + """ + :- '%*' + """ + $\{1:target-wing} $\{2:from} + $\{3:wing} $\{4:new-value} + == + """ + :- '%^' + """ + $\{1:gate} + $\{2:arg1} + $\{3:arg2} + $\{4:arg3} + """ + :- '%+' + """ + $\{1:gate} + $\{2:arg1} + $\{3:arg2} + """ + :- '%~' + """ + $\{1:arm} + $\{2:core} + $\{3:arg} + """ + :- '%=' + """ + $\{1:target} + $\{2:wing} $\{3:new-value} + == + """ + :: + :- '.^' + """ + $\{1:mold} + $\{2:path} + """ + :- '.+' + """ + $\{1:atom} + """ + :- '.*' + """ + $\{1:subject} + $\{2:formula} + """ + :- '.=' + """ + $\{1:a} + $\{2:b} + """ + :- '.?' + """ + $\{1:noun} + """ + :: + :- '^|' + """ + $\{1:iron-core} + """ + :- '^.' + """ + $\{1:a} + $\{2:b} + """ + :- '^+' + """ + $\{1:like} + $\{2:body} + """ + :- '^-' + """ + $\{1:type} + $\{2:body} + """ + :- '^&' + """ + $\{1:zinc-core} + """ + :- '^~' + """ + $\{1:constant} + """ + :- '^=' + """ + $\{1:face} + $\{2:body} + """ + :- '^?' + """ + $\{1:lead-core} + """ + :- '^*' + """ + $\{1:type} + """ + :- '^:' + """ + $\{1:type} + """ + :: + :- '~|' + """ + $\{1:trace} + $\{2:body} + """ + :- '~_' + """ + $\{1:tank} + $\{2:body} + """ + :- '~%' + """ + $\{1:name} + $\{2:parent} + ~ + $\{3:body} + """ + :- '~/' + """ + $\{1:name} + $\{2:body} + """ + :- '~<' + """ + $\{1:hint} + $\{2:body} + """ + :- '~>' + """ + $\{1:hint} + $\{2:body} + """ + :- '~$' + """ + $\{1:name} + $\{2:body} + """ + :- '~+' + """ + + $\{1:body} + """ + :- '~&' + """ + $\{1:printf} + $\{2:body} + """ + :- '~=' + """ + $\{1:a} + $\{2:b} + """ + :- '~?' + """ + $\{1:condition} + $\{2:printf} + $\{3:body} + """ + :- '~!' + """ + $\{1:type} + $\{2:body} + """ + :: + :- ';=' + """ + $\{1:manx} + == + """ + :- ';:' + """ + $\{1:gate} + $\{2:args} + == + """ + :- ';/' + """ + $\{1:tape} + """ + :- ';<' + """ + $\{1:type} bind:m $\{2:body1} + $\{3:body2} + """ + :- ';~' + """ + $\{1:gate} + $\{2:args} + == + """ + :- ';;' + """ + $\{1:type} + $\{2:body} + """ + :: + :- '=|' + """ + $\{1:type} + $\{2:body} + """ + :- '=:' + """ + $\{1:wing} $\{2:value} + == + $\{3:body} + """ + :- '=/' + """ + $\{1:face} + $\{2:value} + $\{3:body} + """ + :- '=;' + """ + $\{1:face} + $\{2:body} + $\{3:value} + """ + :- '=.' + """ + $\{1:wing} + $\{2:value} + $\{3:body} + """ + :- '=?' + """ + $\{1:wing} $\{2:condition} + $\{3:value} + $\{4:body} + """ + :- '=<' + """ + $\{1:formula} + $\{2:subject} + """ + :- '=-' + """ + $\{1:body} + $\{2:value} + """ + :- '=>' + """ + $\{1:subject} + $\{2:formula} + """ + :- '=^' + """ + $\{1:face} $\{2:wing} + $\{3:computation} + $\{4:body} + """ + :- '=+' + """ + $\{1:value} + $\{2:body} + """ + :- '=~' + """ + + $\{1:body} + """ + :- '=*' + """ + $\{1:alias} $\{2:value} + $\{3:body} + """ + :- '=,' + """ + $\{1:alias} + $\{3:body} + """ + :: + :- '?|' + """ + $\{1:condition} + == + """ + :- '?-' + """ + $\{1:case} + $\{2:type} $\{3:value} + == + """ + :- '?:' + """ + $\{1:if} + $\{2:then} + $\{3:else} + """ + :- '?.' + """ + $\{1:if} + $\{2:else} + $\{3:then} + """ + :- '?^' + """ + $\{1:value} + $\{2:if-cell} + $\{3:if-atom} + """ + :- '?<' + """ + $\{1:assertion} + $\{2:body} + """ + :- '?>' + """ + $\{1:assertion} + $\{2:body} + """ + :- '?+' + """ + $\{1:case} $\{2:else} + $\{3:type} $\{4:value} + == + """ + :- '?&' + """ + $\{1:condition} + == + """ + :- '?@' + """ + $\{1:value} + $\{2:if-atom} + $\{3:if-cell} + """ + :- '?~' + """ + $\{1:value} + $\{2:if-null} + $\{3:if-nonnull} + """ + :- '?#' + """ + $\{1:skin} + $\{2:wing} + """ + :- '?=' + """ + $\{1:type} + $\{2:wing} + """ + :- '?!' + """ + $\{1:loobean} + """ + :: + :- '!,' + """ + *hoon + $\{1:ast} + """ + :- '!>' + """ + $\{1:value} + """ + :- '!;' + """ + $\{1:type} + $\{2:body} + """ + :- '!=' + """ + $\{1:body} + """ + :- '!@' + """ + $\{1:wing} + $\{2:if-exists} + $\{3:if-not-exists} + """ + :- '!?' + """ + $\{1:version} + $\{2:body} + """ + :- '!!' + "" + == +-- +|= rune=tape +^- (list completion-item:lsp-sur) +=? rune =(' ' (snag 0 rune)) + (slag 1 rune) +~& rune +%+ turn (search-prefix:auto (crip rune) runes) +|= [name=cord snippet=tape] +^- completion-item:lsp-sur +[name 1 '' '' (crip snippet) 2] diff --git a/pkg/base-dev/lib/server.hoon b/pkg/base-dev/lib/server.hoon new file mode 100644 index 0000000000..431b5db8ac --- /dev/null +++ b/pkg/base-dev/lib/server.hoon @@ -0,0 +1,159 @@ +=, eyre +|% ++$ request-line + $: [ext=(unit @ta) site=(list @t)] + args=(list [key=@t value=@t]) + == +:: +parse-request-line: take a cord and parse out a url +:: +++ parse-request-line + |= url=@t + ^- request-line + (fall (rush url ;~(plug apat:de-purl:html yque:de-purl:html)) [[~ ~] ~]) +:: +++ manx-to-octs + |= man=manx + ^- octs + (as-octt:mimes:html (en-xml:html man)) +:: +++ json-to-octs + |= jon=json + ^- octs + (as-octt:mimes:html (en-json:html jon)) +:: +++ app + |% + :: + :: +require-authorization: + :: redirect to the login page when unauthenticated + :: otherwise call handler on inbound request + :: + ++ require-authorization + |= $: =inbound-request:eyre + handler=$-(inbound-request:eyre simple-payload:http) + == + ^- simple-payload:http + :: + ?: authenticated.inbound-request + ~! this + ~! +:*handler + (handler inbound-request) + :: + =- [[307 ['location' -]~] ~] + %^ cat 3 + '/~/login?redirect=' + url.request.inbound-request + :: + :: +require-authorization-simple: + :: redirect to the login page when unauthenticated + :: otherwise pass through simple-paylod + :: + ++ require-authorization-simple + |= [=inbound-request:eyre =simple-payload:http] + ^- simple-payload:http + :: + ?: authenticated.inbound-request + ~! this + simple-payload + :: + =- [[307 ['location' -]~] ~] + %^ cat 3 + '/~/login?redirect=' + url.request.inbound-request + :: + ++ give-simple-payload + |= [eyre-id=@ta =simple-payload:http] + ^- (list card:agent:gall) + =/ header-cage + [%http-response-header !>(response-header.simple-payload)] + =/ data-cage + [%http-response-data !>(data.simple-payload)] + :~ [%give %fact ~[/http-response/[eyre-id]] header-cage] + [%give %fact ~[/http-response/[eyre-id]] data-cage] + [%give %kick ~[/http-response/[eyre-id]] ~] + == + -- +++ gen + |% + :: + ++ max-1-da ['cache-control' 'max-age=86400'] + ++ max-1-wk ['cache-control' 'max-age=604800'] + :: + ++ html-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'text/html'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ css-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'text/css'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ js-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'text/javascript'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ png-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'image/png'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ svg-response + =| cache=? + |= =octs + ^- simple-payload:http + :_ `octs + [200 [['content-type' 'image/svg+xml'] ?:(cache [max-1-wk ~] ~)]] + :: + ++ ico-response + |= =octs + ^- simple-payload:http + [[200 [['content-type' 'image/x-icon'] max-1-wk ~]] `octs] + :: + ++ woff2-response + =| cache=? + |= =octs + ^- simple-payload:http + [[200 [['content-type' 'font/woff2'] max-1-wk ~]] `octs] + :: + ++ json-response + =| cache=_| + |= =json + ^- simple-payload:http + :_ `(json-to-octs json) + [200 [['content-type' 'application/json'] ?:(cache [max-1-da ~] ~)]] + :: + ++ manx-response + =| cache=_| + |= man=manx + ^- simple-payload:http + :_ `(manx-to-octs man) + [200 [['content-type' 'text/html'] ?:(cache [max-1-da ~] ~)]] + :: + ++ not-found + ^- simple-payload:http + [[404 ~] ~] + :: + ++ login-redirect + |= =request:http + ^- simple-payload:http + =- [[307 ['location' -]~] ~] + %^ cat 3 + '/~/login?redirect=' + url.request + :: + ++ redirect + |= redirect=cord + ^- simple-payload:http + [[307 ['location' redirect]~] ~] + -- +-- diff --git a/pkg/base-dev/lib/shoe.hoon b/pkg/base-dev/lib/shoe.hoon new file mode 100644 index 0000000000..0348e10e52 --- /dev/null +++ b/pkg/base-dev/lib/shoe.hoon @@ -0,0 +1,532 @@ +:: shoe: console application library +:: +:: /lib/sole: draw some characters +:: /lib/shoe: draw the rest of the fscking app +:: +:: call +agent with a type, then call the resulting function with a core +:: of the shape described in +shoe. +:: you may produce classic gall cards and "shoe-effects", shorthands for +:: sending cli events to connected clients. +:: default implementations for the shoe-specific arms are in +default. +:: for a simple usage example, see /app/shoe. +:: +/- *sole +/+ sole, auto=language-server-complete +|% ++$ state-0 + $: %0 + soles=(map @ta sole-share) + == +:: $card: standard gall cards plus shoe effects +:: ++$ card + $% card:agent:gall + [%shoe sole-ids=(list @ta) effect=shoe-effect] :: ~ sends to all soles + == +:: $shoe-effect: easier sole-effects +:: ++$ shoe-effect + $% :: %sole: raw sole-effect + :: + [%sole effect=sole-effect] + :: %table: sortable, filterable data, with suggested column char widths + :: + [%table head=(list dime) wide=(list @ud) rows=(list (list dime))] + :: %row: line sections with suggested char widths + :: + [%row wide=(list @ud) cols=(list dime)] + == +:: +shoe: gall agent core with extra arms +:: +++ shoe + |* command-type=mold + $_ ^| + |_ bowl:gall + :: +command-parser: input parser for a specific session + :: + :: if the head of the result is true, instantly run the command + :: + ++ command-parser + |~ sole-id=@ta + |~(nail *(like [? command-type])) + :: +tab-list: autocomplete options for the session (to match +command-parser) + :: + ++ tab-list + |~ sole-id=@ta + :: (list [@t tank]) + *(list (option:auto tank)) + :: +on-command: called when a valid command is run + :: + ++ on-command + |~ [sole-id=@ta command=command-type] + *(quip card _^|(..on-init)) + :: + ++ can-connect + |~ sole-id=@ta + *? + :: + ++ on-connect + |~ sole-id=@ta + *(quip card _^|(..on-init)) + :: + ++ on-disconnect + |~ sole-id=@ta + *(quip card _^|(..on-init)) + :: + ::NOTE standard gall agent arms below, though they may produce %shoe cards + :: + ++ on-init + *(quip card _^|(..on-init)) + :: + ++ on-save + *vase + :: + ++ on-load + |~ vase + *(quip card _^|(..on-init)) + :: + ++ on-poke + |~ [mark vase] + *(quip card _^|(..on-init)) + :: + ++ on-watch + |~ path + *(quip card _^|(..on-init)) + :: + ++ on-leave + |~ path + *(quip card _^|(..on-init)) + :: + ++ on-peek + |~ path + *(unit (unit cage)) + :: + ++ on-agent + |~ [wire sign:agent:gall] + *(quip card _^|(..on-init)) + :: + ++ on-arvo + |~ [wire sign-arvo] + *(quip card _^|(..on-init)) + :: + ++ on-fail + |~ [term tang] + *(quip card _^|(..on-init)) + -- +:: +default: bare-minimum implementations of shoe arms +:: +++ default + |* [shoe=* command-type=mold] + |_ =bowl:gall + ++ command-parser + |= sole-id=@ta + (easy *[? command-type]) + :: + ++ tab-list + |= sole-id=@ta + ~ + :: + ++ on-command + |= [sole-id=@ta command=command-type] + [~ shoe] + :: + ++ can-connect + |= sole-id=@ta + (team:title [our src]:bowl) + :: + ++ on-connect + |= sole-id=@ta + [~ shoe] + :: + ++ on-disconnect + |= sole-id=@ta + [~ shoe] + -- +:: +agent: creates wrapper core that handles sole events and calls shoe arms +:: +++ agent + |* command-type=mold + |= =(shoe command-type) + =| state-0 + =* state - + ^- agent:gall + => + |% + ++ deal + |= cards=(list card) + %+ turn cards + |= =card + ^- card:agent:gall + ?. ?=(%shoe -.card) card + ?- -.effect.card + %sole + =- [%give %fact - %sole-effect !>(effect.effect.card)] + %+ turn + ?^ sole-ids.card sole-ids.card + ~(tap in ~(key by soles)) + |= sole-id=@ta + /sole/[sole-id] + :: + %table + =; fez=(list sole-effect) + $(effect.card [%sole %mor fez]) + =, +.effect.card + :- (row:draw & wide head) + %+ turn rows + (cury (cury row:draw |) wide) + :: + %row + $(effect.card [%sole (row:draw | +.effect.card)]) + == + -- + :: + |_ =bowl:gall + +* this . + og ~(. shoe bowl) + :: + ++ on-init + ^- (quip card:agent:gall agent:gall) + =^ cards shoe on-init:og + [(deal cards) this] + :: + ++ on-save !>([%shoe-app on-save:og state]) + :: + ++ on-load + |= old-state=vase + ^- (quip card:agent:gall agent:gall) + :: we could be upgrading from a shoe-less app, in which case the vase + :: contains inner application state instead of our +on-save. + :: to distinguish between the two, we check for the presence of our own + :: +on-save tag in the vase. + :: + ?. ?=([%shoe-app ^] q.old-state) + =^ cards shoe (on-load:og old-state) + [(deal cards) this] + =^ old-inner state +:!<([%shoe-app vase state-0] old-state) + =^ cards shoe (on-load:og old-inner) + [(deal cards) this] + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card:agent:gall agent:gall) + ?. ?=(%sole-action mark) + =^ cards shoe (on-poke:og mark vase) + [(deal cards) this] + :: + =/ act !<(sole-action vase) + =* sole-id id.act + =/ cli-state=sole-share + (~(gut by soles) sole-id *sole-share) + |^ =^ [cards=(list card) =_cli-state] shoe + ?- -.dat.act + %det (apply-edit +.dat.act) + %clr [[~ cli-state] shoe] + %ret try-command + %tab [(tab +.dat.act) shoe] + == + :- (deal cards) + this(soles (~(put by soles) sole-id cli-state)) + :: + ++ effect + |= =sole-effect + ^- card + [%shoe [sole-id]~ %sole sole-effect] + :: + ++ apply-edit + |= =sole-change + ^+ [[*(list card) cli-state] shoe] + =^ inverse cli-state + (~(transceive sole cli-state) sole-change) + :: res: & for fully parsed, | for parsing failure at location + :: + =/ res=(each (unit [run=? cmd=command-type]) @ud) + %+ rose (tufa buf.cli-state) + (command-parser:og sole-id) + ?: ?=(%& -.res) + :: only auto-run eligible commands if they were typed out + :: (that is, not retrieved from command history) + :: + ?. &(?=(^ p.res) run.u.p.res !?=(%set -.ted.sole-change)) + [[~ cli-state] shoe] + (run-command cmd.u.p.res) + :_ shoe + :: parsing failed + :: + ?. &(?=(%del -.inverse) =(+(p.inverse) (lent buf.cli-state))) + :: if edit was somewhere in the middle, let it happen anyway + :: + [~ cli-state] + :: if edit was insertion at buffer tail, revert it + :: + =^ undo cli-state + (~(transmit sole cli-state) inverse) + :_ cli-state + :_ ~ + %+ effect %mor + :~ [%det undo] :: undo edit + [%err p.res] :: cursor to error location + == + :: + ++ try-command + ^+ [[*(list card) cli-state] shoe] + =/ res=(unit [? cmd=command-type]) + %+ rust (tufa buf.cli-state) + (command-parser:og sole-id) + ?^ res (run-command cmd.u.res) + [[[(effect %bel ~)]~ cli-state] shoe] + :: + ++ run-command + |= cmd=command-type + ^+ [[*(list card) cli-state] shoe] + =^ cards shoe (on-command:og sole-id cmd) + :: clear buffer + :: + =^ clear cli-state (~(transmit sole cli-state) [%set ~]) + =- [[[- cards] cli-state] shoe] + %+ effect %mor + :~ [%nex ~] + [%det clear] + == + :: + ++ tab + |= pos=@ud + ^- (quip card _cli-state) + =+ (get-id-cord:auto pos (tufa buf.cli-state)) + =/ needle=term + (fall id %$) + :: autocomplete empty command iff user at start of command + :: + =/ options=(list (option:auto tank)) + (search-prefix:auto needle (tab-list:og sole-id)) + =/ advance=term + (longest-match:auto options) + =/ to-send=tape + %- trip + (rsh [3 (met 3 needle)] advance) + =/ send-pos=@ud + %+ add pos + (met 3 (fall forward '')) + =| cards=(list card) + :: only render the option list if we couldn't complete anything + :: + =? cards &(?=(~ to-send) ?=(^ options)) + [(effect %tab options) cards] + |- ^- (quip card _cli-state) + ?~ to-send + [(flop cards) cli-state] + =^ char cli-state + (~(transmit sole cli-state) [%ins send-pos `@c`i.to-send]) + %_ $ + cards [(effect %det char) cards] + send-pos +(send-pos) + to-send t.to-send + == + -- + :: + ++ on-watch + |= =path + ^- (quip card:agent:gall agent:gall) + ?. ?=([%sole @ ~] path) + =^ cards shoe + (on-watch:og path) + [(deal cards) this] + =* sole-id i.t.path + ?> (can-connect:og sole-id) + =. soles (~(put by soles) sole-id *sole-share) + =^ cards shoe + (on-connect:og sole-id) + :_ this + %- deal + :_ cards + [%shoe [sole-id]~ %sole %pro & dap.bowl "> "] + :: + ++ on-leave + |= =path + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-leave:og path) + [(deal cards) this] + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + ?. =(/x/dbug/state path) ~ + ``noun+(slop on-save:og !>(shoe=state)) + :: + ++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-agent:og wire sign) + [(deal cards) this] + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-arvo:og wire sign-arvo) + [(deal cards) this] + :: + ++ on-fail + |= [=term =tang] + ^- (quip card:agent:gall agent:gall) + =^ cards shoe (on-fail:og term tang) + [(deal cards) this] + -- +:: +++ draw + |% + ++ row + |= [bold=? wide=(list @ud) cols=(list dime)] + ^- sole-effect + :- %mor + ^- (list sole-effect) + =/ cows=(list [wid=@ud col=dime]) + %- head + %^ spin cols wide + |= [col=dime wiz=(list @ud)] + ~| [%too-few-wide col] + ?> ?=(^ wiz) + [[i.wiz col] t.wiz] + =/ cobs=(list [wid=@ud (list tape)]) + (turn cows col-as-lines) + =+ [lin=0 any=|] + =| fez=(list sole-effect) + |- ^+ fez + =; out=tape + :: done when we're past the end of all columns + :: + ?: (levy out (cury test ' ')) + (flop fez) + =; fec=sole-effect + $(lin +(lin), fez [fec fez]) + ?. bold txt+out + klr+[[`%br ~ ~]^[(crip out)]~]~ + %+ roll cobs + |= [[wid=@ud lines=(list tape)] out=tape] + %+ weld out + %+ weld ?~(out "" " ") + =+ l=(swag [lin 1] lines) + ?^(l i.l (reap wid ' ')) + :: + ++ col-as-lines + |= [wid=@ud col=dime] + ^- [@ud (list tape)] + :- wid + %+ turn + (break wid (col-as-text col) (break-sets -.col)) + (cury (cury pad wid) (alignment -.col)) + :: + ++ col-as-text + |= col=dime + ^- tape + ?+ p.col (scow col) + %t (trip q.col) + %tas ['%' (scow col)] + == + :: + ++ alignment + |= wut=@ta + ^- ?(%left %right) + ?: ?=(?(%t %ta %tas %da) wut) + %left + %right + :: + ++ break-sets + |= wut=@ta + :: for: may break directly before these characters + :: aft: may break directly after these characters + :: new: always break on these characters, consuming them + :: + ^- [for=(set @t) aft=(set @t) new=(set @t)] + ?+ wut [(sy " ") (sy ".:-/") (sy "\0a")] + ?(%p %q) [(sy "-") (sy "-") ~] + %ux [(sy ".") ~ ~] + == + :: + ++ break + |= [wid=@ud cot=tape brs=_*break-sets] + ^- (list tape) + ~| [wid cot] + ?: =("" cot) ~ + =; [lin=tape rem=tape] + [lin $(cot rem)] + :: take snip of max width+1, search for breakpoint on that. + :: we grab one char extra, to look-ahead for for.brs. + :: later on, we always transfer _at least_ the extra char. + :: + =^ lin=tape cot + [(scag +(wid) cot) (slag +(wid) cot)] + =+ len=(lent lin) + :: find the first newline character + :: + =/ new=(unit @ud) + =+ new=~(tap in new.brs) + =| las=(unit @ud) + |- + ?~ new las + $(new t.new, las (hunt lth las (find [i.new]~ lin))) + :: if we found a newline, break on it + :: + ?^ new + :- (scag u.new lin) + (weld (slag +(u.new) lin) cot) + :: if it fits, we're done + :: + ?: (lte len wid) + [lin cot] + =+ nil=(flop lin) + :: search for latest aft match + :: + =/ aft=(unit @ud) + :: exclude the look-ahead character from search + :: + =. len (dec len) + =. nil (slag 1 nil) + =- ?~(- ~ `+(u.-)) + ^- (unit @ud) + =+ aft=~(tap in aft.brs) + =| las=(unit @ud) + |- + ?~ aft (bind las (cury sub (dec len))) + $(aft t.aft, las (hunt lth las (find [i.aft]~ nil))) + :: search for latest for match + :: + =/ for=(unit @ud) + =+ for=~(tap in for.brs) + =| las=(unit @ud) + |- + ?~ for (bind las (cury sub (dec len))) + =- $(for t.for, las (hunt lth las -)) + =+ (find [i.for]~ nil) + :: don't break before the first character + :: + ?:(=(`(dec len) -) ~ -) + :: if any result, break as late as possible + :: + =+ brk=(hunt gth aft for) + ?~ brk + :: lin can't break, produce it in its entirety + :: (after moving the look-ahead character back) + :: + :- (scag wid lin) + (weld (slag wid lin) cot) + :- (scag u.brk lin) + =. cot (weld (slag u.brk lin) cot) + :: eat any leading whitespace the next line might have, "clean break" + :: + |- ^+ cot + ?~ cot ~ + ?. ?=(?(%' ' %'\09') i.cot) + cot + $(cot t.cot) + :: + ++ pad + |= [wid=@ud lyn=?(%left %right) lin=tape] + ^+ lin + =+ l=(lent lin) + ?: (gte l wid) lin + =+ p=(reap (sub wid l) ' ') + ?- lyn + %left (weld lin p) + %right (weld p lin) + == + -- +-- diff --git a/pkg/base-dev/lib/sole.hoon b/pkg/base-dev/lib/sole.hoon new file mode 100644 index 0000000000..66684668a6 --- /dev/null +++ b/pkg/base-dev/lib/sole.hoon @@ -0,0 +1,139 @@ +:: +:::: /hoon/sole/lib + :: +/? 310 +/- *sole +:::: + :: +|_ sole-share :: shared-state engine +++ abet +< +++ apply + |= ted=sole-edit + ^+ +> + ?- -.ted + %del +>.$(buf (weld (scag p.ted buf) (slag +(p.ted) buf))) + %ins +>.$(buf (weld (scag p.ted buf) `_buf`[q.ted (slag p.ted buf)])) + %mor |- ^+ +>.^$ + ?~ p.ted + +>.^$ + $(p.ted t.p.ted, +>.^$ ^$(ted i.p.ted)) + %nop +>.$ + %set +>.$(buf p.ted) + == +:: +:::: +:: ++transmute: symmetric operational transformation. +:: +:: for any sole state +>, obeys +:: +:: =+ [x=(transmute a b) y=(transmute b a)] +:: .= (apply:(apply a) x) +:: (apply:(apply b) y) +:: +++ transmute :: dex as after sin + |= [sin=sole-edit dex=sole-edit] + ~| [%transmute sin dex] + ^- sole-edit + ?: ?=(%mor -.sin) + |- ^- sole-edit + ?~ p.sin dex + $(p.sin t.p.sin, dex ^$(sin i.p.sin)) + :: + ?: ?=(%mor -.dex) + :- %mor + |- ^- (list sole-edit) + ?~ p.dex ~ + [^$(dex i.p.dex) $(p.dex t.p.dex)] + :: + ?: |(?=(%nop -.sin) ?=(%nop -.dex)) dex + ?: ?=(%set -.sin) [%nop ~] + ?: ?=(%set -.dex) dex + :: + ?- -.sin + %del + ?- -.dex + %del ?: =(p.sin p.dex) [%nop ~] + ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex) + %ins ?:((lth p.sin p.dex) dex(p (dec p.dex)) dex) + == + :: + %ins + ?- -.dex + %del ?:((lte p.sin p.dex) dex(p +(p.dex)) dex) + %ins ?: =(p.sin p.dex) + ?:((lth q.sin q.dex) dex dex(p +(p.dex))) + ?:((lte p.sin p.dex) dex(p +(p.dex)) dex) + == + == +:: +++ commit :: local change + |= ted=sole-edit + ^- sole-share + abet:(apply(own.ven +(own.ven), leg [ted leg]) ted) +:: +:::: +:: ++inverse: inverse of change in context. +:: +:: for any sole state +>, obeys +:: +:: =(+> (apply:(apply a) (inverse a))) +:: +++ inverse :: relative inverse + |= ted=sole-edit + ^- sole-edit + =. ted ?.(?=([%mor * ~] ted) ted i.p.ted) + ?- -.ted + %del [%ins p.ted (snag p.ted buf)] + %ins [%del p.ted] + %mor :- %mor + %- flop + |- ^- (list sole-edit) + ?~ p.ted ~ + :- ^$(ted i.p.ted) + $(p.ted t.p.ted, +>.^$ (apply i.p.ted)) + %nop [%nop ~] + %set [%set buf] + == +:: +++ receive :: naturalize event + |= sole-change + ^- [sole-edit sole-share] + ?. &(=(his.ler his.ven) (lte own.ler own.ven)) + ~| [%receive-sync his+[his.ler his.ven] own+[own.ler own.ven]] + !! + ?> &(=(his.ler his.ven) (lte own.ler own.ven)) + ?> |(!=(own.ler own.ven) =(`@`0 haw) =(haw (sham buf))) + =. leg (scag (sub own.ven own.ler) leg) + :: ~? !=(own.ler own.ven) [%miss-leg leg] + =+ dat=(transmute [%mor leg] ted) + :: ~? !=(~ leg) [%transmute from+ted to+dat ~] + [dat abet:(apply(his.ven +(his.ven)) dat)] +:: +++ remit :: conditional accept + |= [cal=sole-change ask=$-((list @c) ?)] + ^- [(unit sole-change) sole-share] + =+ old=buf + =^ dat +>+<.$ (receive cal) + ?: (ask buf) + [~ +>+<.$] + =^ lic +>+<.$ (transmit (inverse(buf old) dat)) + [`lic +>+<.$] +:: +++ transmit :: outgoing change + |= ted=sole-edit + ^- [sole-change sole-share] + [[[his.ven own.ven] (sham buf) ted] (commit ted)] +:: +++ transceive :: receive and invert + |= sole-change + ^- [sole-edit sole-share] + =+ old=buf + =^ dat +>+<.$ (receive +<.$) + [(inverse(buf old) dat) +>+<.$] +:: +++ transpose :: adjust position + |= pos=@ud + =+ dat=(transmute [%mor leg] [%ins pos `@c`0]) + ?> ?=(%ins -.dat) + p.dat +-- diff --git a/pkg/base-dev/lib/strand.hoon b/pkg/base-dev/lib/strand.hoon new file mode 100644 index 0000000000..b618f2d4e3 --- /dev/null +++ b/pkg/base-dev/lib/strand.hoon @@ -0,0 +1,167 @@ +|% ++$ card card:agent:gall ++$ input + $% [%poke =cage] + [%sign =wire =sign-arvo] + [%agent =wire =sign:agent:gall] + [%watch =path] + == ++$ strand-input [=bowl in=(unit input)] ++$ tid @tatid ++$ bowl + $: our=ship + src=ship + tid=tid + mom=(unit tid) + wex=boat:gall + sup=bitt:gall + eny=@uvJ + now=@da + byk=beak + == +:: +:: cards: cards to send immediately. These will go out even if a +:: later stage of the computation fails, so they shouldn't have +:: any semantic effect on the rest of the system. +:: Alternately, they may record an entry in contracts with +:: enough information to undo the effect if the computation +:: fails. +:: wait: don't move on, stay here. The next sign should come back +:: to this same callback. +:: skip: didn't expect this input; drop it down to be handled +:: elsewhere +:: cont: continue computation with new callback. +:: fail: abort computation; don't send effects +:: done: finish computation; send effects +:: +++ strand-output-raw + |* a=mold + $~ [~ %done *a] + $: cards=(list card) + $= next + $% [%wait ~] + [%skip ~] + [%cont self=(strand-form-raw a)] + [%fail err=(pair term tang)] + [%done value=a] + == + == +:: +++ strand-form-raw + |* a=mold + $-(strand-input (strand-output-raw a)) +:: +:: Abort strand computation with error message +:: +++ strand-fail + |= err=(pair term tang) + |= strand-input + [~ %fail err] +:: +:: Asynchronous transcaction monad. +:: +:: Combo of four monads: +:: - Reader on input +:: - Writer on card +:: - Continuation +:: - Exception +:: +++ strand + |* a=mold + |% + ++ output (strand-output-raw a) + :: + :: Type of an strand computation. + :: + ++ form (strand-form-raw a) + :: + :: Monadic pure. Identity computation for bind. + :: + ++ pure + |= arg=a + ^- form + |= strand-input + [~ %done arg] + :: + :: Monadic bind. Combines two computations, associatively. + :: + ++ bind + |* b=mold + |= [m-b=(strand-form-raw b) fun=$-(b form)] + ^- form + |= input=strand-input + =/ b-res=(strand-output-raw b) + (m-b input) + ^- output + :- cards.b-res + ?- -.next.b-res + %wait [%wait ~] + %skip [%skip ~] + %cont [%cont ..$(m-b self.next.b-res)] + %fail [%fail err.next.b-res] + %done [%cont (fun value.next.b-res)] + == + :: + :: The strand monad must be evaluted in a particular way to maintain + :: its monadic character. +take:eval implements this. + :: + ++ eval + |% + :: Indelible state of a strand + :: + +$ eval-form + $: =form + == + :: + :: Convert initial form to eval-form + :: + ++ from-form + |= =form + ^- eval-form + form + :: + :: The cases of results of +take + :: + +$ eval-result + $% [%next ~] + [%fail err=(pair term tang)] + [%done value=a] + == + :: + :: Take a new sign and run the strand against it + :: + ++ take + :: cards: accumulate throughout recursion the cards to be + :: produced now + =| cards=(list card) + |= [=eval-form =strand-input] + ^- [[(list card) =eval-result] _eval-form] + =* take-loop $ + :: run the strand callback + :: + =/ =output (form.eval-form strand-input) + :: add cards to cards + :: + =. cards + %+ welp + cards + :: XX add tag to wires? + cards.output + :: case-wise handle next steps + :: + ?- -.next.output + %wait [[cards %next ~] eval-form] + %skip [[cards %next ~] eval-form] + %fail [[cards %fail err.next.output] eval-form] + %done [[cards %done value.next.output] eval-form] + %cont + :: recurse to run continuation with initialization input + :: + %_ take-loop + form.eval-form self.next.output + strand-input [bowl.strand-input ~] + == + == + -- + -- +-- diff --git a/pkg/base-dev/lib/strandio.hoon b/pkg/base-dev/lib/strandio.hoon new file mode 100644 index 0000000000..03ad35079a --- /dev/null +++ b/pkg/base-dev/lib/strandio.hoon @@ -0,0 +1,742 @@ +/- spider +/+ libstrand=strand +=, strand=strand:libstrand +=, strand-fail=strand-fail:libstrand +|% +++ send-raw-cards + |= cards=(list =card:agent:gall) + =/ m (strand ,~) + ^- form:m + |= strand-input:strand + [cards %done ~] +:: +++ send-raw-card + |= =card:agent:gall + =/ m (strand ,~) + ^- form:m + (send-raw-cards card ~) +:: +++ ignore + |= tin=strand-input:strand + `[%fail %ignore ~] +:: +++ get-bowl + =/ m (strand ,bowl:strand) + ^- form:m + |= tin=strand-input:strand + `[%done bowl.tin] +:: +++ get-beak + =/ m (strand ,beak) + ^- form:m + |= tin=strand-input:strand + `[%done [our q.byk da+now]:bowl.tin] +:: +++ get-time + =/ m (strand ,@da) + ^- form:m + |= tin=strand-input:strand + `[%done now.bowl.tin] +:: +++ get-our + =/ m (strand ,ship) + ^- form:m + |= tin=strand-input:strand + `[%done our.bowl.tin] +:: +++ get-entropy + =/ m (strand ,@uvJ) + ^- form:m + |= tin=strand-input:strand + `[%done eny.bowl.tin] +:: +:: Convert skips to %ignore failures. +:: +:: This tells the main loop to try the next handler. +:: +++ handle + |* a=mold + =/ m (strand ,a) + |= =form:m + ^- form:m + |= tin=strand-input:strand + =/ res (form tin) + =? next.res ?=(%skip -.next.res) + [%fail %ignore ~] + res +:: +:: Wait for a poke with a particular mark +:: +++ take-poke + |= =mark + =/ m (strand ,vase) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %poke @ *] + ?. =(mark p.cage.u.in.tin) + `[%skip ~] + `[%done q.cage.u.in.tin] + == +:: +:: +:: +++ take-sign-arvo + =/ m (strand ,[wire sign-arvo]) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign *] + `[%done [wire sign-arvo]:u.in.tin] + == +:: +:: Wait for a subscription update on a wire +:: +++ take-fact-prefix + |= =wire + =/ m (strand ,[path cage]) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %fact *] + ?. =(watch+wire (scag +((lent wire)) wire.u.in.tin)) + `[%skip ~] + `[%done (slag (lent wire) wire.u.in.tin) cage.sign.u.in.tin] + == +:: +:: Wait for a subscription update on a wire +:: +++ take-fact + |= =wire + =/ m (strand ,cage) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %fact *] + ?. =(watch+wire wire.u.in.tin) + `[%skip ~] + `[%done cage.sign.u.in.tin] + == +:: +:: Wait for a subscription close +:: +++ take-kick + |= =wire + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %kick *] + ?. =(watch+wire wire.u.in.tin) + `[%skip ~] + `[%done ~] + == +:: +++ echo + =/ m (strand ,~) + ^- form:m + %- (main-loop ,~) + :~ |= ~ + ^- form:m + ;< =vase bind:m ((handle ,vase) (take-poke %echo)) + =/ message=tape !<(tape vase) + %- (slog leaf+"{message}..." ~) + ;< ~ bind:m (sleep ~s2) + %- (slog leaf+"{message}.." ~) + (pure:m ~) + :: + |= ~ + ^- form:m + ;< =vase bind:m ((handle ,vase) (take-poke %over)) + %- (slog leaf+"over..." ~) + (pure:m ~) + == +:: +++ take-watch + =/ m (strand ,path) + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %watch *] + `[%done path.u.in.tin] + == +:: +++ take-wake + |= until=(unit @da) + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign [%wait @ ~] %behn %wake *] + ?. |(?=(~ until) =(`u.until (slaw %da i.t.wire.u.in.tin))) + `[%skip ~] + ?~ error.sign-arvo.u.in.tin + `[%done ~] + `[%fail %timer-error u.error.sign-arvo.u.in.tin] + == +:: +++ take-poke-ack + |= =wire + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %poke-ack *] + ?. =(wire wire.u.in.tin) + `[%skip ~] + ?~ p.sign.u.in.tin + `[%done ~] + `[%fail %poke-fail u.p.sign.u.in.tin] + == +:: +++ take-watch-ack + |= =wire + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %agent * %watch-ack *] + ?. =(watch+wire wire.u.in.tin) + `[%skip ~] + ?~ p.sign.u.in.tin + `[%done ~] + `[%fail %watch-ack-fail u.p.sign.u.in.tin] + == +:: +++ poke + |= [=dock =cage] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass /poke %agent dock %poke cage] + ;< ~ bind:m (send-raw-card card) + (take-poke-ack /poke) +:: +++ raw-poke + |= [=dock =cage] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass /poke %agent dock %poke cage] + ;< ~ bind:m (send-raw-card card) + =/ m (strand ,~) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ + `[%wait ~] + :: + [~ %agent * %poke-ack *] + ?. =(/poke wire.u.in.tin) + `[%skip ~] + `[%done ~] + == +:: +++ raw-poke-our + |= [app=term =cage] + =/ m (strand ,~) + ^- form:m + ;< =bowl:spider bind:m get-bowl + (raw-poke [our.bowl app] cage) +:: +++ poke-our + |= [=term =cage] + =/ m (strand ,~) + ^- form:m + ;< our=@p bind:m get-our + (poke [our term] cage) +:: +++ watch + |= [=wire =dock =path] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass watch+wire %agent dock %watch path] + ;< ~ bind:m (send-raw-card card) + (take-watch-ack wire) +:: +++ watch-our + |= [=wire =term =path] + =/ m (strand ,~) + ^- form:m + ;< our=@p bind:m get-our + (watch wire [our term] path) +:: +++ scry + |* [=mold =path] + =/ m (strand ,mold) + ^- form:m + ?> ?=(^ path) + ?> ?=(^ t.path) + ;< =bowl:spider bind:m get-bowl + %- pure:m + .^(mold i.path (scot %p our.bowl) i.t.path (scot %da now.bowl) t.t.path) +:: +++ leave + |= [=wire =dock] + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall [%pass watch+wire %agent dock %leave ~] + (send-raw-card card) +:: +++ leave-our + |= [=wire =term] + =/ m (strand ,~) + ^- form:m + ;< our=@p bind:m get-our + (leave wire [our term]) +:: +++ rewatch + |= [=wire =dock =path] + =/ m (strand ,~) + ;< ~ bind:m ((handle ,~) (take-kick wire)) + ;< ~ bind:m (flog-text "rewatching {} {}") + ;< ~ bind:m (watch wire dock path) + (pure:m ~) +:: +++ wait + |= until=@da + =/ m (strand ,~) + ^- form:m + ;< ~ bind:m (send-wait until) + (take-wake `until) +:: +++ sleep + |= for=@dr + =/ m (strand ,~) + ^- form:m + ;< now=@da bind:m get-time + (wait (add now for)) +:: +++ send-wait + |= until=@da + =/ m (strand ,~) + ^- form:m + =/ =card:agent:gall + [%pass /wait/(scot %da until) %arvo %b %wait until] + (send-raw-card card) +:: +++ map-err + |* computation-result=mold + =/ m (strand ,computation-result) + |= [f=$-([term tang] [term tang]) computation=form:m] + ^- form:m + |= tin=strand-input:strand + =* loop $ + =/ c-res (computation tin) + ?: ?=(%cont -.next.c-res) + c-res(self.next ..loop(computation self.next.c-res)) + ?. ?=(%fail -.next.c-res) + c-res + c-res(err.next (f err.next.c-res)) +:: +++ set-timeout + |* computation-result=mold + =/ m (strand ,computation-result) + |= [time=@dr computation=form:m] + ^- form:m + ;< now=@da bind:m get-time + =/ when (add now time) + =/ =card:agent:gall + [%pass /timeout/(scot %da when) %arvo %b %wait when] + ;< ~ bind:m (send-raw-card card) + |= tin=strand-input:strand + =* loop $ + ?: ?& ?=([~ %sign [%timeout @ ~] %behn %wake *] in.tin) + =((scot %da when) i.t.wire.u.in.tin) + == + `[%fail %timeout ~] + =/ c-res (computation tin) + ?: ?=(%cont -.next.c-res) + c-res(self.next ..loop(computation self.next.c-res)) + ?: ?=(%done -.next.c-res) + =/ =card:agent:gall + [%pass /timeout/(scot %da when) %arvo %b %rest when] + c-res(cards [card cards.c-res]) + c-res +:: +++ send-request + |= =request:http + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass /request %arvo %i %request request *outbound-config:iris) +:: +++ send-cancel-request + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass /request %arvo %i %cancel-request ~) +:: +++ take-client-response + =/ m (strand ,client-response:iris) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign [%request ~] %iris %http-response %finished *] + `[%done client-response.sign-arvo.u.in.tin] + == +:: +:: Wait until we get an HTTP response or cancelation and unset contract +:: +++ take-maybe-sigh + =/ m (strand ,(unit httr:eyre)) + ^- form:m + ;< rep=(unit client-response:iris) bind:m + take-maybe-response + ?~ rep + (pure:m ~) + :: XX s/b impossible + :: + ?. ?=(%finished -.u.rep) + (pure:m ~) + (pure:m (some (to-httr:iris +.u.rep))) +:: +++ take-maybe-response + =/ m (strand ,(unit client-response:iris)) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign [%request ~] %iris %http-response %cancel *] + `[%done ~] + [~ %sign [%request ~] %iris %http-response %finished *] + `[%done `client-response.sign-arvo.u.in.tin] + == +:: +++ extract-body + |= =client-response:iris + =/ m (strand ,cord) + ^- form:m + ?> ?=(%finished -.client-response) + ?> ?=(^ full-file.client-response) + (pure:m q.data.u.full-file.client-response) +:: +++ fetch-cord + |= url=tape + =/ m (strand ,cord) + ^- form:m + =/ =request:http [%'GET' (crip url) ~ ~] + ;< ~ bind:m (send-request request) + ;< =client-response:iris bind:m take-client-response + (extract-body client-response) +:: +++ fetch-json + |= url=tape + =/ m (strand ,json) + ^- form:m + ;< =cord bind:m (fetch-cord url) + =/ json=(unit json) (de-json:html cord) + ?~ json + (strand-fail %json-parse-error ~) + (pure:m u.json) +:: +++ hiss-request + |= =hiss:eyre + =/ m (strand ,(unit httr:eyre)) + ^- form:m + ;< ~ bind:m (send-request (hiss-to-request:html hiss)) + take-maybe-sigh +:: +:: +build-file: build the source file at the specified $beam +:: +++ build-file + |= [[=ship =desk =case] =spur] + =* arg +< + =/ m (strand ,(unit vase)) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %a case spur) + ?~ riot + (pure:m ~) + ?> =(%vase p.r.u.riot) + (pure:m (some !<(vase q.r.u.riot))) +:: +build-mark: build a mark definition to a $dais +:: +++ build-mark + |= [[=ship =desk =case] mak=mark] + =* arg +< + =/ m (strand ,dais:clay) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %b case /[mak]) + ?~ riot + (strand-fail %build-mark >arg< ~) + ?> =(%dais p.r.u.riot) + (pure:m !<(dais:clay q.r.u.riot)) +:: +build-tube: build a mark conversion gate ($tube) +:: +++ build-tube + |= [[=ship =desk =case] =mars:clay] + =* arg +< + =/ m (strand ,tube:clay) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %c case /[a.mars]/[b.mars]) + ?~ riot + (strand-fail %build-tube >arg< ~) + ?> =(%tube p.r.u.riot) + (pure:m !<(tube:clay q.r.u.riot)) +:: +:: +build-nave: build a mark definition to a $nave +:: +++ build-nave + |= [[=ship =desk =case] mak=mark] + =* arg +< + =/ m (strand ,vase) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %e case /[mak]) + ?~ riot + (strand-fail %build-nave >arg< ~) + ?> =(%nave p.r.u.riot) + (pure:m q.r.u.riot) +:: +build-cast: build a mark conversion gate (static) +:: +++ build-cast + |= [[=ship =desk =case] =mars:clay] + =* arg +< + =/ m (strand ,vase) + ^- form:m + ;< =riot:clay bind:m + (warp ship desk ~ %sing %f case /[a.mars]/[b.mars]) + ?~ riot + (strand-fail %build-cast >arg< ~) + ?> =(%cast p.r.u.riot) + (pure:m q.r.u.riot) +:: +:: Read from Clay +:: +++ warp + |= [=ship =riff:clay] + =/ m (strand ,riot:clay) + ;< ~ bind:m (send-raw-card %pass /warp %arvo %c %warp ship riff) + (take-writ /warp) +:: +++ read-file + |= [[=ship =desk =case:clay] =spur] + =* arg +< + =/ m (strand ,cage) + ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur) + ?~ riot + (strand-fail %read-file >arg< ~) + (pure:m r.u.riot) +:: +++ check-for-file + |= [[=ship =desk =case:clay] =spur] + =/ m (strand ,?) + ;< =riot:clay bind:m (warp ship desk ~ %sing %x case spur) + (pure:m ?=(^ riot)) +:: +++ list-tree + |= [[=ship =desk =case:clay] =spur] + =* arg +< + =/ m (strand ,(list path)) + ;< =riot:clay bind:m (warp ship desk ~ %sing %t case spur) + ?~ riot + (strand-fail %list-tree >arg< ~) + (pure:m !<((list path) q.r.u.riot)) +:: +:: Take Clay read result +:: +++ take-writ + |= =wire + =/ m (strand ,riot:clay) + ^- form:m + |= tin=strand-input:strand + ?+ in.tin `[%skip ~] + ~ `[%wait ~] + [~ %sign * ?(%behn %clay) %writ *] + ?. =(wire wire.u.in.tin) + `[%skip ~] + `[%done +>.sign-arvo.u.in.tin] + == +:: +check-online: require that peer respond before timeout +:: +++ check-online + |= [who=ship lag=@dr] + =/ m (strand ,~) + ^- form:m + %+ (map-err ,~) |=(* [%offline *tang]) + %+ (set-timeout ,~) lag + ;< ~ bind:m + (poke [who %hood] %helm-hi !>(~)) + (pure:m ~) +:: +:: Queue on skip, try next on fail %ignore +:: +++ main-loop + |* a=mold + =/ m (strand ,~) + =/ m-a (strand ,a) + =| queue=(qeu (unit input:strand)) + =| active=(unit [in=(unit input:strand) =form:m-a forms=(list $-(a form:m-a))]) + =| state=a + |= forms=(lest $-(a form:m-a)) + ^- form:m + |= tin=strand-input:strand + =* top `form:m`..$ + =. queue (~(put to queue) in.tin) + |^ (continue bowl.tin) + :: + ++ continue + |= =bowl:strand + ^- output:m + ?> =(~ active) + ?: =(~ queue) + `[%cont top] + =^ in=(unit input:strand) queue ~(get to queue) + ^- output:m + =. active `[in (i.forms state) t.forms] + ^- output:m + (run bowl in) + :: + ++ run + ^- form:m + |= tin=strand-input:strand + ^- output:m + ?> ?=(^ active) + =/ res (form.u.active tin) + =/ =output:m + ?- -.next.res + %wait `[%wait ~] + %skip `[%cont ..$(queue (~(put to queue) in.tin))] + %cont `[%cont ..$(active `[in.u.active self.next.res forms.u.active])] + %done (continue(active ~, state value.next.res) bowl.tin) + %fail + ?: &(?=(^ forms.u.active) ?=(%ignore p.err.next.res)) + %= $ + active `[in.u.active (i.forms.u.active state) t.forms.u.active] + in.tin in.u.active + == + `[%fail err.next.res] + == + [(weld cards.res cards.output) next.output] + -- +:: +++ retry + |* result=mold + |= [crash-after=(unit @ud) computation=_*form:(strand (unit result))] + =/ m (strand ,result) + =| try=@ud + |- ^- form:m + =* loop $ + ?: =(crash-after `try) + (strand-fail %retry-too-many ~) + ;< ~ bind:m (backoff try ~m1) + ;< res=(unit result) bind:m computation + ?^ res + (pure:m u.res) + loop(try +(try)) +:: +++ backoff + |= [try=@ud limit=@dr] + =/ m (strand ,~) + ^- form:m + ;< eny=@uvJ bind:m get-entropy + %- sleep + %+ min limit + ?: =(0 try) ~s0 + %+ add + (mul ~s1 (bex (dec try))) + (mul ~s0..0001 (~(rad og eny) 1.000)) +:: +:: ---- +:: +:: Output +:: +++ flog + |= =flog:dill + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass / %arvo %d %flog flog) +:: +++ flog-text + |= =tape + =/ m (strand ,~) + ^- form:m + (flog %text tape) +:: +++ flog-tang + |= =tang + =/ m (strand ,~) + ^- form:m + =/ =wall + (zing (turn (flop tang) (cury wash [0 80]))) + |- ^- form:m + =* loop $ + ?~ wall + (pure:m ~) + ;< ~ bind:m (flog-text i.wall) + loop(wall t.wall) +:: +++ trace + |= =tang + =/ m (strand ,~) + ^- form:m + (pure:m ((slog tang) ~)) +:: +++ app-message + |= [app=term =cord =tang] + =/ m (strand ,~) + ^- form:m + =/ msg=tape :(weld (trip app) ": " (trip cord)) + ;< ~ bind:m (flog-text msg) + (flog-tang tang) +:: +:: ---- +:: +:: Handle domains +:: +++ install-domain + |= =turf + =/ m (strand ,~) + ^- form:m + (send-raw-card %pass / %arvo %e %rule %turf %put turf) +:: +:: ---- +:: +:: Threads +:: +++ start-thread + |= file=term + =/ m (strand ,tid:spider) + ;< =bowl:spider bind:m get-bowl + (start-thread-with-args byk.bowl file *vase) +:: +++ start-thread-with-args + |= [=beak file=term args=vase] + =/ m (strand ,tid:spider) + ^- form:m + ;< =bowl:spider bind:m get-bowl + =/ tid + (scot %ta (cat 3 (cat 3 'strand_' file) (scot %uv (sham file eny.bowl)))) + =/ poke-vase !>([`tid.bowl `tid beak file args]) + ;< ~ bind:m (poke-our %spider %spider-start poke-vase) + ;< ~ bind:m (sleep ~s0) :: wait for thread to start + (pure:m tid) +:: ++$ thread-result + (each vase [term tang]) +:: +++ await-thread + |= [file=term args=vase] + =/ m (strand ,thread-result) + ^- form:m + ;< =bowl:spider bind:m get-bowl + =/ tid (scot %ta (cat 3 'strand_' (scot %uv (sham file eny.bowl)))) + =/ poke-vase !>([`tid.bowl `tid file args]) + ;< ~ bind:m (watch-our /awaiting/[tid] %spider /thread-result/[tid]) + ;< ~ bind:m (poke-our %spider %spider-start poke-vase) + ;< ~ bind:m (sleep ~s0) :: wait for thread to start + ;< =cage bind:m (take-fact /awaiting/[tid]) + ;< ~ bind:m (take-kick /awaiting/[tid]) + ?+ p.cage ~|([%strange-thread-result p.cage file tid] !!) + %thread-done (pure:m %& q.cage) + %thread-fail (pure:m %| !<([term tang] q.cage)) + == +-- diff --git a/pkg/base-dev/lib/verb.hoon b/pkg/base-dev/lib/verb.hoon new file mode 100644 index 0000000000..2737addfcb --- /dev/null +++ b/pkg/base-dev/lib/verb.hoon @@ -0,0 +1,105 @@ +:: Print what your agent is doing. +:: +/- verb +:: +|= [loud=? =agent:gall] +=| bowl-print=_| +^- agent:gall +|^ !. +|_ =bowl:gall ++* this . + ag ~(. agent bowl) +:: +++ on-init + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-init")) + =^ cards agent on-init:ag + [[(emit-event %on-init ~) cards] this] +:: +++ on-save + ^- vase + %- (print bowl |.("{}: on-save")) + on-save:ag +:: +++ on-load + |= old-state=vase + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-load")) + =^ cards agent (on-load:ag old-state) + [[(emit-event %on-load ~) cards] this] +:: +++ on-poke + |= [=mark =vase] + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-poke with mark {}")) + ?: ?=(%verb mark) + ?- !<(?(%loud %bowl) vase) + %loud `this(loud !loud) + %bowl `this(bowl-print !bowl-print) + == + =^ cards agent (on-poke:ag mark vase) + [[(emit-event %on-poke mark) cards] this] +:: +++ on-watch + |= =path + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-watch on path {}")) + =^ cards agent + ?: ?=([%verb %events ~] path) + [~ agent] + (on-watch:ag path) + [[(emit-event %on-watch path) cards] this] +:: +++ on-leave + |= =path + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-leave on path {}")) + ?: ?=([%verb %event ~] path) + [~ this] + =^ cards agent (on-leave:ag path) + [[(emit-event %on-leave path) cards] this] +:: +++ on-peek + |= =path + ^- (unit (unit cage)) + %- (print bowl |.("{}: on-peek on path {}")) + (on-peek:ag path) +:: +++ on-agent + |= [=wire =sign:agent:gall] + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-agent on wire {}, {<-.sign>}")) + =^ cards agent (on-agent:ag wire sign) + [[(emit-event %on-agent wire -.sign) cards] this] +:: +++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card:agent:gall agent:gall) + %- %+ print bowl |. + "{}: on-arvo on wire {}, {<[- +<]:sign-arvo>}" + =^ cards agent (on-arvo:ag wire sign-arvo) + [[(emit-event %on-arvo wire [- +<]:sign-arvo) cards] this] +:: +++ on-fail + |= [=term =tang] + ^- (quip card:agent:gall agent:gall) + %- (print bowl |.("{}: on-fail with term {}")) + =^ cards agent (on-fail:ag term tang) + [[(emit-event %on-fail term) cards] this] +-- +:: +++ print + |= [=bowl:gall render=(trap tape)] + ^+ same + =? . bowl-print + %- (slog >bowl< ~) + . + ?. loud same + %- (slog [%leaf $:render] ~) + same +:: +++ emit-event + |= =event:verb + ^- card:agent:gall + [%give %fact ~[/verb/events] %verb-event !>(event)] +-- diff --git a/pkg/base-dev/mar/belt.hoon b/pkg/base-dev/mar/belt.hoon new file mode 100644 index 0000000000..1c5a6e1ea6 --- /dev/null +++ b/pkg/base-dev/mar/belt.hoon @@ -0,0 +1,29 @@ +:: belt: runtime belt structure +:: +|_ =belt:dill +++ grad %noun +:: +grab: convert from +:: +++ grab + |% + ++ noun belt:dill + ++ json + ^- $-(^json belt:dill) + =, dejs:format + %- of + :~ aro+(su (perk %d %l %r %u ~)) + bac+ul + ctl+(cu taft so) + del+ul + met+(cu taft so) + ret+ul + txt+(ar (cu taft so)) + == + -- +:: +grow: convert to +:: +++ grow + |% + ++ noun belt + -- +-- diff --git a/pkg/base-dev/mar/bill.hoon b/pkg/base-dev/mar/bill.hoon new file mode 100644 index 0000000000..6b7e824479 --- /dev/null +++ b/pkg/base-dev/mar/bill.hoon @@ -0,0 +1,43 @@ +/- *bill +|_ bil=bill +++ grow + |% + ++ mime `^mime`[/text/x-bill (as-octs:mimes:html hoon)] + ++ noun bil + ++ hoon + ^- @t + |^ (crip (of-wall:format (wrap-lines (zing (turn bil spit-chit))))) + :: + ++ wrap-lines + |= taz=wall + ^- wall + ?~ taz ["~"]~ + :- (weld ":~ " i.taz) + %- snoc :_ "==" + (turn t.taz |=(t=tape (weld " " t))) + :: + ++ spit-chit + |= =chit + ^- wall + ?- -.chit + %apes [":- %apes" (wrap-lines (spit-duz duz.chit))] + %fish [":- %fish" (wrap-lines (spit-duz duz.chit))] + == + :: + ++ spit-duz + |= duz=(list dude:gall) + ^- wall + (turn duz |=(=dude:gall "%{}")) + -- + ++ txt (to-wain:format hoon) + -- +++ grab + |% + ++ noun bill + ++ mime + |= [=mite len=@ud tex=@] + ~_ tex + !<(bill (slap !>(~) (ream tex))) + -- +++ grad %noun +-- diff --git a/pkg/base-dev/mar/blit.hoon b/pkg/base-dev/mar/blit.hoon new file mode 100644 index 0000000000..4c23c5705e --- /dev/null +++ b/pkg/base-dev/mar/blit.hoon @@ -0,0 +1,61 @@ +:: blit: runtime blit structure +:: +|_ =blit:dill +++ grad %noun +:: +grab: convert from +:: +++ grab + |% + ++ noun blit:dill + -- +:: +grow: convert to +:: +++ grow + |% + ++ noun blit + ++ json + ^- ^json + =, enjs:format + %+ frond -.blit + ?- -.blit + %bel b+& + %clr b+& + %hop (numb p.blit) + %lin a+(turn p.blit |=(c=@c s+(tuft c))) + %mor b+& + %url s+p.blit + :: + %sag + %- pairs + :~ 'path'^(path p.blit) + 'file'^s+(en:base64:mimes:html (as-octs:mimes:html (jam q.blit))) + == + :: + %sav + %- pairs + :~ 'path'^(path p.blit) + 'file'^s+(en:base64:mimes:html (as-octs:mimes:html q.blit)) + == + :: + %klr + :- %a + %+ turn p.blit + |= [=stye text=(list @c)] + %- pairs + :~ 'text'^a+(turn text |=(c=@c s+(tuft c))) + :: + :- 'stye' + %- pairs + |^ :~ 'back'^(color p.q.stye) + 'fore'^(color q.q.stye) + 'deco'^a+(turn ~(tap in p.stye) |=(d=deco ?~(d ~ s+d))) + == + ++ color + |= =tint + ?@ tint ?~(tint ~ s+tint) + s+(crip ((x-co:co 6) (rep 3 ~[b g r]:tint))) + -- + == + == + -- +-- diff --git a/pkg/base-dev/mar/hoon.hoon b/pkg/base-dev/mar/hoon.hoon new file mode 100644 index 0000000000..b6f590649b --- /dev/null +++ b/pkg/base-dev/mar/hoon.hoon @@ -0,0 +1,49 @@ +:::: /hoon/hoon/mar + :: +/? 310 +:: +=, eyre +|_ own=@t +:: +++ grow :: convert to + |% + ++ mime `^mime`[/text/x-hoon (as-octs:mimes:html own)] :: convert to %mime + ++ elem :: convert to %html + ;div:pre(urb_codemirror "", mode "hoon"):"{(trip own)}" + :: =+ gen-id="src-{<`@ui`(mug own)>}" + :: ;div + :: ;textarea(id "{gen-id}"):"{(trip own)}" + :: ;script:""" + :: CodeMirror.fromTextArea( + :: window[{}], + :: \{lineNumbers:true, readOnly:true} + :: ) + :: """ + :: == + ++ hymn + :: ;html:(head:title:"Source" "+{elem}") + ;html + ;head + ;title:"Source" + ;script@"//cdnjs.cloudflare.com/ajax/libs/codemirror/4.3.0/codemirror.js"; + ;script@"/lib/syntax/hoon.js"; + ;link(rel "stylesheet", href "//cdnjs.cloudflare.com/ajax/libs/". + "codemirror/4.3.0/codemirror.min.css"); + ;link/"/lib/syntax/codemirror.css"(rel "stylesheet"); + == + ;body + ;textarea#src:"{(trip own)}" + ;script:'CodeMirror.fromTextArea(src, {lineNumbers:true, readOnly:true})' + == + == + ++ txt + (to-wain:format own) + -- +++ grab + |% :: convert from + ++ mime |=([p=mite q=octs] q.q) + ++ noun @t :: clam from %noun + ++ txt of-wain:format + -- +++ grad %txt +-- diff --git a/pkg/base-dev/mar/htm.hoon b/pkg/base-dev/mar/htm.hoon new file mode 100644 index 0000000000..a40a432dd1 --- /dev/null +++ b/pkg/base-dev/mar/htm.hoon @@ -0,0 +1,15 @@ +:: +:::: /hoon/htm/mar + :: +/? 310 +|_ own=manx +:: +++ grad %noun +++ grow :: convert to + |% + ++ noun own + ++ hymn own + -- +++ grab |% :: convert from + ++ noun manx :: clam from %noun +-- -- diff --git a/pkg/base-dev/mar/html.hoon b/pkg/base-dev/mar/html.hoon new file mode 100644 index 0000000000..203d75f612 --- /dev/null +++ b/pkg/base-dev/mar/html.hoon @@ -0,0 +1,22 @@ +:: +:::: /hoon/html/mar + :: +/? 310 + :: +:::: compute + :: +=, html +|_ htm=@t +++ grow :: convert to + ^? + |% :: + ++ mime [/text/html (met 3 htm) htm] :: to %mime + ++ hymn (need (de-xml htm)) :: to %hymn + -- :: +++ grab ^? + |% :: convert from + ++ noun @t :: clam from %noun + ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/httr.hoon b/pkg/base-dev/mar/httr.hoon new file mode 100644 index 0000000000..bbac8f9907 --- /dev/null +++ b/pkg/base-dev/mar/httr.hoon @@ -0,0 +1,25 @@ +:: +:::: /hoon/httr/mar + :: +/? 310 +:: +=, eyre +=, format +=, html +|_ hit=httr +++ grad %noun +++ grow |% ++ wall (turn wain trip) + ++ wain (to-wain cord) + ++ json (need (de-json cord)) + ++ cord q:octs + ++ noun hit + ++ octs + ~| hit + ?> =(2 (div p.hit 100)) + (need r.hit) + -- +++ grab :: convert from + |% + ++ noun httr :: clam from %noun + -- +-- diff --git a/pkg/base-dev/mar/hymn.hoon b/pkg/base-dev/mar/hymn.hoon new file mode 100644 index 0000000000..cf01508eae --- /dev/null +++ b/pkg/base-dev/mar/hymn.hoon @@ -0,0 +1,17 @@ +:: +:::: /hoon/hymn/mar + :: +/? 310 +=, mimes:html +=, html +|_ own=manx +:: +++ grad %noun +++ grow :: convert to + |% + ++ html (crip (en-xml own)) :: convert to %html + ++ mime [/text/html (as-octs html)] :: convert to %mime + -- +++ grab |% :: convert from + ++ noun manx :: clam from %noun +-- -- diff --git a/pkg/base-dev/mar/js.hoon b/pkg/base-dev/mar/js.hoon new file mode 100644 index 0000000000..e8fbe7701a --- /dev/null +++ b/pkg/base-dev/mar/js.hoon @@ -0,0 +1,22 @@ +:: +:::: /hoon/js/mar + :: +/? 310 +:: +=, eyre +|_ mud=@ +++ grow + |% + ++ mime [/application/javascript (as-octs:mimes:html (@t mud))] + ++ elem ;script + ;- (trip (@t mud)) + == + ++ hymn ;html:(head:"+{elem}" body) + -- +++ grab + |% :: convert from + ++ mime |=([p=mite q=octs] (@t q.q)) + ++ noun cord :: clam from %noun + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/json.hoon b/pkg/base-dev/mar/json.hoon new file mode 100644 index 0000000000..506b708350 --- /dev/null +++ b/pkg/base-dev/mar/json.hoon @@ -0,0 +1,26 @@ +:: +:::: /hoon/json/mar + :: +/? 310 + :: +:::: compute + :: +=, eyre +=, format +=, html +|_ jon=json +:: +++ grow :: convert to + |% + ++ mime [/application/json (as-octs:mimes -:txt)] :: convert to %mime + ++ txt [(crip (en-json jon))]~ + -- +++ grab + |% :: convert from + ++ mime |=([p=mite q=octs] (fall (rush (@t q.q) apex:de-json) *json)) + ++ noun json :: clam from %noun + ++ numb numb:enjs + ++ time time:enjs + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/json/rpc/response.hoon b/pkg/base-dev/mar/json/rpc/response.hoon new file mode 100644 index 0000000000..91ea2f670e --- /dev/null +++ b/pkg/base-dev/mar/json/rpc/response.hoon @@ -0,0 +1,43 @@ +:: +/- *json-rpc +:: +|_ res=response +:: +++ grad %noun +++ grow + |% + ++ noun res + -- +++ grab :: convert from + |% + ++ noun response :: from noun + ++ httr :: from httr + |= hit=httr:eyre + ^- response + ~| hit + ?: ?=(%2 (div p.hit 100)) + =, html + %- json + ?~ r.hit + a+~ + (need (de-json q:u.r.hit)) + fail+hit + ++ json :: from json + =, dejs-soft:format + |= a=json + ^- response + =; dere + =+ res=((ar dere) a) + ?~ res (need (dere a)) + [%batch u.res] + |= a=json + ^- (unit response) + =/ res=(unit [@t json]) + ::TODO breaks when no id present + ((ot id+so result+some ~) a) + ?^ res `[%result u.res] + ~| a + :+ ~ %error %- need + ((ot id+so error+(ot code+no message+so ~) ~) a) + -- +-- diff --git a/pkg/base-dev/mar/kelvin.hoon b/pkg/base-dev/mar/kelvin.hoon new file mode 100644 index 0000000000..f64063d182 --- /dev/null +++ b/pkg/base-dev/mar/kelvin.hoon @@ -0,0 +1,18 @@ +=/ weft ,[lal=@tas num=@ud] :: TODO remove after merge +|_ kel=weft +++ grow + |% + ++ mime `^mime`[/text/x-kelvin (as-octs:mimes:html hoon)] + ++ noun kel + ++ hoon (crip "{<[lal num]:kel>}\0a") + ++ txt (to-wain:format hoon) + -- +++ grab + |% + ++ noun weft + ++ mime + |= [=mite len=@ud tex=@] + !<(weft (slap !>(~) (ream tex))) + -- +++ grad %noun +-- diff --git a/pkg/base-dev/mar/language-server/rpc/notification.hoon b/pkg/base-dev/mar/language-server/rpc/notification.hoon new file mode 100644 index 0000000000..d464da489a --- /dev/null +++ b/pkg/base-dev/mar/language-server/rpc/notification.hoon @@ -0,0 +1,18 @@ +/- *language-server +/+ lsp-json=language-server-json +|_ not=all:notification +++ grad %noun +++ grab + |% + ++ noun all:notification + ++ json + |= jon=^json + (notification:dejs:lsp-json jon) + -- +++ grow + |% + ++ noun not + ++ json + (notification:enjs:lsp-json not) + -- +-- diff --git a/pkg/base-dev/mar/language-server/rpc/request.hoon b/pkg/base-dev/mar/language-server/rpc/request.hoon new file mode 100644 index 0000000000..989a6f41c4 --- /dev/null +++ b/pkg/base-dev/mar/language-server/rpc/request.hoon @@ -0,0 +1,16 @@ +/- *language-server +/+ lsp-json=language-server-json +|_ req=all:request +++ grad %noun +++ grow + |% + ++ noun req + -- +++ grab + |% + ++ noun all:request + ++ json + |= jon=^json + (request:dejs:lsp-json jon) + -- +-- diff --git a/pkg/base-dev/mar/language-server/rpc/response.hoon b/pkg/base-dev/mar/language-server/rpc/response.hoon new file mode 100644 index 0000000000..f82408b877 --- /dev/null +++ b/pkg/base-dev/mar/language-server/rpc/response.hoon @@ -0,0 +1,17 @@ +/- *language-server +/+ lsp=language-server-json +|_ res=all:response +:: +++ grad %noun +++ grow + |% + ++ noun res + ++ json (response:enjs:lsp res) + -- +:: +++ grab + |% + ++ noun all:response + -- +:: +-- diff --git a/pkg/base-dev/mar/mime.hoon b/pkg/base-dev/mar/mime.hoon new file mode 100644 index 0000000000..83b4daeb5e --- /dev/null +++ b/pkg/base-dev/mar/mime.hoon @@ -0,0 +1,32 @@ +:: +:::: /hoon/mime/mar + :: +/? 310 +:: +|_ own=mime +++ grow + ^? + |% + ++ jam `@`q.q.own + -- +:: +++ grab :: convert from + ^? + |% + ++ noun mime :: clam from %noun + ++ tape + |=(a=_"" [/application/x-urb-unknown (as-octt:mimes:html a)]) + -- +++ grad + ^? + |% + ++ form %mime + ++ diff |=(mime +<) + ++ pact |=(mime +<) + ++ join |=([mime mime] `(unit mime)`~) + ++ mash + |= [[ship desk mime] [ship desk mime]] + ^- mime + ~|(%mime-mash !!) + -- +-- diff --git a/pkg/base-dev/mar/noun.hoon b/pkg/base-dev/mar/noun.hoon new file mode 100644 index 0000000000..5c798d3c2a --- /dev/null +++ b/pkg/base-dev/mar/noun.hoon @@ -0,0 +1,19 @@ +:: +:::: /hoon/noun/mar + :: +/? 310 +!: +:::: A minimal noun mark +|_ non=* +++ grab |% + ++ noun * + -- +++ grad + |% + ++ form %noun + ++ diff |=(* +<) + ++ pact |=(* +<) + ++ join |=([* *] *(unit *)) + ++ mash |=([[ship desk *] [ship desk *]] `*`~|(%noun-mash !!)) + -- +-- diff --git a/pkg/base-dev/mar/path.hoon b/pkg/base-dev/mar/path.hoon new file mode 100644 index 0000000000..2196ba95a5 --- /dev/null +++ b/pkg/base-dev/mar/path.hoon @@ -0,0 +1,11 @@ +|_ pax=path +++ grad %noun +++ grow + |% + ++ noun pax + -- +++ grab + |% + ++ noun path + -- +-- diff --git a/pkg/base-dev/mar/png.hoon b/pkg/base-dev/mar/png.hoon new file mode 100644 index 0000000000..6a60a6a27b --- /dev/null +++ b/pkg/base-dev/mar/png.hoon @@ -0,0 +1,12 @@ +|_ dat=@ +++ grow + |% + ++ mime [/image/png (as-octs:mimes:html dat)] + -- +++ grab + |% + ++ mime |=([p=mite q=octs] q.q) + ++ noun @ + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/purl.hoon b/pkg/base-dev/mar/purl.hoon new file mode 100644 index 0000000000..3fb39fa69d --- /dev/null +++ b/pkg/base-dev/mar/purl.hoon @@ -0,0 +1,18 @@ +:: +:::: /hoon/purl/mar + :: +/? 310 +=, eyre +|_ url=purl +++ grad %noun +:: +++ grow + |% + ++ noun url + ++ hiss [url %get ~ ~] + -- +++ grab :: convert from + |% + ++ noun purl :: clam from %noun + -- +-- diff --git a/pkg/base-dev/mar/sole/action.hoon b/pkg/base-dev/mar/sole/action.hoon new file mode 100644 index 0000000000..149ef5ef16 --- /dev/null +++ b/pkg/base-dev/mar/sole/action.hoon @@ -0,0 +1,50 @@ +:: +:::: /hoon/action/sole/mar + :: +/? 310 +/- sole +:: +:::: + :: +=, sole +|_ sole-action +:: +++ grad %noun +++ grow + |% + ++ noun +<.grad + -- +++ grab :: convert from + |% + ++ json + |= jon=^json ^- sole-action + %- need %. jon + => [dejs-soft:format ..sole-action] + |^ (ot id+so dat+(fo %ret (of det+change tab+ni ~)) ~) + ++ fo + |* [a=term b=fist] + |=(c=json ?.(=([%s a] c) (b c) (some [a ~]))) + :: + ++ ra + |* [a=[term fist] b=fist] + |= c=json %. c + ?.(=(%a -.c) b (pe -.a (ar +.a))) + :: + ++ ke :: callbacks + |* [gar=* sef=(trap fist)] + |= jon=json ^- (unit _gar) + =- ~! gar ~! (need -) - + ((sef) jon) + :: + ++ change (ot ler+(at ni ni ~) ted+(pe 0v0 edit) ~) + ++ char (cu taft so) + ++ edit + %+ ke *sole-edit |. ~+ + %+ fo %nop + %+ ra mor+edit + (of del+ni set+(cu tuba sa) ins+(ot at+ni cha+char ~) ~) + -- + :: + ++ noun sole-action :: clam from %noun + -- +-- diff --git a/pkg/base-dev/mar/sole/effect.hoon b/pkg/base-dev/mar/sole/effect.hoon new file mode 100644 index 0000000000..7b1f7477b3 --- /dev/null +++ b/pkg/base-dev/mar/sole/effect.hoon @@ -0,0 +1,82 @@ +:: +:::: /hoon/effect/sole/mar + :: +/? 310 +/- sole +!: +:: +:::: + :: +=, sole +=, format +|% +++ mar-sole-change :: XX dependency + |_ cha=sole-change + ++ grow + |% ++ json + ^- ^json + =, enjs + =; edi + =,(cha (pairs ted+(edi ted) ler+a+~[(numb own.ler) (numb his.ler)] ~)) + |= det=sole-edit + ?- -.det + %nop [%s 'nop'] + %mor [%a (turn p.det ..$)] + %del (frond %del (numb p.det)) + %set (frond %set (tape (tufa p.det))) + %ins (frond %ins (pairs at+(numb p.det) cha+s+(tuft q.det) ~)) + == + -- + -- +++ wush + |= [wid=@u tan=tang] + ^- tape + (of-wall (turn (flop tan) |=(a=tank (of-wall (wash 0^wid a))))) +:: +++ purge :: discard ++styx style + |= a=styx ^- tape + %- zing %+ turn a + |= a=_?>(?=(^ a) i.a) + ?@(a (trip a) ^$(a q.a)) +-- +:: +|_ sef=sole-effect +:: +++ grad %noun +++ grab :: convert from + |% + ++ noun sole-effect :: clam from %noun + -- +++ grow + =, enjs + |% + ++ noun sef + ++ json + ^- ^json + ?+ -.sef + ~|(unsupported-effect+-.sef !!) + %mor [%a (turn p.sef |=(a=sole-effect json(sef a)))] + %err (frond %hop (numb p.sef)) + %txt (frond %txt (tape p.sef)) + %tan (frond %tan (tape (wush 160 p.sef))) + %det (frond %det json:~(grow mar-sole-change +.sef)) + :: + %pro + %+ frond %pro + (pairs vis+b+vis.sef tag+s+tag.sef cad+(tape (purge cad.sef)) ~) + :: + %tab + :- %a + %+ turn p.sef + |= [=cord =^tank] + %+ frond %tab + %- pairs + :~ match+s+cord + info+(tape ~(ram re tank)) + == + :: + ?(%bel %clr %nex %bye) + (frond %act %s -.sef) + == + -- +-- diff --git a/pkg/base-dev/mar/svg.hoon b/pkg/base-dev/mar/svg.hoon new file mode 100644 index 0000000000..2911e4900c --- /dev/null +++ b/pkg/base-dev/mar/svg.hoon @@ -0,0 +1,12 @@ +|_ dat=@ +++ grow + |% + ++ mime [/image/'svg+xml' (as-octs:mimes:html dat)] + -- +++ grab + |% + ++ mime |=([p=mite q=octs] q.q) + ++ noun @ + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/tang.hoon b/pkg/base-dev/mar/tang.hoon new file mode 100644 index 0000000000..681e939fb3 --- /dev/null +++ b/pkg/base-dev/mar/tang.hoon @@ -0,0 +1,30 @@ +:: +:::: /hoon/tang/mar + :: +/? 310 +:: +=, format +|_ tan=(list tank) +++ grad %noun +++ grow + |% + ++ noun tan + ++ json + =/ result=(each (list ^json) tang) + (mule |.((turn tan tank:enjs:format))) + ?- -.result + %& a+p.result + %| a+[a+[%s '[[output rendering error]]']~]~ + == + :: + ++ elem + =- ;pre:code:"{(of-wall -)}" + ^- wall %- zing ^- (list wall) + (turn (flop tan) |=(a=tank (wash 0^160 a))) + -- +++ grab :: convert from + |% + ++ noun (list ^tank) :: clam from %noun + ++ tank |=(a=^tank [a]~) + -- +-- diff --git a/pkg/base-dev/mar/tape.hoon b/pkg/base-dev/mar/tape.hoon new file mode 100644 index 0000000000..a30176421a --- /dev/null +++ b/pkg/base-dev/mar/tape.hoon @@ -0,0 +1,12 @@ +|_ tap=tape +++ grad %noun +++ grow + |% + ++ noun tap + ++ json s+(crip tap) + -- +++ grab + |% + ++ noun tape + -- +-- diff --git a/pkg/base-dev/mar/txt-diff.hoon b/pkg/base-dev/mar/txt-diff.hoon new file mode 100644 index 0000000000..2c9a500dcf --- /dev/null +++ b/pkg/base-dev/mar/txt-diff.hoon @@ -0,0 +1,16 @@ +:: +:::: /hoon/txt-diff/mar + :: +/? 310 +|_ txt-diff=(urge:clay cord) +:: +++ grad %noun +++ grow + |% + ++ noun txt-diff + -- +++ grab :: convert from + |% + ++ noun (urge:clay cord) :: make from %noun + -- +-- diff --git a/pkg/base-dev/mar/txt.hoon b/pkg/base-dev/mar/txt.hoon new file mode 100644 index 0000000000..1c349b1822 --- /dev/null +++ b/pkg/base-dev/mar/txt.hoon @@ -0,0 +1,275 @@ +:: +:::: /hoon/txt/mar + :: +/? 310 +:: +=, clay +=, differ +=, format +=, mimes:html +|_ txt=wain +:: +++ grab :: convert from + |% + ++ mime |=((pair mite octs) (to-wain q.q)) + ++ noun wain :: clam from %noun + -- +++ grow + => v=. + |% + ++ mime => v [/text/plain (as-octs (of-wain txt))] + ++ elem => v ;pre: {(trip (of-wain txt))} + -- +++ grad + |% + ++ form %txt-diff + ++ diff + |= tyt=wain + ^- (urge cord) + (lusk txt tyt (loss txt tyt)) + :: + ++ pact + |= dif=(urge cord) + ~| [%pacting dif] + ^- wain + (lurk txt dif) + :: + ++ join + |= [ali=(urge cord) bob=(urge cord)] + ^- (unit (urge cord)) + |^ + =. ali (clean ali) + =. bob (clean bob) + |- ^- (unit (urge cord)) + ?~ ali `bob + ?~ bob `ali + ?- -.i.ali + %& + ?- -.i.bob + %& + ?: =(p.i.ali p.i.bob) + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.ali cud]) + ?: (gth p.i.ali p.i.bob) + %+ bind $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob) + |=(cud=(urge cord) [i.bob cud]) + %+ bind $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali)) + |=(cud=(urge cord) [i.ali cud]) + :: + %| + ?: =(p.i.ali (lent p.i.bob)) + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.bob cud]) + ?: (gth p.i.ali (lent p.i.bob)) + %+ bind $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob) + |=(cud=(urge cord) [i.bob cud]) + ~ + == + :: + %| + ?- -.i.bob + %| + ?. =(i.ali i.bob) + ~ + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.ali cud]) + :: + %& + ?: =(p.i.bob (lent p.i.ali)) + %+ bind $(ali t.ali, bob t.bob) + |=(cud=(urge cord) [i.ali cud]) + ?: (gth p.i.bob (lent p.i.ali)) + %+ bind $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali))) + |=(cud=(urge cord) [i.ali cud]) + ~ + == + == + ++ clean :: clean + |= wig=(urge cord) + ^- (urge cord) + ?~ wig ~ + ?~ t.wig wig + ?: ?=(%& -.i.wig) + ?: ?=(%& -.i.t.wig) + $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + ?: ?=(%| -.i.t.wig) + $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + -- + :: + ++ mash + |= $: [als=ship ald=desk ali=(urge cord)] + [bos=ship bod=desk bob=(urge cord)] + == + ^- (urge cord) + |^ + =. ali (clean ali) + =. bob (clean bob) + |- ^- (urge cord) + ?~ ali bob + ?~ bob ali + ?- -.i.ali + %& + ?- -.i.bob + %& + ?: =(p.i.ali p.i.bob) + [i.ali $(ali t.ali, bob t.bob)] + ?: (gth p.i.ali p.i.bob) + [i.bob $(p.i.ali (sub p.i.ali p.i.bob), bob t.bob)] + [i.ali $(ali t.ali, p.i.bob (sub p.i.bob p.i.ali))] + :: + %| + ?: =(p.i.ali (lent p.i.bob)) + [i.bob $(ali t.ali, bob t.bob)] + ?: (gth p.i.ali (lent p.i.bob)) + [i.bob $(p.i.ali (sub p.i.ali (lent p.i.bob)), bob t.bob)] + =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] + (resolve ali bob) + [fic $(ali ali, bob bob)] + :: ~ :: here, alice is good for a while, but not for the whole + == :: length of bob's changes + :: + %| + ?- -.i.bob + %| + =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] + (resolve ali bob) + [fic $(ali ali, bob bob)] + :: + %& + ?: =(p.i.bob (lent p.i.ali)) + [i.ali $(ali t.ali, bob t.bob)] + ?: (gth p.i.bob (lent p.i.ali)) + [i.ali $(ali t.ali, p.i.bob (sub p.i.bob (lent p.i.ali)))] + =/ [fic=(unce cord) ali=(urge cord) bob=(urge cord)] + (resolve ali bob) + [fic $(ali ali, bob bob)] + == + == + :: + ++ annotate :: annotate conflict + |= $: ali=(list @t) + bob=(list @t) + bas=(list @t) + == + ^- (list @t) + %- zing + ^- (list (list @t)) + %- flop + ^- (list (list @t)) + :- :_ ~ + %^ cat 3 '<<<<<<<<<<<<' + %^ cat 3 ' ' + %^ cat 3 `@t`(scot %p bos) + %^ cat 3 '/' + bod + + :- bob + :- ~['------------'] + :- bas + :- ~['++++++++++++'] + :- ali + :- :_ ~ + %^ cat 3 '>>>>>>>>>>>>' + %^ cat 3 ' ' + %^ cat 3 `@t`(scot %p als) + %^ cat 3 '/' + ald + ~ + :: + ++ clean :: clean + |= wig=(urge cord) + ^- (urge cord) + ?~ wig ~ + ?~ t.wig wig + ?: ?=(%& -.i.wig) + ?: ?=(%& -.i.t.wig) + $(wig [[%& (add p.i.wig p.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + ?: ?=(%| -.i.t.wig) + $(wig [[%| (welp p.i.wig p.i.t.wig) (welp q.i.wig q.i.t.wig)] t.t.wig]) + [i.wig $(wig t.wig)] + :: + ++ resolve + |= [ali=(urge cord) bob=(urge cord)] + ^- [fic=[%| p=(list cord) q=(list cord)] ali=(urge cord) bob=(urge cord)] + =- [[%| bac (annotate alc boc bac)] ali bob] + |- ^- $: $: bac=(list cord) + alc=(list cord) + boc=(list cord) + == + ali=(urge cord) + bob=(urge cord) + == + ?~ ali [[~ ~ ~] ali bob] + ?~ bob [[~ ~ ~] ali bob] + ?- -.i.ali + %& + ?- -.i.bob + %& [[~ ~ ~] ali bob] :: no conflict + %| + =+ lob=(lent p.i.bob) + ?: =(lob p.i.ali) + [[p.i.bob p.i.bob q.i.bob] t.ali t.bob] + ?: (lth lob p.i.ali) + [[p.i.bob p.i.bob q.i.bob] [[%& (sub p.i.ali lob)] t.ali] t.bob] + =+ wat=(scag (sub lob p.i.ali) p.i.bob) + =+ ^= res + %= $ + ali t.ali + bob [[%| (scag (sub lob p.i.ali) p.i.bob) ~] t.bob] + == + :* :* (welp bac.res wat) + (welp alc.res wat) + (welp boc.res q.i.bob) + == + ali.res + bob.res + == + == + :: + %| + ?- -.i.bob + %& + =+ loa=(lent p.i.ali) + ?: =(loa p.i.bob) + [[p.i.ali q.i.ali p.i.ali] t.ali t.bob] + ?: (lth loa p.i.bob) + [[p.i.ali q.i.ali p.i.ali] t.ali [[%& (sub p.i.bob loa)] t.bob]] + =+ wat=(slag (sub loa p.i.bob) p.i.ali) + =+ ^= res + %= $ + ali [[%| (scag (sub loa p.i.bob) p.i.ali) ~] t.ali] + bob t.bob + == + :* :* (welp bac.res wat) + (welp alc.res q.i.ali) + (welp boc.res wat) + == + ali.res + bob.res + == + :: + %| + =+ loa=(lent p.i.ali) + =+ lob=(lent p.i.bob) + ?: =(loa lob) + [[p.i.ali q.i.ali q.i.bob] t.ali t.bob] + =+ ^= res + ?: (gth loa lob) + $(ali [[%| (scag (sub loa lob) p.i.ali) ~] t.ali], bob t.bob) + ~& [%scagging loa=loa pibob=p.i.bob slag=(scag loa p.i.bob)] + $(ali t.ali, bob [[%| (scag (sub lob loa) p.i.bob) ~] t.bob]) + :* :* (welp bac.res ?:((gth loa lob) p.i.bob p.i.ali)) + (welp alc.res q.i.ali) + (welp boc.res q.i.bob) + == + ali.res + bob.res + == + == + == + -- + -- +-- diff --git a/pkg/base-dev/mar/udon.hoon b/pkg/base-dev/mar/udon.hoon new file mode 100644 index 0000000000..72c9e6f5cf --- /dev/null +++ b/pkg/base-dev/mar/udon.hoon @@ -0,0 +1,32 @@ +:: +:::: /hoon/udon/mar + :: +/+ cram +:: +|_ mud=@t +++ grow + |% + ++ mime [/text/x-unmark (as-octs:mimes:html mud)] + ++ txt + (to-wain:format mud) + ++ elem + ^- manx + =, cram + elm:(static (ream mud)) + ++ front :: XX performance, types + ^- (map term knot) + %- ~(run by inf:(static:cram (ream mud))) + |= a=dime ^- cord + ?+ (end 3 p.a) (scot a) + %t q.a + == + -- +++ grab + |% + ++ mime |=((pair mite octs) q.q) + ++ noun @t + ++ txt of-wain:format + -- +++ grad %txt +++ garb /down +-- diff --git a/pkg/base-dev/mar/umd.hoon b/pkg/base-dev/mar/umd.hoon new file mode 100644 index 0000000000..d249bcff85 --- /dev/null +++ b/pkg/base-dev/mar/umd.hoon @@ -0,0 +1,32 @@ +:: +:::: /hoon/umd/mar + :: +/+ cram +:: +|_ mud=@t +++ grow + |% + ++ mime [/text/x-unmark (as-octs:mimes:html mud)] + ++ txt + (to-wain:format mud) + ++ elem + ^- manx + =, cram + elm:(static (ream mud)) + ++ front :: XX performance, types + ^- (map term knot) + %- ~(run by inf:(static:cram (ream mud))) + |= a=dime ^- cord + ?+ (end 3 p.a) (scot a) + %t q.a + == + -- +++ grab + |% + ++ mime |=((pair mite octs) q.q) + ++ noun @t + ++ txt of-wain:format + -- +++ grad %txt +++ garb /down +-- diff --git a/pkg/base-dev/mar/urb.hoon b/pkg/base-dev/mar/urb.hoon new file mode 100644 index 0000000000..49545e73f5 --- /dev/null +++ b/pkg/base-dev/mar/urb.hoon @@ -0,0 +1,18 @@ +:: +:::: /hoon/elem/urb/mar + :: +/? 310 +=, mimes:html +=, html +|_ own=manx +:: +++ grad %noun +++ grow :: convert to + |% + ++ hymn ;html:(head body:"+{own}") :: convert to %hymn + ++ html (crip (en-xml hymn)) :: convert to %html + ++ mime [/text/html (as-octs html)] :: convert to %mime + -- +++ grab |% :: convert from + ++ noun manx :: clam from %noun +-- -- diff --git a/pkg/base-dev/mar/urbit.hoon b/pkg/base-dev/mar/urbit.hoon new file mode 100644 index 0000000000..8d2c3c6587 --- /dev/null +++ b/pkg/base-dev/mar/urbit.hoon @@ -0,0 +1,17 @@ +:: +:::: /hoon/urbit/mar + :: +/? 310 +:::: A minimal urbit mark +:: +|_ her=@p +++ grab + |% + ++ noun @p + -- +++ grow + |% + ++ noun her + -- +++ grad %noun +-- diff --git a/pkg/base-dev/mar/woff2.hoon b/pkg/base-dev/mar/woff2.hoon new file mode 100644 index 0000000000..7e72429085 --- /dev/null +++ b/pkg/base-dev/mar/woff2.hoon @@ -0,0 +1,12 @@ +|_ dat=octs +++ grow + |% + ++ mime [/font/woff2 dat] + -- +++ grab + |% + ++ mime |=([=mite =octs] octs) + ++ noun octs + -- +++ grad %mime +-- diff --git a/pkg/base-dev/mar/xml.hoon b/pkg/base-dev/mar/xml.hoon new file mode 100644 index 0000000000..6d52d80242 --- /dev/null +++ b/pkg/base-dev/mar/xml.hoon @@ -0,0 +1,21 @@ +:: +:::: /hoon/xml/mar + :: +/? 310 + :: +:::: compute + :: +=, mimes:html +=, html +|_ xml=@t +:: +++ grad %mime +++ grow :: convert to + |% :: + ++ mime [/application/xml (as-octs xml)] :: to %mime + ++ hymn (need (de-xml xml)) :: to %hymn + -- :: +++ grab |% :: convert from + ++ noun @t :: clam from %noun + ++ mime |=([p=mite q=octs] q.q) :: retrieve form %mime +-- -- diff --git a/pkg/base-dev/sur/bill.hoon b/pkg/base-dev/sur/bill.hoon new file mode 100644 index 0000000000..53c2b31e9b --- /dev/null +++ b/pkg/base-dev/sur/bill.hoon @@ -0,0 +1,23 @@ +|% ++$ bill (list chit) ++$ chit + $% [%apes duz=(list dude:gall)] + [%fish duz=(list dude:gall)] + == +:: +++ read-apes + |= =bill + ^- (list dude:gall) + ?~ bill ~ + ?: ?=(%apes -.i.bill) + duz.i.bill + $(bill t.bill) +:: +++ read-fish + |= =bill + ^- (list dude:gall) + ?~ bill ~ + ?: ?=(%fish -.i.bill) + duz.i.bill + $(bill t.bill) +-- diff --git a/pkg/base-dev/sur/sole.hoon b/pkg/base-dev/sur/sole.hoon new file mode 100644 index 0000000000..e942bccb87 --- /dev/null +++ b/pkg/base-dev/sur/sole.hoon @@ -0,0 +1,87 @@ +:: +:::: /hoon/sole/sur + :: +^? +|% ++$ sole-action :: sole to app + $: id=@ta :: duct id + $= dat + $% :: [%abo ~] :: reset interaction + [%det sole-change] :: command line edit + [%ret ~] :: submit and clear + [%clr ~] :: exit context + [%tab pos=@ud] :: tab complete + == :: + == ++$ sole-buffer (list @c) :: command state ++$ sole-change :: network change + $: ler=sole-clock :: destination clock + haw=@uvH :: source hash + ted=sole-edit :: state change + == :: ++$ sole-clock [own=@ud his=@ud] :: vector clock ++$ sole-edit :: shared state change + $% [%del p=@ud] :: delete one at + [%ins p=@ud q=@c] :: insert at + [%mor p=(list sole-edit)] :: combination + [%nop ~] :: no-op + [%set p=sole-buffer] :: discontinuity + == :: ++$ sole-effect :: app to sole + $% [%bel ~] :: beep + [%blk p=@ud q=@c] :: blink+match char at + [%bye ~] :: close session + [%clr ~] :: clear screen + [%det sole-change] :: edit command + [%err p=@ud] :: error point + [%klr p=styx] :: styled text line + [%mor p=(list sole-effect)] :: multiple effects + [%nex ~] :: save clear command + [%pro sole-prompt] :: set prompt + [%sag p=path q=*] :: save to jamfile + [%sav p=path q=@] :: save to file + [%tab p=(list [=cord =tank])] :: tab-complete list + [%tan p=(list tank)] :: classic tank + :: [%taq p=tanq] :: modern tank + [%txt p=tape] :: text line + [%url p=@t] :: activate url + == :: ++$ sole-command :: command state + $: pos=@ud :: cursor position + say=sole-share :: cursor + == :: ++$ sole-prompt :: prompt definition + $: vis=? :: command visible + tag=term :: history mode + cad=styx :: caption + == :: ++$ sole-share :: symmetric state + $: ven=sole-clock :: our vector clock + leg=(list sole-edit) :: unmerged edits + buf=sole-buffer :: sole state + == :: +:: :: +:: :: +++ sole-dialog :: standard dialog + |* out=$-(* *) :: output structure + $-(sole-input (sole-result out)) :: output function +:: :: ++$ sole-input tape :: prompt input +++ sole-result :: conditional result + |* out=$-(* *) :: output structure + $@(@ud (sole-product out)) :: error position +:: :: +++ sole-product :: success result + |* out=$-(* *) :: + %+ pair (list tank) :: + %+ each (unit out) :: ~ is abort + (pair sole-prompt (sole-dialog out)) :: ask and continue +:: :: ++$ sole-gen :: XX virtual type + $% [%say $-((sole-args) (cask))] :: direct noun + [%ask $-((sole-args) (sole-product (cask)))] :: dialog + == :: +++ sole-args :: generator arguments + |* _[* *] :: + ,[[now=@da eny=@uvJ bek=beak] [,+<- ,+<+]] :: +-- diff --git a/pkg/base-dev/sur/spider.hoon b/pkg/base-dev/sur/spider.hoon new file mode 100644 index 0000000000..5fe7a76268 --- /dev/null +++ b/pkg/base-dev/sur/spider.hoon @@ -0,0 +1,14 @@ +/+ libstrand=strand +=, strand=strand:libstrand +|% ++$ thread $-(vase _*form:(strand ,vase)) ++$ input [=tid =cage] ++$ tid tid:strand ++$ bowl bowl:strand ++$ http-error + $? %bad-request :: 400 + %forbidden :: 403 + %nonexistent :: 404 + %offline :: 504 + == +-- diff --git a/pkg/base-dev/sur/verb.hoon b/pkg/base-dev/sur/verb.hoon new file mode 100644 index 0000000000..f7d19f658a --- /dev/null +++ b/pkg/base-dev/sur/verb.hoon @@ -0,0 +1,12 @@ +|% ++$ event + $% [%on-init ~] + [%on-load ~] + [%on-poke =mark] + [%on-watch =path] + [%on-leave =path] + [%on-agent =wire sign=term] + [%on-arvo =wire vane=term sign=term] + [%on-fail =term] + == +-- \ No newline at end of file diff --git a/pkg/base-dev/sys.kelvin b/pkg/base-dev/sys.kelvin new file mode 100644 index 0000000000..b7464903af --- /dev/null +++ b/pkg/base-dev/sys.kelvin @@ -0,0 +1 @@ +[%zuse 420] diff --git a/pkg/landscape/gen/dbug.hoon b/pkg/landscape/gen/dbug.hoon index b5611ad7f8..62d7f78aa8 100644 --- a/pkg/landscape/gen/dbug.hoon +++ b/pkg/landscape/gen/dbug.hoon @@ -1,3 +1,4 @@ +:: :: +dbug: tell /lib/dbug app to print some generic state :: :: :app +dbug