mirror of
https://github.com/ilyakooo0/urbit.git
synced 2025-01-01 19:46:36 +03:00
Merge remote-tracking branch 'eglaysher/new-dojo-unified' into piaf
Non-compiling branch which uses the features it adds.
This commit is contained in:
commit
2575255c9e
586
app/dojo.hoon
586
app/dojo.hoon
@ -42,6 +42,7 @@
|
||||
{$poke p/goal} :: poke app
|
||||
{$show p/?($0 $1 $2 $3)} :: print val+span+twig
|
||||
{$verb p/term} :: store variable
|
||||
{$help p/(list term)} :: look up help
|
||||
== ::
|
||||
++ dojo-source :: construction node
|
||||
$: p/@ud :: assembly index
|
||||
@ -170,6 +171,18 @@
|
||||
(dp-variable (cold %lib lus) ;~(pfix gap dp-hooves))
|
||||
==
|
||||
==
|
||||
::
|
||||
;~ pfix hax
|
||||
;~ pose
|
||||
;~ pfix ace
|
||||
%+ cook
|
||||
|= a/(list term)
|
||||
[[%help a] 0 %ex [%make p=~[[%.y p=1]] q=~]]
|
||||
(most col sym)
|
||||
==
|
||||
(easy [[%help ~] 0 %ex [%make p=~[[%.y p=1]] q=~]])
|
||||
==
|
||||
==
|
||||
::
|
||||
;~((glue ace) dp-sink dp-source)
|
||||
(stag [%show %0] dp-source)
|
||||
@ -461,10 +474,10 @@
|
||||
$eny ~|(%entropy-is-eternal !!)
|
||||
$now ~|(%time-is-immutable !!)
|
||||
$our ~|(%self-is-immutable !!)
|
||||
$lib
|
||||
$lib
|
||||
.(lib ((dy-cast (list hoof:ford) !>(*(list hoof:ford))) q.cay))
|
||||
::
|
||||
$sur
|
||||
$sur
|
||||
.(sur ((dy-cast (list hoof:ford) !>(*(list hoof:ford))) q.cay))
|
||||
::
|
||||
$dir =+ ^= pax ^- path
|
||||
@ -478,7 +491,10 @@
|
||||
rose+[" " `~]^~[leaf+"=%" (smyt (en-beam he-beak s.dir))]
|
||||
==
|
||||
::
|
||||
$poke
|
||||
$help
|
||||
(dy-inspect +.p.mad p.q.cay)
|
||||
::
|
||||
$poke
|
||||
%- he-card(poy ~)
|
||||
:* %deal
|
||||
/poke
|
||||
@ -537,6 +553,563 @@
|
||||
t=(turn `wain`?~(r.hit ~ (to-wain:format q.u.r.hit)) trip)
|
||||
==
|
||||
::
|
||||
++ dy-inspect
|
||||
|= {topic/(list term) sut/span}
|
||||
%+ dy-rash %tan
|
||||
|^ ^- tang
|
||||
=+ to-display=(find-item-in-span (flop topic) sut)
|
||||
?~ to-display
|
||||
[%leaf "Could not find help"]~
|
||||
(flop (print-item u.to-display))
|
||||
:> # %models
|
||||
+|
|
||||
::
|
||||
:> an overview of all named things in the span.
|
||||
:>
|
||||
:> each item in the overview list is either a documentation for a sublist
|
||||
:> or an association between a term and documentation for it.
|
||||
++ overview (list overview-item)
|
||||
::
|
||||
:> in instance in the ++overview list.
|
||||
++ overview-item
|
||||
$% :> a header {doc} which will indent its {children}.
|
||||
{$header doc/what children/overview}
|
||||
:> an item in a list with {name} and {docs}.
|
||||
{$item name/tape doc/what}
|
||||
==
|
||||
::
|
||||
:> the part of a {span} being inspected.
|
||||
++ item
|
||||
$% :> overview of span
|
||||
{$view items/overview}
|
||||
:> inspecting a full core.
|
||||
$: $core
|
||||
name/tape
|
||||
docs/what
|
||||
sut/span
|
||||
con/coil
|
||||
children/(unit item)
|
||||
==
|
||||
:> inspecting a single arm on a core.
|
||||
$: $arm
|
||||
name/tape
|
||||
docs/what
|
||||
f/foot
|
||||
sut/span
|
||||
==
|
||||
:> inspecting a single chapter on a core.
|
||||
$: $chapter
|
||||
name/tape
|
||||
docs/what
|
||||
sut/span
|
||||
con/coil
|
||||
chapter-id/@
|
||||
==
|
||||
:> inspecting a face and what's behind it.
|
||||
$: $face
|
||||
name/tape
|
||||
docs/what
|
||||
children/(unit item)
|
||||
==
|
||||
==
|
||||
:> #
|
||||
:> # %searching
|
||||
:> #
|
||||
:> functions which find what to print
|
||||
+|
|
||||
:> returns the item to print while searching through {topic}.
|
||||
:>
|
||||
:> this gate is called recursively to find the path {topic} in the span
|
||||
:> {sut}. once it finds the correct part of the span, it switches to
|
||||
:> ++build-inspectable-recursively to describe that part of the span.
|
||||
++ find-item-in-span
|
||||
|= {topics/(list term) sut/span}
|
||||
^- (unit item)
|
||||
?~ topics
|
||||
:: we have no more search path. return the rest as an overview
|
||||
(build-inspectable-recursively sut)
|
||||
?- sut
|
||||
{$atom *} ~
|
||||
::
|
||||
{$cell *}
|
||||
=+ lhs=$(sut p.sut)
|
||||
?~ lhs
|
||||
$(sut q.sut)
|
||||
lhs
|
||||
::
|
||||
{$core *}
|
||||
=+ core-docs=r.q.sut
|
||||
?~ p.core-docs
|
||||
:: todo: this core has no toplevel documentation. it might have
|
||||
:: an arm though. check that next.
|
||||
$(sut p.sut)
|
||||
?: !=(i.topics u.p.core-docs)
|
||||
:: the current topic isn't the toplevel core topic.
|
||||
=+ arm=(find-arm-in-coil i.topics q.sut)
|
||||
?~ arm
|
||||
:: the current topic is neither the name of the core or an arm
|
||||
:: on the core.
|
||||
$(sut p.sut)
|
||||
`[%arm (trip i.topics) p.u.arm q.u.arm p.sut]
|
||||
?~ t.topics
|
||||
:: we matched the core name and have no further search terms.
|
||||
=* compiled-against (build-inspectable-recursively p.sut)
|
||||
`[%core (trip i.topics) q.core-docs p.sut q.sut compiled-against]
|
||||
:: search the core for chapters.
|
||||
=/ tombs/(list (pair @ tomb)) (~(tap by q.s.q.sut))
|
||||
|-
|
||||
^- (unit item)
|
||||
?~ tombs
|
||||
~
|
||||
?~ p.p.q.i.tombs
|
||||
:: this has no chapter name.
|
||||
$(tombs t.tombs)
|
||||
?: !=(i.t.topics u.p.p.q.i.tombs)
|
||||
:: this isn't the topic.
|
||||
$(tombs t.tombs)
|
||||
`[%chapter (trip i.t.topics) q.p.q.i.tombs p.sut q.sut p.i.tombs]
|
||||
::
|
||||
{$face *}
|
||||
?. ?=(term q.p.sut)
|
||||
:: todo: is there something we could do if we have a tune?
|
||||
~
|
||||
?. =(i.topics q.p.sut)
|
||||
:: this face has a name, but it's not the name we're looking for.
|
||||
~
|
||||
?~ t.topics
|
||||
`[%face (trip q.p.sut) p.p.sut (build-inspectable-recursively q.sut)]
|
||||
(find-item-in-span t.topics q.sut)
|
||||
::
|
||||
{$fork *}
|
||||
=/ spans/(list span) (~(tap in p.sut))
|
||||
|-
|
||||
?~ spans
|
||||
~
|
||||
=+ res=(find-item-in-span topics i.spans)
|
||||
?~ res
|
||||
$(spans t.spans)
|
||||
res
|
||||
::
|
||||
{$help *}
|
||||
:: while we found a raw help, it's associated on the wrong side of a
|
||||
:: set of topics. Walk through it instead of showing it.
|
||||
(find-item-in-span t.topics q.sut)
|
||||
::
|
||||
{$hold *} $(sut (~(play ut p.sut) q.sut))
|
||||
$noun ~
|
||||
$void ~
|
||||
==
|
||||
::
|
||||
:> changes a {span} into an {item}.
|
||||
++ build-inspectable-recursively
|
||||
|= sut/span
|
||||
^- (unit item)
|
||||
?- sut
|
||||
::
|
||||
{$atom *} ~
|
||||
::
|
||||
{$cell *}
|
||||
%+ join-items
|
||||
(build-inspectable-recursively p.sut)
|
||||
(build-inspectable-recursively q.sut)
|
||||
::
|
||||
{$core *}
|
||||
=* name (fall p.r.q.sut '')
|
||||
=* compiled-against (build-inspectable-recursively p.sut)
|
||||
`[%core (trip name) q.r.q.sut p.sut q.sut compiled-against]
|
||||
::
|
||||
{$face *}
|
||||
?. ?=(term q.p.sut)
|
||||
:: todo: can we do anything here if this face doesn't have a term?
|
||||
~
|
||||
=* compiled-against (build-inspectable-recursively q.sut)
|
||||
`[%face (trip q.p.sut) p.p.sut compiled-against]
|
||||
::
|
||||
{$fork *}
|
||||
=* spans (~(tap in p.sut))
|
||||
=* items (turn spans build-inspectable-recursively)
|
||||
(roll items join-items)
|
||||
::
|
||||
{$help *}
|
||||
=* rest-span (build-inspectable-recursively q.sut)
|
||||
`[%view [%header p.sut (item-as-overview rest-span)]~]
|
||||
::
|
||||
{$hold *} $(sut (~(play ut p.sut) q.sut))
|
||||
$noun ~
|
||||
$void ~
|
||||
==
|
||||
::
|
||||
:> combines two {(unit item)} together
|
||||
++ join-items
|
||||
|= {lhs/(unit item) rhs/(unit item)}
|
||||
^- (unit item)
|
||||
?~ lhs rhs
|
||||
?~ rhs lhs
|
||||
`[%view (weld (item-as-overview lhs) (item-as-overview rhs))]
|
||||
::
|
||||
:> changes an item into an overview.
|
||||
++ item-as-overview
|
||||
|= uit/(unit item)
|
||||
^- overview
|
||||
?~ uit ~
|
||||
=+ itm=u.uit
|
||||
?- itm
|
||||
::
|
||||
{$view *}
|
||||
items.itm
|
||||
::
|
||||
{$core *}
|
||||
?~ name.itm
|
||||
(item-as-overview children.itm)
|
||||
:- [%item name.itm docs.itm]
|
||||
(item-as-overview children.itm)
|
||||
::
|
||||
{$arm *}
|
||||
[%item name.itm docs.itm]~
|
||||
::
|
||||
{$chapter *}
|
||||
[%item name.itm docs.itm]~
|
||||
::
|
||||
{$face *}
|
||||
?~ name.itm
|
||||
~
|
||||
[%item name.itm docs.itm]~
|
||||
==
|
||||
::
|
||||
:> translate the internals of a core's {tomb} into an {overview}.
|
||||
++ arms-as-overview
|
||||
|= {a/(map term (pair what foot)) sut/span}
|
||||
^- overview
|
||||
%+ turn (~(tap by a))
|
||||
|= (pair term (pair what foot))
|
||||
=* doc (select-arm-docs p.q q.q sut)
|
||||
[%item (weld "++" (trip p)) -.doc]
|
||||
::
|
||||
:> if {arm-name} is an arm in {c}, returns its documentation.
|
||||
++ find-arm-in-coil
|
||||
|= {arm-name/term con/coil}
|
||||
^- (unit (pair what foot))
|
||||
=/ tombs (~(tap by q.s.con))
|
||||
|-
|
||||
?~ tombs
|
||||
~
|
||||
=+ item=(~(get by q.q.i.tombs) arm-name)
|
||||
?~ item
|
||||
$(tombs t.tombs)
|
||||
[~ u.item]
|
||||
::
|
||||
:> returns an overview for a core's arms and chapters.
|
||||
:>
|
||||
:> returns an overview for arms which are part of unnamed chapters,
|
||||
:> and an overview of the named chapters.
|
||||
++ arm-and-chapter-overviews
|
||||
|= {sut/span con/coil core-name/tape}
|
||||
^- {overview overview}
|
||||
=| arm-docs/overview :< documented arms
|
||||
=| chapter-docs/overview :< documented chapters
|
||||
=/ tombs (~(tap by q.s.con))
|
||||
|-
|
||||
?~ tombs
|
||||
[(sort-overview arm-docs) (sort-overview chapter-docs)]
|
||||
=* current q.i.tombs
|
||||
?~ p.p.current
|
||||
:: this chapter has no name. add all the foot documentation
|
||||
:: to arm-docs.
|
||||
=. arm-docs (weld arm-docs (arms-as-overview q.current sut))
|
||||
$(tombs t.tombs)
|
||||
:: this chapter has a name. add it to the list of chapters
|
||||
=. chapter-docs
|
||||
%+ weld chapter-docs
|
||||
^- overview
|
||||
[%item :(weld (trip u.p.p.current) ":" core-name) q.p.current]~
|
||||
$(tombs t.tombs)
|
||||
::
|
||||
:> returns an overview of the arms in a specific chapter.
|
||||
++ arms-in-chapter
|
||||
|= {sut/span con/coil chapter-id/@}
|
||||
^- overview
|
||||
=* chapter-tomb (~(got by q.s.con) chapter-id)
|
||||
(sort-overview (arms-as-overview q.chapter-tomb sut))
|
||||
::
|
||||
:> sort the items.
|
||||
++ sort-overview
|
||||
|= ovr/overview
|
||||
^- overview
|
||||
%+ sort ovr
|
||||
|= {lhs/overview-item rhs/overview-item}
|
||||
(aor (get-overview-name lhs) (get-overview-name rhs))
|
||||
::
|
||||
++ get-overview-name
|
||||
|= ovr/overview-item
|
||||
?- ovr
|
||||
{$header *} ""
|
||||
{$item *} name.ovr
|
||||
==
|
||||
::
|
||||
++ what-from-span
|
||||
|= sut/span
|
||||
?+ sut ~
|
||||
{$core *} q.r.q.sut
|
||||
{$help *} p.sut
|
||||
{$hold *} $(sut (~(play ut p.sut) q.sut))
|
||||
==
|
||||
::
|
||||
:> #
|
||||
:> # %printing
|
||||
:> #
|
||||
:> functions which display output of various types.
|
||||
+|
|
||||
++ print-item
|
||||
|= itm/item
|
||||
^- tang
|
||||
?- itm
|
||||
{$view *} (print-overview items.itm)
|
||||
{$core *} (print-core +.itm)
|
||||
{$arm *} (print-arm +.itm)
|
||||
{$chapter *} (print-chapter +.itm)
|
||||
{$face *} (print-face +.itm)
|
||||
==
|
||||
::
|
||||
:> renders the documentation for a full core.
|
||||
++ print-core
|
||||
|= {core-name/tape docs/what sut/span con/coil uit/(unit item)}
|
||||
^- tang
|
||||
=+ [arms chapters]=(arm-and-chapter-overviews sut con core-name)
|
||||
;: weld
|
||||
(print-header (trip (fall p.r.con '')) q.r.con)
|
||||
::
|
||||
:: todo: figure out how to display the default arm, which should
|
||||
:: be rendered separately.
|
||||
::
|
||||
?~ arms
|
||||
~
|
||||
(print-overview [%header `['arms:' ~] arms]~)
|
||||
::
|
||||
?~ chapters
|
||||
~
|
||||
(print-overview [%header `['chapters:' ~] chapters]~)
|
||||
::
|
||||
=+ compiled=(item-as-overview uit)
|
||||
?~ compiled
|
||||
~
|
||||
(print-overview [%header `['compiled against:' ~] compiled]~)
|
||||
==
|
||||
::
|
||||
:> figures out which {what}s to use.
|
||||
:>
|
||||
:> there are three places with a relevant {what}: the {arm-doc} on the
|
||||
:> arm, the {what} in the computed span of the foot, and the {what} on
|
||||
:> the product of the default arm when the computed span is a core.
|
||||
++ select-arm-docs
|
||||
|= {arm-doc/what f/foot sut/span}
|
||||
:> the computed arm documentation and the product documentation.
|
||||
^- {what what}
|
||||
=+ foot-span=(~(play ut sut) p.f)
|
||||
=+ raw-product=(what-from-span foot-span)
|
||||
=/ product-product/what
|
||||
?. ?=({$core *} foot-span)
|
||||
~
|
||||
=* inner-span (~(play ut foot-span) [%limb %$])
|
||||
(what-from-span inner-span)
|
||||
:-
|
||||
?~ arm-doc
|
||||
raw-product
|
||||
arm-doc
|
||||
?~ arm-doc
|
||||
product-product
|
||||
raw-product
|
||||
::
|
||||
:> renders the documentation for a single arm in a core.
|
||||
++ print-arm
|
||||
|= {arm-name/tape arm-doc/what f/foot sut/span}
|
||||
:: todo: need to get the sample here. also hoist this to the general
|
||||
:: core printing machinery, too.
|
||||
=+ [main-doc product-doc]=(select-arm-docs arm-doc f sut)
|
||||
%+ weld
|
||||
(print-header arm-name main-doc)
|
||||
?~ product-doc
|
||||
~
|
||||
%+ weld
|
||||
`tang`[[%leaf ""] [%leaf "product:"] ~]
|
||||
(print-header "" product-doc)
|
||||
::
|
||||
:> renders the documentation for a chapter in a core.
|
||||
++ print-chapter
|
||||
|= {name/tape doc/what sut/span con/coil chapter-id/@}
|
||||
;: weld
|
||||
(print-header name doc)
|
||||
::
|
||||
?~ doc
|
||||
~
|
||||
(print-sections q.u.doc)
|
||||
::
|
||||
=+ arms=(arms-in-chapter sut con chapter-id)
|
||||
?~ arms
|
||||
~
|
||||
(print-overview [%header `['arms:' ~] arms]~)
|
||||
==
|
||||
::
|
||||
:> renders the documentation for a face.
|
||||
++ print-face
|
||||
|= {name/tape doc/what children/(unit item)}
|
||||
%+ weld
|
||||
(print-header name doc)
|
||||
?~ children
|
||||
~
|
||||
(print-item u.children)
|
||||
::
|
||||
:> returns a set of lines from a {chap}
|
||||
++ print-header
|
||||
|= {name/tape doc/what}
|
||||
^- tang
|
||||
?~ name
|
||||
?~ doc
|
||||
[%leaf "(Undocumented)"]~
|
||||
%+ weld
|
||||
`tang`[%leaf "{(trip p.u.doc)}"]~
|
||||
(print-sections q.u.doc)
|
||||
?~ doc
|
||||
[%leaf name]~
|
||||
%+ weld
|
||||
`tang`[%leaf "{name}: {(trip p.u.doc)}"]~
|
||||
(print-sections q.u.doc)
|
||||
::
|
||||
:> renders an overview as {tang}
|
||||
++ print-overview
|
||||
|= ovr/overview
|
||||
^- tang
|
||||
|^ (print-level ovr 0)
|
||||
++ print-level
|
||||
:> indentation: multiply by 2 to get number of spaces.
|
||||
|= {ovr/overview indentation/@u}
|
||||
^- tang
|
||||
:> max-key-length: length of the longest {item} term.
|
||||
=/ max-key-length (calculate-max-key-length ovr)
|
||||
:> output: what we return
|
||||
=| output/tang
|
||||
|-
|
||||
?~ ovr
|
||||
output
|
||||
?- i.ovr
|
||||
::
|
||||
{$header *}
|
||||
%= $
|
||||
output ;: weld
|
||||
output
|
||||
?~ doc.i.ovr
|
||||
~
|
||||
`tang`[[%leaf ""] [%leaf "{(trip p.u.doc.i.ovr)}"] ~]
|
||||
?~ doc.i.ovr
|
||||
~
|
||||
(print-sections q.u.doc.i.ovr)
|
||||
(print-level children.i.ovr (add 1 indentation))
|
||||
==
|
||||
ovr t.ovr
|
||||
==
|
||||
::
|
||||
{$item *}
|
||||
=* rendered (render-item indentation max-key-length +.i.ovr)
|
||||
%= $
|
||||
output (weld output rendered)
|
||||
ovr t.ovr
|
||||
==
|
||||
==
|
||||
::
|
||||
:>
|
||||
++ calculate-max-key-length
|
||||
|= ovr/overview
|
||||
^- @u
|
||||
%- dy-longest-tape
|
||||
(turn ovr get-overview-name)
|
||||
::
|
||||
:> renders a single item line with the given indentation level.
|
||||
++ render-item
|
||||
|= {indentation/@u max-key-length/@u name/tape doc/what}
|
||||
^- tang
|
||||
=+ spaces=(mul indentation 2)
|
||||
=+ line=(weld (dy-build-space spaces) name)
|
||||
=* line-len (lent line)
|
||||
=* name-len (lent name)
|
||||
=+ diff=(sub max-key-length name-len)
|
||||
=? line (gth diff 0)
|
||||
(weld line (dy-build-space diff))
|
||||
=/ slogan/tape
|
||||
?~ doc
|
||||
~
|
||||
(trip p.u.doc)
|
||||
=? line !=(0 (lent slogan))
|
||||
;: weld
|
||||
line
|
||||
" : "
|
||||
(dy-truncate (sub 80 :(add 1 spaces line-len)) slogan)
|
||||
==
|
||||
[%leaf line]~
|
||||
--
|
||||
::
|
||||
:> renders a list of sections as {tang}
|
||||
:>
|
||||
:> prints the longform documentation.
|
||||
++ print-sections
|
||||
|= sections/(list sect)
|
||||
^- tang
|
||||
=| output/tang
|
||||
|-
|
||||
?~ sections
|
||||
output
|
||||
=. output ;: weld
|
||||
output
|
||||
`tang`[%leaf ""]~
|
||||
(print-section i.sections)
|
||||
==
|
||||
$(sections t.sections)
|
||||
::
|
||||
:> renders an individual {sect} to a {tang}
|
||||
++ print-section
|
||||
|= section/sect
|
||||
^- tang
|
||||
%+ turn section
|
||||
|= pica
|
||||
^- tank
|
||||
?: p
|
||||
[%leaf (trip q)]
|
||||
[%leaf " {(trip q)}"]
|
||||
--
|
||||
::
|
||||
:> truncates `t` down to `i` characters, adding an ellipsis.
|
||||
++ dy-truncate
|
||||
:: todo: when ~palfun's string library is landed, switch to his
|
||||
:: implementation.
|
||||
|= {i/@u t/tape}
|
||||
^- tape
|
||||
=+ t-len=(lent t)
|
||||
?: (lth t-len i)
|
||||
t
|
||||
:(weld (scag (sub i 4) t) "...")
|
||||
::
|
||||
:> creates a tape of i spaces, used for padding.
|
||||
++ dy-build-space
|
||||
:: todo: when ~palfun's string library is landed, switch to his
|
||||
:: implementation.
|
||||
|= i/@u
|
||||
^- tape
|
||||
=| t/tape
|
||||
|-
|
||||
?: =(0 i)
|
||||
t
|
||||
$(t (weld " " t), i (sub i 1))
|
||||
::
|
||||
:> returns the length of the longest tape in c.
|
||||
++ dy-longest-tape
|
||||
|= c/(list tape)
|
||||
=| ret/@ud
|
||||
|-
|
||||
?~ c
|
||||
ret
|
||||
=+ l=(lent i.c)
|
||||
?: (gth l ret)
|
||||
$(ret l, c t.c)
|
||||
$(c t.c)
|
||||
::
|
||||
++ dy-show-span-noun
|
||||
|= a/span ^- tank
|
||||
=- >[-]<
|
||||
@ -653,6 +1226,13 @@
|
||||
?~(b !>([~ ~]) (dy-vase p.u.b))
|
||||
::
|
||||
++ dy-twig-head :: dynamic state
|
||||
:: todo: how do i separate the toplevel 'dojo state' comment?
|
||||
:> dojo state
|
||||
:>
|
||||
:> our: the name of this urbit
|
||||
:> now: the current time
|
||||
:> eny: a piece of random entropy
|
||||
:>
|
||||
^- cage
|
||||
:- %noun
|
||||
=+ sloop=|=({a/vase b/vase} ?:(=(*vase a) b ?:(=(*vase b) a (slop a b))))
|
||||
|
@ -5,26 +5,26 @@
|
||||
:: all lines must be under 80 characters. no blank lines.
|
||||
:: any line longer than 60 characters is probably too long.
|
||||
:: uppercase or non-ascii letters are strongly discouraged.
|
||||
::
|
||||
::
|
||||
:: informal comments (lines with {::}) should be used only for
|
||||
:: meta-discussion *about* the code.
|
||||
:: meta-discussion *about* the code.
|
||||
::
|
||||
:: whenever possible, use formal decorations. {:>} decorates
|
||||
:: the next expression; {:<} decorates the previous one.
|
||||
::
|
||||
:: there are two places to put decorations: in line with the
|
||||
:: there are two places to put decorations: in line with the
|
||||
:: code, and on the right margin.
|
||||
::
|
||||
:: in comments and decorations, use *phrase* for emphasis
|
||||
:: and {braces} to surround code literals. (documentation will
|
||||
:: and {braces} to surround code literals. (documentation will
|
||||
:: eventually be automatically generated from formal comments.)
|
||||
:: %literal, ++literal, ~ship need no braces. for a valid
|
||||
:: %literal, ++literal, ~ship need no braces. for a valid
|
||||
:: hoon expression, `exp.
|
||||
::
|
||||
:: there are three conventions for naming: *ultralapidary*,
|
||||
:: *lapidary*, and *natural*. this file is mostly natural.
|
||||
::
|
||||
:: when in doubt, use the *natural* naming convention. for
|
||||
:: when in doubt, use the *natural* naming convention. for
|
||||
:: both arms and faces, natural naming means long, legible,
|
||||
:: english-language phrases, in hyphen-separated {kebab-case}.
|
||||
::
|
||||
@ -34,7 +34,7 @@
|
||||
::
|
||||
:: ultralapidary conventions use single-letter names starting
|
||||
:: with {a}. use this convention only for one-liners, etc.
|
||||
::
|
||||
::
|
||||
:: the file below is a medium-sized generator, built around
|
||||
:: a typical two-core structure. the cores are labeled {%arch}
|
||||
:: (structures) and {%work} (productions). this is canonical.
|
||||
@ -46,15 +46,15 @@
|
||||
:: a forward decoration block {:>} is either a *document block* or
|
||||
:: a *definition block*.
|
||||
|
||||
:: a document block has two parts, each of which is optional:
|
||||
:: the *title* and the *body*,
|
||||
:: a document block has two parts, each of which is optional:
|
||||
:: the *title* and the *body*,
|
||||
::
|
||||
:: the title is a ++term preceded by {:> || %}. only cores
|
||||
:: the title is a ++term preceded by {:> # %}. only cores
|
||||
:: and core chapters (preceded by {+|}) can use titles. titles
|
||||
:: are optionally surrounded by blank or semi-blank decorations,
|
||||
:: {:>} or {:> ||}.
|
||||
:: are optionally surrounded by blank or semi-blank decorations,
|
||||
:: {:>} or {:> #}.
|
||||
::
|
||||
:: the body is either short or long. a short body is a *single line*
|
||||
:: the body is either short or long. a short body is a *single line*
|
||||
:: preceded by {:> } - ie, not indented. a long body starts with
|
||||
:: a *single line* indented by two extra spaces, {:> }, then a
|
||||
:: blank line, then a series of paragraphs.
|
||||
@ -78,9 +78,9 @@
|
||||
:- %say
|
||||
|= *
|
||||
=< [%noun (say-hello %world)]
|
||||
=> :> ||
|
||||
:> || %arch
|
||||
:> ||
|
||||
=> :> #
|
||||
:> # %arch
|
||||
:> #
|
||||
:> structures for our imaginary hello, world generator.
|
||||
:>
|
||||
:> nothing forces us to put structures in a separate core.
|
||||
@ -94,11 +94,9 @@
|
||||
:> most code will not need its own patterns. but put them
|
||||
:> in a separate chapter (separated by {+|}).
|
||||
|%
|
||||
:> ||
|
||||
:> || %model
|
||||
:> ||
|
||||
:> # %model
|
||||
:> models (molds) are functions that normalize nouns.
|
||||
:>
|
||||
:>
|
||||
:> arms producing molds are introduced with {+=}. for molds,
|
||||
:> we decorate the mold rather than the arm. the compiler
|
||||
:> will copy the mold decoration onto the arm.
|
||||
@ -116,7 +114,10 @@
|
||||
{$pear p/@ q/@} :< good for cider
|
||||
{$acai p/@} :< aztec superfood
|
||||
==
|
||||
:> || %pattern
|
||||
:> #
|
||||
:> # %pattern
|
||||
:> #
|
||||
:>
|
||||
:> patterns are functions that build models.
|
||||
:>
|
||||
:> other languages might call these "type constructors"
|
||||
@ -125,16 +126,17 @@
|
||||
++ binary-tree :< tree pattern
|
||||
|* a/$-(* *)
|
||||
$@($~ {n/a l/(binary-tree a) r/(binary-tree a)})
|
||||
:> ||
|
||||
:> || %constant
|
||||
:> ||
|
||||
:> #
|
||||
:> # %constant
|
||||
:> #
|
||||
:> if you have constants, put them in their own chapter.
|
||||
+|
|
||||
++ answer :< answer to everything
|
||||
42
|
||||
--
|
||||
:> || %work
|
||||
:> engines for our imaginary hello, world app.
|
||||
:> # %work
|
||||
:>
|
||||
:> engines for our imaginary hello, world app.
|
||||
:>
|
||||
:> note that ++say-goodbye is the correct notation, even though
|
||||
:> it's a {+-} arm.
|
||||
@ -148,12 +150,11 @@
|
||||
txt/term
|
||||
^- tape
|
||||
"hello, {(rip 3 txt)}"
|
||||
:>
|
||||
:> ++say-goodbye: say a really proper goodbye
|
||||
:> ++say-goodbye: say a really proper goodbye
|
||||
:>
|
||||
:> some paragraphs about the goodbye algorithm, possibly
|
||||
:> including code indented by four extra spaces:
|
||||
:>
|
||||
:>
|
||||
:> ?: =(%hello %world)
|
||||
:> %hello
|
||||
:> %world
|
||||
|
@ -24,7 +24,7 @@
|
||||
:: computer's life. during this sequence, each state is a function
|
||||
:: that, passed the next event, produces the next state.
|
||||
::
|
||||
:: a regular event is a `[date wire type data]` tuple, where `date` is a
|
||||
:: each event is a `[date wire type data]` tuple, where `date` is a
|
||||
:: 128-bit Urbit date; `wire` is an opaque path which output can
|
||||
:: match to track causality; `type` is a symbol describing the type
|
||||
:: of input; and `data` is input data specific to `type`.
|
||||
@ -60,7 +60,7 @@
|
||||
!= ::
|
||||
:: first we use the boot formula (event 1) to set up
|
||||
:: the pair of state function and main sequence. the boot
|
||||
:: formula peels off the first 5 events
|
||||
:: formula peels off the first n (currently 3) events
|
||||
:: to set up the lifecycle loop.
|
||||
::
|
||||
=+ [state-gate main-sequence]=.*(full-sequence boot-formula)
|
||||
@ -232,9 +232,8 @@
|
||||
:: /ren %ford renderers
|
||||
:: /web %eyre web content
|
||||
:: /sys system files
|
||||
:: /neo new system files
|
||||
::
|
||||
(user /app /gen /lib /mar /neo /ren /sec /sur /sys /web ~)
|
||||
(user /app /gen /lib /mar /ren /sec /sur /sys /web ~)
|
||||
==
|
||||
:: ::
|
||||
++ user :: userspace loading
|
||||
|
267
gen/walk.hoon
267
gen/walk.hoon
@ -11,262 +11,6 @@
|
||||
::
|
||||
++ ap
|
||||
|_ gen/twig
|
||||
::
|
||||
++ walk :: forward traverse
|
||||
|* life/mold
|
||||
|= $: vit/life
|
||||
$= mac
|
||||
$- $: twig
|
||||
life
|
||||
$-({? twig life} {twig life})
|
||||
==
|
||||
(unit (pair twig life))
|
||||
==
|
||||
^- {twig life}
|
||||
=/ use &
|
||||
=< apex
|
||||
|%
|
||||
++ apex
|
||||
|- ^- {twig life}
|
||||
=* aid |= {use/? gen/twig vit/life}
|
||||
^$(use use, gen gen, vit vit)
|
||||
=/ gun ?:(use (mac gen vit aid) ~)
|
||||
?^ gun u.gun
|
||||
?: ?=(^ -.gen)
|
||||
%.(gen dubs)
|
||||
?- -.gen
|
||||
$$ (lead -.gen %.(+.gen noop))
|
||||
$base (lead -.gen %.(+.gen noop))
|
||||
$bunt (lead -.gen %.(+.gen expr))
|
||||
$bust (lead -.gen %.(+.gen noop))
|
||||
$dbug (lead -.gen %.(+.gen nexp))
|
||||
$hand (lead -.gen %.(+.gen noop))
|
||||
$knit (lead -.gen %.(+.gen (moto bark)))
|
||||
$leaf (lead -.gen %.(+.gen noop))
|
||||
$limb (lead -.gen %.(+.gen noop))
|
||||
$lost (lead -.gen %.(+.gen expr))
|
||||
$rock (lead -.gen %.(+.gen noop))
|
||||
$sand (lead -.gen %.(+.gen noop))
|
||||
$tell (lead -.gen %.(+.gen moar))
|
||||
$tune (lead -.gen %.(+.gen tung))
|
||||
$wing (lead -.gen %.(+.gen noop))
|
||||
$yell (lead -.gen %.(+.gen moar))
|
||||
$claw (lead -.gen %.(+.gen dubs))
|
||||
$shoe (lead -.gen %.(+.gen expr))
|
||||
$bank (lead -.gen %.(+.gen moar))
|
||||
$book (lead -.gen %.(+.gen moar))
|
||||
$lamb (lead -.gen %.(+.gen dubs))
|
||||
$bush (lead -.gen %.(+.gen dubs))
|
||||
$pick (lead -.gen %.(+.gen moar))
|
||||
$coat (lead -.gen %.(+.gen nexp))
|
||||
$grow (lead -.gen %.(+.gen expr))
|
||||
$door (lead -.gen %.(+.gen (trio noop expr arms)))
|
||||
$door (lead -.gen %.(+.gen (trio noop expr arms)))
|
||||
$gasp (lead -.gen %.(+.gen (twin noop dubs)))
|
||||
$corp (lead -.gen %.(+.gen (twin noop arms)))
|
||||
$trap (lead -.gen %.(+.gen (twin noop expr)))
|
||||
$cork (lead -.gen %.(+.gen (trio noop expr arms)))
|
||||
$loop (lead -.gen %.(+.gen (twin noop expr)))
|
||||
$port (lead -.gen %.(+.gen (twin noop dubs)))
|
||||
$gill (lead -.gen %.(+.gen (twin noop dubs)))
|
||||
$gate (lead -.gen %.(+.gen (twin noop dubs)))
|
||||
$tray (lead -.gen %.(+.gen (twin noop expr)))
|
||||
$scon (lead -.gen %.(+.gen dubs))
|
||||
$conq (lead -.gen %.(+.gen (quad expr expr expr expr)))
|
||||
$cons (lead -.gen %.(+.gen dubs))
|
||||
$cont (lead -.gen %.(+.gen trey))
|
||||
$conl (lead -.gen %.(+.gen moar))
|
||||
$conp (lead -.gen %.(+.gen moar))
|
||||
$keep (lead -.gen %.(+.gen (twin noop moan)))
|
||||
$lace (lead -.gen %.(+.gen dubs))
|
||||
$call (lead -.gen %.(+.gen (twin expr moar)))
|
||||
$bake (lead -.gen %.(+.gen (trio noop expr moan)))
|
||||
$calq (lead -.gen %.(+.gen (quad expr expr expr expr)))
|
||||
$calt (lead -.gen %.(+.gen trey))
|
||||
$open (lead -.gen %.(+.gen (trio noop expr moar)))
|
||||
$make (lead -.gen %.(+.gen (twin noop moan)))
|
||||
$wish (lead -.gen %.(+.gen dubs))
|
||||
$bump (lead -.gen %.(+.gen expr))
|
||||
$nock (lead -.gen %.(+.gen dubs))
|
||||
$same (lead -.gen %.(+.gen dubs))
|
||||
$deep (lead -.gen %.(+.gen expr))
|
||||
$iron (lead -.gen %.(+.gen expr))
|
||||
$ward (lead -.gen %.(+.gen dubs))
|
||||
$like (lead -.gen %.(+.gen dubs))
|
||||
$cast (lead -.gen %.(+.gen dubs))
|
||||
$zinc (lead -.gen %.(+.gen expr))
|
||||
$burn (lead -.gen %.(+.gen expr))
|
||||
$name (lead -.gen %.(+.gen nexp))
|
||||
$lead (lead -.gen %.(+.gen expr))
|
||||
$halo (lead -.gen %.(+.gen nexp))
|
||||
$help (lead -.gen %.(+.gen nexp))
|
||||
$show (lead -.gen %.(+.gen dubs))
|
||||
$lurk (lead -.gen %.(+.gen dubs))
|
||||
$crap (lead -.gen %.(+.gen (raid expr)))
|
||||
$fast (lead -.gen %.(+.gen (quad noop expr moan expr)))
|
||||
$funk (lead -.gen %.(+.gen nexp))
|
||||
$thin (lead -.gen %.(+.gen (twin toad expr)))
|
||||
$hint (lead -.gen %.(+.gen (twin toad expr)))
|
||||
$poll (lead -.gen %.(+.gen nexp))
|
||||
$memo (lead -.gen %.(+.gen nexp))
|
||||
$dump (lead -.gen %.(+.gen trip))
|
||||
$ddup (lead -.gen %.(+.gen dubs))
|
||||
$warn (lead -.gen %.(+.gen (quad noop expr expr expr)))
|
||||
$peep (lead -.gen %.(+.gen dubs))
|
||||
$wad (lead -.gen %.(+.gen (twin expr moar)))
|
||||
$nub (lead -.gen %.(+.gen expr))
|
||||
$dip (lead -.gen %.(+.gen (twin expr moar)))
|
||||
$fry (lead -.gen %.(+.gen dubs))
|
||||
$new (lead -.gen %.(+.gen dubs))
|
||||
$fix (lead -.gen %.(+.gen (twin moan expr)))
|
||||
$var (lead -.gen %.(+.gen (trio tora expr expr)))
|
||||
$rev (lead -.gen %.(+.gen (trio tora expr expr)))
|
||||
$set (lead -.gen %.(+.gen trip))
|
||||
$huh (lead -.gen %.(+.gen (quad noop expr expr expr)))
|
||||
$rap (lead -.gen %.(+.gen dubs))
|
||||
$nip (lead -.gen %.(+.gen dubs))
|
||||
$per (lead -.gen %.(+.gen dubs))
|
||||
$sip (lead -.gen %.(+.gen (quad tora noop expr expr)))
|
||||
$pin (lead -.gen %.(+.gen dubs))
|
||||
$tow (lead -.gen %.(+.gen moar))
|
||||
$aka (lead -.gen %.(+.gen trip))
|
||||
$use (lead -.gen %.(+.gen dubs))
|
||||
$or (lead -.gen %.(+.gen moar))
|
||||
$case (lead -.gen %.(+.gen (twin noop (moto dubs))))
|
||||
$if (lead -.gen %.(+.gen trey))
|
||||
$lest (lead -.gen %.(+.gen trey))
|
||||
$ifcl (lead -.gen %.(+.gen trip))
|
||||
$deny (lead -.gen %.(+.gen dubs))
|
||||
$sure (lead -.gen %.(+.gen dubs))
|
||||
$deft (lead -.gen %.(+.gen (trio noop expr (moto dubs))))
|
||||
$and (lead -.gen %.(+.gen moar))
|
||||
$ifat (lead -.gen %.(+.gen trip))
|
||||
$ifno (lead -.gen %.(+.gen trip))
|
||||
$fits (lead -.gen %.(+.gen (twin expr noop)))
|
||||
$not (lead -.gen %.(+.gen expr))
|
||||
$twig (lead -.gen %.(+.gen dubs))
|
||||
$wrap (lead -.gen %.(+.gen expr))
|
||||
$spit (lead -.gen %.(+.gen dubs))
|
||||
$code (lead -.gen %.(+.gen expr))
|
||||
$need (lead -.gen %.(+.gen nexp))
|
||||
$fail (lead -.gen %.(+.gen noop))
|
||||
==
|
||||
++ arms
|
||||
(raid (twin noop (raid (twin noop heel))))
|
||||
::
|
||||
++ bark
|
||||
|= wof/woof
|
||||
?-(wof @ [wof vit], ^ (lead ~ (expr p.wof)))
|
||||
::
|
||||
++ dubs
|
||||
(twin expr expr)
|
||||
::
|
||||
++ expr
|
||||
|= p/twig
|
||||
^$(gen p)
|
||||
::
|
||||
++ heel
|
||||
|= bud/foot
|
||||
?- -.bud
|
||||
$ash =^(nex vit ^$(gen p.bud) [[%ash nex] vit])
|
||||
$elm =^(nex vit ^$(gen p.bud) [[%elm nex] vit])
|
||||
==
|
||||
::
|
||||
++ lead
|
||||
|* {sem/@tas out/{* life}}
|
||||
[[sem -.out] +.out]
|
||||
::
|
||||
++ lede
|
||||
|* {sem/@tas out/{* life}}
|
||||
[`twig`[sem -.out] +.out]
|
||||
::
|
||||
++ moan
|
||||
(moto nexp)
|
||||
::
|
||||
++ moar
|
||||
(moto expr)
|
||||
::
|
||||
++ moto
|
||||
|* etc/$-(* {* life})
|
||||
|* bud/*
|
||||
^+ [bud vit]
|
||||
?: =(~ bud) [bud vit]
|
||||
=^ heb vit (etc -.bud)
|
||||
=^ mor vit $(bud +.bud)
|
||||
[[heb mor] vit]
|
||||
::
|
||||
++ nexp
|
||||
(twin noop expr)
|
||||
::
|
||||
++ noop
|
||||
|* bud/*
|
||||
[bud vit]
|
||||
::
|
||||
++ quad
|
||||
|* $: one/$-(* {* life})
|
||||
two/$-(* {* life})
|
||||
tri/$-(* {* life})
|
||||
qua/$-(* {* life})
|
||||
==
|
||||
|* bud/*
|
||||
=^ yal vit (one -.bud)
|
||||
=^ ves vit (two +<.bud)
|
||||
=^ jot vit (tri +>-.bud)
|
||||
=^ wip vit (qua +>+.bud)
|
||||
[[yal ves jot wip] vit]
|
||||
::
|
||||
++ raid
|
||||
|* etc/$-(* {* life})
|
||||
|* bud/*
|
||||
^+ [bud vit]
|
||||
?: =(~ bud) [bud vit]
|
||||
=^ lef vit $(bud +<.bud)
|
||||
=^ ryt vit $(bud +>.bud)
|
||||
=^ top vit (etc ->.bud)
|
||||
[[[-<.bud top] lef ryt] vit]
|
||||
::
|
||||
++ trey
|
||||
(trio expr expr expr)
|
||||
::
|
||||
++ trio
|
||||
|* $: one/$-(* {* life})
|
||||
two/$-(* {* life})
|
||||
tri/$-(* {* life})
|
||||
==
|
||||
|* bud/*
|
||||
=^ yal vit (one -.bud)
|
||||
=^ ves vit (two +<.bud)
|
||||
=^ jot vit (tri +>.bud)
|
||||
[[yal ves jot] vit]
|
||||
::
|
||||
++ trip
|
||||
(trio noop expr expr)
|
||||
::
|
||||
++ toad
|
||||
|= bud/$@(term {p/term q/twig})
|
||||
?@ bud [bud vit]
|
||||
(lead p.bud (expr q.bud))
|
||||
::
|
||||
++ tora
|
||||
(twin noop twee)
|
||||
::
|
||||
++ tung
|
||||
|= bud/{p/what q/$@(term tune)}
|
||||
?@ q.bud [bud vit]
|
||||
(lead p.bud %.(q.bud (twin (raid (twin noop twee)) (moto expr))))
|
||||
::
|
||||
++ twee
|
||||
|= bud/(unit twig)
|
||||
?~ bud [~ vit]
|
||||
(lead ~ (expr u.bud))
|
||||
::
|
||||
++ twin
|
||||
|* {one/$-(* {* life}) two/$-(* {* life})}
|
||||
|* bud/*
|
||||
=^ yal vit (one -.bud)
|
||||
=^ ves vit (two +.bud)
|
||||
[[yal ves] vit]
|
||||
--
|
||||
++ gi
|
||||
=| whit
|
||||
=* wit -
|
||||
@ -384,10 +128,10 @@
|
||||
::
|
||||
++ humm
|
||||
|* {pif/@tas suf/*}
|
||||
|= {wat/what cog/term}
|
||||
|= {cog/term wat/what)
|
||||
^- (pair twig whit)
|
||||
=^ taw wit (grif cog wat)
|
||||
[[pif [taw cog] suf] wit]
|
||||
[[pif [cog taw] suf] wit]
|
||||
::
|
||||
++ runk
|
||||
^- (pair twig whit)
|
||||
@ -411,13 +155,6 @@
|
||||
[[%2 one two] wit]
|
||||
==
|
||||
--
|
||||
::
|
||||
++ graf
|
||||
:: ^- (unit twig)
|
||||
:: =^ nex wit ((walk whit) wit grad)
|
||||
:: ?:(gray ~ `nex)
|
||||
=^ nex wit ((walk whit) wit grad)
|
||||
nex
|
||||
--
|
||||
--
|
||||
--
|
||||
|
@ -5371,7 +5371,7 @@
|
||||
{$d p/twig} :: take $-(marl marl)
|
||||
{$e p/twig q/(list tuna)} :: element literal
|
||||
== ::
|
||||
++ chap (pair (list term) what) :: labeled help
|
||||
++ chap (pair (unit term) what) :: labeled help
|
||||
++ chum $? lef/term :: jet name
|
||||
{std/term kel/@} :: kelvin version
|
||||
{ven/term pro/term kel/@} :: vendor and product
|
||||
@ -5592,7 +5592,7 @@
|
||||
$% {$atom p/term q/(unit @)} :: atom / constant
|
||||
{$cell p/span q/span} :: ordered pair
|
||||
{$core p/span q/coil} :: object
|
||||
{$face p/{p/what q/tool} q/span} :: namespace (new)
|
||||
{$face p/{p/what q/$@(term tune)} q/span} :: namespace (new)
|
||||
{$fork p/(set span)} :: union
|
||||
{$help p/what q/span} :: documentation
|
||||
{$hold p/span q/twig} :: lazy evaluation
|
||||
@ -6284,7 +6284,7 @@
|
||||
:_ wit(lab ~, boy ~)
|
||||
=- [pif - suf]
|
||||
^- chap
|
||||
:- ?~(lab p.pac [u.lab ~])
|
||||
:- ?~(lab p.pac [~ u.lab])
|
||||
?~(boy q.pac boy)
|
||||
::
|
||||
++ helk
|
||||
@ -9251,7 +9251,12 @@
|
||||
?+ typ ~
|
||||
{$hold *} $(typ ~(repo ut typ))
|
||||
{$core *}
|
||||
(turn (~(tap by q.s.q.typ) ~) |=({a/term *} a))
|
||||
%- zing
|
||||
%+ turn (~(tap by q.s.q.typ) ~)
|
||||
|= {* b/tomb}
|
||||
%+ turn (~(tap by q.b) ~)
|
||||
|= {a/term *}
|
||||
a
|
||||
==
|
||||
::
|
||||
++ slop :: cons two vases
|
||||
@ -9386,11 +9391,11 @@
|
||||
:: fine: definition line
|
||||
::
|
||||
++ line (cook crip ;~(plug prz (star prn)))
|
||||
++ head ;~(pfix ;~(plug bar bar ace ace cen) sym)
|
||||
++ head ;~(pfix ;~(plug hax ace ace cen) sym)
|
||||
++ text (pick line code)
|
||||
++ code (cook crip (dubs (star prn)))
|
||||
++ null (star ace)
|
||||
++ noel ;~(pose (step ;~(sfix ;~(plug bar bar) (star ace))) null)
|
||||
++ noel ;~(pose (step ;~(sfix hax (star ace))) null)
|
||||
++ fine ;~(plug sym (cook crip ;~(pfix ;~(plug col ace) (star prn))))
|
||||
::
|
||||
:: lean: line delimited
|
||||
@ -10429,7 +10434,7 @@
|
||||
~&(duplicate-arm+p.i.q.i.a ~)
|
||||
$(q.i.a t.q.i.a, e (~(put by e) p.i.q.i.a q.i.q.i.a))
|
||||
?~ d ~
|
||||
=* hap `chap`[?~(lab.p.i.a ~ [u.lab.p.i.a ~]) boy.p.i.a]
|
||||
=* hap `chap`[?~(lab.p.i.a ~ [~ u.lab.p.i.a]) boy.p.i.a]
|
||||
$(a t.a, b (~(put by b) c [hap u.d]), c +(c))
|
||||
;~ pose
|
||||
dun
|
||||
|
Loading…
Reference in New Issue
Block a user