mirror of
https://github.com/ilyakooo0/urbit.git
synced 2024-12-17 20:01:32 +03:00
take out docs
This commit is contained in:
parent
7ebefb7c5f
commit
2e72056fb5
24
pub/docs.md
24
pub/docs.md
@ -1,24 +0,0 @@
|
||||
---
|
||||
anchor: none
|
||||
layout: no-anchor
|
||||
logo: black
|
||||
---
|
||||
|
||||
<div class="short lead">
|
||||
|
||||
# Urbit documentation
|
||||
|
||||
The Urbit doc is divided into three parts: [user doc](docs/user),
|
||||
[developer doc](docs/dev), and [theory](docs/theory) (whitepaper, essays,
|
||||
videos, etc).
|
||||
|
||||
If you want to try Urbit, start with the user doc. If you want
|
||||
to learn about Urbit, try the theory. Or just start with the
|
||||
user doc; it doesn't assume any prior knowledge.
|
||||
|
||||
The most fun thing to do with Urbit is code, but the developer
|
||||
doc remains under construction. Sorry. We'll have more soon.
|
||||
|
||||
<list dataSort="true" class="children"></list>
|
||||
|
||||
</div>
|
@ -1,28 +0,0 @@
|
||||
---
|
||||
logo: black
|
||||
sort: 2
|
||||
title: Developer doc
|
||||
---
|
||||
<div class="short">
|
||||
|
||||
# Developer documentation
|
||||
|
||||
Urbit has three programming layers: [Nock](dev/nock) (combinator nano-VM),
|
||||
[Hoon](dev/hoon) (strict functional language), and [Arvo](dev/arvo) (functional
|
||||
OS).
|
||||
|
||||
To code in Urbit, the least you need to learn is Hoon, plus a
|
||||
little bit of Arvo. Nock is a sort of functional assembly
|
||||
language -- you don't need to know it, but it's useful to.
|
||||
Nock is also the easiest thing in the world to learn.
|
||||
|
||||
You can program for Arvo without knowing much about Arvo
|
||||
internals, but again it helps. But you need to know Hoon.
|
||||
Don't worry, it's easier than it looks.
|
||||
|
||||
Alas, the developer doc is still under construction. We'll have
|
||||
more soon.
|
||||
|
||||
<list></list>
|
||||
|
||||
</div>
|
@ -1,13 +0,0 @@
|
||||
---
|
||||
logo: black
|
||||
sort: 3
|
||||
title: Arvo
|
||||
---
|
||||
<div class="short">
|
||||
|
||||
# Arvo
|
||||
|
||||
Arvo is a functional operating system. But hopefully you knew that! Sorry,
|
||||
please watch this space for actual documentation.
|
||||
|
||||
</div>
|
@ -1,11 +0,0 @@
|
||||
---
|
||||
hide: true
|
||||
logo: black
|
||||
sort: 4
|
||||
title: Frontend tools
|
||||
---
|
||||
|
||||
Frontend tools
|
||||
==============
|
||||
|
||||
<list></list>
|
@ -1,59 +0,0 @@
|
||||
# `:tree`
|
||||
|
||||
`:tree` is the web filesystem interface. Odds are this file has been rendered for you by `:tree`.
|
||||
|
||||
`:tree` is a single-page app that uses a backend in `/home/tree` to load
|
||||
contents from `%clay` as the user navigates around as `%json`. The frontend
|
||||
lives in `/home/pub/tree` and is a fairly straightforward
|
||||
[React](https://facebook.github.io/react/) /
|
||||
[Flux](https://facebook.github.io/flux/) app.
|
||||
|
||||
## Frontend
|
||||
|
||||
The frontend code for `:tree` can be found in `/home/pub/tree/src/`.
|
||||
|
||||
### CSS
|
||||
|
||||
The CSS is written in [Stylus](https://learnboost.github.io/stylus/). The main entry point is `main.styl` and can be compiled with `stylus main.styl` which should output a `main.css`
|
||||
|
||||
### JS
|
||||
|
||||
The JS is written in [CoffeeScript](http://coffeescript.org/) and packaged with
|
||||
[Browserify](http://browserify.org/). The main entry point is `main.coffee` and
|
||||
is compiled with `browserify -t coffeeify main.coffee > main.js`. You'll need
|
||||
to `npm install` first.
|
||||
|
||||
Each page is loaded as JSON and then rendered using React on the page. This
|
||||
allows us to write JSX in our markdown to implement simple components. Check
|
||||
out `/home/pub/tree/src/js/components` to see the component library.
|
||||
|
||||
You'll notice that some of these doc pages use things like `<list>` in the raw markdown files.
|
||||
|
||||
## JSON API
|
||||
Async provides loading by schema
|
||||
|
||||
`{path name sein sibs next prev}` are all immediately accesible from the store
|
||||
|
||||
a `getPath` method, if present (defaulting to current url), is used to determine the query root node.
|
||||
|
||||
## JSON Internals
|
||||
|
||||
### `/[desk]/tree/{path}.json`
|
||||
`tree/json.hook` accepts a query string schema `q` in light noun encoding
|
||||
|
||||
++ schema (dict ,[term $|(mark schema)])
|
||||
++ dict |*(a=_,* $&([a (dict a)] a))
|
||||
|
||||
which is normalized and type-checked to a `query` list of
|
||||
- `[%kids query]`, the only recursive value, which executes for all subpaths
|
||||
XX descent is only currently supported to a single level as a performance optimization
|
||||
- `[%name %t]`, the node name
|
||||
- `[%path %t]`, the current path
|
||||
- `[%snip %r]`, a snippet, extracted via `react-snip-json`
|
||||
- `[%head %r]`, the first `<h1/>`, extracted via `react-head-json`
|
||||
- `[%body %r]`, the `react-json` body
|
||||
- `[%meta %j]`, json frontmatter per the `mdy` mark definition
|
||||
|
||||
The request types above are `%t` text, `%r` html-derived tree, and `%j`
|
||||
arbitrary json; an example query, used by the main content renderer, is
|
||||
`"q=body.r__kids_name.t"` (`body:'r' kids:{name:'t'}` )
|
@ -1,213 +0,0 @@
|
||||
---
|
||||
sort: 6
|
||||
title: Contributing
|
||||
---
|
||||
|
||||
# Contributing to urbit
|
||||
|
||||
Thank you for your interest in contributing to urbit.
|
||||
|
||||
## Development practice
|
||||
|
||||
You may have an identity on the live network, but doing all your
|
||||
development on the live network would be cumbersome and unnecessary.
|
||||
Standard practice in urbit development is to work on a fake `~zod`. A
|
||||
fake `~zod` will get its initial files from the `urb/zod/` directory
|
||||
rather than trying to sync them over the network, which is invaluable
|
||||
for working in Hoon. Also, a fake `~zod` or any fake urbit instances you
|
||||
start do not talk to the live network, but to a fake network that exists
|
||||
only on your computer.
|
||||
|
||||
To start a fake `~zod`, the command is:
|
||||
|
||||
bin/urbit -F -I zod -c [pier directory]
|
||||
|
||||
To resume one that was already created, just as on the live network,
|
||||
remove `-c` (but leave the rest of the options there). `-F` uses the
|
||||
fake network, and `-I` starts an "imperial" instance - that is, an 8-bit
|
||||
galaxy.
|
||||
|
||||
## Kernel development
|
||||
|
||||
Working on either C or non-kernel Hoon should not bring any surprises,
|
||||
but the Hoon kernel (anything under `urb/zod/arvo/`) is bootstrapped
|
||||
from `urbit.pill` in `urb/`, and must be manually recompiled if any
|
||||
changes are made. The command to manually recompile the kernel and
|
||||
install the new kernel is `|reset` in `dojo`. This rebuilds from the
|
||||
`arvo` directory in the `home` desk in `%clay`. Currently, `|reset`
|
||||
does not reload apps like `dojo` itself, which will still reference the
|
||||
old kernel. To force them to reload, make a trivial edit to their main
|
||||
source file (under the `ape` directory) in `%clay`.
|
||||
|
||||
If you do any kernel development, be sure to read the section below about
|
||||
pills.
|
||||
|
||||
## Git practice
|
||||
|
||||
Since we use the GitHub issue tracker, it is helpful to contribute via a
|
||||
GitHub pull request. If you already know what you are doing, skip down
|
||||
to the Style section.
|
||||
|
||||
Start by cloning the repository on your work machine:
|
||||
|
||||
git clone https://github.com/urbit/urbit
|
||||
|
||||
And, additionally, fork the repository on GitHub by clicking the "Fork"
|
||||
button. Add your fork as a remote:
|
||||
|
||||
git remote add [username] https://github.com/[username]/urbit
|
||||
|
||||
and set it as the default remote to push to:
|
||||
|
||||
git config --local remote.pushDefault [username]
|
||||
|
||||
This is good practice for any project that uses git. You will pull
|
||||
upstream branches from urbit/urbit and push to your personal urbit fork
|
||||
by default.
|
||||
|
||||
Next, check out `test`, which is the mainline development branch, and
|
||||
base a new branch on it to do your work on:
|
||||
|
||||
git checkout test
|
||||
git checkout -b [branch name]
|
||||
|
||||
Now you are free to do your work on this branch. When finished, you may
|
||||
want to clean up your commits:
|
||||
|
||||
git rebase -i test
|
||||
|
||||
Then you can push to your public fork with `git push` and make a pull
|
||||
request via the GitHub UI. Make sure you request to merge your branch
|
||||
into `test`, not `master`.
|
||||
|
||||
After your changes are merged upstream, you can delete your branch (via
|
||||
github UI or `git push :[branch]` remotely, and with `git branch -d`
|
||||
locally).
|
||||
|
||||
## Style
|
||||
|
||||
The urbit project uses two-space indentation and avoids tab characters.
|
||||
In C code, it should not be too difficult to mimic the style of the code
|
||||
around you, which is just fairly standard K&R with braces on every
|
||||
compound statement. One thing to watch out for is top-level sections in
|
||||
source files that are denoted by comments and are actually indented one
|
||||
level.
|
||||
|
||||
Hoon will be a less familiar language to many contributors. Some of our
|
||||
less obvious stylistic rules are:
|
||||
|
||||
- Keep your source files 80 characters or less wide. Many urbit
|
||||
developers use 80 character terminals/tmux panes/&c.
|
||||
- Tab characters are actually a syntax error, so be extra sure your
|
||||
editor is not inserting any. Trailing whitespace is *usually* not a
|
||||
syntax error, but avoiding it is encouraged.
|
||||
- The kernel convention is that line comments start at column 57 with
|
||||
the `::` followed by 2 spaces. This leaves 20 characters for the
|
||||
comment. Outside the kernel, things are less strict.
|
||||
- Tall arms within a core are conventionally separated by empty comments
|
||||
(just `::`) at the same indentation level as the initial `++` or `+-`.
|
||||
The last arm in a core is not followed by an empty comment, because it
|
||||
is visually closed by the `--` that closes the core. The empty comment
|
||||
is also sometimes omitted in data structure definitions.
|
||||
|
||||
## The kernel and pills
|
||||
|
||||
urbit bootstraps itself using a binary blob called `urbit.pill`, which
|
||||
we do indeed keep in version control. This creates some special
|
||||
requirements. If you are not changing anything in the kernel (everything
|
||||
under `urb/zod/arvo/`) then you can skim this section (please do not
|
||||
skip it entirely, though). If you *are* working there, then this
|
||||
section is critically important!
|
||||
|
||||
The procedure for creating `urbit.pill` is often called "soliding". It
|
||||
is somewhat similar to `|reset`, but instead of replacing your running
|
||||
kernel, it writes the compiled kernel to a file. The command to solid
|
||||
is, on a fakezod:
|
||||
|
||||
.urbit/pill +solid
|
||||
|
||||
When the compilation finishes, your `urbit.pill` will be found in the
|
||||
`[pier]/.urb/put/` directory. Copy it into `urb/` and add it to your
|
||||
commit.
|
||||
|
||||
The requirement here is that every commit that changes the kernel must
|
||||
come with an `urbit.pill` built from the same code in `urb/zod/arvo/`
|
||||
for that commit. (Only changing the actual Hoon code counts, so a change
|
||||
to a jet with no corresponding Hoon change does not require a new pill.)
|
||||
This is so that checking out an arbitrary revision and starting up a
|
||||
fakezod actually works as expected. However you do this is fine, but I
|
||||
like to do it as part of my committing process - just before `git
|
||||
commit`, I fire up a new fakezod. This will use the previous
|
||||
`urbit.pill`, but the kernel code in `%clay` will be copied from
|
||||
`urb/zod/arvo/`, so `+solid` will compile it. Then I copy `urbit.pill`
|
||||
into `urb/` and make my commit.
|
||||
|
||||
If you rebase or interactive rebase your commits, be sure to preserve
|
||||
this property on all the commits you end up with. If multiple people
|
||||
were collaborating on your branch, you may end up with conflicts in
|
||||
`urbit.pill` and have to merge the branch into itself to resolve them.
|
||||
Just do the same procedure to create a new, merged pill before
|
||||
committing the merge. Otherwise, just make sure to use the correct
|
||||
`urbit.pill` for each commit.
|
||||
|
||||
## Debug urbit with `gdb`
|
||||
|
||||
Follow the build instructions in README.md but run `make` with argument `DEBUG=yes`:
|
||||
|
||||
(If you've already built urbit first run `make clean`.)
|
||||
|
||||
make DEBUG=yes
|
||||
|
||||
Run `gdb`, while loading `bin/urbit` and its symbol table:
|
||||
|
||||
gdb bin/urbit
|
||||
|
||||
Set a breakpoint on `main()` (optional):
|
||||
|
||||
break main
|
||||
|
||||
Run your urbit comet `mycomet`:
|
||||
|
||||
run mycomet
|
||||
|
||||
Continue from the breakpoint on `main()`:
|
||||
|
||||
continue
|
||||
|
||||
## What to work on
|
||||
|
||||
If you are not thinking of contributing with a specific goal in mind,
|
||||
the GitHub issue tracker is the first place you should look for ideas.
|
||||
Issues are tagged with a priority and a difficulty. A good place to
|
||||
start is on either a low-difficulty issue or a low-priority issue.
|
||||
Higher priority issues are likely to be assigned to someone - if this is
|
||||
the case, then contacting that person to coordinate before starting to
|
||||
work is probably a good idea.
|
||||
|
||||
There is also a "help wanted" tag for things that we are especially
|
||||
eager to have outside contributions on. Check here first!
|
||||
|
||||
## Staying in touch
|
||||
|
||||
The urbit developers communicate on urbit itself. Joining the
|
||||
`~doznec/urbit-meta` channel on `talk` is highly recommended.
|
||||
Subscribing to `urbit-dev` on Google Groups is also recommended, since
|
||||
this is where continuity breach notifications are sent.
|
||||
|
||||
You can also contact one of the following people:
|
||||
|
||||
- Philip Monk
|
||||
|
||||
email: philip.monk@tlon.io
|
||||
|
||||
urbit: `~wictuc-folrex`
|
||||
|
||||
GitHub: [@philipcmonk](https://github.com/philipcmonk/)
|
||||
|
||||
- Raymond Pasco
|
||||
|
||||
email: ray@the.ug
|
||||
|
||||
urbit: `~ramtev-wisbyt`
|
||||
|
||||
GitHub: [@juped](https://github.com/juped/)
|
@ -1,24 +0,0 @@
|
||||
---
|
||||
logo: black
|
||||
sort: 2
|
||||
title: Hoon
|
||||
---
|
||||
|
||||
<div class="short">
|
||||
|
||||
# Hoon
|
||||
|
||||
Hoon is a strict, typed, pure functional language. This site is
|
||||
served by an urbit written in Hoon.
|
||||
|
||||
If you're interested in learning the fundamentals of Hoon from
|
||||
the bottom up, start with [Principles of
|
||||
Hoon](hoon/principles).
|
||||
|
||||
If you want to jump into building things right away and prefer to
|
||||
learn from the top down, check out [Leap into
|
||||
Hoon](hoon/leap-in/1-basic).
|
||||
|
||||
Both of these are under active development.
|
||||
|
||||
</div>
|
@ -1,8 +0,0 @@
|
||||
---
|
||||
hide: false
|
||||
next: false
|
||||
sort: 1
|
||||
title: Leap into Hoon
|
||||
---
|
||||
|
||||
<list></list>
|
@ -1,421 +0,0 @@
|
||||
---
|
||||
logo: black
|
||||
sort: 1
|
||||
next: true
|
||||
title: Basic Hoon
|
||||
---
|
||||
|
||||
# Basic Hoon
|
||||
|
||||
Our goal is to get you programming interesting and useful things
|
||||
as soon as possible. To get there we have to quickly cover some
|
||||
of the fundamentals of hoon. To do this we'll walk through two
|
||||
simple programs: the first [Project
|
||||
Euler](https://projecteuler.net/) problem and
|
||||
[fizzbuzz](https://en.wikipedia.org/wiki/Fizz_buzz).
|
||||
|
||||
To run this code, you'll need an urbit, and you'll need the
|
||||
`%examples` desk from `~wactex-ribmex`. If you haven't installed
|
||||
urbit yet, check out the [installation
|
||||
instructions](http://urbit.org/docs/user/install). Once urbit is
|
||||
intalled, take a look at the [basic
|
||||
operation](http://urbit.org/docs/user/basic) of your urbit.
|
||||
|
||||
If you haven't pulled the examples desk from `~wactex-ribmex`, do
|
||||
so now:
|
||||
|
||||
~fintud-macrep:dojo> |merge %examples ~wactex-ribmex %examples
|
||||
>=
|
||||
; ~wactex-ribmex is your neighbor
|
||||
; ~wactex-ribmex is your neighbor
|
||||
[time passes...]
|
||||
merged with strategy %init
|
||||
|
||||
The merge could take several minutes; you'll know it's done when
|
||||
"merged with strategy %init" is printed. Mount the new files to
|
||||
your Unix pier directory:
|
||||
|
||||
~fintud-macrep:dojo> |mount /=examples=
|
||||
|
||||
Switch desks to run commands from the `%examples` desk:
|
||||
|
||||
~fintud-macrep:dojo> =dir /=examples=
|
||||
=% /~fintud-macrep/examples/~2015.11.13..02.25.00..41e9/
|
||||
|
||||
Run an example:
|
||||
|
||||
~fintud-macrep:dojo> +euler1
|
||||
233.168
|
||||
|
||||
## Euler 1
|
||||
|
||||
Let's check out the code for Euler 1. First, the problem:
|
||||
|
||||
```
|
||||
If we list all the natural numbers below 10 that are multiples of
|
||||
3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
|
||||
|
||||
Find the sum of all the multiples of 3 or 5 below 1000.
|
||||
```
|
||||
|
||||
Here is the hoon solution (which should be in your pier directory
|
||||
under `/examples/gen/euler1.hoon`):
|
||||
|
||||
```
|
||||
:: project euler 1
|
||||
:: https://projecteuler.net/problem=1
|
||||
:: run in dojo with +euler1
|
||||
::
|
||||
:::: /hoon/euler1/gen
|
||||
::
|
||||
:- %say |= *
|
||||
:- %noun
|
||||
=< (sum 1.000)
|
||||
::
|
||||
:::: ~fintud-macrep
|
||||
::
|
||||
|%
|
||||
++ three
|
||||
|= a=@
|
||||
=| b=@
|
||||
|- ^- @u
|
||||
?: (lth a b)
|
||||
0
|
||||
(add b $(b (add 3 b)))
|
||||
|
||||
++ five
|
||||
|= a=@
|
||||
=| b=@
|
||||
|- ^- @
|
||||
?: (lte a b)
|
||||
0
|
||||
?: =((mod b 3) 0)
|
||||
$(b (add b 5))
|
||||
(add b $(b (add b 5)))
|
||||
|
||||
++ sum
|
||||
|= a=@u
|
||||
(add (five a) (three a))
|
||||
--
|
||||
```
|
||||
|
||||
> Hoon is not generally whitespace sensitive, but we do have two
|
||||
> different kinds of whitespace: a single space and a gap, which
|
||||
> is two or more spaces or a linebreak. Tabs are taboo. Do not
|
||||
> use them. Really. For a more detailed explanation of when to
|
||||
> use spaces vs. gaps, see the syntax section before the first
|
||||
> excercises.
|
||||
|
||||
### Lines 1-11:
|
||||
|
||||
Any line that begins with `::` is a comment.
|
||||
|
||||
:- %say |= *
|
||||
:- %noun
|
||||
=< (sum 1.000)
|
||||
|
||||
All you need to know about the lines above is that they call the
|
||||
`++sum` function with an argument of `1.000`. We'll cover them in
|
||||
more detail later.
|
||||
|
||||
### How to form expressions
|
||||
|
||||
Hoon does not use reserved words to form expressions. Instead,
|
||||
expressions are formed with runes, which are diagraphs of two
|
||||
ascii symbols. Each rune takes a specific number of
|
||||
children--either expressions formed by other runes or literals
|
||||
that produce their own value.
|
||||
|
||||
For example, the rune `?:` from line 17 is the classic
|
||||
'if-then-else' statement, and thus takes three children:
|
||||
|
||||
?: (lth a b) :: if first child evals to true
|
||||
0 :: then produce result of second
|
||||
(add b $(b (add 3 b))) :: else, produce result of third
|
||||
|
||||
Since runes are such a fundamental structure in Hoon, we found
|
||||
ourselves speaking them out loud frequently. It quickly grew
|
||||
cumbersome to have to say "question mark, colon" to describe
|
||||
`?:`. To alleviate this problem, we came up with our own naming
|
||||
scheme: each ascii glyph has a single syllable pronunciation
|
||||
phonetically designed to be both easily remembered and easily
|
||||
pronounced in conjunction with the other glyphs (when forming a
|
||||
rune).
|
||||
|
||||
See the entire naming schema below/or link to it:
|
||||
|
||||
```
|
||||
ace [1 space] gal < pel (
|
||||
bar | gap [>1 space, nl] per )
|
||||
bas \ gar > sel [
|
||||
buc $ hax # sem ;
|
||||
cab _ hep - ser ]
|
||||
cen % kel { soq '
|
||||
col : ker } tar *
|
||||
com , ket ^ tec `
|
||||
doq " lus + tis =
|
||||
dot . pam & wut ?
|
||||
fas / pat @ zap !
|
||||
```
|
||||
|
||||
Using our naming scheme `?:` is said 'wut col'.
|
||||
|
||||
### Lines 12-34
|
||||
|
||||
Now let's quickly walk through this code line-by-line. Lines
|
||||
12-34 are wrapped in a `|%` (pronounced 'bar cen'), which
|
||||
produces a core, a fundamental datatype in hoon similar to a
|
||||
struct, class, or object. A core is just a map of names
|
||||
to any kind of code, whether it be functions or data. Each
|
||||
element in this map begins with a `++` followed by the name and
|
||||
the corresponding code. Since `|%` takes an arbitrary number of
|
||||
children, it needs to be closed with a `--`.
|
||||
|
||||
> `++` is not technically a rune, since it is only used in core
|
||||
> syntax as shown above
|
||||
|
||||
Let's step into each of the three arms within our core.
|
||||
|
||||
### `++ sum`
|
||||
|
||||
++ sum
|
||||
|= a=@
|
||||
(add (five a) (three a))
|
||||
--
|
||||
|
||||
`|=` produces a function, much like a lambda in lisp. It takes two children:
|
||||
|
||||
- A set of argument(s). In this case our argument set only
|
||||
contains one: `a` which is required to be an atom or natural
|
||||
number, denoted by `@`.
|
||||
|
||||
- The body of the function itself, which is executed when the
|
||||
function is called (in this case, with `(sum 1.000)`). This
|
||||
particular function adds the results of evaluating the gates `++
|
||||
five` and `++three` with each of their respective input
|
||||
parameters set to `a`.
|
||||
|
||||
### ++ three
|
||||
|
||||
++ three
|
||||
|= a=@
|
||||
=| b=@
|
||||
|- ^- @u
|
||||
?: (lth a b)
|
||||
0
|
||||
(add b $(b (add 3 b)))
|
||||
|
||||
As above, `++three` takes an integer argument, `a`, and then
|
||||
executes the remainder of the code with `a` set to the actual
|
||||
arguments.
|
||||
|
||||
Similarly, `=|` pushes its first child, `b` into our context (in
|
||||
other words, it declares a variable `b`) and executes the
|
||||
remainder of the code. However, `b` is not an argument; `=|`
|
||||
sets `b` to the default value of whatever type it is declared as.
|
||||
Since the default value of an atom is `0`, b is set to `0`.
|
||||
|
||||
So now we have two variables: `a` is set to our input, and `b` is
|
||||
initialized to `0`.
|
||||
|
||||
The easiest way to think about `|-` that it lays down a recursion
|
||||
point. More on this later.
|
||||
|
||||
`^-` is just a cast that sets the result of the remainder of the
|
||||
code to an unsigned integer, `@u`.
|
||||
|
||||
In pseudocode, the last three lines read like this: if `a` is
|
||||
less than `b`, produce zero. Else, add `b` to the result of
|
||||
rerunning the segment of the function following the `|-` with the
|
||||
value of `b` changed to `b` plus three.
|
||||
|
||||
The only thing that should look completely unfamiliar to you here
|
||||
is the `$(b (add 3 b))`, which causes us to recurse back to our
|
||||
last recursion point with the value of `b` set to `(add 3 b)`.
|
||||
Note that we only specify what changes (`b` in this case). If
|
||||
you recurse by an actual function call, then you have to specify
|
||||
every argument.
|
||||
|
||||
> If you're familiar with Clojure, `|-` is `loop` and `$()` is
|
||||
> recur.
|
||||
|
||||
|
||||
## Excercises
|
||||
|
||||
Please tweak your code to complete the following excercises.
|
||||
|
||||
There are a few runes and some syntax that we have yet to cover that
|
||||
you will need to complete the excercises below. For these, please
|
||||
refer to our cheatsheat at the bottom.
|
||||
|
||||
1. Read and understand `++five` line by line.
|
||||
|
||||
2. Change `++sum` to accept two variables, `a` and `b`. Pass `a`
|
||||
to three and `b` to five. Then run the code with `a` set to
|
||||
`1.000` and b set to `2.000`.
|
||||
|
||||
3. Check if this new result is under one thousand. If it is,
|
||||
return the string 'result is less than one thousand'. If not,
|
||||
return 'result is greater than or equal to one thousand'.
|
||||
|
||||
```
|
||||
Review
|
||||
|
||||
|% start core (collection of named ++ arms)
|
||||
|= define function
|
||||
=| define variable from type with default value
|
||||
|- drop a recursion point
|
||||
^- cast
|
||||
?: if-then-else
|
||||
=(a b) test equality
|
||||
(function args ...) call function
|
||||
|
||||
New material
|
||||
|
||||
- :- make a cell of values. The irregular wide form of this is
|
||||
[a b] with two expressions separated by a single space.
|
||||
|
||||
- Cords are one datatype for text in hoon. They're just a big
|
||||
atom formed from adjacent unicode bytes -- a "c string". To
|
||||
produce a cord enclose text within single quotes. To set the type
|
||||
of an argument to a cord, use @t.
|
||||
|
||||
- There are two syntaxes for writing Hoon: tall form and wide
|
||||
form.
|
||||
|
||||
In tall form, expressions are formed with either two spaces or
|
||||
a line break separating both a rune from its children and each
|
||||
of its children from one another. We use tall form when writing
|
||||
multiline expressions.
|
||||
|
||||
For more concise expressions, we use wideform, which is always
|
||||
a single line. Wideform can be used inside tall form
|
||||
expressions, but not vice versa.
|
||||
|
||||
Wideform expressions are formed with a rune followed by ()
|
||||
containing its children, all of which are separated by a
|
||||
single space. For example to make a cell of two elements:
|
||||
|
||||
:-(a b)
|
||||
|
||||
We've already seen wideform in action, for example with
|
||||
=((mod b 3) 0). In this case = is actually an irregular form
|
||||
of .=, which tests its two children for equality.
|
||||
|
||||
Another irregular form is [a b] for :-(a b)
|
||||
|
||||
Surrounding a function with () is an irregular wide form
|
||||
syntax for calling a function with n arguments.
|
||||
```
|
||||
|
||||
|
||||
## The subject
|
||||
|
||||
Now we're going to cover the boiler plate that we skimmed over
|
||||
earlier.
|
||||
|
||||
:- %say |= *
|
||||
:- %noun
|
||||
=< (sum [1.000 2.000])
|
||||
|
||||
This program is a cell of two elements: the first, `%say`, tells
|
||||
the interpreter what to produce--in this case a value.
|
||||
|
||||
The second element is `|=`, which we know produces a function.
|
||||
`|=`'s first child is its argument(s), which in this case is any
|
||||
noun (`*`). Its second child is the remainder of the program.
|
||||
|
||||
Similarly, the rest of the program is a cell of the literal
|
||||
`%noun`, which tells the shell that we're producing a value of
|
||||
type `noun`, and the second child contains the code that we run
|
||||
to actually produce our value of the type `noun`.
|
||||
|
||||
`=<` is a rune that takes two children. The second child is the
|
||||
context against which we run the first child. So in this case, we
|
||||
are running the expression `(sum 1.000)` against everything
|
||||
contained within the `|%`. In Hoon, we call the code executed the
|
||||
"formula" and its context the "subject".
|
||||
|
||||
```
|
||||
::::::::::::::::::::::::::::::
|
||||
=< (sum 1.000) :: formula
|
||||
::::::::::::::::::::::::::::::
|
||||
|% ::
|
||||
++ three ::
|
||||
|= a=@ ::
|
||||
=| b=@ ::
|
||||
|- ^- @u ::
|
||||
?: (lth a b) ::
|
||||
0 ::
|
||||
(add b $(b (add 3 b))) ::
|
||||
::
|
||||
++ five ::
|
||||
|= a=@ :: subject
|
||||
=| b=@ ::
|
||||
|- ^- @ ::
|
||||
?: (lte a b) ::
|
||||
0 ::
|
||||
?: =((mod b 3) 0) ::
|
||||
$(b (add b 5)) ::
|
||||
(add b $(b (add b 5))) ::
|
||||
::
|
||||
++ sum ::
|
||||
|= a=@u ::
|
||||
(add (five a) (three a)) ::
|
||||
-- ::
|
||||
::::::::::::::::::::::::::::::
|
||||
```
|
||||
|
||||
In nearly every language there is a similar concept of a
|
||||
"context" in which expressions are executed. For example, in C
|
||||
this includes things like the call stack, stack variables, and so
|
||||
on.
|
||||
|
||||
Hoon is unique in that this context is a first-class value.
|
||||
Scheme allows a sort of reification of the context through
|
||||
continutations, and some may see a parallel to Forth's stack, but
|
||||
Hoon takes takes the concept one step further.
|
||||
|
||||
Our starting subject is the standard library, which is defined in
|
||||
`/arvo/hoon.hoon` and `/arvo/zuse.hoon`. This is where functions
|
||||
like `add` are defined. When we define a core with `|%`, we
|
||||
don't throw away the subject (i.e. the standard library); rather,
|
||||
we stack the new core on top of the old subject so that both are
|
||||
accessible.
|
||||
|
||||
## Exercises:
|
||||
|
||||
4. Pass `++sum` its arguments (`2000` and `3000`) from the
|
||||
commandline.
|
||||
|
||||
5. Comment out all of the arms of the `|%`. Now add another arm
|
||||
and call it `++add`, have it accept two arguments and procduce
|
||||
42 (regardless of input). Change the `=<` line to `[(add 5 7)
|
||||
(^add 5 7)]`. Can you recognize what's happening?
|
||||
|
||||
6. Write fizbuzz:
|
||||
|
||||
Write a program that prints the numbers from 1 to 100
|
||||
(entered from the command line). But for multiples of three
|
||||
print 'Fizz' instead of the number and for the multiples of
|
||||
five print 'Buzz'. For numbers which are multiples of both
|
||||
three and five print 'FizzBuzz'.
|
||||
|
||||
Cheatsheet:
|
||||
|
||||
- To pass arguments from the command line to a program, you
|
||||
replace the `*` in the first line of the boiler plate to
|
||||
`[^ [[arg=TYPE ~] ~]]` where `TYPE` is replaced with the
|
||||
type of argument you're expecting. Then `+euler1 a` from
|
||||
the dojo sets `arg` to `a`.
|
||||
- A list of strings is of type `(list ,@t)`, so the result of
|
||||
the fizzbuzz function is of this type (hint: you'll need to
|
||||
use `^-`)
|
||||
- The empty list is `~`
|
||||
- Lisp-style cons (construct a cell/prepend an element) is
|
||||
`[new-element list]`
|
||||
- For example, the first three positive integers are `[1 2 3
|
||||
~]`
|
||||
- `gte` tests whether `a` is greater than or equal to `b`.
|
||||
- `mod` runs the modulo operation on two atoms.
|
||||
- See the [basic math section]() for more info.
|
@ -1,335 +0,0 @@
|
||||
---
|
||||
next: false
|
||||
sort: 2
|
||||
title: Network Messages
|
||||
---
|
||||
|
||||
Enough of pure hoonery. Let's get to the good stuff. Let's get
|
||||
our planets to talk to each other.
|
||||
|
||||
Of course, for talking to be of any use, we need someone
|
||||
listening. What we've written up until now are just shell
|
||||
commands that produce a value and then disappear. We need an
|
||||
actual app to listen for messages from another planet. Let's
|
||||
take a look at a very basic one.
|
||||
|
||||
```
|
||||
:: There is no love that is not an echo
|
||||
::
|
||||
:::: /hoon/echo/ape
|
||||
::
|
||||
/? 314
|
||||
!:
|
||||
|_ [bowl state=~]
|
||||
++ poke-noun
|
||||
|= arg=*
|
||||
^- [(list) _+>.$]
|
||||
~& [%argument arg]
|
||||
[~ +>.$]
|
||||
--
|
||||
```
|
||||
|
||||
This is a very simple app that does only one thing. If you poke
|
||||
it with a value it prints that out. You have to start the app,
|
||||
then you can poke it from the command line with the following
|
||||
commands:
|
||||
|
||||
```
|
||||
~fintud-macrep:dojo> |start %echo
|
||||
>=
|
||||
~fintud-macrep:dojo> :echo 5
|
||||
[%argument 5]
|
||||
>=
|
||||
~fintud-macrep:dojo> :echo [1 2]
|
||||
[%argument [1 2]]
|
||||
>=
|
||||
```
|
||||
|
||||
> There is currently a bug where the `%argument` lines are
|
||||
> printed *above* the line you entered, so your output may not
|
||||
> look exactly like this.
|
||||
|
||||
Most of the app code should be simple enough to guess its
|
||||
function. The important part of this code is the definition of
|
||||
`++poke-noun`.
|
||||
|
||||
Once an app starts, it's always on in the background, and you
|
||||
interact with it by sending it messages. The most
|
||||
straightforward way to do that is to poke it from the command
|
||||
line. When you do that, `++poke-noun` is called from your app.
|
||||
|
||||
In our case, `++poke-noun` takes an argument `arg` and prints it
|
||||
out with `~&`. This is an unusual rune that formally "does
|
||||
nothing", but the interpreter detects it and printfs the first
|
||||
child. This is a slightly hacky way of printing to the console,
|
||||
and we'll get to the correct way later on.
|
||||
|
||||
But what does `++poke-noun` produce? Recall that `^-` casts to a
|
||||
type. In this case, it's declaring that end result of the
|
||||
function will be of type `[(list) _+>.$]`. But what does this
|
||||
mean?
|
||||
|
||||
The phrase to remember is "a list of moves and our state". Urbit
|
||||
is a message passing system, so whenver we want to do something
|
||||
that interacts with the rest of the system we send a message.
|
||||
Thus, a move is arvo's equivalent of a syscall. The first
|
||||
thing that `++poke-noun` produces is a list of messages, called
|
||||
"moves". In this case, we don't actually want the system to do
|
||||
anything, so we produce the empty list, `~` (in the `[~ +>.$]`
|
||||
line).
|
||||
|
||||
The second thing `++poke-noun` produces is our state. `+>.$`
|
||||
refers to a particular address in our subject where our formal
|
||||
app state is stored. It'll become clear why this is later on,
|
||||
but for now pretend that `+>.$` is a magic invocation that means
|
||||
"app state".
|
||||
|
||||
Let's look at another example. Say we want to only accept a
|
||||
number, and then print out the square of that number.
|
||||
|
||||
```
|
||||
/? 314
|
||||
!:
|
||||
|_ [bowl state=~]
|
||||
::
|
||||
++ poke-atom
|
||||
|= arg=@
|
||||
^- [(list) _+>.$]
|
||||
~& [%square (mul arg arg)]
|
||||
[~ +>.$]
|
||||
--
|
||||
```
|
||||
|
||||
A few things have changed. Firstly, we no longer accept
|
||||
arbitrary nouns because we can only square atoms. Thus, our
|
||||
argument is now `arg=@`. Secondly, it's `++poke-atom` rather
|
||||
than `++poke-noun`.
|
||||
|
||||
Are there other `++poke`s? Definitely. In fact, `noun` and
|
||||
`atom` are just two of arbitrarily many "marks". A mark is
|
||||
fundamentally a type definition, but accessible at the arvo
|
||||
level. Each mark is defined in the `/mar` directory. Some marks
|
||||
have conversion routines to other marks, and some have diff,
|
||||
patch, and merge algorithms. None of these are required for a
|
||||
mark to exist, though.
|
||||
|
||||
`noun` and `atom` are two of dozens of predefined marks, and the
|
||||
user may add more at will. The type associated with `noun` is
|
||||
`*`, and the type associated with `atom` is `@`.
|
||||
|
||||
Data constructed on the command line is by default marked with
|
||||
`noun`. In this case, the app is expecting an atom, so we have
|
||||
to explicitly mark the data with `atom`. Try the following
|
||||
commands:
|
||||
|
||||
```
|
||||
~fintud-macrep:dojo> |start %square
|
||||
>=
|
||||
~fintud-macrep:dojo> :square 6
|
||||
gall: %square: no poke arm for noun
|
||||
~fintud-macrep:dojo> :square &atom 6
|
||||
[%square 36]
|
||||
>=
|
||||
```
|
||||
|
||||
> Recall the bug where `%square` may get printed above the input
|
||||
> line.
|
||||
|
||||
Marks are powerful, and they're the backbone of urbit's data
|
||||
pipeline, so we'll be getting quite used to them.
|
||||
|
||||
**Exercises**:
|
||||
|
||||
- Write an app that computes fizzbuzz on its input (as in the
|
||||
previous section).
|
||||
|
||||
- One way of representing strings is with double quoted strings
|
||||
called "tapes". The hoon type is `tape`, and there is a
|
||||
corresponding mark with the same name. Write an app that
|
||||
accepts a tape and prints out `(flop argument)`, where
|
||||
`argument` is the input. What does this do?
|
||||
|
||||
|
||||
Let's write our first network message! Here's `/ape/pong.hoon`:
|
||||
|
||||
```
|
||||
/? 314
|
||||
|%
|
||||
++ move ,[bone term path *]
|
||||
--
|
||||
!:
|
||||
|_ [bowl state=~]
|
||||
::
|
||||
++ poke-urbit
|
||||
|= to=@p
|
||||
^- [(list move) _+>.$]
|
||||
[[[ost %poke /sending [to %pong] %atom 'howdy'] ~] +>.$]
|
||||
::
|
||||
++ poke-atom
|
||||
|= arg=@
|
||||
^- [(list move) _+>.$]
|
||||
~& [%receiving (,@t arg)]
|
||||
[~ +>.$]
|
||||
::
|
||||
++ coup |=(* [~ +>.$])
|
||||
--
|
||||
```
|
||||
|
||||
Run it with these commands:
|
||||
|
||||
```
|
||||
~fintud-macrep:dojo> |start %pong
|
||||
>=
|
||||
~fintud-macrep:dojo> :pong &urbit ~sampel-sipnym
|
||||
>=
|
||||
```
|
||||
|
||||
Replace `~sampel-sipnym` with another urbit. Don't forget to
|
||||
start the `%pong` app on that urbit too. You should see, on the
|
||||
foreign urbit, this output:
|
||||
|
||||
```
|
||||
[%receiving 'howdy']
|
||||
```
|
||||
|
||||
Most of the code should be straightforward. In `++poke-atom`,
|
||||
the only new thing is the expression `(,@t arg)`. As we already
|
||||
know, `@t` is the type of "cord" text strings. `,` is an
|
||||
operator that turns a type into a validator function -- that is,
|
||||
a function whose domain is all nouns and range is the given type,
|
||||
and which is identity when the domain is restricted to the given
|
||||
type. In simpler terms, it's a function that coerces any value
|
||||
to the given type. We call this `,@t` function on the argument.
|
||||
This coerces the argument to text, so that we can print it out
|
||||
prettily.
|
||||
|
||||
The more interesting part is in `++poke-urbit`. The `urbit` mark
|
||||
is an urbit identity, and the hoon type associated with it is
|
||||
`@p` (the "p" stands for "phonetic base").
|
||||
|
||||
Recall that in a `++poke` arm we produce "a list of moves and our
|
||||
state". Until now, we've left the list of moves empty, since we
|
||||
haven't wanted to tell arvo to do anything in particular. Now we
|
||||
want to send a message to another urbit. Thus, we produce a list
|
||||
with one element:
|
||||
|
||||
```
|
||||
[ost %poke /sending [to %pong] %atom 'howdy']
|
||||
```
|
||||
|
||||
The general form of a move is
|
||||
|
||||
`[bone term path *]`
|
||||
|
||||
If you look up `++bone` in `hoon.hoon`, you'll see that it's a
|
||||
number (`@ud`), and that it's an opaque reference to a duct.
|
||||
`++duct` in hoon.hoon is a list of `wire`s, where `wire` is an
|
||||
alias for `path`. `++path` is a list of `span`s, which are ASCII
|
||||
text. Thus, a duct is a list of paths, and a bone is an opaque
|
||||
reference to that duct (in the same way that a Unix file
|
||||
descriptor is an opaque reference to a file structure). Thus,
|
||||
the center of all this is the concept of a "duct".
|
||||
|
||||
A duct is stack of causes, represented as paths. At the bottom
|
||||
of every duct is a unix event, such as a keystroke, network
|
||||
packet, file change, or timer event. When arvo is given this
|
||||
event, it routes the event to appropriate kernel module for
|
||||
handling.
|
||||
|
||||
Sometimes, the module can immediately handle the event and
|
||||
produce any necessary results. Otherwise, it asks other kernel
|
||||
modules or applications to do certain things, and produces the
|
||||
result from that. When it sends a message to another kernel
|
||||
module or application, it sends it "along" the duct it was given,
|
||||
plus with a new path. Arvo pushes the new path onto the duct.
|
||||
Now the duct has two entries, with the unix even on the bottom
|
||||
and the kernel module that handled it next. This process can
|
||||
continue indefinitely, adding more and more layers onto the duct.
|
||||
When an entity produces a result, a layer is popped off the duct.
|
||||
|
||||
In effect, a duct is an arvo-level call stack. The duct system
|
||||
creates a structured message-passing system. It's worth noting
|
||||
that while in traditional call stacks a function call happens
|
||||
synchronously and returns exactly once, in arvo multiple moves
|
||||
can be sent at once, they are evaluated asynchronously, and each
|
||||
one may be responded to zero or more times.
|
||||
|
||||
Anyhow, the point is that whatever caused `++poke-urbit` to be
|
||||
called is also the root cause for the network message we're
|
||||
trying to send. Thus, we say to send the network message along
|
||||
the given bone `ost`. Of course, we have to push a layer to the
|
||||
duct. This layer can have any data we want in it, but we don't
|
||||
need anything specific here, so we just use `/sending`. If we
|
||||
were expecting a response (which we're not), it would come back
|
||||
along the `/sending` path. It's a good idea for debugging
|
||||
purposes to make the path human-readable, but it's not necessary.
|
||||
|
||||
Looking back at the general form of a move, there is a `term`,
|
||||
which in this case is `%poke`. This is the name of the
|
||||
particular kind of move we're sending. If you think of a move as
|
||||
a syscall (which you should), then this `term` is the name of the
|
||||
syscall. Common ones include: `%poke`, to message an app;
|
||||
`%warp`, to read from the filesystem; `%wait`, to set a timer;
|
||||
and `%them`, to send an http request.
|
||||
|
||||
The general form ends with `*` since each type of move takes
|
||||
different data. In our case, a `%poke` move takes a target
|
||||
(urbit and app) and marked data and pokes that app on that urbit
|
||||
with that data. `[to %pong]` is the target urbit and app,
|
||||
`%atom` is the mark`, and `'howdy'` is the data.
|
||||
|
||||
When arvo receives a `%poke` move, it calls the appropriate
|
||||
`++poke`. The same mechanism is used for sending messages
|
||||
between apps on the same urbit as for sending messages between
|
||||
apps on different urbits.
|
||||
|
||||
> We said earlier that we're not expecting a response. This is
|
||||
> not entirely true: the `++coup` is called when we receive
|
||||
> acknowledgment that the `++poke` was called. We don't do
|
||||
> anything with this information right now, but we could.
|
||||
|
||||
**Exercises**:
|
||||
|
||||
- Extend either of the apps in the first two exercises to accept
|
||||
input over the network in the same way as `pong`.
|
||||
|
||||
- Modify `pong` to print out a message when it receives an ack.
|
||||
|
||||
- Write two apps, `even` and `odd`. When you pass an atom to
|
||||
`even`, check whether it's even. If so, divide it by two and
|
||||
recurse; otherwise, poke `odd` with it. When `odd` recieves
|
||||
an atom, check whether it's equal to one. If so, terminate,
|
||||
printing "%success". Otherwise, check whether it's odd. If
|
||||
so, multiply it by three, add one, and recurse; otherwise, poke
|
||||
`even` with it. multiply it by three and add one. When either
|
||||
app receives a number, print it out along with the name of the
|
||||
app. In the end, you should be able to watch Collatz's
|
||||
conjecture play out between the two apps. Sample output:
|
||||
|
||||
```
|
||||
~fintud-macrep:dojo> :even &atom 18
|
||||
[%even 18]
|
||||
[%odd 9]
|
||||
[%even 28]
|
||||
[%even 14]
|
||||
[%odd 7]
|
||||
[%even 22]
|
||||
[%odd 11]
|
||||
[%even 34]
|
||||
[%odd 17]
|
||||
[%even 52]
|
||||
[%even 26]
|
||||
[%odd 13]
|
||||
[%even 40]
|
||||
[%even 20]
|
||||
[%even 10]
|
||||
[%odd 5]
|
||||
[%even 16]
|
||||
[%even 8]
|
||||
[%even 4]
|
||||
[%even 2]
|
||||
%success
|
||||
```
|
||||
|
||||
- Put `even` and `odd` on two separate ships and pass the
|
||||
messages over the network.
|
@ -1,55 +0,0 @@
|
||||
---
|
||||
hide: true
|
||||
next: false
|
||||
sort: 3
|
||||
title: Advanced Applications
|
||||
---
|
||||
|
||||
XXX PLACEHOLDER
|
||||
|
||||
But what is our app state, exactly? In Unix systems, application
|
||||
state is just a block of memory, which you need to serialize to
|
||||
disk if you want to keep it around for very long.
|
||||
|
||||
In urbit, app state is a single (usually complex) value. In our
|
||||
example, we don't have any special state, so we defined
|
||||
`state=~`, meaning that our state is null. Of course, `state` is
|
||||
just a name we're assigning to it, and you're free to use
|
||||
whatever name you want.
|
||||
|
||||
Since urbit is purely functional, we can't just implicitly "have"
|
||||
and "change" our state. Rather, it's explicitly passed to us, in
|
||||
the `|_ [bowl state=~]` line, and we produce the new state with
|
||||
`+>.$` in the `[~ +>.$]` line.
|
||||
|
||||
Two points you may be wondering about. Firstly, `bowl` is a set
|
||||
of general global state that is managed by the system. It
|
||||
includes things like `now` (current time), `our` (our urbit
|
||||
identity), and `eny` (256 bits of guaranteed-fresh entropy). For
|
||||
the full list of things in `++bowl`, search for `++ bowl` (note
|
||||
the double space) in `/arvo/zuse.hoon`.
|
||||
|
||||
> This is a very common technique in learning hoon. While some
|
||||
> documentation exists, often the easiest way to learn about an
|
||||
> identifier you see in code is to search in `/arvo/zuse.hoon`
|
||||
> and `/arvo/hoon.hoon` for it. These are our two "standard
|
||||
> libraries", and they're usually not hard to read. Since
|
||||
> urbit's codebase is relatively small (those two files are less
|
||||
> than 15000 lines of code combined, and besides the standard
|
||||
> library they include the hoon parser and compiler, plus the
|
||||
> /arvo microkernel), you can usually use the code and the
|
||||
> comments as reference doc.
|
||||
|
||||
Second point is that urbit needs no "serialize to disk" step.
|
||||
Everything you produce in the app state is persistent across
|
||||
calls to the app, restarts of the urbit, and even power failure.
|
||||
If you want to write to the filesystem, you can, but it's not
|
||||
needed for persistence. Urbit has transactional events, which
|
||||
makes it an ACID operating system. Persistence is just another
|
||||
one of those things you don't have to worry about when
|
||||
programming in urbit.
|
||||
|
||||
As fascinating as state is, we don't actually need any state to
|
||||
accomplish our immediate goal, which is to get apps on two urbits
|
||||
talking to each other. We'll discuss state more in a later
|
||||
chapter.
|
@ -1,7 +0,0 @@
|
||||
Library
|
||||
========
|
||||
|
||||
<list dataPreview="true" titlesOnly="true"></list>
|
||||
|
||||
|
||||
<search/>
|
@ -1,37 +0,0 @@
|
||||
volume 0, Kelvin Versioning.
|
||||
===========================
|
||||
|
||||
### `++hoon`
|
||||
|
||||
++ hoon %164 :: version stub
|
||||
|
||||
Declares the current Hoon version number in degrees Kelvin.
|
||||
|
||||
When normal people release normal software, they count by fractions, and
|
||||
they count up. Thus, they can keep extending and revising their systems
|
||||
incrementally. This is generally considered a good thing. It generally
|
||||
is.
|
||||
|
||||
In some cases, however, specifications needs to be permanently frozen.
|
||||
This requirement is generally found in the context of standards. Some
|
||||
standards are extensible or versionable, but some are not. ASCII, for
|
||||
instance, is perma-frozen. So is IPv4 (its relationship to IPv6 is
|
||||
little more than nominal - if they were really the same protocol, they'd
|
||||
have the same ethertype). Moreover, many standards render themselves
|
||||
incompatible in practice through excessive enthusiasm for extensibility.
|
||||
They may not be perma-frozen, but they probably should be.
|
||||
|
||||
The true, Martian way to perma-freeze a system is what I call Kelvin
|
||||
versioning. In Kelvin versioning, releases count down by integer degrees
|
||||
Kelvin. At absolute zero, the system can no longer be changed. At 1K,
|
||||
one more modification is possible. And so on. For instance, Nock is at
|
||||
5K. It might change, though it probably won't. Nouns themselves are at
|
||||
0K - it is impossible to imagine changing anything about their three
|
||||
sentence definition.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
~zod/try=> stub
|
||||
164
|
||||
|
||||
------------------------------------------------------------------------
|
File diff suppressed because it is too large
Load Diff
@ -1,450 +0,0 @@
|
||||
chapter 2a, basic unsigned math
|
||||
===============================
|
||||
|
||||
### `++add`
|
||||
|
||||
Add
|
||||
|
||||
++ add :: add
|
||||
~/ %add
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: =(0 a) b
|
||||
$(a (dec a), b +(b))
|
||||
::
|
||||
|
||||
Produces the sum of `a` and `b` as an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (add 2 2)
|
||||
4
|
||||
~zod/try=> (add 1 1.000.000)
|
||||
1.000.001
|
||||
~zod/try=> (add 1.333 (mul 2 2))
|
||||
1.337
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++cap`
|
||||
|
||||
Tree head
|
||||
|
||||
++ cap :: tree head
|
||||
~/ %cap
|
||||
|= a=@
|
||||
^- ?(%2 %3)
|
||||
?- a
|
||||
%2 %2
|
||||
%3 %3
|
||||
?(%0 %1) !!
|
||||
* $(a (div a 2))
|
||||
==
|
||||
::
|
||||
|
||||
Tests whether an `a` is in the head or tail of a noun. Produces the
|
||||
[cube]() `%2` if it is within the head, or the [cube]() `%3` if is is
|
||||
within the tail.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
~zod/try=> (cap 4)
|
||||
%2
|
||||
~zod/try=> (cap 6)
|
||||
%3
|
||||
~zod/try=> (cap (add 10 9))
|
||||
%2
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dec`
|
||||
|
||||
Decrement
|
||||
|
||||
++ dec :: decrement
|
||||
~/ %dec
|
||||
|= a=@
|
||||
~| %decrement-underflow
|
||||
?< =(0 a)
|
||||
=+ b=0
|
||||
|- ^- @
|
||||
?: =(a +(b)) b
|
||||
$(b +(b))
|
||||
::
|
||||
|
||||
Produces `a-1` as an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
~zod/try=> (dec 7)
|
||||
6
|
||||
~zod/try=> (dec 0)
|
||||
! decrement-underflow
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++div`
|
||||
|
||||
Divide
|
||||
|
||||
++ div :: divide
|
||||
~/ %div
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
~| 'div'
|
||||
?< =(0 b)
|
||||
=+ c=0
|
||||
|-
|
||||
?: (lth a b) c
|
||||
$(a (sub a b), c +(c))
|
||||
::
|
||||
|
||||
Computes `a` divided by `b`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (div 4 2)
|
||||
2
|
||||
~zod/try=> (div 17 8)
|
||||
2
|
||||
~zod/try=> (div 20 30)
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fac`
|
||||
|
||||
Factorial
|
||||
|
||||
++ fac :: factorial
|
||||
~/ %fac
|
||||
|= a=@
|
||||
^- @
|
||||
?: =(0 a) 1
|
||||
(mul a $(a (dec a)))
|
||||
::
|
||||
|
||||
Computes the factorial of `a`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
~zod/try=> (fac 3)
|
||||
6
|
||||
~zod/try=> (fac 0)
|
||||
1
|
||||
~zod/try=> (fac 11)
|
||||
39.916.800
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gte`
|
||||
|
||||
Greater-than/equal
|
||||
|
||||
++ gte :: greater-equal
|
||||
~/ %gte
|
||||
|= [a=@ b=@]
|
||||
^- ?
|
||||
!(lth a b)
|
||||
::
|
||||
|
||||
Tests whether `a` is greater than a number `b`, producing a loobean.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (gte 100 10)
|
||||
%.y
|
||||
~zod/try=> (gte 4 4)
|
||||
%.y
|
||||
~zod/try=> (gte 3 4)
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gth`
|
||||
|
||||
Greater-than
|
||||
|
||||
++ gth :: greater-than
|
||||
~/ %gth
|
||||
|= [a=@ b=@]
|
||||
^- ?
|
||||
!(lte a b)
|
||||
::
|
||||
|
||||
Tests whether `a` is greater than `b`, producing a loobean.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (gth 'd' 'c')
|
||||
%.y
|
||||
~zod/try=> (gth ~h1 ~m61)
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lte`
|
||||
|
||||
Less-than/equal
|
||||
|
||||
++ lte :: less-equal
|
||||
~/ %lte
|
||||
|= [a=@ b=@]
|
||||
|(=(a b) (lth a b))
|
||||
::
|
||||
|
||||
Tests whether `a` is less than or equal to `b`, producing a loobean.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (lte 4 5)
|
||||
%.y
|
||||
~zod/try=> (lte 5 4)
|
||||
%.n
|
||||
~zod/try=> (lte 5 5)
|
||||
%.y
|
||||
~zod/try=> (lte 0 0)
|
||||
%.y
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lth`
|
||||
|
||||
Less-than
|
||||
|
||||
++ lth :: less-than
|
||||
~/ %lth
|
||||
|= [a=@ b=@]
|
||||
^- ?
|
||||
?& !=(a b)
|
||||
|-
|
||||
?| =(0 a)
|
||||
?& !=(0 b)
|
||||
$(a (dec a), b (dec b))
|
||||
== == ==
|
||||
::
|
||||
|
||||
Tests whether `a` is less than `b`, producing a loobean.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (lth 4 5)
|
||||
%.y
|
||||
~zod/try=> (lth 5 4)
|
||||
%.n
|
||||
~zod/try=> (lth 5 5)
|
||||
%.n
|
||||
~zod/try=> (lth 5 0)
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mas`
|
||||
|
||||
Axis within head/tail
|
||||
|
||||
++ mas :: tree body
|
||||
~/ %mas
|
||||
|= a=@
|
||||
^- @
|
||||
?- a
|
||||
1 !!
|
||||
2 1
|
||||
3 1
|
||||
* (add (mod a 2) (mul $(a (div a 2)) 2))
|
||||
==
|
||||
::
|
||||
|
||||
Computes the axis of `a` within the head or the tail, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
~zod/try=> (mas 3)
|
||||
1
|
||||
~zod/try=> (mas 4)
|
||||
2
|
||||
~zod/try=> (mas 5)
|
||||
3
|
||||
~zod/try=> (mas 6)
|
||||
2
|
||||
~zod/try=> (mas 0)
|
||||
! exit
|
||||
~zod/try=> (mas 1)
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++max`
|
||||
|
||||
Maximum
|
||||
|
||||
++ max :: maximum
|
||||
~/ %max
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: (gth a b) a
|
||||
b
|
||||
::
|
||||
|
||||
Computes the maximum of `a` and `b`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (max 10 100)
|
||||
100
|
||||
~zod/try=> (max 10.443 9)
|
||||
10.443
|
||||
~zod/try=> (max 0 1)
|
||||
1
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++min`
|
||||
|
||||
Minimum
|
||||
|
||||
++ min :: minimum
|
||||
~/ %min
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: (lth a b) a
|
||||
b
|
||||
::
|
||||
|
||||
Computes the minimum of `a` and `b`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (min 10 100)
|
||||
10
|
||||
~zod/try=> (min 10.443 9)
|
||||
9
|
||||
~zod/try=> (min 0 1)
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mod`
|
||||
|
||||
Modulus
|
||||
|
||||
++ mod :: remainder
|
||||
~/ %mod
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?< =(0 b)
|
||||
(sub a (mul b (div a b)))
|
||||
::
|
||||
|
||||
Computes the remainder of dividing `a` by `b`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mul`
|
||||
|
||||
Multiply
|
||||
|
||||
++ mul :: multiply
|
||||
~/ %mul
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
=+ c=0
|
||||
|-
|
||||
?: =(0 a) c
|
||||
$(a (dec a), c (add b c))
|
||||
::
|
||||
|
||||
Multiplies `a` by `b`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (mul 3 4)
|
||||
12
|
||||
~zod/try=> (mul 0 1)
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++peg`
|
||||
|
||||
Axis within axis
|
||||
|
||||
++ peg :: tree connect
|
||||
~/ %peg
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?- b
|
||||
1 a
|
||||
2 (mul a 2)
|
||||
3 +((mul a 2))
|
||||
* (add (mod b 2) (mul $(b (div b 2)) 2))
|
||||
==
|
||||
::
|
||||
|
||||
Computes the axis of `b` within axis `a`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (peg 4 1)
|
||||
4
|
||||
~zod/try=> (peg 4 2)
|
||||
8
|
||||
~zod/try=> (peg 8 45)
|
||||
269
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sub`
|
||||
|
||||
Subtract
|
||||
|
||||
++ sub :: subtract
|
||||
~/ %sub
|
||||
|= [a=@ b=@]
|
||||
~| %subtract-underflow
|
||||
^- @
|
||||
?: =(0 b) a
|
||||
$(a (dec a), b (dec b))
|
||||
|
||||
Subtracts `b` from `a`, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
~zod/try=> (sub 10 5)
|
||||
5
|
||||
~zod/try=> (sub 243 44)
|
||||
199
|
||||
~zod/try=> (sub 5 0)
|
||||
5
|
||||
~zod/try=> (sub 0 5)
|
||||
! subtract-underflow
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,907 +0,0 @@
|
||||
chapter 2b, basic containers
|
||||
============================
|
||||
|
||||
Section 2bA, units
|
||||
------------------
|
||||
|
||||
### `++biff`
|
||||
|
||||
Unit as argument
|
||||
|
||||
++ biff :: apply
|
||||
|* [a=(unit) b=$+(* (unit))]
|
||||
?~ a ~
|
||||
(b u.a)
|
||||
|
||||
Applies a gate that produces a unit, `b`, to the value (`u.a`) of a unit
|
||||
`a`. If `a` is empty, `~` is produced.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
`b` is a [gate]() that accepts a noun and produces a unit.
|
||||
|
||||
~zod/try=> (biff (some 5) |=(a=@ (some (add a 2))))
|
||||
[~ u=7]
|
||||
~zod/try=> (biff ~ |=(a=@ (some (add a 2))))
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++bind`
|
||||
|
||||
Bind
|
||||
|
||||
++ bind :: argue
|
||||
|* [a=(unit) b=gate]
|
||||
?~ a ~
|
||||
[~ u=(b u.a)]
|
||||
|
||||
Applies a function `b` to the value (`u.a`) of a unit `a`, producing a
|
||||
unit.
|
||||
|
||||
`a` is a [unit]()
|
||||
|
||||
`b` is a [gate]().
|
||||
|
||||
~zod/try=> (bind ((unit ,@) [~ 97]) ,@t)
|
||||
[~ `a`]
|
||||
~zod/try=> =a |=(a=@ (add a 1))
|
||||
~zod/try=> (bind ((unit ,@) [~ 2]) a)
|
||||
[~ 3]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++bond`
|
||||
|
||||
Replace null
|
||||
|
||||
++ bond :: replace
|
||||
|* a=trap
|
||||
|* b=(unit)
|
||||
?~ b $:a
|
||||
u.b
|
||||
|
||||
Replaces an empty unit `b` with the product of a kicked trap `a`. If the
|
||||
unit is not empty, then the original unit is produced.
|
||||
|
||||
`a` is a [trap]().
|
||||
|
||||
`b` is a [unit]().
|
||||
|
||||
~zod/try=> (bex 10)
|
||||
1.024
|
||||
~zod/try=> ((bond |.((bex 10))) ~)
|
||||
1.024
|
||||
~zod/try=> ((bond |.((bex 10))) (slaw %ud '123'))
|
||||
123
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++both`
|
||||
|
||||
Group unit values
|
||||
|
||||
++ both :: all the above
|
||||
|* [a=(unit) b=(unit)]
|
||||
?~ a ~
|
||||
?~ b ~
|
||||
[~ u=[u.a u.b]]
|
||||
|
||||
Produces a unit whose value is a cell of the values of two input units
|
||||
`a` and `b`. If either of the two units are empty, `~` is produced.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
`b` is a [unit]().
|
||||
|
||||
~zod/try=> (both (some 1) (some %b))
|
||||
[~ u=[1 %b]]
|
||||
~zod/try=> (both ~ (some %b))
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++clap`
|
||||
|
||||
Apply gate to two units
|
||||
|
||||
++ clap :: combine
|
||||
|* [a=(unit) b=(unit) c=_|=(^ +<-)]
|
||||
?~ a b
|
||||
?~ b a
|
||||
[~ u=(c u.a u.b)]
|
||||
|
||||
Applies a binary operation `c` which produces a unit to the values of
|
||||
two units `a` and `b`.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
`b` is a [unit]().
|
||||
|
||||
`c` is a [gate]() that performs a binary operation.
|
||||
|
||||
~zod/try=> =u ((unit ,@t) [~ 'a'])
|
||||
~zod/try=> =v ((unit ,@t) [~ 'b'])
|
||||
~zod/try=> (clap u v |=([a=@t b=@t] (welp (trip a) (trip b))))
|
||||
[~ u="ab"]
|
||||
~zod/try=> =a ((unit ,@u) [~ 1])
|
||||
~zod/try=> =b ((unit ,@u) [~ 2])
|
||||
~zod/try=> =c |=([a=@ b=@] (add a b))
|
||||
~zod/try=> (clap a b c)
|
||||
[~ 3]
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++drop`
|
||||
|
||||
Unit list
|
||||
|
||||
++ drop :: enlist
|
||||
|* a=(unit)
|
||||
?~ a ~
|
||||
[i=u.a t=~]
|
||||
|
||||
Produces a [list]() of the value from a unit `a`.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
~zod/try=> =a ((unit ,@) [~ 97])
|
||||
~zod/try=> (drop a)
|
||||
[i=97 t=~]
|
||||
~zod/try=> =a ((unit ,@) [~])
|
||||
~zod/try=> (drop a)
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fall`
|
||||
|
||||
Default unit
|
||||
|
||||
++ fall :: default
|
||||
|* [a=(unit) b=*]
|
||||
?~(a b u.a)
|
||||
|
||||
Produces a default value `b` for a unit `a` in cases where the unit is
|
||||
null.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
`b` is a [noun]() used as the default value.
|
||||
|
||||
~zod/try=> (fall ~ `a`)
|
||||
`a`
|
||||
~zod/try=> (fall [~ u=0] `a`)
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lift`
|
||||
|
||||
Fmap
|
||||
|
||||
++ lift :: lift gate (fmap)
|
||||
|* a=gate :: flipped
|
||||
|* b=(unit) :: curried
|
||||
(bind b a) :: bind
|
||||
|
||||
Similar to `fmap` in Haskell: accepts a gate `a` that accepts and
|
||||
produces an unwrapped value, passes it the value of a unit `b`, and then
|
||||
produces a unit value.
|
||||
|
||||
`a` is a [gate]().
|
||||
|
||||
`b` is a [unit]().
|
||||
|
||||
~zod/try=> ((lift dec) `(unit ,@)`~)
|
||||
~
|
||||
~zod/try=> ((lift dec) `(unit ,@)`[~ 20])
|
||||
[~ 19]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mate`
|
||||
|
||||
Choose
|
||||
|
||||
++ mate :: choose
|
||||
|* [a=(unit) b=(unit)]
|
||||
?~ b a
|
||||
?~ a b
|
||||
?.(=(u.a u.b) ~|('mate' !!) a)
|
||||
|
||||
Accepts two units `a` and `b` whose values are expected to be
|
||||
equivalent. If either is empty, then the value of the other is produced.
|
||||
If neither are empty, it asserts that both values are the same and
|
||||
produces that value. If the assertion fails, `++mate` crashes with
|
||||
`'mate'` in the stack trace.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
`b` is a [unit]().
|
||||
|
||||
~zod/try=> =a ((unit ,@) [~ 97])
|
||||
~zod/try=> =b ((unit ,@) [~ 97])
|
||||
~zod/try=> (mate a b)
|
||||
[~ 97]
|
||||
~zod/try=> =a ((unit ,@) [~ 97])
|
||||
~zod/try=> =b ((unit ,@) [~])
|
||||
~zod/try=> (mate a b)
|
||||
[~ 97]
|
||||
~zod/try=> =a ((unit ,@) [~ 97])
|
||||
~zod/try=> =b ((unit ,@) [~ 98])
|
||||
~zod/try=> (mate a b)
|
||||
! 'mate'
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++need`
|
||||
|
||||
Unwrap
|
||||
|
||||
++ need :: demand
|
||||
|* a=(unit)
|
||||
?~ a !!
|
||||
u.a
|
||||
|
||||
Retrieve the value from a unit and crash if the unit is null.
|
||||
|
||||
`a` is a [unit]().
|
||||
|
||||
~zod/try=> =a ((unit ,[@t @t]) [~ ['a' 'b']])
|
||||
~zod/try=> (need a)
|
||||
['a' 'b']
|
||||
~zod/try=> =a ((unit ,@ud) [~ 17])
|
||||
~zod/try=> (need a)
|
||||
17
|
||||
~zod/try=> =a ((unit ,@) [~])
|
||||
~zod/try=> (need a)
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++some`
|
||||
|
||||
Unify
|
||||
|
||||
++ some :: lift (pure)
|
||||
|* a=*
|
||||
[~ u=a]
|
||||
|
||||
Takes any atom `a` and produces a unit with the value set to `a`.
|
||||
|
||||
`a` is a [noun]().
|
||||
|
||||
~zod/try=> (some [`a` `b`])
|
||||
[~ u=[`a` `b`]]
|
||||
~zod/try=> (some &)
|
||||
[~ u=%.y]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
section 2bB, lists
|
||||
------------------
|
||||
|
||||
### `++flop`
|
||||
|
||||
Reverse
|
||||
|
||||
++ flop :: reverse
|
||||
~/ %flop
|
||||
|* a=(list)
|
||||
=> .(a (homo a))
|
||||
^+ a
|
||||
=+ b=`_a`~
|
||||
|-
|
||||
?~ a b
|
||||
$(a t.a, b [i.a b])
|
||||
|
||||
Produces the list `a` in reverse order.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
~zod/try=> =a (limo [1 2 3 ~])
|
||||
~zod/try=> (flop a)
|
||||
~[3 2 1]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++homo`
|
||||
|
||||
Homogenize
|
||||
|
||||
++ homo :: homogenize
|
||||
|* a=(list)
|
||||
^+ =< $
|
||||
|% +- $ ?:(_? ~ [i=(snag 0 a) t=$])
|
||||
--
|
||||
a
|
||||
|
||||
Produces a list whose type is a fork of all the contained types in the
|
||||
list `a`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
~zod/try=> lyst
|
||||
[i=1 t=[i=97 t=[i=2 t=[i=98 t=[i=[~ u=10] t=~]]]]]
|
||||
~zod/try=> (homo lyst)
|
||||
~[1 97 2 98 [~ u=10]]
|
||||
~zod/try=> =a (limo [1 2 3 ~])
|
||||
~zod/try=> a
|
||||
[i=1 t=[i=2 t=[i=3 t=~]]]
|
||||
~zod/try=> (homo a)
|
||||
~[1 2 3]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++limo`
|
||||
|
||||
List Constructor
|
||||
|
||||
++ limo :: listify
|
||||
|* a=*
|
||||
^+ =< $
|
||||
|% +- $ ?~(a ~ ?:(_? i=-.a t=$ $(a +.a)))
|
||||
--
|
||||
a
|
||||
|
||||
Turns a null-terminated tuple into a list.
|
||||
|
||||
`a` is a null-terminated tuple.
|
||||
|
||||
~zod/try=> (limo [1 2 3 ~])
|
||||
[i=1 t=[i=2 t=[i=3 t=~]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lent`
|
||||
|
||||
List length
|
||||
|
||||
++ lent :: length
|
||||
~/ %lent
|
||||
|= a=(list)
|
||||
^- @
|
||||
=+ b=0
|
||||
|-
|
||||
?~ a b
|
||||
$(a t.a, b +(b))
|
||||
|
||||
Produces the length of any list `a` as an atom.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
~zod/try=> (lent (limo [1 2 3 4 ~]))
|
||||
4
|
||||
~zod/try=> (lent (limo [1 'a' 2 'b' (some 10) ~]))
|
||||
5
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++levy`
|
||||
|
||||
"and" to list
|
||||
|
||||
++ levy
|
||||
~/ %levy :: all of
|
||||
|* [a=(list) b=_|=(p=* .?(p))]
|
||||
|- ^- ?
|
||||
?~ a &
|
||||
?. (b i.a) |
|
||||
$(a t.a)
|
||||
|
||||
Produces the Boolean "and" of the result of every element in list `a`
|
||||
passed to gate `b`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]().
|
||||
|
||||
~zod/try=> =a |=(a=@ (lte a 1))
|
||||
~zod/try=> (levy (limo [0 1 2 1 ~]) a)
|
||||
%.n
|
||||
~zod/try=> =a |=(a=@ (lte a 3))
|
||||
~zod/try=> (levy (limo [0 1 2 1 ~]) a)
|
||||
%.y
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lien`
|
||||
|
||||
"or" to list
|
||||
|
||||
++ lien :: some of
|
||||
~/ %lien
|
||||
|* [a=(list) b=$+(* ?)]
|
||||
|- ^- ?
|
||||
?~ a |
|
||||
?: (b i.a) &
|
||||
$(a t.a)
|
||||
|
||||
Produces the Boolean "or" of the result of every element in list `a`
|
||||
passed to gate `b`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]().
|
||||
|
||||
~zod/try=> =a |=(a=@ (gte a 1))
|
||||
~zod/try=> (lien (limo [0 1 2 1 ~]) a)
|
||||
%.y
|
||||
~zod/try=> =a |=(a=@ (gte a 3))
|
||||
~zod/try=> (lien (limo [0 1 2 1 ~]) a)
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++murn`
|
||||
|
||||
Maybe transform
|
||||
|
||||
++ murn :: maybe transform
|
||||
|* [a=(list) b=$+(* (unit))]
|
||||
|-
|
||||
?~ a ~
|
||||
=+ c=(b i.a)
|
||||
?~ c
|
||||
$(a t.a)
|
||||
[i=u.c t=$(a t.a)]
|
||||
|
||||
Passes each member of list `a` to gate `b`, which must produce a unit.
|
||||
Produces a new list with all the results that do not produce `~`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]() that produces a [unit]().
|
||||
|
||||
~zod/try=> =a |=(a=@ ?.((gte a 2) ~ (some (add a 10))))
|
||||
~zod/try=> (murn (limo [0 1 2 3 ~]) a)
|
||||
[i=12 t=[i=13 t=~]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++reap`
|
||||
|
||||
Replicate
|
||||
|
||||
++ reap :: replicate
|
||||
|* [a=@ b=*]
|
||||
|- ^- (list ,_b)
|
||||
?~ a ~
|
||||
[b $(a (dec a))]
|
||||
|
||||
Replicate: produces a list containing `a` copies of `b`.
|
||||
|
||||
`a` is an [atom]()
|
||||
|
||||
`b` is a [noun]()
|
||||
|
||||
~zod/try=> (reap 20 %a)
|
||||
~[%a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a %a]
|
||||
~zod/try=> (reap 5 ~s1)
|
||||
~[~s1 ~s1 ~s1 ~s1 ~s1]
|
||||
~zod/try=> `@dr`(roll (reap 5 ~s1) add)
|
||||
~s5
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++reel`
|
||||
|
||||
Right fold
|
||||
|
||||
++ reel :: right fold
|
||||
~/ %reel
|
||||
|* [a=(list) b=_|=([* *] +<+)]
|
||||
|- ^+ +<+.b
|
||||
?~ a
|
||||
+<+.b
|
||||
(b i.a $(a t.a))
|
||||
|
||||
Right fold: moves right to left across a list `a`, recursively slamming
|
||||
a binary gate `b` with an element from `a` and an accumulator, producing
|
||||
the final value of the accumulator.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a binary [gate]().
|
||||
|
||||
~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
|
||||
~zod/try=> (reel (limo [1 2 3 4 5 ~]) sum)
|
||||
15
|
||||
~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
|
||||
~zod/try=> (reel (limo [6 3 1 ~]) a)
|
||||
4
|
||||
~zod/try=> (reel (limo [3 6 1 ~]) a)
|
||||
! subtract-underflow
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++roll`
|
||||
|
||||
Left fold
|
||||
|
||||
++ roll :: left fold
|
||||
~/ %roll
|
||||
|* [a=(list) b=_|=([* *] +<+)]
|
||||
|- ^+ +<+.b
|
||||
?~ a
|
||||
+<+.b
|
||||
$(a t.a, b b(+<+ (b i.a +<+.b)))
|
||||
|
||||
Left fold: moves left to right across a list `a`, recursively slamming a
|
||||
binary gate `b` with an element from the list and an accumulator,
|
||||
producing the final value of the accumulator.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a binary [gate]().
|
||||
|
||||
~zod/try=> =sum =|([p=@ q=@] |.((add p q)))
|
||||
~zod/try=> (roll (limo [1 2 3 4 5 ~]) sum)
|
||||
q=15
|
||||
~zod/try=> =a =|([p=@ q=@] |.((sub p q)))
|
||||
~zod/try=> (roll (limo [6 3 1 ~]) a)
|
||||
! subtract-underflow
|
||||
! exit
|
||||
~zod/try=> (roll (limo [1 3 6 ~]) a)
|
||||
q=4
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++skid`
|
||||
|
||||
Separate
|
||||
|
||||
++ skid :: separate
|
||||
|* [a=(list) b=$+(* ?)]
|
||||
|- ^+ [p=a q=a]
|
||||
?~ a [~ ~]
|
||||
=+ c=$(a t.a)
|
||||
?:((b i.a) [[i.a p.c] q.c] [p.c [i.a q.c]])
|
||||
|
||||
Seperates a list `a` into two lists - Those elements of `a` who produce
|
||||
true when slammed to gate `b` and those who produce `%.n`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]() that accepts one argument and produces a loobean.
|
||||
|
||||
~zod/try=> =a |=(a=@ (gth a 1))
|
||||
~zod/try=> (skid (limo [0 1 2 3 ~]) a)
|
||||
[p=[i=2 t=[i=3 t=~]] q=[i=0 t=[i=1 t=~]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++skim`
|
||||
|
||||
Suffix
|
||||
|
||||
++ skim :: only
|
||||
~/ %skim
|
||||
|* [a=(list) b=_|=(p=* .?(p))]
|
||||
|-
|
||||
^+ a
|
||||
?~ a ~
|
||||
?:((b i.a) [i.a $(a t.a)] $(a t.a))
|
||||
|
||||
Cycles through the members of a list `a`, passing them to a gate `b` and
|
||||
producing a list of all of the members that produce `%.y`. Inverse of
|
||||
`++skip`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]() that accepts one argument and produces a loobean.
|
||||
|
||||
~zod/try=> =a |=(a=@ (gth a 1))
|
||||
~zod/try=> (skim (limo [0 1 2 3 ~]) a)
|
||||
[i=2 t=[i=3 t=~]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++skip`
|
||||
|
||||
Except
|
||||
|
||||
++ skip :: except
|
||||
~/ %skip
|
||||
|* [a=(list) b=_|=(p=* .?(p))]
|
||||
|-
|
||||
^+ a
|
||||
?~ a ~
|
||||
?:((b i.a) $(a t.a) [i.a $(a t.a)])
|
||||
|
||||
Cycles through the members of a list `a`, passing them to a gate `b` and
|
||||
producing a list of all of the members that produce `%.n`. Inverse of
|
||||
`++skim`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]() that accepts one argument and produces a loobean.
|
||||
|
||||
~zod/try=> =a |=(a=@ (gth a 1))
|
||||
~zod/try=> (skip (limo [0 1 2 3 ~]) a)
|
||||
[i=0 t=[i=1 t=~]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++scag`
|
||||
|
||||
Prefix
|
||||
|
||||
++ scag :: prefix
|
||||
~/ %scag
|
||||
|* [a=@ b=(list)]
|
||||
|- ^+ b
|
||||
?: |(?=(~ b) =(0 a)) ~
|
||||
[i.b $(b t.b, a (dec a))]
|
||||
|
||||
Accepts an atom `a` and list `b`, producing the first `a` elements of
|
||||
the front of the list.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is a [list]().
|
||||
|
||||
~zod/try=> (scag 2 (limo [0 1 2 3 ~]))
|
||||
[i=0 t=[i=1 t=~]]
|
||||
~zod/try=> (scag 10 (limo [1 2 3 4 ~]))
|
||||
[i=1 t=[i=2 t=[i=3 t=[i=4 t=~]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++slag`
|
||||
|
||||
Suffix
|
||||
|
||||
++ slag :: suffix
|
||||
~/ %slag
|
||||
|* [a=@ b=(list)]
|
||||
|- ^+ b
|
||||
?: =(0 a) b
|
||||
?~ b ~
|
||||
$(b t.b, a (dec a))
|
||||
|
||||
Accepts an atom `a` and list `b`, producing the remaining elements from
|
||||
`b` starting at `a`.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is a [list]().
|
||||
|
||||
~zod/try=> (slag 2 (limo [1 2 3 4 ~]))
|
||||
[i=3 t=[i=4 t=~]]
|
||||
~zod/try=> (slag 1 (limo [1 2 3 4 ~]))
|
||||
[i=2 t=[i=3 t=[i=4 t=~]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++snag`
|
||||
|
||||
Index
|
||||
|
||||
++ snag :: index
|
||||
~/ %snag
|
||||
|* [a=@ b=(list)]
|
||||
|-
|
||||
?~ b
|
||||
~|('snag-fail' !!)
|
||||
?: =(0 a) i.b
|
||||
$(b t.b, a (dec a))
|
||||
|
||||
Accepts an atom `a` and a list `b`, producing the element at the index
|
||||
of `a`and failing if the list is null. Lists are 0-indexed.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is a [list]().
|
||||
|
||||
~zod/try=> (snag 2 "asdf")
|
||||
~~d
|
||||
~zod/try=> (snag 0 `(list ,@ud)`~[1 2 3 4])
|
||||
1
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sort`
|
||||
|
||||
Quicksort
|
||||
|
||||
++ sort :: quicksort
|
||||
~/ %sort
|
||||
|* [a=(list) b=$+([* *] ?)]
|
||||
=> .(a ^.(homo a))
|
||||
|- ^+ a
|
||||
?~ a ~
|
||||
%+ weld
|
||||
$(a (skim t.a |=(c=_i.a (b c i.a))))
|
||||
^+ t.a
|
||||
[i.a $(a (skim t.a |=(c=_i.a !(b c i.a))))]
|
||||
|
||||
Quicksort: accepts a list `a` and a gate `b` which accepts two nouns and
|
||||
produces a loobean. `++sort` then produces a list of the elements of `a`
|
||||
sorted according to `b`.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is a [gate]() which accepts two nouns and produces a loobean.
|
||||
|
||||
~zod/try=> =a =|([p=@ q=@] |.((gth p q)))
|
||||
~zod/try=> (sort (limo [0 1 2 3 ~]) a)
|
||||
~[3 2 1 0]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++swag`
|
||||
|
||||
Infix
|
||||
|
||||
++ swag :: infix
|
||||
|* [[a=@ b=@] c=(list)]
|
||||
(scag b (slag a c))
|
||||
|
||||
Similar to `substr` in JavaScript: extracts a string infix, beginning at
|
||||
inclusive index `a`, producing `b` number of characters.
|
||||
|
||||
`a` and `b` are [atom]()s.
|
||||
|
||||
`c` is a [list]().
|
||||
|
||||
~zod/try=> (swag [2 5] "roly poly")
|
||||
"ly po"
|
||||
~zod/try=> (swag [2 2] (limo [1 2 3 4 ~]))
|
||||
[i=3 t=[i=4 t=~]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++turn`
|
||||
|
||||
Gate to list
|
||||
|
||||
++ turn :: transform
|
||||
~/ %turn
|
||||
|* [a=(list) b=_,*]
|
||||
|-
|
||||
?~ a ~
|
||||
[i=(b i.a) t=$(a t.a)]
|
||||
|
||||
Accepts a list `a` and a gate `b`. Produces a list with the gate applied
|
||||
to each element of the original list.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
`b` is a [gate]().
|
||||
|
||||
~zod/try=> (turn (limo [104 111 111 110 ~]) ,@t)
|
||||
<|h o o n|>
|
||||
~zod/try=> =a |=(a=@ (add a 4))
|
||||
~zod/try=> (turn (limo [1 2 3 4 ~]) a)
|
||||
~[5 6 7 8]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++weld`
|
||||
|
||||
Concatenate
|
||||
|
||||
++ weld :: concatenate
|
||||
~/ %weld
|
||||
|* [a=(list) b=(list)]
|
||||
=> .(a ^.(homo a), b ^.(homo b))
|
||||
|- ^+ b
|
||||
?~ a b
|
||||
[i.a $(a t.a)]
|
||||
|
||||
Concatenate two lists `a` and `b`.
|
||||
|
||||
`a` and `b` are [list]()s.
|
||||
|
||||
~zod/try=> (weld "urb" "it")
|
||||
~[~~u ~~r ~~b ~~i ~~t]
|
||||
~zod/try=> (weld (limo [1 2 ~]) (limo [3 4 ~]))
|
||||
~[1 2 3 4]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++welp`
|
||||
|
||||
Perfect weld
|
||||
|
||||
++ welp :: perfect weld
|
||||
=| [* *]
|
||||
|%
|
||||
+- $
|
||||
?~ +<-
|
||||
+<-(. +<+)
|
||||
+<-(+ $(+<- +<->))
|
||||
--
|
||||
|
||||
Concatenate two lists `a` and `b` without losing their type information
|
||||
to homogenization.
|
||||
|
||||
`a` and `b` are [list]()s.
|
||||
|
||||
~zod/try=> (welp "foo" "bar")
|
||||
"foobar"
|
||||
~zod/arvo=/hoon/hoon> (welp ~[60 61 62] ~[%a %b %c])
|
||||
[60 61 62 %a %b %c ~]
|
||||
~zod/arvo=/hoon/hoon> :type; (welp ~[60 61 62] ~[%a %b %c])
|
||||
[60 61 62 %a %b %c ~]
|
||||
[@ud @ud @ud %a %b %c %~]
|
||||
~zod/arvo=/hoon/hoon> (welp [sa/1 so/2 ~] si/3)
|
||||
[[%sa 1] [%so 2] %si 3]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wild`
|
||||
|
||||
XXDELETE
|
||||
|
||||
++ wild :: concatenate
|
||||
|* [a=(list) b=(list)]
|
||||
=> .(a ^.(homo a), b ^.(homo b))
|
||||
|-
|
||||
?~ a b
|
||||
[i=i.a $(a t.a)]
|
||||
|
||||
Concatenates two lists `a` and `b`, homogenizing their types
|
||||
individually.
|
||||
|
||||
`a` and `b` are [list]()s.
|
||||
|
||||
~zod/try=> (wild (limo ~[1 2 3]) (limo [4]~))
|
||||
~[1 2 3 4]
|
||||
~zod/try=> (wild (limo 60 61 62 ~) (limo %a %b %c ~))
|
||||
[i=60 [i=61 [i=62 ~[%a %b %c]]]]
|
||||
~zod/try=> (weld (limo 60 61 62 ~) (limo %a %b %c ~))
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.000 15].[10.016 57]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.001 15].[10.016 57]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.002 15].[10.016 57]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.004 15].[10.016 57]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 15].[10.016 57]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.006 29].[10.006 44]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.056 3].[10.061 13]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.058 3].[10.061 13]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.059 3].[10.061 13]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[10.060 5].[10.060 47]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.826 7].[9.844 35]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 7].[9.844 35]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.827 11].[9.838 13]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.828 11].[9.838 13]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.829 13].[9.831 47]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.830 13].[9.831 47]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.706 7].[9.712 25]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.707 7].[9.712 25]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.708 7].[9.712 25]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 7].[9.712 25]>
|
||||
! /~zod/arvo/~2014.10.2..22.58.23..5af9/hoon/:<[9.712 8].[9.712 25]>
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++zing`
|
||||
|
||||
Cons
|
||||
|
||||
++ zing :: promote
|
||||
=| *
|
||||
|%
|
||||
+- $
|
||||
?~ +<
|
||||
+<
|
||||
(welp +<- $(+< +<+))
|
||||
--
|
||||
|
||||
Turns a list of lists into a single list by promoting the elements of
|
||||
each sublist into the higher.
|
||||
|
||||
Accepts a [list]() of lists.
|
||||
|
||||
~zod/try=> (zing (limo [(limo ['a' 'b' 'c' ~]) (limo ['e' 'f' 'g' ~]) (limo ['h' 'i' 'j' ~]) ~]))
|
||||
~['a' 'b' 'c' 'e' 'f' 'g' 'h' 'i' 'j']
|
||||
~zod/try=> (zing (limo [(limo [1 'a' 2 'b' ~]) (limo [3 'c' 4 'd' ~]) ~]))
|
||||
~[1 97 2 98 3 99 4 100]
|
||||
|
||||
------------------------------------------------------------------------
|
File diff suppressed because it is too large
Load Diff
@ -1,437 +0,0 @@
|
||||
section 2dA, sets
|
||||
=================
|
||||
|
||||
### `++apt`
|
||||
|
||||
Set verification
|
||||
|
||||
++ apt :: set invariant
|
||||
|= a=(tree)
|
||||
?~ a
|
||||
&
|
||||
?& ?~(l.a & ?&((vor n.a n.l.a) (hor n.l.a n.a)))
|
||||
?~(r.a & ?&((vor n.a n.r.a) (hor n.a n.r.a)))
|
||||
==
|
||||
::
|
||||
|
||||
Produces a loobean indicating whether `a` is a set or not.
|
||||
|
||||
`a` is a [tree]().
|
||||
|
||||
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
|
||||
~zod/try=> (apt b)
|
||||
%.y
|
||||
~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ['c' 4] ['d' 5] ~])
|
||||
~zod/try=> m
|
||||
{[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
|
||||
~zod/try=> (apt m)
|
||||
%.y
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++in`
|
||||
|
||||
Set operations
|
||||
|
||||
++ in :: set engine
|
||||
~/ %in
|
||||
|/ a=(set)
|
||||
|
||||
Input arm.
|
||||
|
||||
~zod/try=> ~(. in (sa "asd"))
|
||||
<13.evb [nlr(^$1{@tD $1}) <414.fvk 101.jzo 1.ypj %164>]>
|
||||
|
||||
`a` is a [set]()
|
||||
|
||||
### `+-all:in`
|
||||
|
||||
Logical AND
|
||||
|
||||
+- all :: logical AND
|
||||
~/ %all
|
||||
|* b=$+(* ?)
|
||||
|- ^- ?
|
||||
?~ a
|
||||
&
|
||||
?&((b n.a) $(a l.a) $(a r.a))
|
||||
::
|
||||
|
||||
Computes the logical AND on every element in `a` slammed with `b`,
|
||||
producing a loobean.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [wet gate]() that accepts a noun and produces a loobean.
|
||||
|
||||
~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(all in b) |=(a=* ?@(+.a & |)))
|
||||
%.n
|
||||
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
|
||||
~zod/try=> (~(all in b) |=(a=@t (gte a 100)))
|
||||
%.y
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-any:in`
|
||||
|
||||
Logical OR
|
||||
|
||||
+- any :: logical OR
|
||||
~/ %any
|
||||
|* b=$+(* ?)
|
||||
|- ^- ?
|
||||
?~ a
|
||||
|
|
||||
?|((b n.a) $(a l.a) $(a r.a))
|
||||
::
|
||||
|
||||
Computes the logical OR on every element of `a` slammed with `b`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [gate]() that accepts a noun and produces a loobean.
|
||||
|
||||
~zod/try=> =b (sa `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(any in b) |=(a=* ?@(+.a & |)))
|
||||
%.y
|
||||
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
|
||||
~zod/try=> (~(any in b) |=(a=@t (lte a 100)))
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-del:in`
|
||||
|
||||
Remove noun
|
||||
|
||||
+- del :: b without any a
|
||||
~/ %del
|
||||
|* b=*
|
||||
|- ^+ a
|
||||
?~ a
|
||||
~
|
||||
?. =(b n.a)
|
||||
?: (hor b n.a)
|
||||
[n.a $(a l.a) r.a]
|
||||
[n.a l.a $(a r.a)]
|
||||
|- ^- ?(~ _a)
|
||||
?~ l.a r.a
|
||||
?~ r.a l.a
|
||||
?: (vor n.l.a n.r.a)
|
||||
[n.l.a l.l.a $(l.a r.l.a)]
|
||||
[n.r.a $(r.a l.r.a) r.r.a]
|
||||
::
|
||||
|
||||
Removes `b` from the set `a`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [noun]().
|
||||
|
||||
~zod/try=> =b (sa `(list ,@t)`['a' 'b' 'c' ~])
|
||||
~zod/try=> (~(del in b) 'a')
|
||||
{'c' 'b'}
|
||||
~zod/try=> =b (sa `(list ,@t)`['john' 'bonita' 'daniel' 'madeleine' ~])
|
||||
~zod/try=> (~(del in b) 'john')
|
||||
{'bonita' 'madeleine' 'daniel'}
|
||||
~zod/try=> (~(del in b) 'susan')
|
||||
{'bonita' 'madeleine' 'daniel' 'john'}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-dig:in`
|
||||
|
||||
Axis a in b
|
||||
|
||||
+- dig :: axis of a in b
|
||||
|= b=*
|
||||
=+ c=1
|
||||
|- ^- (unit ,@)
|
||||
?~ a ~
|
||||
?: =(b n.a) [~ u=(peg c 2)]
|
||||
?: (gor b n.a)
|
||||
$(a l.a, c (peg c 6))
|
||||
$(a r.a, c (peg c 7))
|
||||
::
|
||||
|
||||
Produce the axis of `b` within `a`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [noun]().
|
||||
|
||||
~zod/try=> =a (sa `(list ,@)`[1 2 3 4 5 6 7 ~])
|
||||
~zod/try=> a
|
||||
{5 4 7 6 1 3 2}
|
||||
~zod/try=> -.a
|
||||
n=6
|
||||
~zod/try=> (~(dig in a) 7)
|
||||
[~ 12]
|
||||
~zod/try=> (~(dig in a) 2)
|
||||
[~ 14]
|
||||
~zod/try=> (~(dig in a) 6)
|
||||
[~ 2]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-gas:in`
|
||||
|
||||
Concatenate
|
||||
|
||||
+- gas :: concatenate
|
||||
~/ %gas
|
||||
|= b=(list ,_?>(?=(^ a) n.a))
|
||||
|- ^+ a
|
||||
?~ b
|
||||
a
|
||||
$(b t.b, a (put(+< a) i.b))
|
||||
::
|
||||
|
||||
Insert the elements of a list `b` into a set `a`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [list]().
|
||||
|
||||
~zod/try=> b
|
||||
{'bonita' 'madeleine' 'rudolf' 'john'}
|
||||
~zod/try=> (~(gas in b) `(list ,@t)`['14' 'things' 'number' '1.337' ~])
|
||||
{'1.337' '14' 'number' 'things' 'bonita' 'madeleine' 'rudolf' 'john'}
|
||||
~zod/try=> (~(gas in s) `(list ,@t)`['1' '2' '3' ~])
|
||||
{'1' '3' '2' 'e' 'd' 'a' 'c' 'b'}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-has:in`
|
||||
|
||||
b in a?
|
||||
|
||||
+- has :: b exists in a check
|
||||
~/ %has
|
||||
|* b=*
|
||||
|- ^- ?
|
||||
?~ a
|
||||
|
|
||||
?: =(b n.a)
|
||||
&
|
||||
?: (hor b n.a)
|
||||
$(a l.a)
|
||||
$(a r.a)
|
||||
::
|
||||
|
||||
Checks if `b` is an element of `a`, producing a loobean.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [noun]().
|
||||
|
||||
~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
|
||||
~zod/try=> (~(has in a) `a`)
|
||||
%.y
|
||||
~zod/try=> (~(has in a) 'z')
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-int:in`
|
||||
|
||||
Intersection
|
||||
|
||||
+- int :: intersection
|
||||
~/ %int
|
||||
|* b=_a
|
||||
|- ^+ a
|
||||
?~ b
|
||||
~
|
||||
?~ a
|
||||
~
|
||||
?. (vor n.a n.b)
|
||||
$(a b, b a)
|
||||
?: =(n.b n.a)
|
||||
[n.a $(a l.a, b l.b) $(a r.a, b r.b)]
|
||||
?: (hor n.b n.a)
|
||||
%- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
|
||||
%- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
|
||||
|
||||
Produces a set of the intersection between two sets of the same type,
|
||||
`a` and `b`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [set]().
|
||||
|
||||
~zod/try=> (~(int in (sa "ac")) (sa "ha"))
|
||||
{~~a}
|
||||
~zod/try=> (~(int in (sa "acmo")) ~)
|
||||
{}
|
||||
~zod/try=> (~(int in (sa "acmo")) (sa "ham"))
|
||||
{~~a ~~m}
|
||||
~zod/try=> (~(int in (sa "acmo")) (sa "lep"))
|
||||
{}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-put:in`
|
||||
|
||||
Put b in a
|
||||
|
||||
+- put :: puts b in a
|
||||
~/ %put
|
||||
|* b=*
|
||||
|- ^+ a
|
||||
?~ a
|
||||
[b ~ ~]
|
||||
?: =(b n.a)
|
||||
a
|
||||
?: (hor b n.a)
|
||||
=+ c=$(a l.a)
|
||||
?> ?=(^ c)
|
||||
?: (vor n.a n.c)
|
||||
[n.a c r.a]
|
||||
[n.c l.c [n.a r.c r.a]]
|
||||
=+ c=$(a r.a)
|
||||
?> ?=(^ c)
|
||||
?: (vor n.a n.c)
|
||||
[n.a l.a c]
|
||||
[n.c [n.a l.a l.c] r.c]
|
||||
::
|
||||
|
||||
Add an element `b` to the set `a`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [noun]().
|
||||
|
||||
~zod/try=> =a (~(gas in `(set ,@t)`~) `(list ,@t)`[`a` `b` `c` ~])
|
||||
~zod/try=> =b (~(put in a) `d`)
|
||||
~zod/try=> b
|
||||
{`d` `a` `c` `b`}
|
||||
~zod/try=> -.l.+.b
|
||||
n=`d`
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-rep:in`
|
||||
|
||||
Accumulate
|
||||
|
||||
+- rep :: replace by tile
|
||||
|* [b=* c=_,*]
|
||||
|-
|
||||
?~ a b
|
||||
$(a r.a, b $(a l.a, b (c n.a b)))
|
||||
::
|
||||
|
||||
Accumulate the elements of `a` using a gate `c` and an accumulator `b`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [noun]() that accepts a noun and produces a loobean.
|
||||
|
||||
`c` is a [gate]().
|
||||
|
||||
~zod/try=> =a (~(gas in *(set ,@)) [1 2 3 ~])
|
||||
~zod/try=> a
|
||||
{1 3 2}
|
||||
~zod/try=> (~(rep in a) 0 |=([a=@ b=@] (add a b)))
|
||||
6
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-tap:in`
|
||||
|
||||
Set to list
|
||||
|
||||
+- tap :: list tiles a set
|
||||
~/ %tap
|
||||
|= b=(list ,_?>(?=(^ a) n.a))
|
||||
^+ b
|
||||
?~ a
|
||||
b
|
||||
$(a r.a, b [n.a $(a l.a)])
|
||||
::
|
||||
|
||||
Flatten the set `a` into a list.
|
||||
|
||||
`a` is an [set]().
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [list]().
|
||||
|
||||
~zod/try=> =s (sa `(list ,@t)`['a' 'b' 'c' 'd' 'e' ~])
|
||||
~zod/try=> s
|
||||
{'e' 'd' 'a' 'c' 'b'}
|
||||
~zod/try=> (~(tap in s) `(list ,@t)`['1' '2' '3' ~])
|
||||
~['b' 'c' 'a' 'd' 'e' '1' '2' '3']
|
||||
~zod/try=> b
|
||||
{'bonita' 'madeleine' 'daniel' 'john'}
|
||||
~zod/try=> (~(tap in b) `(list ,@t)`['david' 'people' ~])
|
||||
~['john' 'daniel' 'madeleine' 'bonita' 'david' 'people']
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-uni:in`
|
||||
|
||||
Union
|
||||
|
||||
+- uni :: union
|
||||
~/ %uni
|
||||
|* b=_a
|
||||
|- ^+ a
|
||||
?~ b
|
||||
a
|
||||
?~ a
|
||||
b
|
||||
?: (vor n.a n.b)
|
||||
?: =(n.b n.a)
|
||||
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
|
||||
?: (hor n.b n.a)
|
||||
$(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
|
||||
$(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
|
||||
?: =(n.a n.b)
|
||||
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
|
||||
?: (hor n.a n.b)
|
||||
$(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
|
||||
$(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
|
||||
|
||||
Produces a set of the union between two sets of the same type, `a` and
|
||||
`b`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a [set]().
|
||||
|
||||
~zod/try=> (~(uni in (sa "ac")) (sa "ha"))
|
||||
{~~a ~~c ~~h}
|
||||
~zod/try=> (~(uni in (sa "acmo")) ~)
|
||||
{~~a ~~c ~~m ~~o}
|
||||
~zod/try=> (~(uni in (sa "acmo")) (sa "ham"))
|
||||
{~~a ~~c ~~m ~~o ~~h}
|
||||
~zod/try=> (~(uni in (sa "acmo")) (sa "lep"))
|
||||
{~~e ~~a ~~c ~~m ~~l ~~o ~~p}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-wyt:in`
|
||||
|
||||
Set size
|
||||
|
||||
+- wyt :: size of set
|
||||
|- ^- @
|
||||
?~(a 0 +((add $(a l.a) $(a r.a))))
|
||||
|
||||
Produce the number of elements in set `a` as an atom.
|
||||
|
||||
`a` is an [set]().
|
||||
|
||||
~zod/try=> =a (~(put in (~(put in (sa)) 'a')) 'b')
|
||||
~zod/try=> ~(wyt in a)
|
||||
2
|
||||
~zod/try=> b
|
||||
{'bonita' 'madeleine' 'daniel' 'john'}
|
||||
~zod/try=> ~(wyt in b)
|
||||
4
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,813 +0,0 @@
|
||||
section 2dB, maps
|
||||
=================
|
||||
|
||||
### `++ept`
|
||||
|
||||
Map invariant.
|
||||
|
||||
++ ept :: map invariant
|
||||
|= a=(tree ,[p=* q=*])
|
||||
?~ a
|
||||
&
|
||||
?& ?~(l.a & ?&((vor p.n.a p.n.l.a) (hor p.n.l.a p.n.a)))
|
||||
?~(r.a & ?&((vor p.n.a p.n.r.a) (hor p.n.a p.n.r.a)))
|
||||
==
|
||||
|
||||
Computes whether `a` is a [map](), producing a loobean.
|
||||
|
||||
`a` is a [tree]().
|
||||
|
||||
~zod/try=> m
|
||||
{[p='d' q=5] [p='a' q=1] [p='c' q=4] [p='b' q=[2 3]]}
|
||||
~zod/try=> (ept m)
|
||||
%.y
|
||||
~zod/try=> b
|
||||
{'bonita' 'madeleine' 'daniel' 'john'}
|
||||
~zod/try=> (ept b)
|
||||
! type-fail
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ja`
|
||||
|
||||
Jar engine
|
||||
|
||||
++ ja :: jar engine
|
||||
|/ a=(jar)
|
||||
|
||||
A container arm for `++jar` operation arms. A `++jar` is a `++map` of
|
||||
`++list`s. The contained arms inherit the [sample]() jar.
|
||||
|
||||
`a` is a [jar]().
|
||||
|
||||
~zod/try=> ~(. ja (mo (limo a/"ho" b/"he" ~)))
|
||||
<2.dgz [nlr([p={%a %b} q=""]) <414.fvk 101.jzo 1.ypj %164>]>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-get:ja`
|
||||
|
||||
Grab value by key
|
||||
|
||||
+- get :: grab value by key
|
||||
|* b=*
|
||||
=+ c=(~(get by a) b)
|
||||
?~(c ~ u.c)
|
||||
|
||||
Produces a list retrieved from jar `a` using the key `b`.
|
||||
|
||||
`a` is a [`++jar`](/doc/hoon/library/1#++jar).
|
||||
|
||||
`b` is a key of the same type as the keys in `a`.
|
||||
|
||||
~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
|
||||
~zod/try=> l
|
||||
{[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
|
||||
~zod/try=> (~(get ja l) 'a')
|
||||
~[1 2 3]
|
||||
~zod/try=> (~(get ja l) 'b')
|
||||
~[4 5 6]
|
||||
~zod/try=> (~(get ja l) 'c')
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-add:ja`
|
||||
|
||||
Prepend to list
|
||||
|
||||
+- add :: adds key-list pair
|
||||
|* [b=* c=*]
|
||||
=+ d=(get(+< a) b)
|
||||
(~(put by a) b [c d])
|
||||
|
||||
Produces jar `a` with value `c` prepended to the list located at key
|
||||
`b`.
|
||||
|
||||
`a` is a [jar]().
|
||||
|
||||
`b` is a key of the same type as the keys in `a`.
|
||||
|
||||
`c` is a value of the same type as the values in `a`.
|
||||
|
||||
~zod/try=> =l (mo `(list ,[@t (list ,@)])`[['a' `(list ,@)`[1 2 3 ~]] ['b' `(list ,@)`[4 5 6 ~]] ~])
|
||||
~zod/try=> l
|
||||
{[p='a' q=~[1 2 3]] [p='b' q=~[4 5 6]]}
|
||||
~zod/try=> (~(add ja l) 'b' 7)
|
||||
{[p='a' q=~[1 2 3]] [p='b' q=~[7 4 5 6]]}
|
||||
~zod/try=> (~(add ja l) 'a' 100)
|
||||
{[p='a' q=~[100 1 2 3]] [p='b' q=~[4 5 6]]}
|
||||
~zod/try=> (~(add ja l) 'c' 7)
|
||||
{[p='a' q=~[1 2 3]] [p='c' q=~[7]] [p='b' q=~[4 5 6]]}
|
||||
~zod/try=> (~(add ja l) 'c' `(list ,@)`[7 8 9 ~])
|
||||
! type-fail
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ju`
|
||||
|
||||
Jug operations
|
||||
|
||||
++ ju :: jug engine
|
||||
|/ a=(jug)
|
||||
|
||||
Container arm for jug operation arms. A `++jug` is a `++map` of
|
||||
`++sets`. The contained arms inherit its [sample]() jug, `a`.
|
||||
|
||||
`a` is a [jug]().
|
||||
|
||||
~zod/try=> ~(. ju (mo (limo a/(sa "ho") b/(sa "he") ~)))
|
||||
<2.dgz [nlr([p={%a %b} q={nlr(^$1{@tD $1}) nlr(^$3{@tD $3})}]) <414.fvk 101.jzo 1.ypj %164>]>
|
||||
|
||||
### `+-del:ju`
|
||||
|
||||
Remove
|
||||
|
||||
+- del :: delete at key b
|
||||
|* [b=* c=*]
|
||||
^+ a
|
||||
=+ d=(get(+< a) b)
|
||||
=+ e=(~(del in d) c)
|
||||
?~ e
|
||||
(~(del by a) b)
|
||||
(~(put by a) b e)
|
||||
|
||||
Produces jug `a` with value `c` removed from set located at key `b`.
|
||||
|
||||
`a` is a [jug]().
|
||||
|
||||
`b` is a key of the same type as the keys in `a`.
|
||||
|
||||
`c` is the value of the same type of the keys in `a` that is to be
|
||||
removed.
|
||||
|
||||
~zod/try=> s
|
||||
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(del ju s) 'a' 1)
|
||||
{[p='a' q={3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(del ju s) 'c' 7)
|
||||
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-get:ju`
|
||||
|
||||
Retrieve set
|
||||
|
||||
+- get :: gets set by key
|
||||
|* b=*
|
||||
=+ c=(~(get by a) b)
|
||||
?~(c ~ u.c)
|
||||
|
||||
Produces a set retrieved from jar `a` using key `b`.
|
||||
|
||||
`a` is a [jar]().
|
||||
|
||||
`b` is a key of the same type as the keys in `a`.
|
||||
|
||||
~zod/try=> s
|
||||
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(get ju s) 'a')
|
||||
{1 3 2}
|
||||
~zod/try=> (~(get ju s) 'b')
|
||||
{5 4 6}
|
||||
~zod/try=> (~(get ju s) 'c')
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-has:ju`
|
||||
|
||||
Check contents
|
||||
|
||||
+- has :: existence check
|
||||
|* [b=* c=*]
|
||||
^- ?
|
||||
(~(has in (get(+< a) b)) c)
|
||||
|
||||
Computes whether a value `c` exists within the set located at key `b`
|
||||
with jar `a`. Produces a loobean.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a key as a [noun]().
|
||||
|
||||
`c` is a value as a [noun]().
|
||||
|
||||
~zod/try=> s
|
||||
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(has ju s) 'a' 3)
|
||||
%.y
|
||||
~zod/try=> (~(has ju s) 'b' 6)
|
||||
%.y
|
||||
~zod/try=> (~(has ju s) 'a' 7)
|
||||
%.n
|
||||
~zod/try=> (~(has jus s) 'c' 7)
|
||||
! -find-limb.jus
|
||||
! find-none
|
||||
! exit
|
||||
~zod/try=> (~(has ju s) 'c' 7)
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-put:ju`
|
||||
|
||||
Add key-set pair
|
||||
|
||||
+- put :: adds key-element pair
|
||||
|* [b=* c=*]
|
||||
^+ a
|
||||
=+ d=(get(+< a) b)
|
||||
(~(put by a) b (~(put in d) c))
|
||||
|
||||
Produces jar `a` with `c` added to the set value located at key `b`.
|
||||
|
||||
`a` is a [set]().
|
||||
|
||||
`b` is a key as a [noun]().
|
||||
|
||||
`c` is a [value]().
|
||||
|
||||
~zod/try=> s
|
||||
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(put ju s) 'a' 7)
|
||||
{[p='a' q={7 1 3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(put ju s) 'a' 1)
|
||||
{[p='a' q={1 3 2}] [p='b' q={5 4 6}]}
|
||||
~zod/try=> (~(put ju s) 'c' 7)
|
||||
{[p='a' q={1 3 2}] [p='c' q={7}] [p='b' q={5 4 6}]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++by`
|
||||
|
||||
Map operations
|
||||
|
||||
++ by :: map engine
|
||||
~/ %by
|
||||
|/ a=(map)
|
||||
|
||||
Container arm for map operation arms. A map is a set of key, value
|
||||
pairs. The contained arms inherit it's [sample]() [map](), `a`.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
~zod/try=> ~(. by (mo (limo [%a 1] [%b 2] ~)))
|
||||
<19.irb [nlr([p={%a %b} q=@ud]) <414.rvm 101.jzo 1.ypj %164>]>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-all:by`
|
||||
|
||||
Logical AND
|
||||
|
||||
+- all :: logical AND
|
||||
~/ %all
|
||||
|* b=$+(* ?)
|
||||
|- ^- ?
|
||||
?~ a
|
||||
&
|
||||
?&((b q.n.a) $(a l.a) $(a r.a))
|
||||
|
||||
Computes the logical AND on the results of slamming every element in map
|
||||
`a` with gate `b`. Produces a loobean.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [wet gate]().
|
||||
|
||||
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
|
||||
%.n
|
||||
~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
|
||||
~zod/try=> (~(all by a) |=(a=@ (lte a 6)))
|
||||
%.y
|
||||
~zod/try=> (~(all by a) |=(a=@ (lte a 4)))
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-any:by`
|
||||
|
||||
Logical OR
|
||||
|
||||
+- any :: logical OR
|
||||
~/ %any
|
||||
|* b=$+(* ?)
|
||||
|- ^- ?
|
||||
?~ a
|
||||
|
|
||||
?|((b q.n.a) $(a l.a) $(a r.a))
|
||||
|
||||
Computes the logical OR on the results of slamming every element with
|
||||
gate `b`. Produces a loobean.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [wet gate]().
|
||||
|
||||
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(all by b) |=(a=* ?@(a & |)))
|
||||
%.y
|
||||
~zod/try=> =a (mo `(list ,[@t @u])`[['a' 1] ['b' 2] ['c' 3] ['d' 4] ['e' 5] ~])
|
||||
~zod/try=> (~(any by a) |=(a=@ (lte a 4)))
|
||||
%.y
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-del:by`
|
||||
|
||||
Delete
|
||||
|
||||
+- del :: delete at key b
|
||||
~/ %del
|
||||
|* b=*
|
||||
|- ^+ a
|
||||
?~ a
|
||||
~
|
||||
?. =(b p.n.a)
|
||||
?: (gor b p.n.a)
|
||||
[n.a $(a l.a) r.a]
|
||||
[n.a l.a $(a r.a)]
|
||||
|- ^- ?(~ _a)
|
||||
?~ l.a r.a
|
||||
?~ r.a l.a
|
||||
?: (vor p.n.l.a p.n.r.a)
|
||||
[n.l.a l.l.a $(l.a r.l.a)]
|
||||
[n.r.a $(r.a l.r.a) r.r.a]
|
||||
|
||||
Produces map `a` with the element located at key `b` removed.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a key as a [noun]().
|
||||
|
||||
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(del by b) `a`)
|
||||
{[p=`b` q=[2 3]]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-dig:by`
|
||||
|
||||
Axis of key
|
||||
|
||||
+- dig :: axis of key
|
||||
|= b=*
|
||||
=+ c=1
|
||||
|- ^- (unit ,@)
|
||||
?~ a ~
|
||||
?: =(b p.n.a) [~ u=(peg c 2)]
|
||||
?: (gor b p.n.a)
|
||||
$(a l.a, c (peg c 6))
|
||||
$(a r.a, c (peg c 7))
|
||||
|
||||
Produce the axis of key `b` within map `a`.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a key as a [noun]().
|
||||
|
||||
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(dig by b) `b`)
|
||||
[~ 2]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-gas:by`
|
||||
|
||||
Concatenate
|
||||
|
||||
+- gas :: concatenate
|
||||
~/ %gas
|
||||
|* b=(list ,[p=* q=*])
|
||||
=> .(b `(list ,_?>(?=(^ a) n.a))`b)
|
||||
|- ^+ a
|
||||
?~ b
|
||||
a
|
||||
$(b t.b, a (put(+< a) p.i.b q.i.b))
|
||||
|
||||
Insert a list of key-value pairs `b` into map `a`.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [list]() of [cells]() of key-value nouns `p` and `q`.
|
||||
|
||||
~zod/try=> =a (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
|
||||
~zod/try=> =b `(list ,[@t *])`[[`c` 3] [`d` 4] ~]
|
||||
~zod/try=> (~(gas by a) b)
|
||||
{[p=`d` q=4] [p=`a` q=1] [p=`c` q=3] [p=`b` q=2]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-get:by`
|
||||
|
||||
Grab unit value
|
||||
|
||||
+- get :: unit value by key
|
||||
~/ %get
|
||||
|* b=*
|
||||
|- ^- ?(~ [~ u=_?>(?=(^ a) q.n.a)])
|
||||
?~ a
|
||||
~
|
||||
?: =(b p.n.a)
|
||||
[~ u=q.n.a]
|
||||
?: (gor b p.n.a)
|
||||
$(a l.a)
|
||||
$(a r.a)
|
||||
|
||||
Produce the unit value of the value located at key `b` within map `a`.
|
||||
|
||||
`a` is a [map]()
|
||||
|
||||
`b` is a [key]() as a [noun]()
|
||||
|
||||
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(get by b) `b`)
|
||||
[~ [2 3]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-got:by`
|
||||
|
||||
Assert
|
||||
|
||||
+- got
|
||||
|* b=*
|
||||
%- need
|
||||
%- get(+< a) b
|
||||
|
||||
Produce the value located at key `b` within map `a`. Crash if key `b`
|
||||
does not exist.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [key]().
|
||||
|
||||
~zod/try=> =m (mo `(list ,[@t *])`[['a' 1] ['b' 2] ~])
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> (~(get by m) 'a')
|
||||
[~ 1]
|
||||
~zod/try=> (~(got by m) 'a')
|
||||
1
|
||||
~zod/try=> (~(got by m) 'c')
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-has:by`
|
||||
|
||||
Key existence check
|
||||
|
||||
+- has :: key existence check
|
||||
~/ %has
|
||||
|* b=*
|
||||
!=(~ (get(+< a) b))
|
||||
|
||||
Checks whether map `a` contains an element with key `b`, producing a
|
||||
loobean.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a key as a [noun]().
|
||||
|
||||
~zod/try=> =b (mo `(list ,[@t *])`[['a' 1] ['b' [2 3]] ~])
|
||||
~zod/try=> (~(has by b) `b`)
|
||||
%.y
|
||||
~zod/try=> (~(has by b) `c`)
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-int:by`
|
||||
|
||||
Intersection
|
||||
|
||||
+- int :: intersection
|
||||
~/ %int
|
||||
|* b=_a
|
||||
|- ^+ a
|
||||
?~ b
|
||||
~
|
||||
?~ a
|
||||
~
|
||||
?: (vor p.n.a p.n.b)
|
||||
?: =(p.n.b p.n.a)
|
||||
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
|
||||
?: (hor p.n.b p.n.a)
|
||||
%- uni(+< $(a l.a, b [n.b l.b ~])) $(b r.b)
|
||||
%- uni(+< $(a r.a, b [n.b ~ r.b])) $(b l.b)
|
||||
?: =(p.n.a p.n.b)
|
||||
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
|
||||
?: (hor p.n.a p.n.b)
|
||||
%- uni(+< $(b l.b, a [n.a l.a ~])) $(a r.a)
|
||||
%- uni(+< $(b r.b, a [n.a ~ r.a])) $(a l.a)
|
||||
|
||||
Produces a map of the (key) intersection between two maps of the same
|
||||
type, `a` and `b`. If both maps have an identical key that point to
|
||||
different values, the element from map `b` is used.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [map]().
|
||||
|
||||
~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 3] ~])
|
||||
~zod/try=> n
|
||||
{[p='a' q=1] [p='c' q=3]}
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> (~(int by m) n)
|
||||
{[p='a' q=1]}
|
||||
~ravpel-holber/try=> =p (mo `(list ,[@t *])`[['a' 2] ['b' 2] ~])
|
||||
~zod/try=> p
|
||||
{[p='a' q=2] [p='b' q=2]}
|
||||
~zod/try=> (~(int by p) n)
|
||||
{[p='a' q=2]}
|
||||
~zod/try=> =q (mo `(list ,[@t *])`[['a' 2] ['c' 2] ~])
|
||||
~zod/try=> q
|
||||
{[p='a' q=2] [p='b' q=2]}
|
||||
~zod/try=> (~(int by p) q)
|
||||
{[p='a' q=2] [p='b' q=2]}
|
||||
~zod/try=> =o (mo `(list ,[@t *])`[['c' 3] ['d' 4] ~])
|
||||
~zod/try=> (~(int by m) o)
|
||||
{}
|
||||
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-mar:by`
|
||||
|
||||
Assert and Add
|
||||
|
||||
+- mar :: add with validation
|
||||
|* [b=_?>(?=(^ a) p.n.a) c=(unit ,_?>(?=(^ a) q.n.a))]
|
||||
?~ c
|
||||
(del b)
|
||||
(put b u.c)
|
||||
|
||||
Produces map `a` with the addition of a key-value pair, where the value
|
||||
is a nonempty unit.
|
||||
|
||||
Accept a noun and a unit of a noun of the type of the map's keys and
|
||||
values, respectively. Validate that the value is not null and put the
|
||||
pair in the map. If the value is null, delete the key.
|
||||
|
||||
XX This arm is broken, asana task 15186618346453
|
||||
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> (~(mar by m) 'c' (some 3))
|
||||
! -find-limb.n
|
||||
! find-none
|
||||
! exit
|
||||
~zod/try=> (~(mar by m) 'c' ~)
|
||||
! -find-limb.n
|
||||
! find-none
|
||||
! exit
|
||||
~zod/try=> (~(mar by m) 'b' ~)
|
||||
! -find-limb.n
|
||||
! find-none
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-put:by`
|
||||
|
||||
Add key-value pair
|
||||
|
||||
+- put :: adds key-value pair
|
||||
~/ %put
|
||||
|* [b=* c=*]
|
||||
|- ^+ a
|
||||
?~ a
|
||||
[[b c] ~ ~]
|
||||
?: =(b p.n.a)
|
||||
?: =(c q.n.a)
|
||||
a
|
||||
[[b c] l.a r.a]
|
||||
?: (gor b p.n.a)
|
||||
=+ d=$(a l.a)
|
||||
?> ?=(^ d)
|
||||
?: (vor p.n.a p.n.d)
|
||||
[n.a d r.a]
|
||||
[n.d l.d [n.a r.d r.a]]
|
||||
=+ d=$(a r.a)
|
||||
?> ?=(^ d)
|
||||
?: (vor p.n.a p.n.d)
|
||||
[n.a l.a d]
|
||||
[n.d [n.a l.a l.d] r.d]
|
||||
|
||||
Produces `a` with the addition of the key-value pair of `b` and `c`.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a key of the same type as the keys in `a`.
|
||||
|
||||
`c` is a value of the same type of the values in `a`.
|
||||
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> (~(put by m) 'c' 3)
|
||||
{[p='a' q=1] [p='c' q=3] [p='b' q=2]}
|
||||
~zod/try=> (~(put by m) "zod" 26)
|
||||
! type-fail
|
||||
! exit
|
||||
~zod/try=> (~(put by m) 'a' 2)
|
||||
{[p='a' q=2] [p='b' q=2]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-rep:by`
|
||||
|
||||
+- rep :: replace by product
|
||||
|* [b=* c=_,*]
|
||||
|-
|
||||
?~ a b
|
||||
$(a r.a, b $(a l.a, b (c q.n.a b)))
|
||||
|
||||
Accumulate using gate from values in map
|
||||
|
||||
XX interface changing.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-rib:by`
|
||||
|
||||
+- rib :: transform + product
|
||||
|* [b=* c=_,*]
|
||||
|- ^+ [b a]
|
||||
?~ a [b ~]
|
||||
=+ d=(c n.a b)
|
||||
=. n.a +.d
|
||||
=+ e=$(a l.a, b -.d)
|
||||
=+ f=$(a r.a, b -.e)
|
||||
[-.f [n.a +.e +.f]]
|
||||
|
||||
Replace values with accumulator
|
||||
|
||||
XX interface changing, possibly disappearing
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-run:by`
|
||||
|
||||
Transform values
|
||||
|
||||
+- run :: turns to tuples
|
||||
|* b=_,*
|
||||
|-
|
||||
?~ a a
|
||||
a(n (b q.n.a), l $(a l.a), r $(a r.a))
|
||||
|
||||
Iterates over every value in set `a` using gate `b`. Produces a map.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [wet gate]().
|
||||
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> ^+(m (~(run by m) dec))
|
||||
{[p='a' q=0] [p='b' q=1]}
|
||||
~zod/try=> `(map ,@tas ,@t)`(~(run by m) (cury scot %ux))
|
||||
{[p=%a q='0x1'] [p=%b q='0x2']}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-tap:by`
|
||||
|
||||
Listify pairs
|
||||
|
||||
+- tap :: listify pairs
|
||||
~/ %tap
|
||||
|= b=(list ,_?>(?=(^ a) n.a))
|
||||
^+ b
|
||||
?~ a
|
||||
b
|
||||
$(a r.a, b [n.a $(a l.a)])
|
||||
|
||||
Produces the list of all elements in map `a` that is prepended to list
|
||||
`b`, which is empty by default.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [list]().
|
||||
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> `*`m
|
||||
[[98 2] [[97 1] 0 0] 0]
|
||||
~zod/try=> (~(tap by m))
|
||||
~[[p='b' q=2] [p='a' q=1]]
|
||||
~zod/try=> `*`(~(tap by m))
|
||||
[[98 2] [97 1] 0]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-uni:by`
|
||||
|
||||
Union
|
||||
|
||||
+- uni :: union, merge
|
||||
~/ %uni
|
||||
|* b=_a
|
||||
|- ^+ a
|
||||
?~ b
|
||||
a
|
||||
?~ a
|
||||
b
|
||||
?: (vor p.n.a p.n.b)
|
||||
?: =(p.n.b p.n.a)
|
||||
[n.b $(a l.a, b l.b) $(a r.a, b r.b)]
|
||||
?: (hor p.n.b p.n.a)
|
||||
$(a [n.a $(a l.a, b [n.b l.b ~]) r.a], b r.b)
|
||||
$(a [n.a l.a $(a r.a, b [n.b ~ r.b])], b l.b)
|
||||
?: =(p.n.a p.n.b)
|
||||
[n.b $(b l.b, a l.a) $(b r.b, a r.a)]
|
||||
?: (hor p.n.a p.n.b)
|
||||
$(b [n.b $(b l.b, a [n.a l.a ~]) r.b], a r.a)
|
||||
$(b [n.b l.b $(b r.b, a [n.a ~ r.a])], a l.a)
|
||||
|
||||
Produces a map of the union between the keys of `a` and `b`. If `b`
|
||||
shares a key with `a`, the tuple from `a` is preserved.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [map]().
|
||||
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> o
|
||||
{[p='d' q=4] [p='c' q=3]}
|
||||
~zod/try=> (~(uni by m) o)
|
||||
{[p='d' q=4] [p='a' q=1] [p='c' q=3] [p='b' q=2]}
|
||||
~zod/try=> (~(uni by m) ~)
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> n
|
||||
{[p='a' q=1] [p='c' q=9]}
|
||||
~zod/try=> (~(uni by o) n)
|
||||
{[p='d' q=4] [p='a' q=1] [p='c' q=3]}
|
||||
~zod/try=> =n (mo `(list ,[@t *])`[['a' 1] ['c' 9] ~])
|
||||
~zod/try=> n
|
||||
{[p='a' q=1] [p='c' q=9]}
|
||||
~zod/try=> (~(uni by o) n)
|
||||
{[p='d' q=4] [p='a' q=1] [p='c' q=9]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-urn:by`
|
||||
|
||||
Turn (with key)
|
||||
|
||||
+- urn :: turn
|
||||
|* b=$+([* *] *)
|
||||
|-
|
||||
?~ a ~
|
||||
[n=[p=p.n.a q=(b p.n.a q.n.a)] l=$(a l.a) r=$(a r.a)]
|
||||
|
||||
Iterates over every value in map `a` using gate `b`, which accepts both
|
||||
the key and the value of each element as its sample.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
`b` is a [wet gate]() that accepts two nouns (a key and a value) and
|
||||
produces a noun (the new value).
|
||||
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> (~(urn by m) |=(a=[p=* q=*] q.a))
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> (~(urn by m) |=(a=[p=* q=*] 7))
|
||||
{[p='a' q=7] [p='b' q=7]}
|
||||
~zod/try=> (~(urn by m) |=(a=[p=* q=*] p.a))
|
||||
{[p='a' q=97] [p='b' q=98]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-wyt:by`
|
||||
|
||||
Depth
|
||||
|
||||
+- wyt :: depth of map
|
||||
|- ^- @
|
||||
?~(a 0 +((add $(a l.a) $(a r.a))))
|
||||
|
||||
Produce the depth of the tree map `a`.
|
||||
|
||||
`a` is a [map]().
|
||||
|
||||
~zod/try=> m
|
||||
{[p='a' q=1] [p='b' q=2]}
|
||||
~zod/try=> o
|
||||
{[p='d' q=4] [p='c' q=3]}
|
||||
~zod/try=> ~(wyt by m)
|
||||
2
|
||||
~zod/try=> ~(wyt by o)
|
||||
2
|
||||
~zod/try=> ~(wyt by (~(uni by m) o))
|
||||
4
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,221 +0,0 @@
|
||||
section 2dC, queues
|
||||
===================
|
||||
|
||||
### `++to`
|
||||
|
||||
Queue engine
|
||||
|
||||
++ to :: queue engine
|
||||
|/ a=(qeu)
|
||||
|
||||
Container arm for queue operation arms. The contained arms inherit its
|
||||
[sample]() `++qeu` `a`.
|
||||
|
||||
`a` is a queue, [++qeu]().
|
||||
|
||||
### `+-bal:to`
|
||||
|
||||
Balance
|
||||
|
||||
+- bal
|
||||
|- ^+ a
|
||||
?~ a ~
|
||||
?. |(?=(~ l.a) (vor n.a n.l.a))
|
||||
$(a [n.l.a l.l.a $(a [n.a r.l.a r.a])])
|
||||
?. |(?=(~ r.a) (vor n.a n.r.a))
|
||||
$(a [n.r.a $(a [n.a l.a l.r.a]) r.r.a])
|
||||
a
|
||||
::
|
||||
|
||||
Vertically rebalances queue `a`.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
~zod/try=> `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
|
||||
{"a" "b" "c" "d" "e" "f" "g"}
|
||||
~zod/try=> `*`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]
|
||||
[[97 0] 0 [98 0] 0 [99 0] 0 [100 0] 0 [101 0] 0 [102 0] 0 [103 0] 0 0]
|
||||
~zod/try=> ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
|
||||
{"a" "b" "c" "d" "e" "f" "g"}
|
||||
~zod/try=> `*`~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
|
||||
[[100 0] [[99 0] [[98 0] [[97 0] 0 0] 0] 0] [101 0] 0 [102 0] 0 [103 0] 0 0]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-dep:to`
|
||||
|
||||
Maximum Depth
|
||||
|
||||
+- dep :: max depth of queue
|
||||
|- ^- @
|
||||
?~ a 0
|
||||
+((max $(a l.a) $(a r.a)))
|
||||
::
|
||||
|
||||
Produces the maximum depth of leaves (r.a and l.a) in queue `a`.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 7 ~])
|
||||
~zod/try=> ~(dep to a)
|
||||
4
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 ~])
|
||||
~zod/try=> ~(dep to a)
|
||||
3
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 ~])
|
||||
~zod/try=> ~(dep to a)
|
||||
2
|
||||
~zod/try=> ~(dep to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~])
|
||||
7
|
||||
~zod/try=> ~(dep to ~(bal to `(qeu tape)`["a" ~ "b" ~ "c" ~ "d" ~ "e" ~ "f" ~ "g" ~ ~]))
|
||||
4
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-gas`
|
||||
|
||||
Push list
|
||||
|
||||
+- gas :: insert list to queue
|
||||
|= b=(list ,_?>(?=(^ a) n.a))
|
||||
|- ^+ a
|
||||
?~(b a $(b t.b, a (put(+< a) i.b)))
|
||||
::
|
||||
|
||||
Push all elements of list `b` into the queue.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
`b` is a list.
|
||||
|
||||
~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
|
||||
{3 2 1}
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 ~])
|
||||
~zod/try=> =b `(list ,@)`[4 5 6 ~]
|
||||
~zod/try=> (~(gas to a) b)
|
||||
{6 5 4 3 2 1}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-get:to`
|
||||
|
||||
Pop
|
||||
|
||||
+- get :: head-tail pair
|
||||
|- ^+ [p=?>(?=(^ a) n.a) q=a]
|
||||
?~ a
|
||||
!!
|
||||
?~ r.a
|
||||
[n.a l.a]
|
||||
=+ b=$(a r.a)
|
||||
:- p.b
|
||||
?: |(?=(~ q.b) (vor n.a n.q.b))
|
||||
[n.a l.a q.b]
|
||||
[n.q.b [n.a l.a l.q.b] r.q.b]
|
||||
::
|
||||
|
||||
Produces the head and tail queue of `a`.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
~zod/try=> =s (~(gas to *(qeu ,@)) `(list ,@)`~[1 2 3])
|
||||
~zod/try=> ~(get to s)
|
||||
[p=1 q={3 2}]
|
||||
~zod/try=> ~(get to ~)
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-nap:to`
|
||||
|
||||
Remove last in
|
||||
|
||||
+- nap :: removes head
|
||||
?> ?=(^ a)
|
||||
?: =(~ l.a) r.a
|
||||
=+ b=get(+< l.a)
|
||||
bal(+< ^+(a [p.b q.b r.a]))
|
||||
::
|
||||
|
||||
Removes the head of queue `a`, producing the resulting queue.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
|
||||
~zod/try=> -.a
|
||||
n=6
|
||||
~zod/try=> =b ~(nap to a)
|
||||
~zod/try=> -.b
|
||||
n=2
|
||||
~zod/try=> b
|
||||
{5 4 3 2 1}
|
||||
~zod/try=> a
|
||||
{6 5 4 3 2 1}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-put:to`
|
||||
|
||||
Insert
|
||||
|
||||
+- put :: insert new tail
|
||||
|* b=*
|
||||
|- ^+ a
|
||||
?~ a
|
||||
[b ~ ~]
|
||||
bal(+< a(l $(a l.a)))
|
||||
::
|
||||
|
||||
Accept any noun `b` and adds to queue `a` as the head, producing the
|
||||
resulting queue.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
`b` is any noun.
|
||||
|
||||
~zod/try=> (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
|
||||
~zod/try=> (~(put to a) 7)
|
||||
{7 6 5 4 2 1 3}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-tap:to`
|
||||
|
||||
Queue to list
|
||||
|
||||
+- tap :: queue to list
|
||||
|= b=(list ,_?>(?=(^ a) n.a))
|
||||
^+ b
|
||||
?~ a
|
||||
b
|
||||
$(a r.a, b [n.a $(a l.a)])
|
||||
::
|
||||
|
||||
Produces queue `a` as a list from front to back.
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[3 1 2 4 5 6 ~])
|
||||
~zod/try=> `*`a
|
||||
[6 0 2 [4 [5 0 0] 0] 1 0 3 0 0]
|
||||
~zod/try=> (~(tap to a) `(list ,@)`[99 100 101 ~])
|
||||
~[3 1 2 4 5 6 99 100 101]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `+-top:to`
|
||||
|
||||
+- top :: produces head
|
||||
|- ^- (unit ,_?>(?=(^ a) n.a))
|
||||
?~ a ~
|
||||
?~(r.a [~ n.a] $(a r.a))
|
||||
|
||||
Produces the head of queue `a` as a unit (an empty queue has no head).
|
||||
|
||||
`a` is a [queue]().
|
||||
|
||||
~zod/try=> =a (~(gas to `(qeu ,@)`~) `(list ,@)`[1 2 3 4 5 6 ~])
|
||||
~zod/try=> ~(top to a)
|
||||
[~ 1]
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,69 +0,0 @@
|
||||
section 2dD, casual containers
|
||||
==============================
|
||||
|
||||
### `++mo`
|
||||
|
||||
Map from list
|
||||
|
||||
++ mo :: map from list
|
||||
|* a=(list)
|
||||
=> .(a `_(homo a)`a)
|
||||
=> .(a `(list ,[p=_-<.a q=_->.a])`a)
|
||||
=+ b=*(map ,_?>(?=(^ a) p.i.a) ,_?>(?=(^ a) q.i.a))
|
||||
(~(gas by b) a)
|
||||
::
|
||||
|
||||
Produces a map of key-value pairs from the left-right cell pairs of list
|
||||
`a`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
~zod/try=> (mo `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
|
||||
{[p=`a` q=1] [p=`b` q=2]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sa`
|
||||
|
||||
Set from list
|
||||
|
||||
++ sa :: set from list
|
||||
|* a=(list)
|
||||
=> .(a `_(homo a)`a)
|
||||
=+ b=*(set ,_?>(?=(^ a) i.a))
|
||||
(~(gas in b) a)
|
||||
::
|
||||
|
||||
Produces a set of the elements in list `a`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
~zod/try=> (sa `(list ,@)`[1 2 3 4 5 ~])
|
||||
{5 4 1 3 2}
|
||||
~zod/try=> (sa `(list ,[@t *])`[[`a` 1] [`b` 2] ~])
|
||||
{[`a` 1] [`b` 2]}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++qu`
|
||||
|
||||
Queue from list
|
||||
|
||||
++ qu :: queue from list
|
||||
|* a=(list)
|
||||
=> .(a `_(homo a)`a)
|
||||
=+ b=*(qeu ,_?>(?=(^ a) i.a))
|
||||
(~(gas to b) a)
|
||||
|
||||
Produces a queue from list `a`.
|
||||
|
||||
`a` is a [list]().
|
||||
|
||||
~zod/try=> (qu `(list ,@ud)`~[1 2 3 5])
|
||||
{5 3 2 1}
|
||||
~zod/try=> (qu "sada")
|
||||
{'a' 'd' 'a' 's'}
|
||||
~zod/try=> ~(top to (qu "sada"))
|
||||
[~ 's']
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,162 +0,0 @@
|
||||
section 2eA, packing
|
||||
====================
|
||||
|
||||
### `++cue`
|
||||
|
||||
Unpack atom to noun
|
||||
|
||||
++ cue :: unpack atom to noun
|
||||
~/ %cue
|
||||
|= a=@
|
||||
^- *
|
||||
=+ b=0
|
||||
=+ m=`(map ,@ ,*)`~
|
||||
=< q
|
||||
|- ^- [p=@ q=* r=_m]
|
||||
?: =(0 (cut 0 [b 1] a))
|
||||
=+ c=(rub +(b) a)
|
||||
[+(p.c) q.c (~(put by m) b q.c)]
|
||||
=+ c=(add 2 b)
|
||||
?: =(0 (cut 0 [+(b) 1] a))
|
||||
=+ u=$(b c)
|
||||
=+ v=$(b (add p.u c), m r.u)
|
||||
=+ w=[q.u q.v]
|
||||
[(add 2 (add p.u p.v)) w (~(put by r.v) b w)]
|
||||
=+ d=(rub c a)
|
||||
[(add 2 p.d) (need (~(get by m) q.d)) m]
|
||||
::
|
||||
|
||||
Produces a noun unpacked from atom `a`. The inverse of jam.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
~zod/try=> (cue 12)
|
||||
1
|
||||
~zod/try=> (cue 817)
|
||||
[1 1]
|
||||
~zod/try=> (cue 4.657)
|
||||
[1 2]
|
||||
~zod/try=> (cue 39.689)
|
||||
[0 19]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++jam`
|
||||
|
||||
++ jam :: pack
|
||||
~/ %jam
|
||||
|= a=*
|
||||
^- @
|
||||
=+ b=0
|
||||
=+ m=`(map ,* ,@)`~
|
||||
=< q
|
||||
|- ^- [p=@ q=@ r=_m]
|
||||
=+ c=(~(get by m) a)
|
||||
?~ c
|
||||
=> .(m (~(put by m) a b))
|
||||
?: ?=(@ a)
|
||||
=+ d=(mat a)
|
||||
[(add 1 p.d) (lsh 0 1 q.d) m]
|
||||
=> .(b (add 2 b))
|
||||
=+ d=$(a -.a)
|
||||
=+ e=$(a +.a, b (add b p.d), m r.d)
|
||||
[(add 2 (add p.d p.e)) (mix 1 (lsh 0 2 (cat 0 q.d q.e))) r.e]
|
||||
?: ?&(?=(@ a) (lte (met 0 a) (met 0 u.c)))
|
||||
=+ d=(mat a)
|
||||
[(add 1 p.d) (lsh 0 1 q.d) m]
|
||||
=+ d=(mat u.c)
|
||||
[(add 2 p.d) (mix 3 (lsh 0 2 q.d)) m]
|
||||
::
|
||||
|
||||
Produces an atom unpacked from noun `a`. The inverse of cue.
|
||||
|
||||
`a` is a [noun]().
|
||||
|
||||
~zod/try=> (jam 1)
|
||||
12
|
||||
~zod/try=> (jam [1 1])
|
||||
817
|
||||
~zod/try=> (jam [1 2])
|
||||
4.657
|
||||
~zod/try=> (jam [~ u=19])
|
||||
39.689
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mat`
|
||||
|
||||
Length-encode
|
||||
|
||||
++ mat :: length-encode
|
||||
~/ %mat
|
||||
|= a=@
|
||||
^- [p=@ q=@]
|
||||
?: =(0 a)
|
||||
[1 1]
|
||||
=+ b=(met 0 a)
|
||||
=+ c=(met 0 b)
|
||||
:- (add (add c c) b)
|
||||
(cat 0 (bex c) (mix (end 0 (dec c) b) (lsh 0 (dec c) a)))
|
||||
|
||||
Produces a cell whose tail `q` is atom `a` with a bit representation of
|
||||
its length prepended to it (as the least significant bits). The head `p`
|
||||
is the length of `q` in bits.
|
||||
|
||||
`a` is an atom.
|
||||
|
||||
~zod/try=> (mat 0xaaa)
|
||||
[p=20 q=699.024]
|
||||
~zod/try=> (met 0 q:(mat 0xaaa))
|
||||
20
|
||||
~zod/try=> `@ub`q:(mat 0xaaa)
|
||||
0b1010.1010.1010.1001.0000
|
||||
~zod/try=> =a =-(~&(- -) `@ub`0xaaa)
|
||||
0b1010.1010.1010
|
||||
~zod/try=> =b =-(~&(- -) `@ub`(xeb a))
|
||||
0b1100
|
||||
~zod/try=> =b =-(~&(- -) `@ub`(met 0 a))
|
||||
0b1100
|
||||
~zod/try=> =c =-(~&(- -) (xeb b))
|
||||
4
|
||||
~zod/try=> [`@ub`a `@ub`(end 0 (dec c) b) `@ub`(bex c)]
|
||||
[0b1010.1010.1010 0b100 0b1.0000]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++rub`
|
||||
|
||||
Length-decode
|
||||
|
||||
++ rub :: length-decode
|
||||
~/ %rub
|
||||
|= [a=@ b=@]
|
||||
^- [p=@ q=@]
|
||||
=+ ^= c
|
||||
=+ [c=0 m=(met 0 b)]
|
||||
|- ?< (gth c m)
|
||||
?. =(0 (cut 0 [(add a c) 1] b))
|
||||
c
|
||||
$(c +(c))
|
||||
?: =(0 c)
|
||||
[1 0]
|
||||
=+ d=(add a +(c))
|
||||
=+ e=(add (bex (dec c)) (cut 0 [d (dec c)] b))
|
||||
[(add (add c c) e) (cut 0 [(add d (dec c)) e] b)]
|
||||
|
||||
The inverse of `++mat`. Accepts a cell of index `a` and a bitstring `b`
|
||||
and produces the cell whose tail `q` is the decoded atom at index `a`
|
||||
and whose head is the length of the encoded atom `q`, by which the
|
||||
offset `a` is advanced. Only used internally as a helper cue.
|
||||
|
||||
`a` is an atom.
|
||||
|
||||
`b` is a bitstring as an atom.
|
||||
|
||||
~zod/try=> `@ub`(jam 0xaaa)
|
||||
0b1.0101.0101.0101.0010.0000
|
||||
~zod/try=> (rub 1 0b1.0101.0101.0101.0010.0000)
|
||||
[p=20 q=2.730]
|
||||
~zod/try=> `@ux`q:(rub 1 0b1.0101.0101.0101.0010.0000)
|
||||
0xaaa
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,63 +0,0 @@
|
||||
section 2eB, parsing (tracing)
|
||||
==============================
|
||||
|
||||
### `++last`
|
||||
|
||||
Farther trace
|
||||
|
||||
++ last |= [zyc=hair naz=hair] :: farther trace
|
||||
^- hair
|
||||
?: =(p.zyc p.naz)
|
||||
?:((gth q.zyc q.naz) zyc naz)
|
||||
?:((gth p.zyc p.naz) zyc naz)
|
||||
::
|
||||
|
||||
Compares two line-column pairs, `zyc` and `naz`, and produces whichever
|
||||
[hair]() is farther along.
|
||||
|
||||
`zyc` is a [hair]().
|
||||
|
||||
`naz` is a [hair]().
|
||||
|
||||
~zod/try=> (last [1 1] [1 2])
|
||||
[p=1 q=2]
|
||||
~zod/try=> (last [2 1] [1 2])
|
||||
[p=2 q=1]
|
||||
~zod/try=> (last [0 0] [99 0])
|
||||
[p=99 q=0]
|
||||
~zod/try=> (last [7 7] [7 7])
|
||||
[p=7 q=7]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lust`
|
||||
|
||||
Detect newline
|
||||
|
||||
++ lust |= [weq=char naz=hair] :: detect newline
|
||||
^- hair
|
||||
?:(=(10 weq) [+(p.naz) 1] [p.naz +(q.naz)])
|
||||
|
||||
Advances the hair `naz` by a row if the char `weq` is a newline, or by a
|
||||
column if `weq` is any other character.
|
||||
|
||||
`weq` is a [char]().
|
||||
|
||||
`naz` is a [hair]().
|
||||
|
||||
~zod/try=> (lust `a` [1 1])
|
||||
[p=1 q=2]
|
||||
~zod/try=> (lust `@t`10 [1 1])
|
||||
[p=2 q=1]
|
||||
~zod/try=> (lust '9' [10 10])
|
||||
[p=10 q=11]
|
||||
/~zod/try=> (roll "maze" [.(+<+ [1 1])]:lust)
|
||||
[1 5]
|
||||
/~zod/try=> %- roll :_ [.(+<+ [1 1])]:lust
|
||||
"""
|
||||
Sam
|
||||
lokes
|
||||
"""
|
||||
[2 6]
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,652 +0,0 @@
|
||||
section 2eC, parsing (custom rules)
|
||||
===================================
|
||||
|
||||
### `++cold`
|
||||
|
||||
Replace with constant
|
||||
|
||||
++ cold :: replace w/ constant
|
||||
~/ %cold
|
||||
|* [cus=* sef=_rule]
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
=+ vex=(sef tub)
|
||||
?~ q.vex
|
||||
vex
|
||||
[p=p.vex q=[~ u=[p=cus q=q.u.q.vex]]]
|
||||
::
|
||||
|
||||
Parser modifier. Accepts a rule `sef` and produces a parser that
|
||||
produces a constant `cus`, if `sef` is successful.
|
||||
|
||||
`cus` is a constant [noun]().
|
||||
|
||||
`sef` is a [`++rule`]().
|
||||
|
||||
~zod/try=> ((cold %foo (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=%foo q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((cold %foo (just 'a')) [[1 1] "bc"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++cook`
|
||||
|
||||
Apply gate
|
||||
|
||||
++ cook :: apply gate
|
||||
~/ %cook
|
||||
|* [poq=_,* sef=_rule]
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
=+ vex=(sef tub)
|
||||
?~ q.vex
|
||||
vex
|
||||
[p=p.vex q=[~ u=[p=(poq p.u.q.vex) q=q.u.q.vex]]]
|
||||
::
|
||||
|
||||
Parser modifier. Produces a parser that takes a (successful) result of a
|
||||
rule `sef` and slams it through `poq`.
|
||||
|
||||
`poq` is a [gate]().
|
||||
|
||||
`sef` is a [`++rule`]().
|
||||
|
||||
~zod/try=> ((cook ,@ud (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((cook ,@tas (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=%a q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((cook |=(a=@ +(a)) (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=98 q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((cook |=(a=@ `@t`+(a)) (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p='b' q=[p=[p=1 q=2] q="bc"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++easy`
|
||||
|
||||
Always parse
|
||||
|
||||
++ easy :: always parse
|
||||
~/ %easy
|
||||
|* huf=*
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
^- (like ,_huf)
|
||||
[p=p.tub q=[~ u=[p=huf q=tub]]]
|
||||
::
|
||||
|
||||
Parser generator. Produces a parser that succeeds with given noun `huf`
|
||||
without consuming any text.
|
||||
|
||||
~zod/try=> ((easy %foo) [[1 1] "abc"])
|
||||
[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="abc"]]]]
|
||||
~zod/try=> ((easy %foo) [[1 1] "bc"])
|
||||
[p=[p=1 q=1] q=[~ [p=%foo q=[p=[p=1 q=1] q="bc"]]]]
|
||||
~zod/try=> ((easy 'a') [[1 1] "bc"])
|
||||
[p=[p=1 q=1] q=[~ [p='a' q=[p=[p=1 q=1] q="bc"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fail`
|
||||
|
||||
Never parse
|
||||
|
||||
++ fail |=(tub=nail [p=p.tub q=~]) :: never parse
|
||||
|
||||
Produces an [edge]() at the same text position ([hair]()) with a failing
|
||||
result (`q=~`).
|
||||
|
||||
`tub` is a [`++nail`]().
|
||||
|
||||
~zod/try=> (fail [[1 1] "abc"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
~zod/try=> (fail [[p=1.337 q=70] "Parse me, please?"])
|
||||
[p=[p=1.337 q=70] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++full`
|
||||
|
||||
Parse to end
|
||||
|
||||
++ full :: parse to end
|
||||
|* sef=_rule
|
||||
|= tub=nail
|
||||
=+ vex=(sef tub)
|
||||
?~(q.vex vex ?:(=(~ q.q.u.q.vex) vex [p=p.vex q=~]))
|
||||
::
|
||||
|
||||
Accepts a [`++nail`](), `tub`, and produces a parser that succeeds only
|
||||
when a `tub` success consumes the remainder of the [tape]().
|
||||
|
||||
`sef` is a [`++rule`]().
|
||||
|
||||
~zod/try=> ((full (just 'a')) [[1 1] "ab"])
|
||||
[p=[p=1 q=2] q=~]
|
||||
~zod/try=> ((full (jest 'ab')) [[1 1] "ab"])
|
||||
[p=[p=1 q=3] q=[~ u=[p='ab' q=[p=[p=1 q=3] q=""]]]]
|
||||
~zod/try=> ((full ;~(plug (just 'a') (just 'b'))) [[1 1] "ab"])
|
||||
[p=[p=1 q=3] q=[~ u=[p=[~~a ~~b] q=[p=[p=1 q=3] q=""]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++funk`
|
||||
|
||||
Add to tape
|
||||
|
||||
++ funk :: add to tape first
|
||||
|* [pre=tape sef=_rule]
|
||||
|= tub=nail
|
||||
(sef p.tub (weld pre q.tub))
|
||||
::
|
||||
|
||||
Parser modifier: prepend text to tape before applying parser.
|
||||
|
||||
`pre` is a [`++tape`]()
|
||||
|
||||
`sef` is a [`++rule`]()
|
||||
|
||||
~zod/try=> ((funk "abc prefix-" (jest 'abc')) [[1 1] "to be parsed"])
|
||||
[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=" prefix-to be parsed"]]]]
|
||||
~zod/try=> ((funk "parse" (just 'a')) [[1 4] " me"])
|
||||
[p=[p=1 q=4] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++here`
|
||||
|
||||
Place-based apply
|
||||
|
||||
++ here :: place-based apply
|
||||
~/ %here
|
||||
|* [hez=_|=([a=pint b=*] [a b]) sef=_rule]
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
=+ vex=(sef tub)
|
||||
?~ q.vex
|
||||
vex
|
||||
[p=p.vex q=[~ u=[p=(hez [p.tub p.q.u.q.vex] p.u.q.vex) q=q.u.q.vex]]]
|
||||
::
|
||||
|
||||
Parser modifier. Similar to [`++cook`](), produces a parser that takes a
|
||||
(successful) result of `sef` and slams it through `hez`. `hez` accepts a
|
||||
[`++pint`]() `a` and a noun `b`, which is what the parser parsed.
|
||||
|
||||
`hez` is a [gate]().
|
||||
|
||||
`sef` is a [`++rule`]()
|
||||
|
||||
~zod/try=> (scan "abc" (star alf))
|
||||
"abc"
|
||||
~zod/try=> (scan "abc" (here |*(^ +<) (star alf)))
|
||||
[[[p=1 q=1] p=1 q=4] "abc"]
|
||||
~zod/try=> (scan "abc" (star (here |*(^ +<) alf)))
|
||||
~[[[[p=1 q=1] p=1 q=2] ~~a] [[[p=1 q=2] p=1 q=3] ~~b] [[[p=1 q=3] p=1 q=4] ~~c]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++inde`
|
||||
|
||||
Indentation block
|
||||
|
||||
++ inde |* sef=_rule :: indentation block
|
||||
|= nail ^+ (sef)
|
||||
=+ [har tap]=[p q]:+<
|
||||
=+ lev=(fil 3 (dec q.har) ' ')
|
||||
=+ eol=(just `@t`10)
|
||||
=+ =- roq=((star ;~(pose prn ;~(sfix eol (jest lev)) -)) har tap)
|
||||
;~(simu ;~(plug eol eol) eol)
|
||||
?~ q.roq roq
|
||||
=+ vex=(sef har(q 1) p.u.q.roq)
|
||||
=+ fur=p.vex(q (add (dec q.har) q.p.vex))
|
||||
?~ q.vex vex(p fur)
|
||||
=- vex(p fur, u.q -)
|
||||
:+ &3.vex
|
||||
&4.vex(q.p (add (dec q.har) q.p.&4.vex))
|
||||
=+ res=|4.vex
|
||||
|- ?~ res |4.roq
|
||||
?. =(10 -.res) [-.res $(res +.res)]
|
||||
(welp [`@t`10 (trip lev)] $(res +.res))
|
||||
::
|
||||
|
||||
Apply rule to indented block starting at current column number, omitting
|
||||
the leading whitespace.
|
||||
|
||||
`sef` is a [`++rule`]()
|
||||
|
||||
~zod/try=> (scan "abc" (inde (star ;~(pose prn (just `@`10)))))
|
||||
"abc"
|
||||
~zod/try=> (scan "abc" (star ;~(pose prn (just `@`10))))
|
||||
"abc"
|
||||
~zod/try=> (scan " abc\0ade" ;~(pfix ace ace (star ;~(pose prn (just `@`10)))))
|
||||
"abc
|
||||
de"
|
||||
~zod/try=> (scan " abc\0ade" ;~(pfix ace ace (inde (star ;~(pose prn (just `@`10))))))
|
||||
! {1 6}
|
||||
! exit
|
||||
~zod/try=> (scan " abc\0a de" ;~(pfix ace ace (inde (star ;~(pose prn (just `@`10))))))
|
||||
"abc
|
||||
de"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++jest`
|
||||
|
||||
Match a cord
|
||||
|
||||
++ jest :: match a cord
|
||||
|= daf=@t
|
||||
|= tub=nail
|
||||
=+ fad=daf
|
||||
|- ^- (like ,@t)
|
||||
?: =(0 daf)
|
||||
[p=p.tub q=[~ u=[p=fad q=tub]]]
|
||||
?: |(?=(~ q.tub) !=((end 3 1 daf) i.q.tub))
|
||||
(fail tub)
|
||||
$(p.tub (lust i.q.tub p.tub), q.tub t.q.tub, daf (rsh 3 1 daf))
|
||||
::
|
||||
|
||||
Match and consume a cord.
|
||||
|
||||
`daf` is a `@t`
|
||||
|
||||
~zod/try=> ((jest 'abc') [[1 1] "abc"])
|
||||
[p=[p=1 q=4] q=[~ [p='abc' q=[p=[p=1 q=4] q=""]]]]
|
||||
~zod/try=> (scan "abc" (jest 'abc'))
|
||||
'abc'
|
||||
~zod/try=> (scan "abc" (jest 'acb'))
|
||||
! {1 2}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> ((jest 'john doe') [[1 1] "john smith"])
|
||||
[p=[p=1 q=6] q=~]
|
||||
~zod/try=> ((jest 'john doe') [[1 1] "john doe"])
|
||||
[p=[p=1 q=9] q=[~ [p='john doe' q=[p=[p=1 q=9] q=""]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++just`
|
||||
|
||||
Match a char
|
||||
|
||||
++ just :: XX redundant, jest
|
||||
~/ %just :: match a char
|
||||
|= daf=char
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
^- (like char)
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?. =(daf i.q.tub)
|
||||
(fail tub)
|
||||
(next tub)
|
||||
::
|
||||
|
||||
Match and consume a single character.
|
||||
|
||||
`daf` is a [`++char`]()
|
||||
|
||||
~zod/try=> ((just 'a') [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> (scan "abc" (just 'a'))
|
||||
! {1 2}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> (scan "a" (just 'a'))
|
||||
~~a
|
||||
~zod/try=> (scan "%" (just '%'))
|
||||
~~~25.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++knee`
|
||||
|
||||
Recursive parsers
|
||||
|
||||
++ knee :: callbacks
|
||||
|* [gar=* sef=_|.(rule)]
|
||||
|= tub=nail
|
||||
^- (like ,_gar)
|
||||
((sef) tub)
|
||||
::
|
||||
|
||||
Used for recursive parsers, which would otherwise be infinite when
|
||||
compiled.
|
||||
|
||||
`gar` is a noun.
|
||||
|
||||
`sef` is a [gate]() that accepts a [`++rule`]()
|
||||
|
||||
~zod/try=> |-(;~(plug prn ;~(pose $ (easy ~))))
|
||||
! rest-loop
|
||||
! exit
|
||||
~zod/try=> |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~))))
|
||||
< 1.obo
|
||||
[ c=c=tub=[p=[p=@ud q=@ud] q=""]
|
||||
b
|
||||
< 1.bes
|
||||
[ c=tub=[p=[p=@ud q=@ud] q=""]
|
||||
b=<1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>
|
||||
a=<1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>
|
||||
v=<414.fvk 101.jzo 1.ypj %164>
|
||||
]
|
||||
>
|
||||
a
|
||||
... 450 lines omitted ...
|
||||
]
|
||||
>
|
||||
~zod/try=> (scan "abcd" |-(;~(plug prn ;~(pose (knee *tape |.(^$)) (easy ~)))))
|
||||
[~~a "bcd"]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mask`
|
||||
|
||||
Match char
|
||||
|
||||
++ mask :: match char in set
|
||||
~/ %mask
|
||||
|= bud=(list char)
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
^- (like char)
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?. (lien bud |=(a=char =(i.q.tub a)))
|
||||
(fail tub)
|
||||
(next tub)
|
||||
::
|
||||
|
||||
Parser generator. Matches the next character if it is in a list of
|
||||
characters.
|
||||
|
||||
`bud` is a list of [`++char`]()
|
||||
|
||||
~zod/try=> (scan "a" (mask "cba"))
|
||||
~~a
|
||||
~zod/try=> ((mask "abc") [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((mask "abc") [[1 1] "bbc"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~b q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((mask "abc") [[1 1] "dbc"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++next`
|
||||
|
||||
Consume char
|
||||
|
||||
++ next :: consume a char
|
||||
|= tub=nail
|
||||
^- (like char)
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
=+ zac=(lust i.q.tub p.tub)
|
||||
[zac [~ i.q.tub [zac t.q.tub]]]
|
||||
::
|
||||
|
||||
Consume any character, producing it as a result.
|
||||
|
||||
`tub` is a [`++nail`]()
|
||||
|
||||
~zod/try=> (next [[1 1] "ebc"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~e q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> (next [[1 1] "john jumps jones"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~j q=[p=[p=1 q=2] q="ohn jumps jones"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sear`
|
||||
|
||||
Conditional `++cook`
|
||||
|
||||
++ sear :: conditional cook
|
||||
|* [pyq=_|=(* *(unit)) sef=_rule]
|
||||
|= tub=nail
|
||||
=+ vex=(sef tub)
|
||||
?~ q.vex
|
||||
vex
|
||||
=+ gey=(pyq p.u.q.vex)
|
||||
?~ gey
|
||||
[p=p.vex q=~]
|
||||
[p=p.vex q=[~ u=[p=u.gey q=q.u.q.vex]]]
|
||||
::
|
||||
|
||||
Conditional [`++cook`](). Slams the result through a gate that produces
|
||||
a unit; if that unit is empty, fail.
|
||||
|
||||
`tub` is a [`++nail`](/doc/hoon/library/1#++nail)
|
||||
|
||||
~zod/try=> ((sear |=(a=* ?@(a (some a) ~)) (just `a`)) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=97 q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((sear |=(* ~) (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++shim`
|
||||
|
||||
Char in range
|
||||
|
||||
++ shim :: match char in range
|
||||
~/ %shim
|
||||
|= [les=@ mos=@]
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
^- (like char)
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?. ?&((gte i.q.tub les) (lte i.q.tub mos))
|
||||
(fail tub)
|
||||
(next tub)
|
||||
::
|
||||
|
||||
Match characters within a range.
|
||||
|
||||
`les` and `mos` are atoms, `@`.
|
||||
|
||||
~zod/try=> ((shim 'a' 'z') [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~a q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((shim 'a' 'Z') [[1 1] "abc"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
~zod/try=> ((shim 'a' 'Z') [[1 1] "Abc"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~41. q=[p=[p=1 q=2] q="bc"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++stag`
|
||||
|
||||
Add label
|
||||
|
||||
++ stag :: add a label
|
||||
~/ %stag
|
||||
|* [gob=* sef=_rule]
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
=+ vex=(sef tub)
|
||||
?~ q.vex
|
||||
vex
|
||||
[p=p.vex q=[~ u=[p=[gob p.u.q.vex] q=q.u.q.vex]]]
|
||||
::
|
||||
|
||||
Add a label to an edge parsed by a rule.
|
||||
|
||||
`gob` is a noun.
|
||||
|
||||
`sef` is a rule.
|
||||
|
||||
~zod/try=> ((stag %foo (just 'a')) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=[%foo ~~a] q=[p=[p=1 q=2] q="bc"]]]]
|
||||
~zod/try=> ((stag "xyz" (jest 'abc')) [[1 1] "abc"])
|
||||
[p=[p=1 q=4] q=[~ u=[p=["xyz" 'abc'] q=[p=[p=1 q=4] q=""]]]]
|
||||
~zod/try=> ((stag 10.000 (shim 0 100)) [[1 1] "abc"])
|
||||
[p=[p=1 q=2] q=[~ u=[p=[10.000 ~~a] q=[p=[p=1 q=2] q="bc"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++stet`
|
||||
|
||||
Add faces
|
||||
|
||||
++ stet
|
||||
|* leh=(list ,[?(@ [@ @]) _rule])
|
||||
|-
|
||||
?~ leh
|
||||
~
|
||||
[i=[p=-.i.leh q=+.i.leh] t=$(leh t.leh)]
|
||||
::
|
||||
|
||||
Add `[p q]` faces to range-parser pairs in a list.
|
||||
|
||||
`leh` is a list of range-parsers.
|
||||
|
||||
~zod/try=> (stet (limo [[5 (just 'a')] [1 (jest 'abc')] [[1 1] (shim 0 200)]
|
||||
[[1 10] (cold %foo (just 'a'))]~]))
|
||||
~[
|
||||
[p=5 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
|
||||
[p=1 q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
|
||||
[p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
|
||||
[p=[1 10] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
|
||||
]
|
||||
~zod/try=> [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]
|
||||
[ [[1 1] <1.tnv [tub=[p=[p=@ud q=@ud] q=""] <1.ktu [daf=@tD <414.fvk 101.jzo 1.ypj %164>]>]>]
|
||||
[[2 1] <1.fvg [tub=[p=[p=@ud q=@ud] q=""] <1.khu [[les=@ mos=@] <414.fvk 101.jzo 1.ypj %164>]>]>]
|
||||
~
|
||||
]
|
||||
~zod/try=> (stet (limo [[[1 1] (just 'a')] [[2 1] (shim 0 200)] ~]))
|
||||
~[
|
||||
[p=[1 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
|
||||
[p=[2 1] q=<1.lrk [tub=[p=[p=@ud q=@ud] q=""] <1.nqy [daf=@tD <394.imz 97.kdz 1.xlc %164>]>]>]
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++stew`
|
||||
|
||||
Switch by first
|
||||
|
||||
++ stew :: switch by first char
|
||||
~/ %stew
|
||||
|* leh=(list ,[p=?(@ [@ @]) q=_rule]) :: char/range keys
|
||||
=+ ^= wor :: range complete lth
|
||||
|= [ort=?(@ [@ @]) wan=?(@ [@ @])]
|
||||
?@ ort
|
||||
?@(wan (lth ort wan) (lth ort -.wan))
|
||||
?@(wan (lth +.ort wan) (lth +.ort -.wan))
|
||||
=+ ^= hel :: build parser map
|
||||
=+ hel=`(tree $_(?>(?=(^ leh) i.leh)))`~
|
||||
|- ^+ hel
|
||||
?~ leh
|
||||
~
|
||||
=+ yal=$(leh t.leh)
|
||||
|- ^+ hel
|
||||
?~ yal
|
||||
[i.leh ~ ~]
|
||||
?: (wor p.i.leh p.n.yal)
|
||||
=+ nuc=$(yal l.yal)
|
||||
?> ?=(^ nuc)
|
||||
?: (vor p.n.yal p.n.nuc)
|
||||
[n.yal nuc r.yal]
|
||||
[n.nuc l.nuc [n.yal r.nuc r.yal]]
|
||||
=+ nuc=$(yal r.yal)
|
||||
?> ?=(^ nuc)
|
||||
?: (vor p.n.yal p.n.nuc)
|
||||
[n.yal l.yal nuc]
|
||||
[n.nuc [n.yal l.yal l.nuc] r.nuc]
|
||||
~% %fun ..^$ ~
|
||||
|= tub=nail
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
|-
|
||||
?~ hel
|
||||
(fail tub)
|
||||
?: ?@ p.n.hel
|
||||
=(p.n.hel i.q.tub)
|
||||
?&((gte i.q.tub -.p.n.hel) (lte i.q.tub +.p.n.hel))
|
||||
:: (q.n.hel [(lust i.q.tub p.tub) t.q.tub])
|
||||
(q.n.hel tub)
|
||||
?: (wor i.q.tub p.n.hel)
|
||||
$(hel l.hel)
|
||||
$(hel r.hel)
|
||||
::
|
||||
|
||||
Parser generator. From an associative list of characters or character
|
||||
ranges to rules, construct a map, and parse tapes only with rules
|
||||
associated with a range the tape's first character falls in.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++stir`
|
||||
|
||||
Parse repeatedly
|
||||
|
||||
++ stir :: parse repeatedly
|
||||
~/ %stir
|
||||
|* [rud=* raq=_|*([a=* b=*] [a b]) fel=_rule]
|
||||
~/ %fun
|
||||
|= tub=nail
|
||||
^- (like ,_rud)
|
||||
=+ vex=(fel tub)
|
||||
?~ q.vex
|
||||
[p.vex [~ rud tub]]
|
||||
=+ wag=$(tub q.u.q.vex)
|
||||
?> ?=(^ q.wag)
|
||||
[(last p.vex p.wag) [~ (raq p.u.q.vex p.u.q.wag) q.u.q.wag]]
|
||||
::
|
||||
|
||||
Parse with rule as many times as possible, and fold over results with a
|
||||
binary gate.
|
||||
|
||||
`rud` is a noun.
|
||||
|
||||
`raq` is a gate that takes two nouns and produces a cell.
|
||||
|
||||
`fel` is a rule.
|
||||
|
||||
~zod/try=> (scan "abc" (stir *@ add prn))
|
||||
294
|
||||
~zod/try=> (roll "abc" add)
|
||||
b=294
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++stun`
|
||||
|
||||
Parse several times
|
||||
|
||||
++ stun :: parse several times
|
||||
|* [[les=@ mos=@] fel=_rule]
|
||||
|= tub=nail
|
||||
^- (like (list ,_(wonk (fel))))
|
||||
?: =(0 mos)
|
||||
[p.tub [~ ~ tub]]
|
||||
=+ vex=(fel tub)
|
||||
?~ q.vex
|
||||
?: =(0 les)
|
||||
[p.vex [~ ~ tub]]
|
||||
vex
|
||||
=+ ^= wag %= $
|
||||
les ?:(=(0 les) 0 (dec les))
|
||||
mos ?:(=(0 mos) 0 (dec mos))
|
||||
tub q.u.q.vex
|
||||
==
|
||||
?~ q.wag
|
||||
wag
|
||||
[p.wag [~ [p.u.q.vex p.u.q.wag] q.u.q.wag]]
|
||||
|
||||
Parse bounded number of times.
|
||||
|
||||
`[les=@ mos=@]` is a cell of atoms indicating the bounds.
|
||||
|
||||
`fel` is a rule.
|
||||
|
||||
~zod/try=> ((stun [5 10] prn) [1 1] "aquickbrownfoxran")
|
||||
[p=[p=1 q=11] q=[~ [p="aquickbrow" q=[p=[p=1 q=11] q="nfoxran"]]]]
|
||||
~zod/try=> ((stun [5 10] prn) [1 1] "aquickbro")
|
||||
[p=[p=1 q=10] q=[~ [p="aquickbro" q=[p=[p=1 q=10] q=""]]]]
|
||||
~zod/try=> ((stun [5 10] prn) [1 1] "aqui")
|
||||
[p=[p=1 q=5] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,289 +0,0 @@
|
||||
section 2eD
|
||||
===========
|
||||
|
||||
### `++bend`
|
||||
|
||||
Conditional composer
|
||||
|
||||
++ bend :: conditional comp
|
||||
~/ %bend
|
||||
|* raq=_|*([a=* b=*] [~ u=[a b]])
|
||||
~/ %fun
|
||||
|* [vex=edge sab=_rule]
|
||||
?~ q.vex
|
||||
vex
|
||||
=+ yit=(sab q.u.q.vex)
|
||||
=+ yur=(last p.vex p.yit)
|
||||
?~ q.yit
|
||||
[p=yur q=q.vex]
|
||||
=+ vux=(raq p.u.q.vex p.u.q.yit)
|
||||
?~ vux
|
||||
[p=yur q=q.vex]
|
||||
[p=yur q=[~ u=[p=u.vux q=q.u.q.yit]]]
|
||||
::
|
||||
|
||||
Parsing composer: connects the edge `vex` with the subsequent rule `sab`
|
||||
as an optional suffix, using the gate `raq` to compose or reject its
|
||||
result. If there is no suffix, or if the suffix fails to be composed
|
||||
with the current result, the current result is produced. Used to map a
|
||||
group of rules to a specified output.
|
||||
|
||||
`raq` is a [gate]().
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qs")
|
||||
[p=[p=1 q=3] q=[~ u=[p=~~q q=[p=[p=1 q=2] q="s"]]]]
|
||||
~zod/try=> (;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn) [1 1] "qqq")
|
||||
[p=[p=1 q=3] q=[~ u=[p=~~r q=[p=[p=1 q=3] q="q"]]]]
|
||||
~zod/try=> (scan "aa" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
|
||||
~~b
|
||||
~zod/try=> (scan "ba" ;~((bend |=([a=char b=char] ?.(=(a b) ~ (some +(a))))) prn prn))
|
||||
! {1 3}
|
||||
! exit
|
||||
~zod/try=> `(unit ,@tas)`(scan "" ;~((bend) (easy ~) sym))
|
||||
~
|
||||
~zod/try=> `(unit ,@tas)`(scan "sep" ;~((bend) (easy ~) sym))
|
||||
[~ %sep]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++comp`
|
||||
|
||||
Arbitrary compose
|
||||
|
||||
++ comp
|
||||
~/ %comp
|
||||
|* raq=_|*([a=* b=*] [a b]) :: arbitrary compose
|
||||
~/ %fun
|
||||
|* [vex=edge sab=_rule]
|
||||
?~ q.vex
|
||||
vex
|
||||
=+ yit=(sab q.u.q.vex)
|
||||
=+ yur=(last p.vex p.yit)
|
||||
?~ q.yit
|
||||
[p=yur q=q.yit]
|
||||
[p=yur q=[~ u=[p=(raq p.u.q.vex p.u.q.yit) q=q.u.q.yit]]]
|
||||
::
|
||||
|
||||
Parsing composer: connects the edge `vex` with a following rule `sab`,
|
||||
combining the contents of `vex` with the result of `sab` using a binary
|
||||
gate `raq`. Used to fold over the results of several rules.
|
||||
|
||||
`raq` is a [gate]() that accepts a cell of two nouns, `a` and `b`, and
|
||||
produces a cell of two nouns.
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> (scan "123" ;~((comp |=([a=@u b=@u] (add a b))) dit dit dit))
|
||||
6
|
||||
~zod/try=> (scan "12" ;~((comp |=([a=@u b=@u] (add a b))) dit dit dit))
|
||||
! {1 3}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++glue`
|
||||
|
||||
Skip delimiter
|
||||
|
||||
++ glue :: add rule
|
||||
~/ %glue
|
||||
|* bus=_rule
|
||||
~/ %fun
|
||||
|* [vex=edge sab=_rule]
|
||||
(plug vex ;~(pfix bus sab))
|
||||
::
|
||||
|
||||
Parsing composer: connects an edge `vex` with a following rule `sab` by
|
||||
parsing the rule `bus` (the delimiting symbol) and throwing out the
|
||||
result.
|
||||
|
||||
`bus` is a [rule]().
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> (scan "200|mal|bon" ;~((glue bar) dem sym sym))
|
||||
[q=200 7.102.829 7.237.474]
|
||||
~zod/try=> `[@u @tas @tas]`(scan "200|mal|bon" ;~((glue bar) dem sym sym))
|
||||
[200 %mal %bon]
|
||||
~zod/try=> (scan "200|;|bon" ;~((glue bar) dem sem sym))
|
||||
[q=200 ~~~3b. 7.237.474]
|
||||
~zod/try=> (scan "200.;.bon" ;~((glue dot) dem sem sym))
|
||||
[q=200 ~~~3b. 7.237.474]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++less`
|
||||
|
||||
Parse unless
|
||||
|
||||
++ less :: no first and second
|
||||
|* [vex=edge sab=_rule]
|
||||
?~ q.vex
|
||||
=+ roq=(sab)
|
||||
[p=(last p.vex p.roq) q=q.roq]
|
||||
vex(q ~)
|
||||
::
|
||||
|
||||
Parsing composer: if an edge `vex` reflects a success, fail. Otherwise,
|
||||
connect `vex` with the following rule.
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> (scan "sas-/lo" (star ;~(less lus bar prn)))
|
||||
"sas-/lo"
|
||||
~zod/try=> (scan "sas-/l+o" (star ;~(less lus bar prn)))
|
||||
! {1 8}
|
||||
! exit
|
||||
~zod/try=> (scan "sas|-/lo" (star ;~(less lus bar prn)))
|
||||
! {1 5}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pfix`
|
||||
|
||||
Discard first rule
|
||||
|
||||
++ pfix :: discard first rule
|
||||
~/ %pfix
|
||||
(comp |*([a=* b=*] b))
|
||||
::
|
||||
|
||||
Parsing composer: connects an [edge]() `vex` with two subsequent rules,
|
||||
ignoring the result of the first and producing the result of the second.
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> `@t`(scan "%him" ;~(pfix cen sym))
|
||||
'him'
|
||||
~zod/try=> (scan "+++10" ;~(pfix (star lus) dem))
|
||||
q=10
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++plug`
|
||||
|
||||
Parse to tuple
|
||||
|
||||
++ plug :: first then second
|
||||
~/ %plug
|
||||
|* [vex=edge sab=_rule]
|
||||
?~ q.vex
|
||||
vex
|
||||
=+ yit=(sab q.u.q.vex)
|
||||
=+ yur=(last p.vex p.yit)
|
||||
?~ q.yit
|
||||
[p=yur q=q.yit]
|
||||
[p=yur q=[~ u=[p=[p.u.q.vex p.u.q.yit] q=q.u.q.yit]]]
|
||||
::
|
||||
|
||||
Parsing composer: connects `vex` with a following rule `sab`, producing
|
||||
a cell of both the results. See also: the monad applicator [;\~]() for a
|
||||
more detailed explanation.
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> (scan "1..20" ;~(plug dem dot dot dem))
|
||||
[q=1 ~~~. ~~~. q=20]
|
||||
~zod/try=> (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so))
|
||||
[1.701.539.693 ~~~2f. [% p=[p=~.da q=170.141.184.500.766.106.671.844.917.172.921.958.400]]]
|
||||
~zod/try=> ;;(,[@tas @t ~ %da @da] (scan "moke/~2014.1.1" ;~(plug sym fas nuck:so)))
|
||||
[%moke '/' ~ %da ~2014.1.1]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pose`
|
||||
|
||||
Parse options
|
||||
|
||||
++ pose :: first or second
|
||||
~/ %pose
|
||||
|* [vex=edge sab=_rule]
|
||||
?~ q.vex
|
||||
=+ roq=(sab)
|
||||
[p=(last p.vex p.roq) q=q.roq]
|
||||
vex
|
||||
|
||||
Parsing composer: if `vex` reflects a failure, connect it with the
|
||||
following rule `sab`. See also: the monad applicator [;\~]()
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> `@t`(scan "+" ;~(pose lus tar cen))
|
||||
'+'
|
||||
~zod/try=> `@t`(scan "*" ;~(pose lus tar cen))
|
||||
'*'
|
||||
~zod/try=> `@t`(scan "%" ;~(pose lus tar cen))
|
||||
'%'
|
||||
~zod/try=> `@t`(scan "-" ;~(pose lus tar cen))
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++simu`
|
||||
|
||||
First and second
|
||||
|
||||
++ simu :: first and second
|
||||
|* [vex=edge sab=_rule]
|
||||
?~ q.vex
|
||||
vex
|
||||
=+ roq=(sab)
|
||||
roq
|
||||
::
|
||||
|
||||
Parsing composer: if an edge `vex` reflects a failure, fail. Otherwise,
|
||||
connect `vex` with the following rule.
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
`vex` is an [edge]().
|
||||
|
||||
~zod/try=> (scan "~zod" scat:vast)
|
||||
[%dtzy p=%p q=0]
|
||||
~zod/try=> (scan "%zod" scat:vast)
|
||||
[%dtzz p=%tas q=6.582.138]
|
||||
~zod/try=> (scan "%zod" ;~(simu cen scat:vast))
|
||||
[%dtzz p=%tas q=6.582.138]
|
||||
~zod/try=> (scan "~zod" ;~(simu cen scat:vast))
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sfix`
|
||||
|
||||
Discard second rule
|
||||
|
||||
++ sfix :: discard second rule
|
||||
~/ %sfix
|
||||
(comp |*([a=* b=*] a))
|
||||
|
||||
Parsing composer: connects `vex` with two subsequent rules returning the
|
||||
result of the first and discarding the result of the second.
|
||||
|
||||
`a` is the result of parsing the first [rule]().
|
||||
|
||||
`b` is the result of of parsing the second [rule]().
|
||||
|
||||
~zod/try=> `@t`(scan "him%" ;~(sfix sym cen))
|
||||
'him'
|
||||
~zod/try=> (scan "10+++" ;~(sfix dem (star lus)))
|
||||
q=10
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,195 +0,0 @@
|
||||
section 2eE, parsing (composers)
|
||||
================================
|
||||
|
||||
### `++bass`
|
||||
|
||||
++ bass
|
||||
|* [wuc=@ tyd=_rule]
|
||||
%+ cook
|
||||
|= waq=(list ,@)
|
||||
%+ roll
|
||||
waq
|
||||
=|([p=@ q=@] |.((add p (mul wuc q))))
|
||||
tyd
|
||||
::
|
||||
|
||||
Parser modifier:
|
||||
[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) ordered list
|
||||
as atom of a base.
|
||||
|
||||
`wuc` is an [atom]().
|
||||
|
||||
`tyd` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "123" (bass 10 (star dit)))
|
||||
q=123
|
||||
~zod/try=> (scan "123" (bass 8 (star dit)))
|
||||
q=83
|
||||
~zod/try=> `@ub`(scan "123" (bass 8 (star dit)))
|
||||
0b101.0011
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++boss`
|
||||
|
||||
++ boss
|
||||
|* [wuc=@ tyd=_rule]
|
||||
%+ cook
|
||||
|= waq=(list ,@)
|
||||
%+ reel
|
||||
waq
|
||||
=|([p=@ q=@] |.((add p (mul wuc q))))
|
||||
tyd
|
||||
::
|
||||
|
||||
Parser modifier:
|
||||
[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) ordered list
|
||||
as atom of a base.
|
||||
|
||||
`wuc` is an [atom]().
|
||||
|
||||
`tyd` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "123" (boss 10 (star dit)))
|
||||
q=321
|
||||
~zod/try=> `@t`(scan "bam" (boss 256 (star alp)))
|
||||
'bam'
|
||||
~zod/try=> `@ux`(scan "bam" (boss 256 (star alp)))
|
||||
0x6d.6162
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ifix`
|
||||
|
||||
++ ifix
|
||||
|* [fel=[p=_rule q=_rule] hof=_rule]
|
||||
;~(pfix p.fel ;~(sfix hof q.fel))
|
||||
::
|
||||
|
||||
Parser modifier: surround with pair of rules, output of which is
|
||||
discarded.
|
||||
|
||||
`fel` is a pair of [rule]()s.
|
||||
|
||||
`hof` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "-40-" (ifix [hep hep] dem))
|
||||
q=40
|
||||
~zod/try=> (scan "4my4" (ifix [dit dit] (star alf)))
|
||||
"my"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++more`
|
||||
|
||||
++ more
|
||||
|* [bus=_rule fel=_rule]
|
||||
;~(pose (most bus fel) (easy ~))
|
||||
::
|
||||
|
||||
Parser modifier: using a delimiter rule, parse a list of matches.
|
||||
|
||||
`bus` is a [rule]().
|
||||
|
||||
`fel` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "" (more ace dem))
|
||||
~
|
||||
~zod/try=> (scan "40 20" (more ace dem))
|
||||
[q=40 ~[q=20]]
|
||||
~zod/try=> (scan "40 20 60 1 5" (more ace dem))
|
||||
[q=40 ~[q=20 q=60 q=1 q=5]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++most`
|
||||
|
||||
++ most
|
||||
|* [bus=_rule fel=_rule]
|
||||
;~(plug fel (star ;~(pfix bus fel)))
|
||||
::
|
||||
|
||||
Parser modifier: using a delimiter rule, parse a list of at least one
|
||||
match.
|
||||
|
||||
`bus` is a [rule]().
|
||||
|
||||
`fel` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "40 20" (most ace dem))
|
||||
[q=40 ~[q=20]]
|
||||
~zod/try=> (scan "40 20 60 1 5" (most ace dem))
|
||||
[q=40 ~[q=20 q=60 q=1 q=5]]
|
||||
~zod/try=> (scan "" (most ace dem))
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++plus`
|
||||
|
||||
++ plus |*(fel=_rule ;~(plug fel (star fel)))
|
||||
|
||||
Parser modifier: parse list of at least one match
|
||||
|
||||
`fel` is a [rule]().
|
||||
|
||||
~zod/try=> (scan ">>>>" (cook lent (plus gar)))
|
||||
4
|
||||
~zod/try=> (scan "- - " (plus ;~(pose ace hep)))
|
||||
[~~- " - "]
|
||||
~zod/try=> `tape`(scan "- - " (plus ;~(pose ace hep)))
|
||||
"- - "
|
||||
~zod/try=> `(pole ,@t)`(scan "- - " (plus ;~(pose ace hep)))
|
||||
['-' [' ' [' ' ['-' [' ' ~]]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++slug`
|
||||
|
||||
++ slug
|
||||
|* raq=_|*([a=* b=*] [a b])
|
||||
|* [bus=_rule fel=_rule]
|
||||
;~((comp raq) fel (stir rud raq ;~(pfix bus fel)))
|
||||
::
|
||||
|
||||
Parser modifier: By composing with a gate, parse a delimited list of
|
||||
matches.
|
||||
|
||||
`bus` is a [rule]().
|
||||
|
||||
`fel` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "20+5+110" ((slug add) lus dem))
|
||||
135
|
||||
~zod/try=> `@t`(scan "a b c" ((slug |=(a=[@ @t] (cat 3 a))) ace alp))
|
||||
'abc'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++star`
|
||||
|
||||
++ star :: 0 or more times
|
||||
|* fel=_rule
|
||||
(stir `(list ,_(wonk *fel))`~ |*([a=* b=*] [a b]) fel)
|
||||
|
||||
Parser modifier: parse list of matches.
|
||||
|
||||
`fel` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "aaaaa" (just 'a'))
|
||||
! {1 2}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> (scan "aaaaa" (star (just 'a')))
|
||||
"aaaaa"
|
||||
~zod/try=> (scan "abcdef" (star (just 'a')))
|
||||
! {1 2}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> (scan "abcabc" (star (jest 'abc')))
|
||||
<|abc abc|>
|
||||
~zod/try=> (scan "john smith" (star (shim 0 200)))
|
||||
"john smith"
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,648 +0,0 @@
|
||||
section 2eF, parsing (ascii)
|
||||
============================
|
||||
|
||||
### `++ace`
|
||||
|
||||
Parse space
|
||||
|
||||
++ ace (just ' ')
|
||||
|
||||
Parses ASCII character 32, space.
|
||||
|
||||
~zod/try=> (scan " " ace)
|
||||
~~.
|
||||
~zod/try=> `cord`(scan " " ace)
|
||||
' '
|
||||
~zod/try=> (ace [[1 1] " "])
|
||||
[p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (ace [[1 1] " abc "])
|
||||
[p=[p=1 q=2] q=[~ [p=~~. q=[p=[p=1 q=2] q="abc "]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++bar`
|
||||
|
||||
Parse vertical bar
|
||||
|
||||
++ bar (just '|')
|
||||
|
||||
Parses ASCII character 124, the vertical bar.
|
||||
|
||||
~zod/try=> (scan "|" bar)
|
||||
~~~7c.
|
||||
~zod/try=> `cord`(scan "|" bar)
|
||||
'|'
|
||||
~zod/try=> (bar [[1 1] "|"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~7c. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (bar [[1 1] "|="])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~7c. q=[p=[p=1 q=2] q="="]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++bas`
|
||||
|
||||
Parse backslash
|
||||
|
||||
++ bas (just '\\')
|
||||
|
||||
Parses ASCII character 92, the backslash. Note the extra `\` in the slam
|
||||
of `bas` with [`++just`](/doc/hoon/library/2ec#++just) is to escape the escape character, `\`.
|
||||
|
||||
~zod/try=> (scan "\\" bas)
|
||||
~~~5c.
|
||||
~zod/try=> `cord`(scan "\\" bas)
|
||||
'\'
|
||||
~zod/try=> (bas [[1 1] "\"])
|
||||
~ <syntax error at [1 18]>
|
||||
~zod/try=> (bas [[1 1] "\\"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~5c. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (bas [[1 1] "\""])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++buc`
|
||||
|
||||
Parse dollar sign
|
||||
|
||||
++ buc (just '$')
|
||||
|
||||
Parses ASCII character 36, the dollar sign.
|
||||
|
||||
~zod/try=> (scan "$" buc)
|
||||
~~~24.
|
||||
~zod/try=> `cord`(scan "$" buc)
|
||||
'$'
|
||||
~zod/try=> (buc [[1 1] "$"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~24. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (buc [[1 1] "$%"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~24. q=[p=[p=1 q=2] q="%"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++cab`
|
||||
|
||||
Parse underscore
|
||||
|
||||
++ cab (just '_')
|
||||
|
||||
Parses ASCII character 95, the underscore.
|
||||
|
||||
~zod/try=> (scan "_" cab)
|
||||
~~~5f.
|
||||
~zod/try=> `cord`(scan "_" cab)
|
||||
'_'
|
||||
~zod/try=> (cab [[1 1] "_"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~5f. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (cab [[1 1] "|_"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++cen`
|
||||
|
||||
Parses percent sign
|
||||
|
||||
++ cen (just '%')
|
||||
|
||||
Parses ASCII character 37, the percent sign.
|
||||
|
||||
~zod/try=> (scan "%" cen)
|
||||
~~~25.
|
||||
~zod/try=> `cord`(scan "%" cen)
|
||||
'%'
|
||||
~zod/try=> (cen [[1 1] "%"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~25. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (cen [[1 1] "%^"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~25. q=[p=[p=1 q=2] q="^"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++col`
|
||||
|
||||
Parse colon
|
||||
|
||||
++ col (just ':')
|
||||
|
||||
Parses ASCII character 58, the colon
|
||||
|
||||
~zod/try=> (scan ":" col)
|
||||
~~~3a.
|
||||
~zod/try=> `cord`(scan ":" col)
|
||||
':'
|
||||
~zod/try=> (col [[1 1] ":"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3a. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (col [[1 1] ":-"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3a. q=[p=[p=1 q=2] q="-"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++com`
|
||||
|
||||
Parse comma
|
||||
|
||||
++ com (just ',')
|
||||
|
||||
Parses ASCII character 44, the comma.
|
||||
|
||||
~zod/try=> (scan "," com)
|
||||
~~~2c.
|
||||
~zod/try=> `cord`(scan "," com)
|
||||
','
|
||||
~zod/try=> (com [[1 1] ","])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~2c. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (com [[1 1] "not com"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++doq`
|
||||
|
||||
Parse double quote
|
||||
|
||||
++ doq (just '"')
|
||||
|
||||
Parses ASCII character 34, the double quote.
|
||||
|
||||
~tadbyl-hilbel/try=> (scan "\"" doq)
|
||||
~~~22.
|
||||
~tadbyl-hilbel/try=> `cord`(scan "\"" doq)
|
||||
'"'
|
||||
~tadbyl-hilbel/try=> (doq [[1 1] "\""])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~22. q=[p=[p=1 q=2] q=""]]]]
|
||||
~tadbyl-hilbel/try=> (doq [[1 1] "not successfully parsed"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
~tadbyl-hilbel/try=> (scan "see?" doq)
|
||||
! {1 1}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dot`
|
||||
|
||||
Parse period
|
||||
|
||||
++ dot (just '.')
|
||||
|
||||
Parses ASCII character 46, the period.
|
||||
|
||||
~zod/try=> (scan "." dot)
|
||||
~~~.
|
||||
~zod/try=> `cord`(scan "." dot)
|
||||
'.'
|
||||
~zod/try=> (dot [[1 1] "."])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (dot [[1 1] ".^"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~. q=[p=[p=1 q=2] q="^"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fas`
|
||||
|
||||
Parse forward slash
|
||||
|
||||
++ fas (just '/')
|
||||
|
||||
Parses ASCII character 47, the forward slash.
|
||||
|
||||
~zod/try=> (scan "/" fas)
|
||||
~~~2f.
|
||||
~zod/try=> `cord`(scan "/" fas)
|
||||
'/'
|
||||
~zod/try=> (fas [[1 1] "/"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~2f. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (fas [[1 1] "|/"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gal`
|
||||
|
||||
Parse less-than sign
|
||||
|
||||
++ gal (just '<')
|
||||
|
||||
Parses ASCII character 60, the less-than sign.
|
||||
|
||||
~zod/try=> (scan "<" gal)
|
||||
~~~3c.
|
||||
~zod/try=> `cord`(scan "<" gal)
|
||||
'<'
|
||||
~zod/try=> (gal [[1 1] "<"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3c. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (gal [[1 1] "<+"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3c. q=[p=[p=1 q=2] q="+"]]]]
|
||||
~zod/try=> (gal [[1 1] "+<"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gar`
|
||||
|
||||
Parse greater-than sign
|
||||
|
||||
++ gar (just '>')
|
||||
|
||||
Parses ASCII character 62, the greater-than sign.
|
||||
|
||||
~zod/try=> (scan ">" gar)
|
||||
~~~3e.
|
||||
~zod/try=> `cord`(scan ">" gar)
|
||||
'>'
|
||||
~zod/try=> (gar [[1 1] ">"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3e. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (gar [[1 1] "=>"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++hax`
|
||||
|
||||
Parse number sign
|
||||
|
||||
++ hax (just '#')
|
||||
|
||||
Parses ASCII character 35, the number sign.
|
||||
|
||||
~zod/try=> (scan "#" hax)
|
||||
~~~23.
|
||||
~zod/try=> `cord`(scan "#" hax)
|
||||
'#'
|
||||
~zod/try=> (hax [[1 1] "#"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~23. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (hax [[1 1] "#!"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~23. q=[p=[p=1 q=2] q="!"]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++kel`
|
||||
|
||||
Parse left curley bracket
|
||||
|
||||
++ kel (just '{')
|
||||
|
||||
Parses ASCII character 123, the left curly bracket. Note that `{`
|
||||
(`kel`) and `}` (`ker`) open and close a Hoon expression for Hoon string
|
||||
interpolation. To parse either of them, they must be escaped.
|
||||
|
||||
~zod/try=> (scan "\{" kel)
|
||||
~~~7b.
|
||||
~zod/try=> `cord`(scan "\{" kel)
|
||||
'{'
|
||||
~zod/try=> (kel [[1 1] "\{"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~7b. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (kel [[1 1] " \{"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ker`
|
||||
|
||||
Parse right curley bracket
|
||||
|
||||
++ ker (just '}')
|
||||
|
||||
Parses ASCII character 125, the right curly bracket. Note that `{`
|
||||
(`kel`) and `}` (`ker`) open and close a Hoon expression for Hoon string
|
||||
interpolation. To parse either of them, they must be escaped.
|
||||
|
||||
~zod/try=> (scan "}" ker)
|
||||
~~~7d.
|
||||
~zod/try=> `cord`(scan "}" ker)
|
||||
'}'
|
||||
~zod/try=> (ker [[1 1] "}"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~7d. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (ker [[1 1] "\{}"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ket`
|
||||
|
||||
Parse caret
|
||||
|
||||
++ ket (just '^')
|
||||
|
||||
Parses ASCII character 94, the caret.
|
||||
|
||||
~zod/try=> (scan "^" ket)
|
||||
~~~5e.
|
||||
~zod/try=> `cord`(scan "^" ket)
|
||||
'^'
|
||||
~zod/try=> (ket [[1 1] "^"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~5e. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (ket [[1 1] ".^"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lus`
|
||||
|
||||
Parse plus sign
|
||||
|
||||
++ lus (just '+')
|
||||
|
||||
Parses ASCII character 43, the plus sign.
|
||||
|
||||
~zod/try=> (scan "+" lus)
|
||||
~~~2b.
|
||||
~zod/try=> `cord`(scan "+" lus)
|
||||
'+'
|
||||
~zod/try=> (lus [[1 1] "+"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~2b. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (lus [[1 1] ".+"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++hep`
|
||||
|
||||
Parse hyphen
|
||||
|
||||
++ hep (just '-')
|
||||
|
||||
Parses ASCII character 45, the hyphen.
|
||||
|
||||
~zod/try=> (scan "-" hep)
|
||||
~~-
|
||||
~zod/try=> `cord`(scan "-" hep)
|
||||
'-'
|
||||
~zod/try=> (hep [[1 1] "-"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~- q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (hep [[1 1] ":-"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pel`
|
||||
|
||||
Parse left parenthesis
|
||||
|
||||
++ pel (just '(')
|
||||
|
||||
Parses ASCII character 40, the left parenthesis.
|
||||
|
||||
~zod/try=> (scan "(" pel)
|
||||
~~~28.
|
||||
~zod/try=> `cord`(scan "(" pel)
|
||||
'('
|
||||
~zod/try=> (pel [[1 1] "("])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~28. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (pel [[1 1] ";("])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pam`
|
||||
|
||||
Parse ampersand
|
||||
|
||||
++ pam (just '&')
|
||||
|
||||
Parses ASCII character 38, the ampersand.
|
||||
|
||||
~zod/try=> (scan "&" pam)
|
||||
~~~26.
|
||||
~zod/try=> `cord`(scan "&" pam)
|
||||
'&'
|
||||
~zod/try=> (pam [[1 1] "&"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~26. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (pam [[1 1] "?&"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++per`
|
||||
|
||||
Parse right parenthesis
|
||||
|
||||
++ per (just ')')
|
||||
|
||||
Parses ASCII character 41, the right parenthesis.
|
||||
|
||||
~zod/try=> (scan ")" per)
|
||||
~~~29.
|
||||
~zod/try=> `cord`(scan ")" per)
|
||||
')'
|
||||
~zod/try=> (per [[1 1] ")"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~29. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (per [[1 1] " )"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pat`
|
||||
|
||||
Parse "at" sign
|
||||
|
||||
++ pat (just '@')
|
||||
|
||||
Parses ASCII character 64, the "at" sign.
|
||||
|
||||
~zod/try=> (scan "@" pat)
|
||||
~~~4.
|
||||
~zod/try=> `cord`(scan "@" pat)
|
||||
'@'
|
||||
~zod/try=> (pat [[1 1] "@"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~4. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (pat [[1 1] "?@"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sel`
|
||||
|
||||
Parse left square bracket
|
||||
|
||||
Left square bracket
|
||||
|
||||
++ sel (just '[')
|
||||
|
||||
Parses ASCII character 91, the left square bracket.
|
||||
|
||||
~zod/try=> (scan "[" sel)
|
||||
~~~5b.
|
||||
~zod/try=> `cord`(scan "[" sel)
|
||||
'['
|
||||
~zod/try=> (sel [[1 1] "["])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~5b. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (sel [[1 1] "-["])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sem`
|
||||
|
||||
Parse semicolon
|
||||
|
||||
++ sem (just ';')
|
||||
|
||||
Parses ASCII character 59, the semicolon.
|
||||
|
||||
### `Examples`
|
||||
|
||||
~zod/try=> (scan ";" sem)
|
||||
~~~3b.
|
||||
~zod/try=> `cord`(scan ";" sem)
|
||||
';'
|
||||
~zod/try=> (sem [[1 1] ";"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3b. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (sem [[1 1] " ;"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ser`
|
||||
|
||||
Parse right square bracket
|
||||
|
||||
++ ser (just ']')
|
||||
|
||||
Parses ASCII character 93, the right square bracket.
|
||||
|
||||
~zod/try=> (scan "]" ser)
|
||||
~~~5d.
|
||||
~zod/try=> `cord`(scan "]" ser)
|
||||
']'
|
||||
~zod/try=> (ser [[1 1] "]"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~5d. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (ser [[1 1] "[ ]"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sig`
|
||||
|
||||
Parse tilde
|
||||
|
||||
++ sig (just '~')
|
||||
|
||||
Parses ASCII character 126, the tilde.
|
||||
|
||||
~zod/try=> (scan "~" sig)
|
||||
~~~~
|
||||
~zod/try=> `cord`(scan "~" sig)
|
||||
'~'
|
||||
~zod/try=> (sig [[1 1] "~"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~~ q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (sig [[1 1] "?~"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++soq`
|
||||
|
||||
Parse single quote
|
||||
|
||||
++ soq (just '\'')
|
||||
|
||||
Parses ASCII character 39, soq. Note the extra '' is to escape the first
|
||||
`soq` because soq delimits a cord.
|
||||
|
||||
~zod/try=> (scan "'" soq)
|
||||
~~~27.
|
||||
~zod/try=> `cord`(scan "'" soq)
|
||||
'''
|
||||
~zod/try=> (soq [[1 1] "'"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~27. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (soq [[1 1] ">'"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++tar`
|
||||
|
||||
Parse asterisk
|
||||
|
||||
++ tar (just '*')
|
||||
|
||||
Parses ASCII character 42, the asterisk.
|
||||
|
||||
~zod/try=> (scan "*" tar)
|
||||
~~~2a.
|
||||
~zod/try=> `cord`(scan "*" tar)
|
||||
'*'
|
||||
~zod/try=> (tar [[1 1] "*"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~2a. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (tar [[1 1] ".*"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++tec`
|
||||
|
||||
Parse backtick
|
||||
|
||||
++ tec (just '`') :: backTiCk
|
||||
|
||||
Parses ASCII character 96, the backtick (also known as the "grave
|
||||
accent".
|
||||
|
||||
~zod/try=> (scan "`" tec)
|
||||
~~~6.
|
||||
~zod/try=> `cord`(scan "`" tec)
|
||||
'`'
|
||||
~zod/try=> (tec [[1 1] "`"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~6. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (tec [[1 1] " `"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++tis`
|
||||
|
||||
Parse equals sign
|
||||
|
||||
++ tis (just '=')
|
||||
|
||||
Parses ASCII character 61, the equals sign.
|
||||
|
||||
~zod/try=> (scan "=" tis)
|
||||
~~~3d.
|
||||
~zod/try=> `cord`(scan "=" tis)
|
||||
'='
|
||||
~zod/try=> (tis [[1 1] "="])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3d. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (tis [[1 1] "|="])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wut`
|
||||
|
||||
Parses question mark
|
||||
|
||||
++ wut (just '?')
|
||||
|
||||
Parses ASCII character 63, wut.
|
||||
|
||||
~zod/try=> (scan "?" wut)
|
||||
~~~3f.
|
||||
~zod/try=> `cord`(scan "?" wut)
|
||||
'?'
|
||||
~zod/try=> (wut [[1 1] "?"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~3f. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (wut [[1 1] ".?"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++zap`
|
||||
|
||||
Exclamation point
|
||||
|
||||
++ zap (just '!')
|
||||
|
||||
Parses ASCII character 33, the exclamation point zap.
|
||||
|
||||
~zod/try=> (scan "!" zap)
|
||||
~~~21.
|
||||
~zod/try=> `cord`(scan "!" zap)
|
||||
'!'
|
||||
~zod/try=> (zap [[1 1] "!"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~21. q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (zap [[1 1] "?!"])
|
||||
[p=[p=1 q=1] q=~]
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,160 +0,0 @@
|
||||
section 2eG, parsing (whitespace)
|
||||
=================================
|
||||
|
||||
### `++dog`
|
||||
|
||||
`.` optional gap
|
||||
|
||||
++ dog ;~(plug dot gay) ::
|
||||
|
||||
Dot followed by an optional gap, used in numbers.
|
||||
|
||||
/~zod/try=> 1.234.
|
||||
703
|
||||
1.234.703
|
||||
~zod/try=> (scan "a. " ;~(pfix alf dog))
|
||||
[~~~. ~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++doh`
|
||||
|
||||
`@p` separator
|
||||
|
||||
++ doh ;~(plug ;~(plug hep hep) gay) ::
|
||||
|
||||
Phonetic base phrase separator
|
||||
|
||||
/~zod/try=> ~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
|
||||
~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
|
||||
/~zod/try=> ~nopfel-botduc-nilnev-dolfyn--
|
||||
haspub-natlun-lodmur-holtyd
|
||||
~nopfel-botduc-nilnev-dolfyn--haspub-natlun-lodmur-holtyd
|
||||
~zod/try=> (scan "--" doh)
|
||||
[[~~- ~~-] ~]
|
||||
~zod/try=> (scan "-- " doh)
|
||||
[[~~- ~~-] ~]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dun`
|
||||
|
||||
`--` to `~`
|
||||
|
||||
++ dun (cold ~ ;~(plug hep hep)) :: -- (phep) to ~
|
||||
|
||||
Parse phep, `--`, to null, `~`.
|
||||
|
||||
~zod/try=> (scan "--" dun)
|
||||
~
|
||||
~zod/try=> (dun [[1 1] "--"])
|
||||
[p=[p=1 q=3] q=[~ u=[p=~ q=[p=[p=1 q=3] q=""]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++duz`
|
||||
|
||||
`==` to `~`
|
||||
|
||||
++ duz (cold ~ ;~(plug tis tis)) :: == (stet) to ~
|
||||
|
||||
Parse stet, `==`, to null `~`.
|
||||
|
||||
~zod/try=> (scan "==" duz)
|
||||
~
|
||||
~zod/try=> (duz [[1 1] "== |=..."])
|
||||
[p=[p=1 q=3] q=[~ u=[p=~ q=[p=[p=1 q=3] q=" |=..."]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gah`
|
||||
|
||||
Newline or ' '
|
||||
|
||||
++ gah (mask [`@`10 ' ' ~]) :: newline or ace
|
||||
|
||||
Whitespace component, either newline or space.
|
||||
|
||||
/~zod/try=> ^- * :: show spaces
|
||||
"""
|
||||
-
|
||||
-
|
||||
-
|
||||
"""
|
||||
[32 32 32 45 10 32 45 10 32 32 45 0]
|
||||
/~zod/try=> ^- *
|
||||
"""
|
||||
|
||||
"""
|
||||
[32 32 32 10 32 10 32 32 0]
|
||||
/~zod/try=> ^- (list ,@)
|
||||
%- scan :_ (star gah)
|
||||
"""
|
||||
|
||||
"""
|
||||
~[32 32 32 10 32 10 32 32]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gap`
|
||||
|
||||
Plural whitespace
|
||||
|
||||
++ gap (cold ~ ;~(plug gaq (star ;~(pose vul gah)))) :: plural whitespace
|
||||
|
||||
Separates tall runes
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gaq`
|
||||
|
||||
End of line
|
||||
|
||||
++ gaq ;~ pose :: end of line
|
||||
(just `@`10)
|
||||
;~(plug gah ;~(pose gah vul))
|
||||
vul
|
||||
==
|
||||
|
||||
Two spaces, a newline, or comment.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gaw`
|
||||
|
||||
Classic whitespace
|
||||
|
||||
++ gaw (cold ~ (star ;~(pose vul gah))) :: classic white
|
||||
|
||||
Terran whitespace
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gay`
|
||||
|
||||
Optional gap.
|
||||
|
||||
++ gay ;~(pose gap (easy ~)) ::
|
||||
|
||||
Optional gap.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++vul`
|
||||
|
||||
++ vul %- cold :- ~ :: comments
|
||||
;~ plug col col
|
||||
(star prn)
|
||||
(just `@`10)
|
||||
==
|
||||
|
||||
Parse comments and produce a null. Note that a comment must be ended
|
||||
with a newline character.
|
||||
|
||||
~zod/try=> (scan "::this is a comment \0a" vul)
|
||||
~
|
||||
~zod/try=> (scan "::this is a comment " vul)
|
||||
! {1 21}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,531 +0,0 @@
|
||||
section 2eH, parsing (idioms)
|
||||
=============================
|
||||
|
||||
### `++alf`
|
||||
|
||||
Alphabetic characters
|
||||
|
||||
++ alf ;~(pose low hig) :: alphabetic
|
||||
|
||||
Parse alphabetic characters, both upper and lowercase.
|
||||
|
||||
~zod/try=> (scan "a" alf)
|
||||
~~a
|
||||
~zod/try=> (scan "A" alf)
|
||||
~~~41.
|
||||
~zod/try=> (scan "AaBbCc" (star alf))
|
||||
"AaBbCc"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++aln`
|
||||
|
||||
Alphanumeric characters
|
||||
|
||||
++ aln ;~(pose low hig nud) :: alphanumeric
|
||||
|
||||
Parse alphanumeric characters - both alphabetic characters and numbers.
|
||||
|
||||
~zod/try=> (scan "0" aln)
|
||||
~~0
|
||||
~zod/try=> (scan "alf42" (star aln))
|
||||
"alf42"
|
||||
~zod/try=> (scan "0123456789abcdef" (star aln))
|
||||
"0123456789abcdef"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++alp`
|
||||
|
||||
Alphanumeric and `-`
|
||||
|
||||
++ alp ;~(pose low hig nud hep) :: alphanumeric and -
|
||||
|
||||
Parse alphanumeric strings and hep, "-".
|
||||
|
||||
~zod/try=> (scan "7" alp)
|
||||
~~7
|
||||
~zod/try=> (scan "s" alp)
|
||||
~~s
|
||||
~zod/try=> (scan "123abc-" (star alp))
|
||||
"123abc-"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++bet`
|
||||
|
||||
Axis syntax `-`, `+`
|
||||
|
||||
++ bet ;~(pose (cold 2 hep) (cold 3 lus)) :: axis syntax - +
|
||||
|
||||
Parse the hep and lus axis syntax.
|
||||
|
||||
~zod/try=> (scan "-" bet)
|
||||
2
|
||||
~zod/try=> (scan "+" bet)
|
||||
3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++bin`
|
||||
|
||||
Binary to atom
|
||||
|
||||
++ bin (bass 2 (most gon but)) :: binary to atom
|
||||
|
||||
Parse a tape of binary (0s and 1s) and produce its atomic
|
||||
representation.
|
||||
|
||||
~zod/try=> (scan "0000" bin)
|
||||
0
|
||||
~zod/try=> (scan "0001" bin)
|
||||
1
|
||||
~zod/try=> (scan "0010" bin)
|
||||
2
|
||||
~zod/try=> (scan "100000001111" bin)
|
||||
2.063
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++but`
|
||||
|
||||
Binary digit
|
||||
|
||||
++ but (cook |=(a=@ (sub a '0')) (shim '0' '1')) :: binary digit
|
||||
|
||||
Parse a single binary digit.
|
||||
|
||||
~zod/try=> (scan "0" but)
|
||||
0
|
||||
~zod/try=> (scan "1" but)
|
||||
1
|
||||
~zod/try=> (scan "01" but)
|
||||
! {1 2}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> (scan "01" (star but))
|
||||
~[0 1]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++cit`
|
||||
|
||||
Octal digit
|
||||
|
||||
++ cit (cook |=(a=@ (sub a '0')) (shim '0' '7')) :: octal digit
|
||||
|
||||
Parse a single octal digit.
|
||||
|
||||
~zod/try=> (scan "1" cit)
|
||||
1
|
||||
~zod/try=> (scan "7" cit)
|
||||
7
|
||||
~zod/try=> (scan "8" cit)
|
||||
! {1 1}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> (scan "60" (star cit))
|
||||
~[6 0]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dem`
|
||||
|
||||
Decimal to atom
|
||||
|
||||
++ dem (bass 10 (most gon dit)) :: decimal to atom
|
||||
|
||||
Parse a decimal number to an atom.
|
||||
|
||||
~zod/try=> (scan "7" dem)
|
||||
7
|
||||
~zod/try=> (scan "42" dem)
|
||||
42
|
||||
~zod/try=> (scan "150000000" dem)
|
||||
150.000.000
|
||||
~zod/try=> (scan "12456" dem)
|
||||
12.456
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dit`
|
||||
|
||||
Decimal digit
|
||||
|
||||
++ dit (cook |=(a=@ (sub a '0')) (shim '0' '9')) :: decimal digit
|
||||
|
||||
Parse a single decimal digit.
|
||||
|
||||
~zod/try=> (scan "7" dit)
|
||||
7
|
||||
~zod/try=> (scan "42" (star dit))
|
||||
~[4 2]
|
||||
~zod/try=> (scan "26000" (star dit))
|
||||
~[2 6 0 0 0]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gul`
|
||||
|
||||
Axis syntax `<` or `>`
|
||||
|
||||
++ gul ;~(pose (cold 2 gal) (cold 3 gar)) :: axis syntax < >
|
||||
|
||||
Parse the axis gal and gar axis syntax.
|
||||
|
||||
~zod/try=> (scan "<" gul)
|
||||
2
|
||||
~zod/try=> (scan ">" gul)
|
||||
3
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++gon`
|
||||
|
||||
Long numbers
|
||||
|
||||
++ gon ;~(pose ;~(plug bas gay fas) (easy ~)) :: long numbers \ /
|
||||
|
||||
Parse long numbers - Numbers which wrap around the shell with the line
|
||||
break characters bas and fas.
|
||||
|
||||
~zod/try=> (scan "\\/" gon)
|
||||
[~~~5c. ~ ~~~2f.]
|
||||
~zod/try=> (gon [[1 1] "\\/"])
|
||||
[p=[p=1 q=3] q=[~ u=[p=[~~~5c. ~ ~~~2f.] q=[p=[p=1 q=3] q=""]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++hex`
|
||||
|
||||
Hex to atom
|
||||
|
||||
++ hex (bass 16 (most gon hit)) :: hex to atom
|
||||
|
||||
Parse any hexadecimal number to an atom.
|
||||
|
||||
~zod/try=> (scan "a" hex)
|
||||
10
|
||||
~zod/try=> (scan "A" hex)
|
||||
10
|
||||
~zod/try=> (scan "2A" hex)
|
||||
42
|
||||
~zod/try=> (scan "1ee7" hex)
|
||||
7.911
|
||||
~zod/try=> (scan "1EE7" hex)
|
||||
7.911
|
||||
~zod/try=> (scan "1EE7F7" hex)
|
||||
2.025.463
|
||||
~zod/try=> `@ux`(scan "1EE7F7" hex)
|
||||
0x1e.e7f7
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++hig`
|
||||
|
||||
Uppercase
|
||||
|
||||
++ hig (shim 'A' 'Z') :: uppercase
|
||||
|
||||
Parse a single uppercase letter.
|
||||
|
||||
~zod/try=> (scan "G" hig)
|
||||
~~~47.
|
||||
~zod/try=> `cord`(scan "G" hig)
|
||||
'G'
|
||||
~zod/try=> (scan "ABCDEFGHIJKLMNOPQRSTUVWXYZ" (star hig))
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
~zod/try=> (hig [[1 1] "G"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~~47. q=[p=[p=1 q=2] q=""]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++hit`
|
||||
|
||||
Hex digits
|
||||
|
||||
++ hit ;~ pose :: hex digits
|
||||
dit
|
||||
(cook |=(a=char (sub a 87)) (shim 'a' 'f'))
|
||||
(cook |=(a=char (sub a 55)) (shim 'A' 'F'))
|
||||
==
|
||||
|
||||
Parse a single hexadecimal digit.
|
||||
|
||||
~zod/try=> (scan "a" hit)
|
||||
10
|
||||
~zod/try=> (scan "A" hit)
|
||||
10
|
||||
~zod/try=> (hit [[1 1] "a"])
|
||||
[p=[p=1 q=2] q=[~ [p=10 q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (scan "2A" (star hit))
|
||||
~[2 10]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++low`
|
||||
|
||||
Lowercase
|
||||
|
||||
++ low (shim 'a' 'z') :: lowercase
|
||||
|
||||
Parse a single lowercase letter.
|
||||
|
||||
~zod/try=> (scan "g" low)
|
||||
~~g
|
||||
~zod/try=> `cord`(scan "g" low)
|
||||
'g'
|
||||
~zod/try=> (scan "abcdefghijklmnopqrstuvwxyz" (star low))
|
||||
"abcdefghijklmnopqrstuvwxyz"
|
||||
~zod/try=> (low [[1 1] "g"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~g q=[p=[p=1 q=2] q=""]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mes`
|
||||
|
||||
Hexbyte
|
||||
|
||||
++ mes %+ cook :: hexbyte
|
||||
|=([a=@ b=@] (add (mul 16 a) b))
|
||||
;~(plug hit hit)
|
||||
|
||||
Parse a hexbyte.
|
||||
|
||||
~zod/try=> (scan "2A" mes)
|
||||
42
|
||||
~zod/try=> (mes [[1 1] "2A"])
|
||||
[p=[p=1 q=3] q=[~ u=[p=42 q=[p=[p=1 q=3] q=""]]]]
|
||||
~zod/try=> (scan "42" mes)
|
||||
66
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++nix`
|
||||
|
||||
Letters, `-`, and `_`
|
||||
|
||||
++ nix (boss 256 (star ;~(pose aln cab))) ::
|
||||
|
||||
Letters, `-`, and `_`
|
||||
|
||||
~zod/try=> (scan "as_me" nix)
|
||||
q=435.626.668.897
|
||||
~zod/try=> `@t`(scan "as_me" nix)
|
||||
'as_me'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++nud`
|
||||
|
||||
Numeric
|
||||
|
||||
++ nud (shim '0' '9') :: numeric
|
||||
|
||||
Parse a numeric character - A number.
|
||||
|
||||
~zod/try=> (scan "0" nud)
|
||||
~~0
|
||||
~zod/try=> (scan "7" nud)
|
||||
~~7
|
||||
~zod/try=> (nud [[1 1] "1"])
|
||||
[p=[p=1 q=2] q=[~ [p=~~1 q=[p=[p=1 q=2] q=""]]]]
|
||||
~zod/try=> (scan "0123456789" (star nud))
|
||||
"0123456789"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++prn`
|
||||
|
||||
Printable character
|
||||
|
||||
++ prn ;~(less (just `@`127) (shim 32 256))
|
||||
|
||||
Parse any printable character
|
||||
|
||||
~zod/try=> (scan "h" prn)
|
||||
~~h
|
||||
~zod/try=> (scan "!" prn)
|
||||
~~~21.
|
||||
~zod/try=> (scan "\01" prn)
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++qat`
|
||||
|
||||
Chars in blockcord
|
||||
|
||||
++ qat ;~ pose :: chars in blockcord
|
||||
prn
|
||||
;~(less ;~(plug (just `@`10) soqs) (just `@`10))
|
||||
==
|
||||
|
||||
Parse character in cord block.
|
||||
|
||||
~zod/try=> (scan "h" qat)
|
||||
~~h
|
||||
~zod/try=> (scan "!" qat)
|
||||
~~~21.
|
||||
~zod/try=> (scan "\0a" qat)
|
||||
~~~a.
|
||||
~zod/try=> (scan "\00" qat)
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++qit`
|
||||
|
||||
Chars in cord
|
||||
|
||||
++ qit ;~ pose :: chars in a cord
|
||||
;~(less bas soq prn)
|
||||
;~(pfix bas ;~(pose bas soq mes)) :: escape chars
|
||||
==
|
||||
|
||||
Parse an individual character to its cord atom representation.
|
||||
|
||||
~zod/try=> (scan "%" qit)
|
||||
37
|
||||
~zod/try=> `@t`(scan "%" qit)
|
||||
'%'
|
||||
~zod/try=> (scan "0" qit)
|
||||
48
|
||||
~zod/try=> (scan "E" qit)
|
||||
69
|
||||
~zod/try=> (scan "a" qit)
|
||||
97
|
||||
~zod/try=> (scan "\\0a" qit)
|
||||
10
|
||||
~zod/try=> `@ux`(scan "\\0a" qit)
|
||||
0xa
|
||||
~zod/try=> (scan "cord" (star qit))
|
||||
~[99 111 114 100]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++qut`
|
||||
|
||||
Cord
|
||||
|
||||
++ qut ;~ pose :: cord
|
||||
;~ less soqs
|
||||
(ifix [soq soq] (boss 256 (more gon qit)))
|
||||
==
|
||||
%- inde %+ ifix
|
||||
:- ;~ plug soqs
|
||||
;~(pose ;~(plug (plus ace) vul) (just '\0a'))
|
||||
==
|
||||
;~(plug (just '\0a') soqs)
|
||||
(boss 256 (star qat))
|
||||
==
|
||||
::
|
||||
|
||||
Parse single-soq cord with `\{gap}/` anywhere in the middle, or
|
||||
triple-soq cord which must be in an indented block.
|
||||
|
||||
~zod/try=> (scan "'cord'" qut)
|
||||
q=1.685.221.219
|
||||
~zod/try=> 'cord'
|
||||
'cord'
|
||||
~zod/try=> `@ud`'cord'
|
||||
1.685.221.219
|
||||
/~zod/try=> '''
|
||||
Heredoc isn't prohibited from containing quotes
|
||||
'''
|
||||
'Heredoc isn't prohibited from containing quotes'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++soqs`
|
||||
|
||||
Delimiting `'''`
|
||||
|
||||
++ soqs ;~(plug soq soq soq) :: delimiting '''
|
||||
|
||||
Triple single quote
|
||||
|
||||
~zod/try=> (scan "'''" soqs)
|
||||
[~~~27. ~~~27. ~~~27.]
|
||||
~zod/try=> (rash '"""' soqs)
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sym`
|
||||
|
||||
Term
|
||||
|
||||
++ sym
|
||||
%+ cook
|
||||
|=(a=tape (rap 3 ^-((list ,@) a)))
|
||||
;~(plug low (star ;~(pose nud low hep)))
|
||||
::
|
||||
|
||||
A term: a letter(lowercase), followed by letters, numbers, or `-`.
|
||||
|
||||
~zod/try=> (scan "sam-2" sym)
|
||||
215.510.507.891
|
||||
~zod/try=> `@t`(scan "sam-2" sym)
|
||||
'sam-2'
|
||||
~zod/try=> (scan "sym" sym)
|
||||
7.174.515
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ven`
|
||||
|
||||
`+>-` axis syntax
|
||||
|
||||
++ ven ;~ (comp |=([a=@ b=@] (peg a b))) :: +>- axis syntax
|
||||
bet
|
||||
=+ hom=`?`|
|
||||
|= tub=nail
|
||||
^- (like axis)
|
||||
=+ vex=?:(hom (bet tub) (gul tub))
|
||||
?~ q.vex
|
||||
[p.tub [~ 1 tub]]
|
||||
=+ wag=$(p.tub p.vex, hom !hom, tub q.u.q.vex)
|
||||
?> ?=(^ q.wag)
|
||||
[p.wag [~ (peg p.u.q.vex p.u.q.wag) q.u.q.wag]]
|
||||
==
|
||||
|
||||
Axis syntax parser
|
||||
|
||||
~zod/arvo=/hoon/hoon> (scan "->+" ven)
|
||||
11
|
||||
~zod/arvo=/hoon/hoon> `@ub`(scan "->+" ven)
|
||||
0b1011
|
||||
~zod/arvo=/hoon/hoon> (peg (scan "->" ven) (scan "+" ven))
|
||||
11
|
||||
~zod/arvo=/hoon/hoon> ->+:[[1 2 [3 4]] 5]
|
||||
[3 4]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++vit`
|
||||
|
||||
Base64 digit
|
||||
|
||||
++ vit :: base64 digit
|
||||
;~ pose
|
||||
(cook |=(a=@ (sub a 65)) (shim 'A' 'Z'))
|
||||
(cook |=(a=@ (sub a 71)) (shim 'a' 'z'))
|
||||
(cook |=(a=@ (add a 4)) (shim '0' '9'))
|
||||
(cold 62 (just '-'))
|
||||
(cold 63 (just '+'))
|
||||
==
|
||||
|
||||
Terran base64
|
||||
|
||||
~zod/arvo=/hoon/hoon> (scan "C" vit)
|
||||
2
|
||||
~zod/arvo=/hoon/hoon> (scan "c" vit)
|
||||
28
|
||||
~zod/arvo=/hoon/hoon> (scan "2" vit)
|
||||
54
|
||||
~zod/arvo=/hoon/hoon> (scan "-" vit)
|
||||
62
|
@ -1,107 +0,0 @@
|
||||
section 2eI, parsing (external)
|
||||
===============================
|
||||
|
||||
### `++rash`
|
||||
|
||||
Parse or crash
|
||||
|
||||
++ rash |*([naf=@ sab=_rule] (scan (trip naf) sab)) ::
|
||||
|
||||
Parse a cord with a given rule and crash if the cord isn't entirely
|
||||
parsed.
|
||||
|
||||
`naf` is an [atom]().
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
~zod/try=> (rash 'I was the world in which I walked, and what I saw' (star (shim 0 200)))
|
||||
"I was the world in which I walked, and what I saw"
|
||||
~zod/try=> (rash 'abc' (just 'a'))
|
||||
! {1 2}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
~zod/try=> (rash 'abc' (jest 'abc'))
|
||||
'abc'
|
||||
`~zod/try=> (rash 'abc' (jest 'ab'))
|
||||
! {1 3}
|
||||
! 'syntax-error'
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++rush`
|
||||
|
||||
Parse or null
|
||||
|
||||
++ rush |*([naf=@ sab=_rule] (rust (trip naf) sab))
|
||||
|
||||
Parse a given with a given rule and produce null if the cord isn't
|
||||
entirely parsed.
|
||||
|
||||
`naf` is an [atom]().
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
~zod/try=> (rush 'I was the world in which I walked, and what I saw' (star (shim 0 200)))
|
||||
[~ "I was the world in which I walked, and what I saw"]
|
||||
~zod/try=> (rush 'abc' (just 'a'))
|
||||
~
|
||||
~zod/try=> (rush 'abc' (jest 'abc'))
|
||||
[~ 'abc']
|
||||
~zod/try=> (rush 'abc' (jest 'ac'))
|
||||
~
|
||||
~zod/try=> (rush 'abc' (jest 'ab'))
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++rust`
|
||||
|
||||
Parse tape or null
|
||||
|
||||
++ rust |* [los=tape sab=_rule]
|
||||
=+ vex=((full sab) [[1 1] los])
|
||||
?~(q.vex ~ [~ u=p.u.q.vex])
|
||||
|
||||
Parse a tape with a given rule and produce null if the tape isn't
|
||||
entirely parsed.
|
||||
|
||||
`los` is a [tape]().
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
~zod/try=> (rust "I was the world in which I walked, and what I saw" (star (shim 0 200)))
|
||||
[~ "I was the world in which I walked, and what I saw"]
|
||||
~zod/try=> (rust "Or heard or felt came not but from myself;" (star (shim 0 200)))
|
||||
[~ "Or heard or felt came not but from myself;"]
|
||||
~zod/try=> (rust "And there I found myself more truly and more strange." (jest 'And there I'))
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++scan`
|
||||
|
||||
Parse tape or crash
|
||||
|
||||
++ scan |* [los=tape sab=_rule]
|
||||
=+ vex=((full sab) [[1 1] los])
|
||||
?~ q.vex
|
||||
~_ (show [%m '{%d %d}'] p.p.vex q.p.vex ~)
|
||||
~|('syntax-error' !!)
|
||||
p.u.q.vex
|
||||
|
||||
Parse a tape with a given rule and crash if the tape isn't entirely
|
||||
parsed.
|
||||
|
||||
`los` is a [tape]().
|
||||
|
||||
`sab` is a [rule]().
|
||||
|
||||
~zod/try=> (scan "I was the world in which I walked, and what I saw" (star (shim 0 200)))
|
||||
"I was the world in which I walked, and what I saw"
|
||||
~zod/try=> (scan "Or heard or felt came not but from myself;" (star (shim 0 200)))
|
||||
"Or heard or felt came not but from myself;"
|
||||
~zod/try=> (scan "And there I found myself more truly and more strange." (jest 'And there I'))
|
||||
! {1 12}
|
||||
! 'syntax-error'
|
||||
! exit
|
@ -1,561 +0,0 @@
|
||||
section 2eJ, formatting (basic text)
|
||||
====================================
|
||||
|
||||
### `++cass`
|
||||
|
||||
To lowercase
|
||||
|
||||
++ cass :: lowercase
|
||||
|= vib=tape
|
||||
%+ rap 3
|
||||
(turn vib |=(a=@ ?.(&((gte a 'A') (lte a 'Z')) a (add 32 a))))
|
||||
::
|
||||
|
||||
Produce the case insensitive (all lowercase) cord of a tape.
|
||||
|
||||
`vib` is a [tape]().
|
||||
|
||||
~zod/try=> (cass "john doe")
|
||||
7.309.170.810.699.673.450
|
||||
~zod/try=> `cord`(cass "john doe")
|
||||
'john doe'
|
||||
~zod/try=> (cass "abc, 123, !@#")
|
||||
2.792.832.775.110.938.439.066.079.945.313
|
||||
~zod/try=> `cord`(cass "abc, 123, !@#")
|
||||
'abc, 123, !@#'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++cuss`
|
||||
|
||||
To uppercase
|
||||
|
||||
++ cuss :: uppercase
|
||||
|= vib=tape
|
||||
^- @t
|
||||
%+ rap 3
|
||||
(turn vib |=(a=@ ?.(&((gte a 'a') (lte a 'z')) a (sub a 32))))
|
||||
::
|
||||
|
||||
Turn all occurances of lowercase letters in any tape into uppercase
|
||||
letters, as a cord.
|
||||
|
||||
`vib` is a [tape]().
|
||||
|
||||
~zod/try=> (cuss "john doe")
|
||||
'JOHN DOE'
|
||||
~zod/try=> (cuss "abc ABC 123 !@#")
|
||||
'ABC ABC 123 !@#'
|
||||
~zod/try=> `@ud`(cuss "abc")
|
||||
4.407.873
|
||||
~zod/try=> (cuss "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsQqRrVvWwXxYyZz")
|
||||
'AABBCCDDEEFFGGHHIIJJKKLLMMNNOOPPQQRRSSQQRRVVWWXXYYZZ'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++crip`
|
||||
|
||||
Tape to cord
|
||||
|
||||
++ crip |=(a=tape `@t`(rap 3 a)) :: tape to cord
|
||||
|
||||
Produce cord from a tape.
|
||||
|
||||
`a` is a [tape]().
|
||||
|
||||
~zod/try=> (crip "john doe")
|
||||
'john doe'
|
||||
~zod/try=> (crip "abc 123 !@#")
|
||||
'abc 123 !@#'
|
||||
~zod/try=> `@ud`(crip "abc")
|
||||
6.513.249
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mesc`
|
||||
|
||||
Escape special chars
|
||||
|
||||
++ mesc :: ctrl code escape
|
||||
|= vib=tape
|
||||
^- tape
|
||||
?~ vib
|
||||
~
|
||||
?: =('\\' i.vib)
|
||||
['\\' '\\' $(vib t.vib)]
|
||||
?: ?|((gth i.vib 126) (lth i.vib 32) =(39 i.vib))
|
||||
['\\' (welp ~(rux at i.vib) '/' $(vib t.vib))]
|
||||
[i.vib $(vib t.vib)]
|
||||
::
|
||||
|
||||
Escape special characters, used in [`++show`](/doc/hoon/library/2ez#++show)
|
||||
|
||||
`vib` is a [tape]().
|
||||
|
||||
/~zod/try=> (mesc "ham lus")
|
||||
"ham lus"
|
||||
/~zod/try=> (mesc "bas\\hur")
|
||||
"bas\\\\hur"
|
||||
/~zod/try=> (mesc "as'saß")
|
||||
"as\0x27/sa\0xc3/\0x9f/"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++runt`
|
||||
|
||||
Prepend `n` times
|
||||
|
||||
++ runt :: prepend repeatedly
|
||||
|= [[a=@ b=@] c=tape]
|
||||
^- tape
|
||||
?: =(0 a)
|
||||
c
|
||||
[b $(a (dec a))]
|
||||
::
|
||||
|
||||
Add `a` repetitions of character `b` to the head of `c`
|
||||
|
||||
`a` and `b` are [atom]()s.
|
||||
|
||||
`c` is a [tape]().
|
||||
|
||||
/~zod/try=> (runt [2 '/'] "ham")
|
||||
"//ham"
|
||||
/~zod/try=> (runt [10 'a'] "")
|
||||
"aaaaaaaaaa"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sand`
|
||||
|
||||
Soft-cast by odor
|
||||
|
||||
++ sand :: atom sanity
|
||||
|= a=@ta
|
||||
|= b=@ ^- (unit ,@)
|
||||
?.(((sane a) b) ~ [~ b])
|
||||
::
|
||||
|
||||
Soft-cast validity by odor.
|
||||
|
||||
`a` is a [`@ta`]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
/~zod/try=> `(unit ,@ta)`((sand %ta) 'sym-som')
|
||||
[~ ~.sym-som]
|
||||
/~zod/try=> `(unit ,@ta)`((sand %ta) 'err!')
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sane`
|
||||
|
||||
Check odor validity
|
||||
|
||||
++ sane :: atom sanity
|
||||
|= a=@ta
|
||||
|= b=@ ^- ?
|
||||
?. =(%t (end 3 1 a))
|
||||
~|(%sane-stub !!)
|
||||
=+ [inx=0 len=(met 3 b)]
|
||||
?: =(%tas a)
|
||||
|- ^- ?
|
||||
?: =(inx len) &
|
||||
=+ cur=(cut 3 [inx 1] b)
|
||||
?& ?| &((gte cur 'a') (lte cur 'z'))
|
||||
&(=('-' cur) !=(0 inx) !=(len inx))
|
||||
&(&((gte cur '0') (lte cur '9')) !=(0 inx))
|
||||
==
|
||||
$(inx +(inx))
|
||||
==
|
||||
?: =(%ta a)
|
||||
|- ^- ?
|
||||
?: =(inx len) &
|
||||
=+ cur=(cut 3 [inx 1] b)
|
||||
?& ?| &((gte cur 'a') (lte cur 'z'))
|
||||
&((gte cur '0') (lte cur '9'))
|
||||
|(=('-' cur) =('~' cur) =('_' cur) =('.' cur))
|
||||
==
|
||||
$(inx +(inx))
|
||||
==
|
||||
|- ^- ?
|
||||
?: =(0 b) &
|
||||
=+ cur=(end 3 1 b)
|
||||
?: &((lth cur 32) !=(10 cur)) |
|
||||
=+ len=(teff cur)
|
||||
?& |(=(1 len) =+(i=1 |-(|(=(i len) &((gte (cut 3 [i 1] b) 128) $(i +(i)))))))
|
||||
$(b (rsh 3 len b))
|
||||
==
|
||||
::
|
||||
|
||||
Check validity by odor. Produces a gate.
|
||||
|
||||
`a` is a [`@ta`]().
|
||||
|
||||
`b` is an [atom]().
|
||||
|
||||
/~zod/try=> ((sane %tas) %mol)
|
||||
%.y
|
||||
/~zod/try=> ((sane %tas) 'lam')
|
||||
%.y
|
||||
/~zod/try=> ((sane %tas) 'more ace')
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++trim`
|
||||
|
||||
Tape split
|
||||
|
||||
++ trim :: tape split
|
||||
|= [a=@ b=tape]
|
||||
^- [p=tape q=tape]
|
||||
?~ b
|
||||
[~ ~]
|
||||
?: =(0 a)
|
||||
[~ b]
|
||||
=+ c=$(a (dec a), b t.b)
|
||||
[[i.b p.c] q.c]
|
||||
::
|
||||
|
||||
Split first `a` characters off tape.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
`b` is a [tape]().
|
||||
|
||||
/~zod/try=> (trim 5 "lasok termun")
|
||||
[p="lasok" q=" termun"]
|
||||
/~zod/try=> (trim 5 "zam")
|
||||
[p="zam" q=""]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++trip`
|
||||
|
||||
Cord to tape
|
||||
|
||||
++ trip :: cord to tape
|
||||
~/ %trip
|
||||
|= a=@ ^- tape
|
||||
?: =(0 (met 3 a))
|
||||
~
|
||||
[^-(@ta (end 3 1 a)) $(a (rsh 3 1 a))]
|
||||
::
|
||||
|
||||
Produce tape from cord.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
/~zod/try=> (trip 'john doe')
|
||||
"john doe"
|
||||
/~zod/try=> (trip 'abc 123 !@#')
|
||||
"abc 123 !@#"
|
||||
/~zod/try=> (trip 'abc')
|
||||
"abc"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++teff`
|
||||
|
||||
UTF8 Length
|
||||
|
||||
++ teff :: length utf8
|
||||
|= a=@t ^- @
|
||||
=+ b=(end 3 1 a)
|
||||
?: =(0 b)
|
||||
?>(=(0 a) 0)
|
||||
?> |((gte b 32) =(10 b))
|
||||
?:((lte b 127) 1 ?:((lte b 223) 2 ?:((lte b 239) 3 4)))
|
||||
::
|
||||
|
||||
Number of utf8 bytes.
|
||||
|
||||
`a` is a [`@t`]().
|
||||
|
||||
/~zod/try=> (teff 'a')
|
||||
1
|
||||
/~zod/try=> (teff 'ß')
|
||||
2
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++turf`
|
||||
|
||||
UTF8 to UTF32 cord
|
||||
|
||||
++ turf :: utf8 to utf32
|
||||
|= a=@t
|
||||
^- @c
|
||||
%+ rap 5
|
||||
|- ^- (list ,@c)
|
||||
=+ b=(teff a)
|
||||
?: =(0 b) ~
|
||||
:- %+ can 0
|
||||
%+ turn
|
||||
^- (list ,[p=@ q=@])
|
||||
?+ b !!
|
||||
1 [[0 7] ~]
|
||||
2 [[8 6] [0 5] ~]
|
||||
3 [[16 6] [8 6] [0 4] ~]
|
||||
4 [[24 6] [16 6] [8 6] [0 3] ~]
|
||||
==
|
||||
|=([p=@ q=@] [q (cut 0 [p q] a)])
|
||||
$(a (rsh 3 b a))
|
||||
::
|
||||
|
||||
Convert utf8 ([cord]()) to utf32 codepoints.
|
||||
|
||||
`a` is a [`@t`]().
|
||||
|
||||
/~zod/try=> (turf 'my ßam')
|
||||
~-my.~df.am
|
||||
/~zod/try=> 'я тут'
|
||||
'я тут'
|
||||
/~zod/try=> (turf 'я тут')
|
||||
~-~44f..~442.~443.~442.
|
||||
/~zod/try=> `@ux`'я тут'
|
||||
0x82.d183.d182.d120.8fd1
|
||||
/~zod/try=> `@ux`(turf 'я тут')
|
||||
0x442.0000.0443.0000.0442.0000.0020.0000.044f
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++tuba`
|
||||
|
||||
UTF8 to UTF32 tape
|
||||
|
||||
++ tuba :: utf8 to utf32 tape
|
||||
|= a=tape
|
||||
^- (list ,@c)
|
||||
(rip 5 (turf (rap 3 a))) :: XX horrible
|
||||
::
|
||||
|
||||
Convert tape to list of codepoints.
|
||||
|
||||
`a` is a [tape]()
|
||||
|
||||
/~zod/try=> (tuba "я тут")
|
||||
~[~-~44f. ~-. ~-~442. ~-~443. ~-~442.]
|
||||
/~zod/try=> (tuba "chars")
|
||||
~[~-c ~-h ~-a ~-r ~-s]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++tufa`
|
||||
|
||||
UTF32 to UTF8 tape
|
||||
|
||||
++ tufa :: utf32 to utf8 tape
|
||||
|= a=(list ,@c)
|
||||
^- tape
|
||||
?~ a ""
|
||||
(weld (rip 3 (tuft i.a)) $(a t.a))
|
||||
::
|
||||
|
||||
Wrap list of utf32 codepoints to utf8 [tape]().
|
||||
|
||||
`a` is a [list]() of [`@c`]().
|
||||
|
||||
/~zod/try=> (tufa ~[~-~44f. ~-. ~-~442. ~-~443. ~-~442.])
|
||||
"я тут"
|
||||
/~zod/try=> (tufa ((list ,@c) ~[%a %b 0xb1 %c]))
|
||||
"ab±c"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++tuft`
|
||||
|
||||
UTF32 to UTF8 text
|
||||
|
||||
++ tuft :: utf32 to utf8 text
|
||||
|= a=@c
|
||||
^- @t
|
||||
%+ rap 3
|
||||
|- ^- (list ,@)
|
||||
?: =(0 a)
|
||||
~
|
||||
=+ b=(end 5 1 a)
|
||||
=+ c=$(a (rsh 5 1 a))
|
||||
?: (lth b 0x7f)
|
||||
[b c]
|
||||
?: (lth b 0x7ff)
|
||||
:* (mix 0b1100.0000 (cut 0 [6 5] b))
|
||||
(mix 0b1000.0000 (end 0 6 b))
|
||||
c
|
||||
==
|
||||
?: (lth b 0xffff)
|
||||
:* (mix 0b1110.0000 (cut 0 [12 4] b))
|
||||
(mix 0b1000.0000 (cut 0 [6 6] b))
|
||||
(mix 0b1000.0000 (end 0 6 b))
|
||||
c
|
||||
==
|
||||
:* (mix 0b1111.0000 (cut 0 [18 3] b))
|
||||
(mix 0b1000.0000 (cut 0 [12 6] b))
|
||||
(mix 0b1000.0000 (cut 0 [6 6] b))
|
||||
(mix 0b1000.0000 (end 0 6 b))
|
||||
c
|
||||
==
|
||||
::
|
||||
|
||||
Convert utf32 glyph to
|
||||
[LSB](http://en.wikipedia.org/wiki/Least_significant_bit) utf8 cord.
|
||||
|
||||
`a` is a [`@c`]().
|
||||
|
||||
/~zod/try=> (tuft `@c`%a)
|
||||
'a'
|
||||
/~zod/try=> (tuft `@c`0xb6)
|
||||
'¶'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wack`
|
||||
|
||||
Coin format encode
|
||||
|
||||
++ wack :: coin format
|
||||
|= a=@ta
|
||||
^- @ta
|
||||
=+ b=(rip 3 a)
|
||||
%+ rap 3
|
||||
|- ^- tape
|
||||
?~ b
|
||||
~
|
||||
?: =('~' i.b) ['~' '~' $(b t.b)]
|
||||
?: =('_' i.b) ['~' '-' $(b t.b)]
|
||||
[i.b $(b t.b)]
|
||||
::
|
||||
|
||||
Escape span `~` as `~~` and `_` as `~-`. Used for printing.
|
||||
|
||||
`a` is a [`@ta`]().
|
||||
|
||||
/~zod/try=> (wack '~20_sam~')
|
||||
~.~~20~-sam~~
|
||||
/~zod/try=> `@t`(wack '~20_sam~')
|
||||
'~~20~-sam~~'
|
||||
~zod/try=> ~(rend co %many ~[`ud/5 `ta/'~20_sam'])
|
||||
"._5_~~.~~20~-sam__"
|
||||
~zod/try=> ._5_~~.~~20~-sam__
|
||||
[5 ~.~20_sam]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wick`
|
||||
|
||||
Coin format decode
|
||||
|
||||
++ wick :: coin format
|
||||
|= a=@
|
||||
^- @ta
|
||||
=+ b=(rip 3 a)
|
||||
%+ rap 3
|
||||
|- ^- tape
|
||||
?~ b
|
||||
~
|
||||
?: =('~' i.b)
|
||||
?~ t.b !!
|
||||
[?:(=('~' i.t.b) '~' ?>(=('-' i.t.b) '_')) $(b t.t.b)]
|
||||
[i.b $(b t.b)]
|
||||
::
|
||||
|
||||
Unescape span `~~` as `~` and `~-` as `_`.
|
||||
|
||||
`a` is a an [atom]().
|
||||
|
||||
/~zod/try=> `@t`(wick '~-ams~~lop')
|
||||
'_ams~lop'
|
||||
/~zod/try=> `@t`(wick (wack '~20_sam~'))
|
||||
'~20_sam~'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++woad`
|
||||
|
||||
Unescape cord
|
||||
|
||||
++ woad :: cord format
|
||||
|= a=@ta
|
||||
^- @t
|
||||
%+ rap 3
|
||||
|- ^- (list ,@)
|
||||
?: =(0 a)
|
||||
~
|
||||
=+ b=(end 3 1 a)
|
||||
=+ c=(rsh 3 1 a)
|
||||
?: =('.' b)
|
||||
[' ' $(a c)]
|
||||
?. =('~' b)
|
||||
[b $(a c)]
|
||||
=> .(b (end 3 1 c), c (rsh 3 1 c))
|
||||
?+ b =- (weld (rip 3 (tuft p.d)) $(a q.d))
|
||||
^= d
|
||||
=+ d=0
|
||||
|- ^- [p=@ q=@]
|
||||
?: =('.' b)
|
||||
[d c]
|
||||
?< =(0 c)
|
||||
%= $
|
||||
b (end 3 1 c)
|
||||
c (rsh 3 1 c)
|
||||
d %+ add (mul 16 d)
|
||||
%+ sub b
|
||||
?: &((gte b '0') (lte b '9')) 48
|
||||
?>(&((gte b 'a') (lte b 'z')) 87)
|
||||
==
|
||||
%'.' ['.' $(a c)]
|
||||
%'~' ['~' $(a c)]
|
||||
==
|
||||
::
|
||||
|
||||
Unescape cord codepoints.
|
||||
|
||||
`a` is a [`@ta`]().
|
||||
|
||||
/~zod/try=> (woad ~.~b6.20.as)
|
||||
'¶20 as'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wood`
|
||||
|
||||
Escape cord
|
||||
|
||||
++ wood :: cord format
|
||||
|= a=@t
|
||||
^- @ta
|
||||
%+ rap 3
|
||||
|- ^- (list ,@)
|
||||
?: =(0 a)
|
||||
~
|
||||
=+ b=(teff a)
|
||||
=+ c=(turf (end 3 b a))
|
||||
=+ d=$(a (rsh 3 b a))
|
||||
?: ?| &((gte c 'a') (lte c 'z'))
|
||||
&((gte c '0') (lte c '9'))
|
||||
=('-' c)
|
||||
==
|
||||
[c d]
|
||||
?+ c
|
||||
:- '~'
|
||||
=+ e=(met 2 c)
|
||||
|- ^- tape
|
||||
?: =(0 c)
|
||||
['.' d]
|
||||
=. e (dec e)
|
||||
=+ f=(rsh 2 e c)
|
||||
[(add ?:((lte f 9) 48 87) f) $(c (end 2 e c))]
|
||||
::
|
||||
%' ' ['.' d]
|
||||
%'.' ['~' '.' d]
|
||||
%'~' ['~' '~' d]
|
||||
==
|
||||
|
||||
Escape cord codepoints.
|
||||
|
||||
`a` is a [`@ta`]().
|
||||
|
||||
/~zod/try=> (wood 'my ßam')
|
||||
~.my.~df.am
|
@ -1,162 +0,0 @@
|
||||
section 2eK, formatting (layout)
|
||||
================================
|
||||
|
||||
### `++re`
|
||||
|
||||
Pretty-printing engine
|
||||
|
||||
++ re
|
||||
|_ tac=tank
|
||||
|
||||
Pretty-printing engine.
|
||||
|
||||
`tac` is a [`++tank`](/doc/hoon/library/1#++tank).
|
||||
|
||||
/~zod/try=> ~(. re leaf/"ham")
|
||||
<2.ghl [[%leaf ""] <414.gly 100.xkc 1.ypj %164>]>
|
||||
|
||||
### `++ram`
|
||||
|
||||
Flatten to tape
|
||||
|
||||
++ ram
|
||||
^- tape
|
||||
?- -.tac
|
||||
%leaf p.tac
|
||||
%palm ram(tac [%rose [p.p.tac (weld q.p.tac r.p.tac) s.p.tac] q.tac])
|
||||
%rose
|
||||
%+ weld
|
||||
q.p.tac
|
||||
|- ^- tape
|
||||
?~ q.tac
|
||||
r.p.tac
|
||||
=+ voz=$(q.tac t.q.tac)
|
||||
(weld ram(tac i.q.tac) ?~(t.q.tac voz (weld p.p.tac voz)))
|
||||
==
|
||||
::
|
||||
|
||||
Flatten tank out into a tape.
|
||||
|
||||
/~zod/try=> ~(ram re leaf/"foo")
|
||||
"foo"
|
||||
/~zod/try=> ~(ram re rose/["." "(" ")"]^~[leaf/"bar" leaf/"baz" leaf/"bam"])
|
||||
"(bar.baz.bam)"
|
||||
|
||||
### `++win`
|
||||
|
||||
Render at indent
|
||||
|
||||
++ win
|
||||
|= [tab=@ edg=@]
|
||||
=+ lug=`wall`~
|
||||
|^ |- ^- wall
|
||||
?- -.tac
|
||||
%leaf (rig p.tac)
|
||||
%palm
|
||||
?: fit
|
||||
(rig ram)
|
||||
?~ q.tac
|
||||
(rig q.p.tac)
|
||||
?~ t.q.tac
|
||||
(rig(tab (add 2 tab), lug $(tac i.q.tac)) q.p.tac)
|
||||
=> .(q.tac `(list tank)`q.tac)
|
||||
=+ lyn=(mul 2 (lent q.tac))
|
||||
=+ ^= qyr
|
||||
|- ^- wall
|
||||
?~ q.tac
|
||||
lug
|
||||
%= ^$
|
||||
tac i.q.tac
|
||||
tab (add tab (sub lyn 2))
|
||||
lug $(q.tac t.q.tac, lyn (sub lyn 2))
|
||||
==
|
||||
(wig(lug qyr) q.p.tac)
|
||||
::
|
||||
%rose
|
||||
?: fit
|
||||
(rig ram)
|
||||
=+ ^= gyl
|
||||
|- ^- wall
|
||||
?~ q.tac
|
||||
?:(=(%$ r.p.tac) lug (rig r.p.tac))
|
||||
^$(tac i.q.tac, lug $(q.tac t.q.tac), tab din)
|
||||
?: =(%$ q.p.tac)
|
||||
gyl
|
||||
(wig(lug gyl) q.p.tac)
|
||||
==
|
||||
::
|
||||
|
||||
Render at indent level `tab` and width `edg`.
|
||||
|
||||
`tab` and `edg` are [atom]()s.
|
||||
|
||||
/~zod/try=> (~(win re leaf/"samoltekon-lapdok") 0 20)
|
||||
<<"samoltekon-lapdok">>
|
||||
/~zod/try=> (~(win re leaf/"samoltekon-lapdok") 0 10)
|
||||
<<"\/samolt\/" " ekon-l" " apdok" "\/ \/">>
|
||||
/~zod/try=> (~(win re rose/["--" "[" "]"]^~[leaf/"1423" leaf/"2316"]) 0 20)
|
||||
<<"[1423--2316]">>
|
||||
/~zod/try=> (~(win re rose/["--" "[" "]"]^~[leaf/"1423" leaf/"2316"]) 0 10)
|
||||
<<"[ 1423" " 2316" "]">>
|
||||
|
||||
### `++din`
|
||||
|
||||
++ din (mod (add 2 tab) (mul 2 (div edg 3)))
|
||||
|
||||
XX document
|
||||
|
||||
### `++fit`
|
||||
|
||||
Fit on one line test
|
||||
|
||||
++ fit (lte (lent ram) (sub edg tab))
|
||||
|
||||
Determine whether `tac` fits on one line. Internal to `++win`
|
||||
|
||||
### `++rig`
|
||||
|
||||
Wrap in `\/`
|
||||
|
||||
++ rig
|
||||
|= hom=tape
|
||||
^- wall
|
||||
?: (lte (lent hom) (sub edg tab))
|
||||
[(runt [tab ' '] hom) lug]
|
||||
=> .(tab (add tab 2), edg (sub edg 2))
|
||||
=+ mut=(trim (sub edg tab) hom)
|
||||
:- (runt [(sub tab 2) ' '] ['\\' '/' (weld p.mut `_hom`['\\' '/' ~])])
|
||||
=> .(hom q.mut)
|
||||
|-
|
||||
?~ hom
|
||||
:- %+ runt
|
||||
[(sub tab 2) ' ']
|
||||
['\\' '/' (runt [(sub edg tab) ' '] ['\\' '/' ~])]
|
||||
lug
|
||||
=> .(mut (trim (sub edg tab) hom))
|
||||
[(runt [tab ' '] p.mut) $(hom q.mut)]
|
||||
::
|
||||
|
||||
Wrap tape in `\/` if it doesn't fit at current indentation. Internal to
|
||||
`++win`
|
||||
|
||||
### `++wig`
|
||||
|
||||
`++win` render tape
|
||||
|
||||
++ wig
|
||||
|= hom=tape
|
||||
^- wall
|
||||
?~ lug
|
||||
(rig hom)
|
||||
=+ lin=(lent hom)
|
||||
=+ wug=:(add 1 tab lin)
|
||||
?. =+ mir=i.lug
|
||||
|- ?~ mir
|
||||
|
|
||||
?|(=(0 wug) ?&(=(' ' i.mir) $(mir t.mir, wug (dec wug))))
|
||||
(rig hom) :: ^ XX regular form?
|
||||
[(runt [tab ' '] (weld hom `tape`[' ' (slag wug i.lug)])) t.lug]
|
||||
--
|
||||
--
|
||||
|
||||
Render tape. Internal to `++win`.
|
File diff suppressed because it is too large
Load Diff
@ -1,758 +0,0 @@
|
||||
section 2eM, regular-expressions
|
||||
================================
|
||||
|
||||
### `++pars`
|
||||
|
||||
++ pars
|
||||
|= [a=tape] :: parse tape to rege
|
||||
^- (unit rege)
|
||||
=+ foo=((full apex:rags) [[1 1] a])
|
||||
?~ q.foo
|
||||
~
|
||||
[~ p.u.q.foo]
|
||||
::
|
||||
|
||||
Parse regular expression
|
||||
|
||||
~zod/try=> (pars "samo")
|
||||
[ ~
|
||||
[ %pair
|
||||
p=[%lite p=~~s]
|
||||
q=[%pair p=[%lite p=~~a] q=[%pair p=[%lite p=~~m] q=[%lite p=~~o]]]
|
||||
]
|
||||
]
|
||||
~zod/try=> (pars "so[,.0-9]")
|
||||
[ ~
|
||||
[ %pair
|
||||
p=[%lite p=~~s]
|
||||
q=[%pair p=[%lite p=~~o] q=[%brac p=288.036.862.105.223.168]]
|
||||
]
|
||||
]
|
||||
~zod/try=> `@ub`288.036.862.105.223.168
|
||||
0b11.1111.1111.0101.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
|
||||
~zod/try=> `@ub`(lsh 0 `@`'9' 1)
|
||||
0b10.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
|
||||
~zod/try=> `@ub`(roll (turn ",.0123456789" |=(a=@ (lsh 0 a 1))) con)
|
||||
0b11.1111.1111.0101.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
|
||||
~zod/try=> (pars "sop.*")
|
||||
[ ~
|
||||
[ %pair
|
||||
p=[%lite p=~~s]
|
||||
q=[%pair p=[%lite p=~~o] q=[%pair p=[%lite p=~~p] q=[%mant p=%dote]]]
|
||||
]
|
||||
]
|
||||
~zod/try=> (pars "(hel)?")
|
||||
[ ~
|
||||
[ %eith
|
||||
p
|
||||
[ %capt
|
||||
p=[%pair p=[%lite p=~~h] q=[%pair p=[%lite p=~~e] q=[%lite p=~~l]]]
|
||||
q=0
|
||||
]
|
||||
q=%empt
|
||||
]
|
||||
]
|
||||
~zod/try=> (pars "(hel)??")
|
||||
[ ~
|
||||
[ %eith
|
||||
p=%empt
|
||||
q
|
||||
[ %capt
|
||||
p=[%pair p=[%lite p=~~h] q=[%pair p=[%lite p=~~e] q=[%lite p=~~l]]]
|
||||
q=0
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/try=> (pars "a\{1,20}")
|
||||
[~ [%betw p=[%lite p=~~a] q=1 r=20]]
|
||||
|
||||
### `++rags`
|
||||
|
||||
++ rags :: rege parsers
|
||||
=> |%
|
||||
|
||||
Regex parser arms
|
||||
|
||||
### `++nor`
|
||||
|
||||
++ nor ;~(less (mask "^$()|*?+.[\\") (shim 1 127)) :: non-control char
|
||||
|
||||
XX document
|
||||
|
||||
### `++les`
|
||||
|
||||
++ les ;~(less bas asp) :: not backslash
|
||||
|
||||
XX document
|
||||
|
||||
### `++lep`
|
||||
|
||||
++ lep ;~(less (mask "^[]\\") asp) :: charset non-control
|
||||
|
||||
XX document
|
||||
|
||||
### `++asp`
|
||||
|
||||
++ asp (shim 32 126) :: printable ascii
|
||||
|
||||
XX document
|
||||
|
||||
### `++alb`
|
||||
|
||||
++ alb ;~(less ser asp) :: charset literal char
|
||||
|
||||
XX document
|
||||
|
||||
### `++mis`
|
||||
|
||||
++ mis ;~(less aln asp) :: non alphanumeric
|
||||
--
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++apex`
|
||||
|
||||
++ apex :: top level
|
||||
%+ knee *rege |. ~+
|
||||
;~ pose
|
||||
;~((bend |=(a=[rege rege] (some [%eith a]))) mall ;~(pfix bar apex))
|
||||
(stag %eith ;~(plug (easy %empt) ;~(pfix bar apex)))
|
||||
(easy %empt)
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++mall`
|
||||
|
||||
++ mall
|
||||
%+ knee *rege |. ~+
|
||||
;~((bend |=(a=[rege rege] (some [%pair a]))) bets mall)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++bets`
|
||||
|
||||
++ bets
|
||||
%+ knee *rege |. ~+
|
||||
|= tub=nail
|
||||
=+ vex=(chun tub)
|
||||
?~ q.vex
|
||||
vex
|
||||
=+ a=p.u.q.vex
|
||||
%- ;~ pose
|
||||
(cold [%eith %empt a] (jest '??'))
|
||||
(cold [%manl a] (jest '*?'))
|
||||
(cold [%plll a] (jest '+?'))
|
||||
(cold [%eith a %empt] wut)
|
||||
(cold [%mant a] tar)
|
||||
(cold [%plls a] lus)
|
||||
(stag %betl ;~(plug (easy a) ;~(sfix rang wut)))
|
||||
(stag %betw ;~(plug (easy a) rang))
|
||||
(stag %binl ;~(plug (easy a) (ifix [kel (jest ',}?')] dim:ag)))
|
||||
(stag %bant ;~(plug (easy a) (ifix [kel (jest '}?')] dim:ag)))
|
||||
(stag %bant ;~(plug (easy a) (ifix [kel ker] dim:ag)))
|
||||
(stag %bint ;~(plug (easy a) (ifix [kel (jest ',}')] dim:ag)))
|
||||
(easy a)
|
||||
==
|
||||
q.u.q.vex
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ranc`
|
||||
|
||||
++ ranc
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?:((gth a b) 0 (con (bex a) $(a +(a))))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++flap`
|
||||
|
||||
++ flap |=(a=@ (mix a (dec (bex 256))))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++rang`
|
||||
|
||||
++ rang
|
||||
%+ sear |=([a=@ b=@] ?:((lte a b) (some [a b]) ~))
|
||||
(ifix [kel ker] ;~(plug dim:ag ;~(pfix com dim:ag)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++chun`
|
||||
|
||||
++ chun
|
||||
%+ knee *rege |. ~+
|
||||
;~ pose
|
||||
(cold %ende buc)
|
||||
(cold %sart ket)
|
||||
(cold %dote dot)
|
||||
%+ cook |=(a=(list char) (reel a |=([p=char q=rege] [%pair [%lite p] q])))
|
||||
;~(pfix (jest '\\Q') cape)
|
||||
|= tub=nail
|
||||
=+ foo=;~(plug kel dim:ag ;~(pose ker (jest ',}') ;~(plug com dim:ag ker)))
|
||||
=+ bar=(foo tub)
|
||||
?~(q.bar (chad tub) (fail tub))
|
||||
(cook |=([a=rege] [%capt a 0]) (ifix [pel per] apex))
|
||||
%+ cook |=([a=rege] [%capt a 0])
|
||||
(ifix [;~(plug (jest '(?P<') (plus aln) gar) per] apex)
|
||||
(ifix [(jest '(?:') per] apex)
|
||||
(stag %brac ;~(pfix sel seac))
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++seac`
|
||||
|
||||
++ seac
|
||||
|= tub=nail
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?: =(i.q.tub '^')
|
||||
(;~(pfix ket (cook flap sead)) tub)
|
||||
(sead tub)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++sead`
|
||||
|
||||
++ sead
|
||||
%+ knee *@ |. ~+
|
||||
;~ pose
|
||||
|= tub=nail
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?. =(i.q.tub ']')
|
||||
(fail tub)
|
||||
?~ t.q.tub
|
||||
(fail tub)
|
||||
?: =(i.t.q.tub '-')
|
||||
?~ t.t.q.tub
|
||||
(fail tub)
|
||||
?: =(i.t.t.q.tub ']')
|
||||
(;~(pfix ser (cook |=(a=@ (con (bex ']') a)) sade)) tub)
|
||||
(fail tub)
|
||||
(;~(pfix ser (cook |=(a=@ (con (bex ']') a)) sade)) tub)
|
||||
|= tub=nail
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?. =(i.q.tub '-')
|
||||
(fail tub)
|
||||
?~ t.q.tub
|
||||
(fail tub)
|
||||
?: =(i.t.q.tub '-')
|
||||
?~ t.t.q.tub
|
||||
(fail tub)
|
||||
?: =(i.t.t.q.tub ']')
|
||||
(;~(pfix hep (cook |=(a=@ (con (bex '-') a)) sade)) tub)
|
||||
(fail tub)
|
||||
(;~(pfix hep (cook |=(a=@ (con (bex '-') a)) sade)) tub)
|
||||
(cook |=(a=[@ @] (con a)) ;~(plug seap sade))
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++sade`
|
||||
|
||||
++ sade
|
||||
%+ knee *@ |. ~+
|
||||
;~ pose
|
||||
(cold (bex '-') (jest '-]'))
|
||||
(cold 0 ser)
|
||||
(cook |=([p=@ q=@] `@`(con p q)) ;~(plug seap sade))
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++seap`
|
||||
|
||||
++ seap
|
||||
%+ knee *@ |. ~+
|
||||
;~ pose
|
||||
unid
|
||||
%+ ifix (jest '[:')^(jest ':]')
|
||||
;~(pose ;~(pfix ket (cook flap chas)) chas)
|
||||
%+ sear |=([a=@ b=@] ?:((gth a b) ~ (some (ranc a b))))
|
||||
;~(plug asp ;~(pfix hep alb))
|
||||
|= tub=nail
|
||||
?~ q.tub
|
||||
(fail tub)
|
||||
?~ t.q.tub
|
||||
((cook bex les) tub)
|
||||
?: =(i.t.q.tub '-')
|
||||
?~ t.t.q.tub
|
||||
((cook bex les) tub)
|
||||
?: =(i.t.t.q.tub ']')
|
||||
((cook bex les) tub)
|
||||
(fail tub)
|
||||
((cook bex les) tub)
|
||||
;~(pfix bas escd)
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++cape`
|
||||
|
||||
++ cape
|
||||
%+ knee *tape |. ~+
|
||||
;~ pose
|
||||
(cold ~ (jest '\\E'))
|
||||
;~(plug next cape)
|
||||
(cook |=(a=char (tape [a ~])) next)
|
||||
(full (easy ~))
|
||||
==
|
||||
|
||||
XX document
|
||||
|
||||
### `++chas`
|
||||
|
||||
++ chas :: ascii character set
|
||||
=- (sear ~(get by -) sym)
|
||||
%- mo ^- (list ,[@tas @I])
|
||||
:~ alnum/alnum alpha/alpha ascii/ascii blank/blank cntrl/cntrl
|
||||
digit/digit graph/graph lower/lower print/print punct/punct
|
||||
space/space upper/upper word/wordc xdigit/xdigit
|
||||
==
|
||||
:: Character sets
|
||||
|
||||
++ alnum :(con lower upper digit)
|
||||
|
||||
|
||||
XX document
|
||||
|
||||
###++alpha
|
||||
|
||||
++ alpha :(con lower upper)
|
||||
|
||||
|
||||
XX document
|
||||
|
||||
###++ascii
|
||||
|
||||
++ ascii (ranc 0 127)
|
||||
|
||||
|
||||
++ blank (con (bex 32) (bex 9))
|
||||
|
||||
XX document
|
||||
|
||||
### `++cntrl`
|
||||
|
||||
++ cntrl :(con (ranc 0 31) (bex 127))
|
||||
|
||||
XX document
|
||||
|
||||
### `++digit`
|
||||
|
||||
++ digit (ranc '0' '9')
|
||||
|
||||
XX document
|
||||
|
||||
### `++graph`
|
||||
|
||||
++ graph (ranc 33 126)
|
||||
|
||||
XX document
|
||||
|
||||
### `++lower`
|
||||
|
||||
++ lower (ranc 'a' 'z')
|
||||
|
||||
XX document
|
||||
|
||||
### `++print`
|
||||
|
||||
++ print (ranc 32 126)
|
||||
|
||||
XX document
|
||||
|
||||
### `++punct`
|
||||
|
||||
++ punct ;: con
|
||||
(ranc '!' '/')
|
||||
(ranc ':' '@')
|
||||
(ranc '[' '`')
|
||||
(ranc '{' '~')
|
||||
==
|
||||
|
||||
XX document
|
||||
|
||||
### `++space`
|
||||
|
||||
++ space :(con (ranc 9 13) (bex ' '))
|
||||
|
||||
XX document
|
||||
|
||||
### `++upper`
|
||||
|
||||
++ upper (ranc 'A' 'Z')
|
||||
|
||||
XX document
|
||||
|
||||
### `++white`
|
||||
|
||||
++ white :(con (bex ' ') (ranc 9 10) (ranc 12 13))
|
||||
|
||||
XX document
|
||||
|
||||
### `++wordc`
|
||||
|
||||
++ wordc :(con digit lower upper (bex '_'))
|
||||
|
||||
XX document
|
||||
|
||||
### `++xdigit`
|
||||
|
||||
++ xdigit :(con (ranc 'a' 'f') (ranc 'A' 'F') digit)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++chad`
|
||||
|
||||
++ chad
|
||||
%+ knee *rege |. ~+
|
||||
;~(pose (stag %lite nor) (stag %brac unid) ;~(pfix bas escp))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++escd`
|
||||
|
||||
++ escd
|
||||
%+ knee *@ |. ~+
|
||||
;~ pose
|
||||
(cold (bex 7) (just 'a'))
|
||||
(cold (bex 9) (just 't'))
|
||||
(cold (bex 10) (just 'n'))
|
||||
(cold (bex 11) (just 'v'))
|
||||
(cold (bex 12) (just 'f'))
|
||||
(cold (bex 13) (just 'r'))
|
||||
(cold (bex 0) (just '0'))
|
||||
(sear |=(a=@ ?:((lth a 256) (some (bex a)) ~)) (bass 8 (stun [2 3] cit)))
|
||||
(cook bex ;~(pfix (just 'x') (bass 16 (stun [2 2] hit))))
|
||||
(cook bex (ifix [(jest 'x{') ker] (bass 16 (stun [2 2] hit))))
|
||||
(cook bex mis)
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++escp`
|
||||
|
||||
++ escp
|
||||
%+ knee *rege |. ~+
|
||||
;~ pose
|
||||
(cold %empt (just 'Q'))
|
||||
(cold [%lite `@tD`0] (just '0'))
|
||||
(cold [%lite `@tD`7] (just 'a'))
|
||||
(cold [%lite `@tD`9] (just 't'))
|
||||
(cold [%lite `@tD`10] (just 'n'))
|
||||
(cold [%lite `@tD`11] (just 'v'))
|
||||
(cold [%lite `@tD`12] (just 'f'))
|
||||
(cold [%lite `@tD`13] (just 'r'))
|
||||
(sear |=(a=@ ?:((lth a 256) (some [%lite a]) ~)) (bass 8 (stun [2 3] cit)))
|
||||
(stag %lite ;~(pfix (just 'x') (bass 16 (stun [2 2] hit))))
|
||||
(stag %lite (ifix [(jest 'x{') ker] (bass 16 (stun [2 2] hit))))
|
||||
(cold %dote (just 'C'))
|
||||
(cold %sart (just 'A'))
|
||||
(cold %ende (just 'z'))
|
||||
(cold %boun (just 'b'))
|
||||
(cold %bout (just 'B'))
|
||||
(stag %brac (cold wordc (just 'w')))
|
||||
(stag %brac (cold (flap wordc) (just 'W')))
|
||||
(stag %lite mis)
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++unid`
|
||||
|
||||
++ unid
|
||||
%+ knee *@ |. ~+
|
||||
;~ pose
|
||||
(cold digit (jest '\\d'))
|
||||
(cold (flap digit) (jest '\\D'))
|
||||
(cold white (jest '\\s'))
|
||||
(cold (flap white) (jest '\\S'))
|
||||
(cold wordc (jest '\\w'))
|
||||
(cold (flap wordc) (jest '\\W'))
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ra`
|
||||
|
||||
++ ra :: regex engine
|
||||
|_ a=rege
|
||||
|
||||
XX document
|
||||
|
||||
### `++proc`
|
||||
|
||||
++ proc :: capture numbering
|
||||
|= b=@
|
||||
=- -(+ +>.$(a a))
|
||||
^- [p=@ a=rege]
|
||||
?- a
|
||||
[%capt *] =+ foo=$(a p.a, b +(b))
|
||||
[p.foo [%capt a.foo b]]
|
||||
[%eith *] =+ foo=$(a p.a)
|
||||
=+ bar=$(a q.a, b p.foo)
|
||||
[p.bar [%eith a.foo a.bar]]
|
||||
[%pair *] =+ foo=$(a p.a)
|
||||
=+ bar=$(a q.a, b p.foo)
|
||||
[p.bar [%pair a.foo a.bar]]
|
||||
[%manl *] =+ foo=$(a p.a)
|
||||
[p.foo [%manl a.foo]]
|
||||
[%plll *] =+ foo=$(a p.a)
|
||||
[p.foo [%plll a.foo]]
|
||||
[%binl *] =+ foo=$(a p.a)
|
||||
[p.foo [%binl a.foo q.a]]
|
||||
[%betl *] =+ foo=$(a p.a)
|
||||
[p.foo [%betl a.foo q.a r.a]]
|
||||
[%mant *] =+ foo=$(a p.a)
|
||||
[p.foo [%mant a.foo]]
|
||||
[%plls *] =+ foo=$(a p.a)
|
||||
[p.foo [%plls a.foo]]
|
||||
[%bant *] =+ foo=$(a p.a)
|
||||
[p.foo [%bant a.foo q.a]]
|
||||
[%bint *] =+ foo=$(a p.a)
|
||||
[p.foo [%bint a.foo q.a]]
|
||||
[%betw *] =+ foo=$(a p.a)
|
||||
[p.foo [%betw a.foo q.a r.a]]
|
||||
* [b a]
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++cont`
|
||||
|
||||
++ cont
|
||||
|= [a=(map ,@u tape) b=(map ,@u tape)]
|
||||
(~(gas by _(map ,@u tape)) (weld (~(tap by a)) (~(tap by b))))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++abor`
|
||||
|
||||
++ abor
|
||||
|= [a=char b=(unit ,[tape (map ,@u tape)])]
|
||||
^- (unit ,[tape (map ,@u tape)])
|
||||
?~ b
|
||||
b
|
||||
[~ [[a -.u.b] +.u.b]]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++matc`
|
||||
|
||||
++ matc
|
||||
|= [b=tape c=tape]
|
||||
^- (unit (map ,@u tape))
|
||||
=+ foo=`(unit ,[tape (map ,@u tape)])`(deep b %empt c)
|
||||
(bind foo |*(a=^ (~(put by +.a) 0 -.a)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++chet`
|
||||
|
||||
++ chet
|
||||
|= [b=(unit ,[tape (map ,@u tape)]) c=tape d=tape]
|
||||
^- (unit ,[tape (map ,@u tape)])
|
||||
?~ b
|
||||
b
|
||||
?~ -.u.b
|
||||
b
|
||||
=+ bar=(deep (slag (lent -.u.b) c) %empt d)
|
||||
?~ bar
|
||||
bar
|
||||
b
|
||||
|
||||
XX document
|
||||
|
||||
### `++blak`
|
||||
|
||||
++ blak (some ["" _(map ,@u tape)])
|
||||
|
||||
XX document
|
||||
|
||||
### `++word`
|
||||
|
||||
++ word |=(a=char =((dis wordc:rags (bex a)) 0))
|
||||
|
||||
XX document
|
||||
|
||||
### `++deep`
|
||||
|
||||
++ deep
|
||||
|= [b=tape c=rege d=tape]
|
||||
^- (unit ,[tape (map ,@u tape)])
|
||||
?- a
|
||||
%dote ?~(b ~ (some [[i.b ~] _(map ,@u tape)]))
|
||||
%ende ?~(b blak ~)
|
||||
%sart ?:(=(b d) blak ~)
|
||||
%empt blak
|
||||
%boun =+ ^= luc
|
||||
?: =(b d)
|
||||
&
|
||||
=+ foo=(slag (dec (sub (lent d) (lent b))) d)
|
||||
(word -.foo)
|
||||
=+ cuc=?~(b & (word -.b))
|
||||
?:(!=(luc cuc) blak ~)
|
||||
%bout =+ ^= luc
|
||||
?: =(b d)
|
||||
&
|
||||
=+ foo=(slag (dec (sub (lent d) (lent b))) d)
|
||||
(word -.foo)
|
||||
=+ cuc=?~(b & (word -.b))
|
||||
?:(=(luc cuc) blak ~)
|
||||
[%capt *] =+ foo=$(a p.a)
|
||||
?~ foo
|
||||
foo
|
||||
=+ ft=u.foo
|
||||
=+ bar=$(a c, b (slag (lent -.ft) b), c %empt)
|
||||
?~ bar
|
||||
bar
|
||||
[~ [-.ft (~(put by +.ft) q.a -.ft)]]
|
||||
[%lite *] ?~(b ~ ?:(=(i.b p.a) (some [[i.b ~] _(map ,@u tape)]) ~))
|
||||
[%brac *] ?~ b
|
||||
~
|
||||
?. =((dis (bex `@`i.b) p.a) 0)
|
||||
(some [[i.b ~] _(map ,@u tape)])
|
||||
~
|
||||
[%eith *] =+ foo=(chet(a c) $(a p.a) b d)
|
||||
=+ bar=(chet(a c) $(a q.a) b d)
|
||||
?~ foo
|
||||
bar
|
||||
?~ bar
|
||||
foo
|
||||
=+ ft=u.foo
|
||||
=+ bt=u.bar
|
||||
?: (gte (lent -.ft) (lent -.bt))
|
||||
foo
|
||||
bar
|
||||
[%pair *] =+ foo=$(a p.a, c [%pair q.a c])
|
||||
?~ foo
|
||||
foo
|
||||
=+ ft=u.foo
|
||||
=+ bar=$(a q.a, b (slag (lent -.ft) b))
|
||||
?~ bar
|
||||
bar
|
||||
=+ bt=u.bar
|
||||
[~ [(weld -.ft -.bt) (cont +.ft +.bt)]]
|
||||
[%manl *] =+ foo=$(a p.a)
|
||||
?~ foo
|
||||
blak
|
||||
?~ -.u.foo
|
||||
blak
|
||||
$(a [%eith %empt [%pair p.a [%eith %empt a]]])
|
||||
[%mant *] =+ foo=$(a p.a)
|
||||
?~ foo
|
||||
blak
|
||||
=+ ft=u.foo
|
||||
?~ -.ft
|
||||
blak
|
||||
$(a [%eith [%pair p.a [%eith a %empt]] %empt])
|
||||
[%plls *] $(a [%pair p.a [%mant p.a]])
|
||||
[%plll *] $(a [%pair p.a [%manl p.a]])
|
||||
[%binl *] =+ min=?:(=(q.a 0) 0 (dec q.a))
|
||||
?: =(q.a 0)
|
||||
$(a [%manl p.a])
|
||||
$(a [%pair p.a [%binl p.a min]])
|
||||
[%bant *] ?: =(0 q.a)
|
||||
blak
|
||||
$(a [%pair p.a [%bant p.a (dec q.a)]])
|
||||
[%bint *] =+ min=?:(=(q.a 0) 0 (dec q.a))
|
||||
?: =(q.a 0)
|
||||
$(a [%mant p.a])
|
||||
$(a [%pair p.a [%bint p.a min]])
|
||||
[%betw *] ?: =(0 r.a)
|
||||
blak
|
||||
?: =(q.a 0)
|
||||
$(a [%eith [%pair p.a [%betw p.a 0 (dec r.a)]] %empt])
|
||||
$(a [%pair p.a [%betw p.a (dec q.a) (dec r.a)]])
|
||||
[%betl *] ?: =(0 r.a)
|
||||
blak
|
||||
?: =(q.a 0)
|
||||
$(a [%eith %empt [%pair p.a [%betl p.a 0 (dec r.a)]]])
|
||||
$(a [%pair p.a [%betl p.a (dec q.a) (dec r.a)]])
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++rexp`
|
||||
|
||||
++ rexp :: Regex match
|
||||
~/ %rexp
|
||||
|= [a=tape b=tape]
|
||||
^- (unit (unit (map ,@u tape)))
|
||||
=+ ^= bar
|
||||
|= [a=@ b=(map ,@u tape)]
|
||||
?: =(a 0)
|
||||
b
|
||||
=+ c=(~(get by b) a)
|
||||
?~ c
|
||||
$(a (dec a), b (~(put by b) a ""))
|
||||
$(a (dec a))
|
||||
=+ par=(pars a)
|
||||
?~ par ~
|
||||
=+ poc=(~(proc ra u.par) 1)
|
||||
=+ c=b
|
||||
|-
|
||||
=+ foo=(matc:poc c b)
|
||||
?~ foo
|
||||
?~ c
|
||||
[~ ~]
|
||||
$(c t.c)
|
||||
[~ [~ (bar (dec p.poc) u.foo)]]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++repg`
|
||||
|
||||
++ repg :: Global regex replace
|
||||
~/ %repg
|
||||
|= [a=tape b=tape c=tape]
|
||||
^- (unit tape)
|
||||
=+ par=(pars a)
|
||||
?~ par ~
|
||||
=+ poc=(~(proc ra u.par) 1)
|
||||
=+ d=b
|
||||
:- ~
|
||||
|-
|
||||
^- tape
|
||||
=+ foo=(matc:poc d b)
|
||||
?~ foo
|
||||
?~ d
|
||||
~
|
||||
[i.d $(d t.d)]
|
||||
=+ ft=(need (~(get by u.foo) 0))
|
||||
?~ d
|
||||
c
|
||||
(weld c $(d `tape`(slag (lent ft) `tape`d)))
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
@ -1,378 +0,0 @@
|
||||
section 2eN, pseudo-cryptography
|
||||
================================
|
||||
|
||||
### `++un`
|
||||
|
||||
Reversible scrambling core
|
||||
|
||||
++ un :: =(x (wred (wren x)))
|
||||
|%
|
||||
|
||||
A core that contains arms that perform reversible scrambling operations.
|
||||
Used in the `@p` phonetic base.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wren`
|
||||
|
||||
Conceal structure
|
||||
|
||||
++ wren :: conceal structure
|
||||
|= pyn=@ ^- @
|
||||
=+ len=(met 3 pyn)
|
||||
?: =(0 len)
|
||||
0
|
||||
=> .(len (dec len))
|
||||
=+ mig=(zaft (xafo len (cut 3 [len 1] pyn)))
|
||||
%+ can 3
|
||||
%- flop ^- (list ,[@ @])
|
||||
:- [1 mig]
|
||||
|- ^- (list ,[@ @])
|
||||
?: =(0 len)
|
||||
~
|
||||
=> .(len (dec len))
|
||||
=+ mog=(zyft :(mix mig (end 3 1 len) (cut 3 [len 1] pyn)))
|
||||
[[1 mog] $(mig mog)]
|
||||
::
|
||||
|
||||
Scrambles a bytestring `pyn` by adding the current position to each
|
||||
byte, looking it up in an s-box, and then performing the XOR operation
|
||||
on the result, pushing it forward. Produces an atom.
|
||||
|
||||
`pyn` is an [atom]().
|
||||
|
||||
~zod/try=> `@ux`(wren:un 'testing')
|
||||
0x30.bf6a.b9fe.7d8f
|
||||
~zod/try=> `@ux`'testing'
|
||||
0x67.6e69.7473.6574
|
||||
~zod/try=> `@da`(wred:un (wren:un ~2001.2.5))
|
||||
~2001.2.5
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wred`
|
||||
|
||||
Restore structure
|
||||
|
||||
++ wred :: restore structure
|
||||
|= cry=@ ^- @
|
||||
=+ len=(met 3 cry)
|
||||
?: =(0 len)
|
||||
0
|
||||
=> .(len (dec len))
|
||||
=+ mig=(cut 3 [len 1] cry)
|
||||
%+ can 3
|
||||
%- flop ^- (list ,[@ @])
|
||||
:- [1 (xaro len (zart mig))]
|
||||
|- ^- (list ,[@ @])
|
||||
?: =(0 len)
|
||||
~
|
||||
=> .(len (dec len))
|
||||
=+ mog=(cut 3 [len 1] cry)
|
||||
[[1 :(mix mig (end 3 1 len) (zyrt mog))] $(mig mog)]
|
||||
::
|
||||
|
||||
Unscrambles a bytestring `cry` by subtracting the current position from
|
||||
each byte, looking it up in an s-box, and performing the XOR operation
|
||||
on the result, pushing it forward. Produces an atom.
|
||||
|
||||
`cry` is an [atom]().
|
||||
|
||||
~zod/try=> (wred:un 0x30.bf6a.b9fe.7d8f)
|
||||
29.113.321.805.538.676
|
||||
~zod/try=> `@t`(wred:un 0x30.bf6a.b9fe.7d8f)
|
||||
'testing'
|
||||
~zod/try=> (wred:un (wren:un 200.038.426))
|
||||
200.038.426
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++xafo`
|
||||
|
||||
Add modulo 255
|
||||
|
||||
++ xafo |=([a=@ b=@] +((mod (add (dec b) a) 255)))
|
||||
|
||||
Produces the sum of two atoms modulo 255, encoded as a nonzero byte.
|
||||
|
||||
~zod/try=> (xafo:un 5 6)
|
||||
11
|
||||
~zod/try=> (xafo:un 256 20)
|
||||
21
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++xaro`
|
||||
|
||||
Subtract modulo 255
|
||||
|
||||
++ xaro |=([a=@ b=@] +((mod (add (dec b) (sub 255 (mod a 255))) 255)))
|
||||
|
||||
Produces the difference between two atoms modulo 255, encoded as a
|
||||
nonzero byte.
|
||||
|
||||
~zod/try=> (xaro:un 17 57)
|
||||
40
|
||||
~zod/try=> (xaro:un 265 12)
|
||||
2
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++zaft`
|
||||
|
||||
Look up in 255 sub box
|
||||
|
||||
++ zaft :: forward 255-sbox
|
||||
|= a=@D
|
||||
=+ ^= b
|
||||
0xcc.75bc.86c8.2fb1.9a42.f0b3.79a0.92ca.21f6.1e41.cde5.fcc0.
|
||||
7e85.51ae.1005.c72d.1246.07e8.7c64.a914.8d69.d9f4.59c2.8038.
|
||||
1f4a.dca2.6fdf.66f9.f561.a12e.5a16.f7b0.a39f.364e.cb70.7318.
|
||||
1de1.ad31.63d1.abd4.db68.6a33.134d.a760.edee.5434.493a.e323.
|
||||
930d.8f3d.3562.bb81.0b24.43cf.bea5.a6eb.52b4.0229.06b2.6704.
|
||||
78c9.45ec.d75e.58af.c577.b7b9.c40e.017d.90c3.87f8.96fa.1153.
|
||||
0372.7f30.1c32.ac83.ff17.c6e4.d36d.6b55.e2ce.8c71.8a5b.b6f3.
|
||||
9d4b.eab5.8b3c.e7f2.a8fe.9574.5de0.bf20.3f15.9784.9939.5f9c.
|
||||
e609.564f.d8a4.b825.9819.94aa.2c08.8e4c.9b22.477a.2840.3ed6.
|
||||
3750.6ef1.44dd.89ef.6576.d00a.fbda.9ed2.3b6c.7b0c.bde9.2ade.
|
||||
5c88.c182.481a.1b0f.2bfd.d591.2726.57ba
|
||||
(cut 3 [(dec a) 1] b)
|
||||
::
|
||||
|
||||
The inverse of [`++zart`](). Looks up a nonzero byte`a\` in a substiution
|
||||
box with 255 values, producing a unique nonzero byte.
|
||||
|
||||
`a` is an [atom]() of one byte in length.
|
||||
|
||||
~zod/try=> (zaft:un 0x12)
|
||||
42
|
||||
~zod/try=> (zaft:un 0xff)
|
||||
204
|
||||
~zod/try=> (zaft:un 0x0)
|
||||
! decrement-underflow
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++zart`
|
||||
|
||||
Reverse look up in 255 sub box
|
||||
|
||||
++ zart :: reverse 255-sbox
|
||||
|= a=@D
|
||||
=+ ^= b
|
||||
0x68.4f07.ea1c.73c9.75c2.efc8.d559.5125.f621.a7a8.8591.5613.
|
||||
dd52.40eb.65a2.60b7.4bcb.1123.ceb0.1bd6.3c84.2906.b164.19b3.
|
||||
1e95.5fec.ffbc.f187.fbe2.6680.7c77.d30e.e94a.9414.fd9a.017d.
|
||||
3a7e.5a55.8ff5.8bf9.c181.e5b6.6ab2.35da.50aa.9293.3bc0.cdc6.
|
||||
f3bf.1a58.4130.f844.3846.744e.36a0.f205.789e.32d8.5e54.5c22.
|
||||
0f76.fce7.4569.0d99.d26e.e879.dc16.2df4.887f.1ffe.4dba.6f5d.
|
||||
bbcc.2663.1762.aed7.af8a.ca20.dbb4.9bc7.a942.834c.105b.c4d4.
|
||||
8202.3e61.a671.90e6.273d.bdab.3157.cfa4.0c2e.df86.2496.f7ed.
|
||||
2b48.2a9d.5318.a343.d128.be9c.a5ad.6bb5.6dfa.c5e1.3408.128d.
|
||||
2c04.0339.97a1.2ff0.49d0.eeb8.6c0a.0b37.b967.c347.d9ac.e072.
|
||||
e409.7b9f.1598.1d3f.33de.8ce3.8970.8e7a
|
||||
(cut 3 [(dec a) 1] b)
|
||||
::
|
||||
|
||||
The inverse of [`++zaft`](). Looks up the index of a nonzero byte `a` in
|
||||
the substitution box with 255 values, producing a unique nonzero byte.
|
||||
|
||||
`a` is an [atom]() of one byte in length.
|
||||
|
||||
~zod/try=> `@ux`(zart:un 204)
|
||||
0xff
|
||||
~zod/try=> `@ux`(zart:un 42)
|
||||
0x12
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++zyft`
|
||||
|
||||
Lookup byte in 256 sub box
|
||||
|
||||
++ zyft :: forward 256-sbox
|
||||
|= a=@D
|
||||
=+ ^= b
|
||||
0xbb49.b71f.b881.b402.17e4.6b86.69b5.1647.115f.dddb.7ca5.
|
||||
8371.4bd5.19a9.b092.605d.0d9b.e030.a0cc.78ba.5706.4d2d.
|
||||
986a.768c.f8e8.c4c7.2f1c.effe.3cae.01c0.253e.65d3.3872.
|
||||
ce0e.7a74.8ac6.daac.7e5c.6479.44ec.4143.3d20.4af0.ee6c.
|
||||
c828.deca.0377.249f.ffcd.7b4f.eb7d.66f2.8951.042e.595a.
|
||||
8e13.f9c3.a79a.f788.6199.9391.7fab.6200.4ce5.0758.e2f1.
|
||||
7594.c945.d218.4248.afa1.e61a.54fb.1482.bea4.96a2.3473.
|
||||
63c2.e7cb.155b.120a.4ed7.bfd8.b31b.4008.f329.fca3.5380.
|
||||
9556.0cb2.8722.2bea.e96e.3ac5.d1bc.10e3.2c52.a62a.b1d6.
|
||||
35aa.d05e.f6a8.0f3b.31ed.559d.09ad.f585.6d21.fd1d.8d67.
|
||||
370b.26f4.70c1.b923.4684.6fbd.cf8b.5036.0539.9cdc.d93f.
|
||||
9068.1edf.8f33.b632.d427.97fa.9ee1
|
||||
(cut 3 [a 1] b)
|
||||
::
|
||||
|
||||
The inverse of [`++zyrt`](). Looks up a byte `a` in a substituion box
|
||||
with 256 values, producing a byte.
|
||||
|
||||
`a` is an [atom]() of one byte in length.
|
||||
|
||||
~zod/try=> (zyft:un 0x12)
|
||||
57
|
||||
~zod/try=> (zyft:un 0x0)
|
||||
225
|
||||
~zod/try=> (zyft:un 0xff)
|
||||
187
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++zyrt`
|
||||
|
||||
Reverse lookup byte in 256 sub box
|
||||
|
||||
++ zyrt :: reverse 256-sbox
|
||||
|= a=@D
|
||||
=+ ^= b
|
||||
0x9fc8.2753.6e02.8fcf.8b35.2b20.5598.7caa.c9a9.30b0.9b48.
|
||||
47ce.6371.80f6.407d.00dd.0aa5.ed10.ecb7.0f5a.5c3a.e605.
|
||||
c077.4337.17bd.9eda.62a4.79a7.ccb8.44cd.8e64.1ec4.5b6b.
|
||||
1842.ffd8.1dfb.fd07.f2f9.594c.3be3.73c6.2cb6.8438.e434.
|
||||
8d3d.ea6a.5268.72db.a001.2e11.de8c.88d3.0369.4f7a.87e2.
|
||||
860d.0991.25d0.16b9.978a.4bf4.2a1a.e96c.fa50.85b5.9aeb.
|
||||
9dbb.b2d9.a2d1.7bba.66be.e81f.1946.29a8.f5d2.f30c.2499.
|
||||
c1b3.6583.89e1.ee36.e0b4.6092.937e.d74e.2f6f.513e.9615.
|
||||
9c5d.d581.e7ab.fe74.f01b.78b1.ae75.af57.0ec2.adc7.3245.
|
||||
12bf.2314.3967.0806.31dc.cb94.d43f.493c.54a6.0421.c3a1.
|
||||
1c4a.28ac.fc0b.26ca.5870.e576.f7f1.616d.905f.ef41.33bc.
|
||||
df4d.225e.2d56.7fd6.1395.a3f8.c582
|
||||
(cut 3 [a 1] b)
|
||||
|
||||
The inverse of [`++zyft`](/doc/hoon/library/2en#++zyft). Looks up a byte `a` in a substituion box
|
||||
with 256 values, producing a byte.
|
||||
|
||||
`a` is an [atom]() of one byte in length.
|
||||
|
||||
~zod/try=> `@ux`(zyrt:un 57)
|
||||
0x12
|
||||
~zod/try=> `@ux`(zyrt:un 225)
|
||||
0x0
|
||||
~zod/try=> `@ux`(zyrt:un 187)
|
||||
0xff
|
||||
|
||||
### `++ob`
|
||||
|
||||
Reversible scrambling core, v2
|
||||
|
||||
++ ob
|
||||
|%
|
||||
|
||||
A core for performing reversible scrambling operations for the `@p` phonetic base.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++feen`
|
||||
|
||||
Conceal structure, v2
|
||||
|
||||
++ feen :: conceal structure v2
|
||||
|= pyn=@ ^- @
|
||||
?: &((gte pyn 0x1.0000) (lte pyn 0xffff.ffff))
|
||||
(add 0x1.0000 (fice (sub pyn 0x1.0000)))
|
||||
?: &((gte pyn 0x1.0000.0000) (lte pyn 0xffff.ffff.ffff.ffff))
|
||||
=+ lo=(dis pyn 0xffff.ffff)
|
||||
=+ hi=(dis pyn 0xffff.ffff.0000.0000)
|
||||
%+ con hi
|
||||
(add 0x1.0000 (fice (sub lo 0x1.0000)))
|
||||
pyn
|
||||
|
||||
Randomly permutes atoms that fit into 17 to 32 bits into one another. If the atom fits into 33 to 64 bits, does the same permutation on the low 32 bits only. Otherwise, passes the atom through unchanged.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fend`
|
||||
|
||||
++ fend :: restore structure v2
|
||||
|= cry=@ ^- @
|
||||
?: &((gte cry 0x1.0000) (lte cry 0xffff.ffff))
|
||||
(add 0x1.0000 (teil (sub cry 0x1.0000)))
|
||||
?: &((gte cry 0x1.0000.0000) (lte cry 0xffff.ffff.ffff.ffff))
|
||||
=+ lo=(dis cry 0xffff.ffff)
|
||||
=+ hi=(dis cry 0xffff.ffff.0000.0000)
|
||||
%+ con hi
|
||||
(add 0x1.0000 (teil (sub lo 0x1.0000)))
|
||||
cry
|
||||
|
||||
Randomly permutes atoms that fit into 17 to 32 bits into one another, and randomly permutes the low 32 bits of atoms that fit into 33 to 64 bits; otherwise, passes the atom through unchanged. The permutation is the inverse of the one applied by [`++feen`]().
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fice`
|
||||
|
||||
++ fice :: adapted from
|
||||
|= nor=@ :: black and rogaway
|
||||
^- @ :: "ciphers with
|
||||
=+ ^= sel :: arbitrary finite
|
||||
%+ rynd 2 :: domains", 2002
|
||||
%+ rynd 1
|
||||
%+ rynd 0
|
||||
[(mod nor 65.535) (div nor 65.535)]
|
||||
(add (mul 65.535 -.sel) +.sel)
|
||||
|
||||
Applies a 3-round Feistel-like cipher to randomly permute atoms in the range `0` to `2^32 - 2^16`. The construction given in Black and Rogaway is ideal for a domain with a size of that form, and as with a conventionel Feistel cipher, three rounds suffice to make the permutation pseudorandom.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++teil`
|
||||
|
||||
++ teil :: reverse ++fice
|
||||
|= vip=@
|
||||
^- @
|
||||
=+ ^= sel
|
||||
%+ rund 0
|
||||
%+ rund 1
|
||||
%+ rund 2
|
||||
[(mod vip 65.535) (div vip 65.535)]
|
||||
(add (mul 65.535 -.sel) +.sel)
|
||||
|
||||
Applies the reverse of the Feistel-like cipher applied by [`++fice`](). Unlike a conventional Feistel cipher that is its own inverse if keys are used in reverse order, this Feistel-like cipher uses two moduli that must be swapped when applying the reverse transformation.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++rynd`
|
||||
|
||||
++ rynd :: feistel round
|
||||
|= [n=@ l=@ r=@]
|
||||
^- [@ @]
|
||||
:- r
|
||||
?~ (mod n 2)
|
||||
(~(sum fo 65.535) l (en:aesc (snag n raku) r))
|
||||
(~(sum fo 65.536) l (en:aesc (snag n raku) r))
|
||||
|
||||
A single round of the Feistel-like cipher [`++fice`](). AES ([`++aesc`]()) is used as the round function.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++rund`
|
||||
|
||||
++ rund :: reverse round
|
||||
|= [n=@ l=@ r=@]
|
||||
^- [@ @]
|
||||
:- r
|
||||
?~ (mod n 2)
|
||||
(~(dif fo 65.535) l (en:aesc (snag n raku) r))
|
||||
(~(dif fo 65.536) l (en:aesc (snag n raku) r))
|
||||
|
||||
A single round of the Feistel-like reverse cipher [`++teil`]().
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++raku`
|
||||
|
||||
++ raku
|
||||
^- (list ,@ux)
|
||||
:~ 0x15f6.25e3.083a.eb3e.7a55.d4db.fb99.32a3.
|
||||
43af.2750.219e.8a24.e5f8.fac3.6c36.f968
|
||||
0xf2ff.24fe.54d0.1abd.4b2a.d8aa.4402.8e88.
|
||||
e82f.19ec.948d.b1bb.ed2e.f791.83a3.8133
|
||||
0xa3d8.6a7b.400e.9e91.187d.91a7.6942.f34a.
|
||||
6f5f.ab8e.88b9.c089.b2dc.95a6.aed5.e3a4
|
||||
==
|
||||
|
||||
Arbitrary keys for use with [`++aesc`]().
|
@ -1,453 +0,0 @@
|
||||
section 2eO, virtualization
|
||||
===========================
|
||||
|
||||
### `++mack`
|
||||
|
||||
Nock subject to unit
|
||||
|
||||
++ mack
|
||||
|= [sub=* fol=*]
|
||||
^- (unit)
|
||||
=+ ton=(mink [sub fol] |=(* ~))
|
||||
?.(?=([0 *] ton) ~ [~ p.ton])
|
||||
::
|
||||
|
||||
Accepts a nock subject-formula cell and wraps it into a [`++unit`]().
|
||||
`fol` is pure nock, meaning that nock `11` operations result in a block,
|
||||
producing a `~`.
|
||||
|
||||
`sub` is a subject [noun]().
|
||||
|
||||
`fol` is a formula [noun](), which is generally a `++nock`.
|
||||
|
||||
~zod/try=> (mack [[1 2 3] [0 1]])
|
||||
[~ [1 2 3]]
|
||||
~zod/try=> (mack [41 4 0 1])
|
||||
[~ 42]
|
||||
~zod/try=> (mack [4 0 4])
|
||||
~
|
||||
~zod/try=> (mack [[[0 2] [1 3]] 4 4 4 4 0 5])
|
||||
[~ 6]
|
||||
~zod/try=> ;;((unit ,@tas) (mack [[1 %yes %no] 6 [0 2] [0 6] 0 7]))
|
||||
[~ %no]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mink`
|
||||
|
||||
Mock interpreter
|
||||
|
||||
++ mink
|
||||
~/ %mink
|
||||
|= [[sub=* fol=*] sky=$+(* (unit))]
|
||||
=+ tax=*(list ,[@ta *])
|
||||
|- ^- tone
|
||||
?@ fol
|
||||
[%2 tax]
|
||||
?: ?=(^ -.fol)
|
||||
=+ hed=$(fol -.fol)
|
||||
?: ?=(%2 -.hed)
|
||||
hed
|
||||
=+ tal=$(fol +.fol)
|
||||
?- -.tal
|
||||
%0 ?-(-.hed %0 [%0 p.hed p.tal], %1 hed)
|
||||
%1 ?-(-.hed %0 tal, %1 [%1 (weld p.hed p.tal)])
|
||||
%2 tal
|
||||
==
|
||||
?+ fol
|
||||
[%2 tax]
|
||||
::
|
||||
[0 b=@]
|
||||
?: =(0 b.fol) [%2 tax]
|
||||
?: =(1 b.fol) [%0 sub]
|
||||
?: ?=(@ sub) [%2 tax]
|
||||
=+ [now=(cap b.fol) lat=(mas b.fol)]
|
||||
$(b.fol lat, sub ?:(=(2 now) -.sub +.sub))
|
||||
::
|
||||
[1 b=*]
|
||||
[%0 b.fol]
|
||||
::
|
||||
[2 b=[^ *]]
|
||||
=+ ben=$(fol b.fol)
|
||||
?. ?=(%0 -.ben) ben
|
||||
?>(?=(^ p.ben) $(sub -.p.ben, fol +.p.ben))
|
||||
::?>(?=(^ p.ben) $([sub fol] p.ben)
|
||||
::
|
||||
[3 b=*]
|
||||
=+ ben=$(fol b.fol)
|
||||
?. ?=(%0 -.ben) ben
|
||||
[%0 .?(p.ben)]
|
||||
::
|
||||
[4 b=*]
|
||||
=+ ben=$(fol b.fol)
|
||||
?. ?=(%0 -.ben) ben
|
||||
?. ?=(@ p.ben) [%2 tax]
|
||||
[%0 .+(p.ben)]
|
||||
::
|
||||
[5 b=*]
|
||||
=+ ben=$(fol b.fol)
|
||||
?. ?=(%0 -.ben) ben
|
||||
?. ?=(^ p.ben) [%2 tax]
|
||||
[%0 =(-.p.ben +.p.ben)]
|
||||
::
|
||||
[6 b=* c=* d=*]
|
||||
$(fol =>(fol [2 [0 1] 2 [1 c d] [1 0] 2 [1 2 3] [1 0] 4 4 b]))
|
||||
::
|
||||
[7 b=* c=*] $(fol =>(fol [2 b 1 c]))
|
||||
[8 b=* c=*] $(fol =>(fol [7 [[0 1] b] c]))
|
||||
[9 b=* c=*] $(fol =>(fol [7 c 0 b]))
|
||||
[10 @ c=*] $(fol c.fol)
|
||||
[10 [b=* c=*] d=*]
|
||||
=+ ben=$(fol c.fol)
|
||||
?. ?=(%0 -.ben) ben
|
||||
?: ?=(?(%hunk %lose %mean %spot) b.fol)
|
||||
$(fol d.fol, tax [[b.fol p.ben] tax])
|
||||
$(fol d.fol)
|
||||
::
|
||||
[11 b=*]
|
||||
=+ ben=$(fol b.fol)
|
||||
?. ?=(%0 -.ben) ben
|
||||
=+ val=(sky p.ben)
|
||||
?~(val [%1 p.ben ~] [%0 u.val])
|
||||
::
|
||||
==
|
||||
::
|
||||
|
||||
Bottom-level [mock]() (virtual nock) interpreter. Produces a
|
||||
[`++tone`](), a nock computation result. If nock 11 is invoked, `sky`
|
||||
computes on the subject and produces a [`++unit`]() result. An empty
|
||||
result becomes a `%1` `++tone`, indicating a block.
|
||||
|
||||
`sub` is the subject as a [noun]().
|
||||
|
||||
`fol` is the formula as a [noun]().
|
||||
|
||||
`sky` is an [`%iron`]() gate invoked with [nock operator 11]().
|
||||
|
||||
~zod/try=> (mink [20 [4 0 1]] ,~)
|
||||
[%0 p=21]
|
||||
~zod/try=> (mink [[90 5 3] [0 3]] ,~)
|
||||
[%0 p=[5 3]]
|
||||
~zod/try=> (mink 20^[4 0 1] ,~)
|
||||
[%0 p=21]
|
||||
~zod/try=> (mink [90 5 3]^[0 3] ,~)
|
||||
[%0 p=[5 3]]
|
||||
~zod/try=> (mink [0]^[11 1 20] ,~)
|
||||
[%1 p=~[20]]
|
||||
~zod/try=> (mink [0]^[11 1 20] |=(a=* `[40 a]))
|
||||
[%0 p=[40 20]]
|
||||
~zod/try=> (mink [5]^[0 2] ,~)
|
||||
[%2 p=~]
|
||||
~zod/try=> (mink [5]^[10 yelp/[0 1] 0 0] ,~)
|
||||
[%2 p=~[[~.yelp 5]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mock`
|
||||
|
||||
Compute formula on subject with hint
|
||||
|
||||
++ mock
|
||||
|= [[sub=* fol=*] sky=$+(* (unit))]
|
||||
(mook (mink [sub fol] sky))
|
||||
::
|
||||
|
||||
Produces a [`++toon`](), which is either a sucessful, blocked, or
|
||||
crashed result. If nock 11 is invoked, `sky` computes on the subject and
|
||||
produces a [`++unit`]() result. An empty result becomes a `%1` `++tune`,
|
||||
indicating a block.
|
||||
|
||||
`sub` is the subject as a [noun]().
|
||||
|
||||
`fol` is the formula as a [noun]().
|
||||
|
||||
`sky` is an [%iron]() gate invoked with [nock operator 11]().
|
||||
|
||||
~zod/try=> (mock [5 4 0 1] ,~)
|
||||
[%0 p=6]
|
||||
~zod/try=> (mock [~ 11 1 0] |=(* `999))
|
||||
[%0 p=999]
|
||||
~zod/try=> (mock [~ 0 1.337] ,~)
|
||||
[%2 p=~]
|
||||
~zod/try=> (mock [~ 11 1 1.337] ,~)
|
||||
[%1 p=~[1.337]]
|
||||
~zod/try=> (mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[+<]))
|
||||
[%0 p=14]
|
||||
~zod/try=> (mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[<+<>]))
|
||||
[%0 p=[49 52 0]]
|
||||
~zod/try=> ;;(tape +:(mock [[[4 4 4 4 0 3] 10] 11 9 2 0 1] |=(* `[<+<>])))
|
||||
"14"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mook`
|
||||
|
||||
Intelligently render crash annotation
|
||||
|
||||
++ mook
|
||||
|= ton=tone
|
||||
^- toon
|
||||
?. ?=([2 *] ton) ton
|
||||
:- %2
|
||||
=+ yel=(lent p.ton)
|
||||
=. p.ton
|
||||
?. (gth yel 256) p.ton
|
||||
%+ weld
|
||||
(scag 128 p.ton)
|
||||
^- (list ,[@ta *])
|
||||
:_ (slag (sub yel 128) p.ton)
|
||||
:- %lose
|
||||
%+ rap 3
|
||||
;: weld
|
||||
"[skipped "
|
||||
~(rend co %$ %ud (sub yel 256))
|
||||
" frames]"
|
||||
==
|
||||
|- ^- (list tank)
|
||||
?~ p.ton ~
|
||||
=+ rex=$(p.ton t.p.ton)
|
||||
?+ -.i.p.ton rex
|
||||
%hunk [(tank +.i.p.ton) rex]
|
||||
%lose [[%leaf (rip 3 (,@ +.i.p.ton))] rex]
|
||||
%mean :_ rex
|
||||
?@ +.i.p.ton [%leaf (rip 3 (,@ +.i.p.ton))]
|
||||
=+ mac=(mack +.i.p.ton +<.i.p.ton)
|
||||
?~(mac [%leaf "####"] (tank u.mac))
|
||||
%spot :_ rex
|
||||
=+ sot=(spot +.i.p.ton)
|
||||
:- %leaf
|
||||
;: weld
|
||||
~(ram re (smyt p.sot))
|
||||
":<["
|
||||
~(rend co ~ %ud p.p.q.sot)
|
||||
" "
|
||||
~(rend co ~ %ud q.p.q.sot)
|
||||
"].["
|
||||
~(rend co ~ %ud p.q.q.sot)
|
||||
" "
|
||||
~(rend co ~ %ud q.q.q.sot)
|
||||
"]>"
|
||||
==
|
||||
==
|
||||
::
|
||||
|
||||
Converts a `%2` `++tone` nock stack trace to a list of [`++tank`]().
|
||||
Each may be a tank, cord, [`++spot`](), or trapped tank. Produces a
|
||||
[`++toon`]().
|
||||
|
||||
`ton` is a [`++tone`]().
|
||||
|
||||
~zod/try=> (mook [%0 5 4 5 1])
|
||||
[%0 p=[5 4 5 1]]
|
||||
~zod/try=> (mook [%2 ~[[%hunk %rose ["<" "," ">"] ~[[%leaf "err"]]]]])
|
||||
[%2 p=~[[%rose p=[p="<" q="," r=">"] q=[i=[%leaf p="err"] t=~]]]]
|
||||
~zod/try=> (mook [%2 ~[[%malformed %elem] [%lose 'do print']]])
|
||||
[%2 p=~[[%leaf p="do print"]]]
|
||||
~zod/try=> (mook [%2 ~[[%mean |.(>(add 5 6)<)]]])
|
||||
[%2 p=~[[%leaf p="11"]]]
|
||||
~zod/try=> (mook [%2 ~[[%spot /b/repl [1 1]^[1 2]] [%mean |.(!!)]]])
|
||||
[%2 p=~[[%leaf p="/b/repl/:<[1 1].[1 2]>"] [%leaf p="####"]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mang`
|
||||
|
||||
Unit: Slam gate with sample
|
||||
|
||||
++ mang
|
||||
|= [[gat=* sam=*] sky=$+(* (unit))]
|
||||
^- (unit)
|
||||
=+ ton=(mong [[gat sam] sky])
|
||||
?.(?=([0 *] ton) ~ [~ p.ton])
|
||||
::
|
||||
|
||||
Produces a [`++unit`]() computation result from slamming `gat` with
|
||||
`sam`, using `sky` to compute or block on nock 11 when applicable.
|
||||
Similar to [`++mong`]().
|
||||
|
||||
`gat` is a [noun]() that is generally a [`gate`]().
|
||||
|
||||
`sam` is a [`sample`]() noun.
|
||||
|
||||
`sky` is an [%iron]() gate invoked with [nock operator 11]().
|
||||
|
||||
~zod/try=> (mang [|=(@ 20) ~] ,~)
|
||||
[~ 20]
|
||||
~zod/try=> (mang [|=(@ !!) ~] ,~)
|
||||
~
|
||||
~zod/try=> (mang [|=(a=@ (add 20 a)) ~] ,~)
|
||||
[~ 20]
|
||||
~zod/try=> (mang [|=(a=[@ @] (add 20 -.a)) ~] ,~)
|
||||
~
|
||||
~zod/try=> (mang [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
|
||||
[~ 24]
|
||||
~zod/try=> (mang [|=(a=@ .^(a)) ~] ,~)
|
||||
~
|
||||
~zod/try=> (mang [|=(a=@ .^(a)) ~] ,[~ %42])
|
||||
[~ 42]
|
||||
~zod/try=> (mang [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
|
||||
[~ [0 6]]
|
||||
~zod/try=> (mang [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
|
||||
[~ [8 6]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mong`
|
||||
|
||||
Slam gate with sample
|
||||
|
||||
++ mong
|
||||
|= [[gat=* sam=*] sky=$+(* (unit))]
|
||||
^- toon
|
||||
?. &(?=(^ gat) ?=(^ +.gat))
|
||||
[%2 ~]
|
||||
(mock [[-.gat [sam +>.gat]] -.gat] sky)
|
||||
::
|
||||
|
||||
Produces a [`++toon`]() computation result from slamming `gat` with
|
||||
`sam`, using `sky` to compute or block on nock 11 when applicable.
|
||||
|
||||
`gat` is a [noun]() that is generally a [`gate`]().
|
||||
|
||||
`sam` is a [`sample`]() noun.
|
||||
|
||||
`sky` is an [%iron]() gate invoked with [nock operator 11]().
|
||||
|
||||
~zod/try=> (mong [|=(@ 20) ~] ,~)
|
||||
[%0 p=20]
|
||||
~zod/try=> (mong [|=(@ !!) ~] ,~)
|
||||
[%2 p=~]
|
||||
~zod/try=> (mong [|=(a=@ (add 20 a)) ~] ,~)
|
||||
[%0 p=20]
|
||||
~zod/try=> (mong [|=(a=[@ @] (add 20 -.a)) ~] ,~)
|
||||
[%2 p=~]
|
||||
~zod/try=> (mong [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
|
||||
[%0 p=24]
|
||||
~zod/try=> (mong [|=(a=@ .^(a)) ~] ,~)
|
||||
[%1 p=~[0]]
|
||||
~zod/try=> (mong [|=(a=@ .^(a)) ~] ,[~ %42])
|
||||
[%0 p=42]
|
||||
~zod/try=> (mong [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
|
||||
[%0 p=[0 6]]
|
||||
~zod/try=> (mong [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
|
||||
[%0 p=[8 6]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mung`
|
||||
|
||||
Virtualize slamming gate
|
||||
|
||||
++ mung
|
||||
|= [[gat=* sam=*] sky=$+(* (unit))]
|
||||
^- tone
|
||||
?. &(?=(^ gat) ?=(^ +.gat))
|
||||
[%2 ~]
|
||||
(mink [[-.gat [sam +>.gat]] -.gat] sky)
|
||||
::
|
||||
|
||||
Produces a [`++tone`]() computation result from slamming `gat` with
|
||||
`sam`, using `sky` to compute or block on nock 11 when applicable.
|
||||
|
||||
`gat` is a [noun]() that is generally a [`gate`]().
|
||||
|
||||
`sam` is a [`sample`]() noun.
|
||||
|
||||
`sky` is an [%iron]() gate invoked with [nock operator 11]().
|
||||
|
||||
~zod/try=> (mung [|=(@ 20) ~] ,~)
|
||||
[%0 p=20]
|
||||
~zod/try=> (mung [|=(@ !!) ~] ,~)
|
||||
[%2 p=~]
|
||||
~zod/try=> (mung [|=(a=@ (add 20 a)) ~] ,~)
|
||||
[%0 p=20]
|
||||
~zod/try=> (mung [|=(a=[@ @] (add 20 -.a)) ~] ,~)
|
||||
[%2 p=~]
|
||||
~zod/try=> (mung [|=(a=[@ @] (add 20 -.a)) [4 6]] ,~)
|
||||
[%0 p=24]
|
||||
~zod/try=> (mung [|=(a=@ .^(a)) ~] ,~)
|
||||
[%1 p=~[0]]
|
||||
~zod/try=> (mung [|=(a=@ .^(a)) ~] ,[~ %42])
|
||||
[%0 p=42]
|
||||
~zod/try=> (mung [|=(a=@ .^(a)) ~] |=(a=* [~ a 6]))
|
||||
[%0 p=[0 6]]
|
||||
~zod/try=> (mung [|=(a=@ .^(a)) 8] |=(a=* [~ a 6]))
|
||||
[%0 p=[8 6]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mule`
|
||||
|
||||
Typed virtual
|
||||
|
||||
++ mule :: typed virtual
|
||||
~/ %mule
|
||||
|* taq=_|.(_*)
|
||||
=+ mud=(mute taq)
|
||||
?- -.mud
|
||||
& [%& p=$:taq]
|
||||
| [%| p=p.mud]
|
||||
==
|
||||
::
|
||||
|
||||
Kicks a `++trap`, producing its results or any errors that occur along
|
||||
the way. Used to lazily compute stack traces.
|
||||
|
||||
`taq` is a [`++trap`](), generally producing a list of [`++tank`]()s.
|
||||
|
||||
~zod/try=> (mule |.(leaf/"hello"))
|
||||
[%.y p=[%leaf "hello"]]
|
||||
~zod/try=> (mule |.(!!))
|
||||
[%.n p=~]
|
||||
~zod/try=> (mule |.(.^(a//=pals/1)))
|
||||
[ %.n
|
||||
p
|
||||
~[
|
||||
[ %rose
|
||||
p=[p="/" q="/" r="/"]
|
||||
q
|
||||
[ i=[%leaf p="a"]
|
||||
t=[i=[%leaf p="~zod"] t=[i=[%leaf p="pals"] t=[i=[%leaf p="1"] t=~]]]
|
||||
]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mute`
|
||||
|
||||
Untyped virtual
|
||||
|
||||
++ mute :: untyped virtual
|
||||
|= taq=_^?(|.(_*))
|
||||
^- (each ,* (list tank))
|
||||
=+ ton=(mock [taq 9 2 0 1] |=(* ~))
|
||||
?- -.ton
|
||||
%0 [%& p.ton]
|
||||
%1 [%| (turn p.ton |=(a=* (smyt (path a))))]
|
||||
%2 [%| p.ton]
|
||||
==
|
||||
|
||||
Kicks a `++trap`, producing its result as a noun or the tanks of any
|
||||
error that occurs. Similar to [`++mule`](), but preserves no type
|
||||
information.
|
||||
|
||||
`taq` is a [`++trap`](/doc/hoon/library/1#++trap).
|
||||
|
||||
~zod/try=> (mute |.(leaf/"hello"))
|
||||
[%.y p=[1.717.658.988 104 101 108 108 111 0]]
|
||||
~zod/try=> (mute |.(!!))
|
||||
[%.n p=~]
|
||||
~zod/try=> (mute |.(.^(a//=pals/1)))
|
||||
[ %.n
|
||||
p
|
||||
~[
|
||||
[ %rose
|
||||
p=[p="/" q="/" r="/"]
|
||||
q=[i=[%leaf p="a"] t=[i=[%leaf p="~zod"] t=[i=[%leaf p="pals"] t=[i=[%leaf p="1"] t=~]]]]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,586 +0,0 @@
|
||||
section 2eP, diff
|
||||
=================
|
||||
|
||||
A- more or less low priority and/or currently in the wrong section
|
||||
anyway.
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++berk`
|
||||
|
||||
Invert diff patches
|
||||
|
||||
++ berk :: invert diff patch
|
||||
|* bur=(urge)
|
||||
|- ^+ bur
|
||||
?~ bur ~
|
||||
:_ $(bur t.bur)
|
||||
?- -.i.bur
|
||||
& i.bur
|
||||
| [%| q.i.bur p.i.bur]
|
||||
==
|
||||
::
|
||||
|
||||
Inverts a list of changes `bur`. Skips stay constant and replaces are
|
||||
swapped. Produces a `bur`.
|
||||
|
||||
`bur` is a [`++urge`]().
|
||||
|
||||
~zod/try=> (berk `(urge)`~[`10 %|^[~[2] ~[3 4]] `5])
|
||||
~[[%.y p=10] [%.n p=~[3 4] q=~[2]] [%.y p=5]]
|
||||
~zod/try=> (lurk "somes" `(urge char)`~[`1 [%| "o" "a"] `3])
|
||||
"sames"
|
||||
~zod/try=> (berk `(urge char)`~[`1 [%| "o" "a"] `3])
|
||||
~[[%.y p=1] [%.n p="a" q="o"] [%.y p=3]]
|
||||
~zod/try=> (lurk "sames" (berk `(urge char)`~[`1 [%| "o" "a"] `3]))
|
||||
"somes"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++diff`
|
||||
|
||||
Generate patch
|
||||
|
||||
++ diff :: generate patch
|
||||
|= pum=umph
|
||||
|= [old=* new=*] ^- udon
|
||||
:- pum
|
||||
?+ pum ~|(%unsupported !!)
|
||||
%a [%d (nude old new)]
|
||||
%b =+ [hel=(cue ((hard ,@) old)) hev=(cue ((hard ,@) new))]
|
||||
[%d (nude hel hev)]
|
||||
%c =+ [hel=(lore ((hard ,@) old)) hev=(lore ((hard ,@) new))]
|
||||
[%c (lusk hel hev (loss hel hev))]
|
||||
==
|
||||
::
|
||||
|
||||
Produces a patch between two nouns, by change type
|
||||
|
||||
`pum` is an [`++umph`]().
|
||||
|
||||
~zod/try=> ((diff %a) 20 21)
|
||||
[p=%a q=[%d p=[%1 p=21] q=[%1 p=20]]]
|
||||
~zod/try=> ((diff %a) [1 2 3] [1 2 4])
|
||||
[ p=%a
|
||||
q
|
||||
[ %d
|
||||
p=[p=[%0 p=2] q=[p=[%0 p=6] q=[%1 p=4]]]
|
||||
q=[p=[%0 p=2] q=[p=[%0 p=6] q=[%1 p=3]]]
|
||||
]
|
||||
]
|
||||
~zod/try=> ~04hh
|
||||
[1 2]
|
||||
~zod/try=> ~0ph
|
||||
[1 1]
|
||||
~zod/try=> ((diff %b) 0v4hh 0vph)
|
||||
[p=%b q=[%d p=[p=[%0 p=2] q=[%0 p=2]] q=[p=[%0 p=3] q=[%1 p=2]]]]
|
||||
~zod/try=> ((diff %c) (role 'sam' 'les' 'les' 'kor' ~) (role 'sam' 'mor' 'kor' ~))
|
||||
[p=%c q=[%c p=~[[%.y p=1] [%.n p=~[7.562.604 7.562.604] q=~[7.499.629]] [%.y p=1]]]]
|
||||
~[[%.y p=0] [%.y p=0] [%.y p=1] [%.n p=<|les les|> q=<|mor|>] [%.y p=1]]
|
||||
~zod/try=> (,[%c %c (urge cord)] ((diff %c) (role 'sam' 'les' 'les' 'kor' ~) (role 'sam' 'mor' 'kor' ~)))
|
||||
[%c %c ~[[%.y p=1] [%.n p=<|les les|> q=<|mor|>] [%.y p=1]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++loss`
|
||||
|
||||
Longest subsequence
|
||||
|
||||
++ loss :: longest subsequence
|
||||
~/ %loss
|
||||
|* [hel=(list) hev=(list)]
|
||||
|- ^+ hev
|
||||
=+ ^= sev
|
||||
=+ [inx=0 sev=*(map ,@t (list ,@ud))]
|
||||
|- ^+ sev
|
||||
?~ hev sev
|
||||
=+ guy=(~(get by sev) i.hev)
|
||||
$(hev t.hev, inx +(inx), sev (~(put by sev) i.hev [inx ?~(guy ~ u.guy)]))
|
||||
=| gox=[p=@ud q=(map ,@ud ,[p=@ud q=_hev])]
|
||||
=< abet
|
||||
=< main
|
||||
|%
|
||||
++ abet =.(q.rag ?:(=([& 0] p.rag) q.rag [p.rag q.rag]) (flop q.rag))
|
||||
++ hink :: extend fits top
|
||||
|= [inx=@ud goy=@ud] ^- ?
|
||||
|(=(p.gox inx) (lth goy p:(need (~(get by q.gox) inx))))
|
||||
::
|
||||
++ lonk :: extend fits bottom
|
||||
|= [inx=@ud goy=@ud] ^- ?
|
||||
|(=(0 inx) (gth goy p:(need (~(get by q.gox) (dec inx)))))
|
||||
::
|
||||
++ lune :: extend
|
||||
|= [inx=@ud goy=@ud]
|
||||
^+ +>
|
||||
%_ +>.$
|
||||
gox
|
||||
:- ?:(=(inx p.gox) +(p.gox) p.gox)
|
||||
%+ ~(put by q.gox) inx
|
||||
[goy (snag goy hev) ?:(=(0 inx) ~ q:(need (~(get by q.gox) (dec inx))))]
|
||||
==
|
||||
::
|
||||
++ merg :: merge all matches
|
||||
|= gay=(list ,@ud)
|
||||
^+ +>
|
||||
=+ ^= zes
|
||||
=+ [inx=0 zes=*(list ,[p=@ud q=@ud])]
|
||||
|- ^+ zes
|
||||
?: |(?=(~ gay) (gth inx p.gox)) zes
|
||||
?. (lonk inx i.gay) $(gay t.gay)
|
||||
?. (hink inx i.gay) $(inx +(inx))
|
||||
$(inx +(inx), gay t.gay, zes [[inx i.gay] zes])
|
||||
|- ^+ +>.^$
|
||||
?~(zes +>.^$ $(zes t.zes, +>.^$ (lune i.zes)))
|
||||
::
|
||||
++ main
|
||||
|- ^+ +
|
||||
?~ hel
|
||||
?~ hev
|
||||
?>(?=(~ lcs) +)
|
||||
$(hev t.hev, rag (done %| ~ [i.hev ~]))
|
||||
?~ hev
|
||||
$(hel t.hel, rag (done %| [i.hel ~] ~))
|
||||
?~ lcs
|
||||
+(rag (done %| (flop hel) (flop hev)))
|
||||
?: =(i.hel i.lcs)
|
||||
?: =(i.hev i.lcs)
|
||||
$(lcs t.lcs, hel t.hel, hev t.hev, rag (done %& 1))
|
||||
$(hev t.hev, rag (done %| ~ [i.hev ~]))
|
||||
?: =(i.hev i.lcs)
|
||||
$(hel t.hel, rag (done %| [i.hel ~] ~))
|
||||
$(hel t.hel, hev t.hev, rag (done %| [i.hel ~] [i.hev ~]))
|
||||
--
|
||||
|
||||
Finds a subsequence of repeated elements within two [`++list`]()s, using
|
||||
several internal helper arms. Produces a [`++tape`]().
|
||||
|
||||
`hel` is a [`++list`]() of characters.
|
||||
|
||||
`hev` is a [++list\`]() of characters.
|
||||
|
||||
~zod/try=> (loss "sam" "sem")
|
||||
"sm"
|
||||
~zod/try=> (loss "samo" "semo")
|
||||
"smo"
|
||||
~zod/try=> (loss "sakmo" "semo")
|
||||
"smo"
|
||||
~zod/try=> (loss "ferdinham" "ferdilapos
|
||||
~ <syntax error at [1 30]>
|
||||
~zod/try=> (loss "ferdinham" "ferdilapos")
|
||||
"ferdia"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++locz`
|
||||
|
||||
Find common
|
||||
|
||||
++ locz :: trivial algorithm
|
||||
|= [hel=tape hev=tape]
|
||||
^- tape
|
||||
=+ [leh=(lent hel) veh=(lent hev)]
|
||||
=- (flop q.yun)
|
||||
^= yun
|
||||
|- ^- [p=@ud q=tape]
|
||||
~+
|
||||
?: |(=(0 leh) =(0 veh)) [0 ~]
|
||||
=+ [dis=(snag (dec leh) hel) dat=(snag (dec veh) hev)]
|
||||
?: =(dis dat)
|
||||
=+ say=$(leh (dec leh), veh (dec veh))
|
||||
[+(p.say) [dis q.say]]
|
||||
=+ [lef=$(leh (dec leh)) rig=$(veh (dec veh))]
|
||||
?:((gth p.lef p.rig) lef rig)
|
||||
::
|
||||
|
||||
Finds a subsequence of repeated elements within two [`++list`](/doc/hoon/library/1#++list)s,
|
||||
producing a [\`++tape]().
|
||||
|
||||
~zod/try=> (locz "samukot" "semelkot")
|
||||
"smkot"
|
||||
~zod/try=> (locz "samukot" "samelkot")
|
||||
"samkot"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lore`
|
||||
|
||||
Split on `\n`
|
||||
|
||||
++ lore :: atom to line list
|
||||
~/ %lore
|
||||
|= lub=@
|
||||
=| tez=(list ,@t)
|
||||
|- ^+ tez
|
||||
?: =(0 lub) (flop tez)
|
||||
=+ ^= meg
|
||||
=+ meg=0
|
||||
|- ^- @ud
|
||||
=+ gam=(cut 3 [meg 1] lub)
|
||||
?:(|(=(10 gam) =(0 gam)) meg $(meg +(meg)))
|
||||
=+ res=(rsh 3 +(meg) lub)
|
||||
?: &(=(0 (cut 3 [meg 1] lub)) !=(0 res))
|
||||
!!
|
||||
$(lub res, tez [(end 3 meg lub) tez])
|
||||
::
|
||||
|
||||
Split on newlines, ascii `10`
|
||||
|
||||
~zod/try=> (lore 'soke\0alas\0amep')
|
||||
<|soke las mep|>
|
||||
~zod/try=> (lore '|= a=@\0a=+ b=(add a 5)\0a(mix b a)')
|
||||
<||= a=@ =+ b=(add a 5) (mix b a)|>
|
||||
~zod/try=> `wain`[(fil 3 80 ' ') (lore '|= a=@\0a=+ b=(add a 5)\0a(mix b a)')]
|
||||
<|
|
||||
|= a=@
|
||||
=+ b=(add a 5)
|
||||
(mix b a)
|
||||
|>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++role`
|
||||
|
||||
Join with `\n`
|
||||
|
||||
++ role :: line list to atom
|
||||
|= tez=(list ,@t)
|
||||
(rap 3 (turn tez |=(a=@t (cat 3 a 10))))
|
||||
::
|
||||
|
||||
Join line list with newlines.
|
||||
|
||||
~zod/try=> (role 'sep' 'tek' 'lap' ~)
|
||||
3.230.709.852.558.292.782.985.274.739
|
||||
~zod/try=> `@t`(role 'sep' 'tek' 'lap' ~)
|
||||
'''
|
||||
sep
|
||||
tek
|
||||
lap
|
||||
'''
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lump`
|
||||
|
||||
Change with `++udon`
|
||||
|
||||
++ lump :: apply patch
|
||||
|= [don=udon src=*]
|
||||
^- *
|
||||
?+ p.don ~|(%unsupported !!)
|
||||
%a
|
||||
?+ -.q.don ~|(%unsupported !!)
|
||||
%a q.q.don
|
||||
%c (lurk ((hard (list)) src) p.q.don)
|
||||
%d (lure src p.q.don)
|
||||
==
|
||||
::
|
||||
%c
|
||||
=+ dst=(lore ((hard ,@) src))
|
||||
%- role
|
||||
?+ -.q.don ~|(%unsupported !!)
|
||||
%a ((hard (list ,@t)) q.q.don)
|
||||
%c (lurk dst p.q.don)
|
||||
==
|
||||
==
|
||||
::
|
||||
|
||||
Use udon to change noun
|
||||
|
||||
~zod/try=> (lump [%a %a 20 25] 20)
|
||||
25
|
||||
~zod/try=> (lump [%a %d [[%0 1] [%0 1]] [%0 2]] 20)
|
||||
[20 20]
|
||||
~zod/try=> (lump [%c %a ~['sa' 'le'] ~['sa' 'lo']] 'sa\0ale')
|
||||
11.473.670.267.251
|
||||
~zod/try=> (,@t (lump [%c %a ~['sa' 'le'] ~['sa' 'lo']] 'sa\0ale'))
|
||||
'''
|
||||
sa
|
||||
lo
|
||||
'''
|
||||
~zod/try=> (,@t (lump [%c %c `1 [%| ~['le'] ~['lo' 'ma']] ~] 'sa\0ale'))
|
||||
'''
|
||||
sa
|
||||
ma
|
||||
lo
|
||||
'''
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lure`
|
||||
|
||||
Patch `a`
|
||||
|
||||
++ lure :: apply tree diff
|
||||
|= [a=* b=upas]
|
||||
^- *
|
||||
?^ -.b
|
||||
[$(b -.b) $(b +.b)]
|
||||
?+ -.b ~|(%unsupported !!)
|
||||
%0 .*(a [0 p.b])
|
||||
%1 .*(a [1 p.b])
|
||||
==
|
||||
|
||||
Patch a by references to axis and literal.
|
||||
|
||||
~zod/try=> (lure ~[1 2] [[%0 2] [%1 3] [%0 7]])
|
||||
[1 3 0]
|
||||
~zod/try=> (lure ~[1 2 4] [[%0 2] [%1 3] [%0 7]])
|
||||
[1 3 4 0]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++limp`
|
||||
|
||||
Reverse patch
|
||||
|
||||
++ limp :: invert patch
|
||||
|= don=udon ^- udon
|
||||
:- p.don
|
||||
?+ -.q.don ~|(%unsupported !!)
|
||||
%a [%a q.q.don p.q.don]
|
||||
%c [%c (berk p.q.don)]
|
||||
%d [%d q.q.don p.q.don]
|
||||
==
|
||||
::
|
||||
|
||||
Reverse a patch (preprocessor unchanged)
|
||||
|
||||
~zod/try=> (limp [%a %a 20 40])
|
||||
[p=%a q=[%a p=40 q=20]]
|
||||
~zod/try=> (limp [%c %c ~[`20 [%| ~[52 53] ~[51]] `6]])
|
||||
[p=%c q=[%c p=~[[%.y p=20] [%.n p=~[51] q=~[52 53]] [%.y p=6]]]]
|
||||
~zod/try=> (limp [%a %d [[%0 1] [%0 1]] [%0 2]])
|
||||
[p=%a q=[%d p=[%0 p=2] q=[p=[%0 p=1] q=[%0 p=1]]]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++hump`
|
||||
|
||||
Prep for diff
|
||||
|
||||
++ hump :: general prepatch
|
||||
|= [pum=umph src=*] ^- *
|
||||
?+ pum ~|(%unsupported !!)
|
||||
%a src
|
||||
%b (cue ((hard ,@) src))
|
||||
%c (lore ((hard ,@) src))
|
||||
==
|
||||
::
|
||||
|
||||
Prep atom for diff: leave alone, cue, or split by newlines.
|
||||
|
||||
~zod/try=> (hump %a ~)
|
||||
0
|
||||
~zod/try=> (hump %a 40)
|
||||
40
|
||||
~zod/try=> (hump %c 40)
|
||||
[40 0]
|
||||
~zod/try=> (hump %c 'as')
|
||||
[29.537 0]
|
||||
~zod/try=> (hump %c 'as\0alok')
|
||||
[29.537 7.040.876 0]
|
||||
~zod/try=> (hump %b 0vph)
|
||||
[1 1]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++husk`
|
||||
|
||||
Atomize post diff
|
||||
|
||||
++ husk :: unprepatch
|
||||
|= [pum=umph dst=*] ^- *
|
||||
?+ pum ~|(%unsupported !!)
|
||||
%a dst
|
||||
%b (jam dst)
|
||||
%c (role ((hard (list ,@)) dst))
|
||||
==
|
||||
::
|
||||
|
||||
Re-atomize after diff: leave alone, jam, or join with newlines.
|
||||
|
||||
~zod/try=> (husk %a 0)
|
||||
0
|
||||
~zod/try=> (husk %a 40)
|
||||
40
|
||||
~zod/try=> (husk %c [40 0])
|
||||
2.600
|
||||
~zod/try=> (rip 3 (,@ (husk %c [40 0])))
|
||||
~[40 10]
|
||||
~zod/try=> (husk %c [%as 0])
|
||||
684.897
|
||||
~zod/try=> (husk %c [%as 0])
|
||||
684.897
|
||||
~zod/try=> (,@t (husk %c [%as 0]))
|
||||
'''
|
||||
as
|
||||
'''
|
||||
~zod/try=> (husk %c [%as %lok 0])
|
||||
2.932.876.065.272.673
|
||||
~zod/try=> (,@t (husk %c [%as %lok 0]))
|
||||
'''
|
||||
as
|
||||
lok
|
||||
'''
|
||||
~zod/try=> (husk %b [1 1])
|
||||
817
|
||||
~zod/try=> (,@uv (husk %b [1 1]))
|
||||
0vph
|
||||
~zod/try=> ~0ph
|
||||
[1 1]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lurk`
|
||||
|
||||
Apply list patch
|
||||
|
||||
++ lurk :: apply list patch
|
||||
|* [hel=(list) rug=(urge)]
|
||||
^+ hel
|
||||
=+ war=`_hel`~
|
||||
|- ^+ hel
|
||||
?~ rug (flop war)
|
||||
?- -.i.rug
|
||||
&
|
||||
%= $
|
||||
rug t.rug
|
||||
hel (slag p.i.rug hel)
|
||||
war (weld (flop (scag p.i.rug hel)) war)
|
||||
==
|
||||
::
|
||||
|
|
||||
%= $
|
||||
rug t.rug
|
||||
hel =+ gur=(flop p.i.rug)
|
||||
|- ^+ hel
|
||||
?~ gur hel
|
||||
?>(&(?=(^ hel) =(i.gur i.hel)) $(hel t.hel, gur t.gur))
|
||||
war (weld q.i.rug war)
|
||||
==
|
||||
==
|
||||
::
|
||||
|
||||
Amend list using an urge: list of `[%& {number skipped}]` and
|
||||
`[%| old new]`
|
||||
|
||||
~zod/try=> (lurk "hema" `(urge char)`~[`1 [%| "e" "ru"] `2])
|
||||
"hurma"
|
||||
~zod/try=> (lurk "koltep" `(urge char)`~[`3 [%| "et" ""] `1])
|
||||
"kolp"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lusk`
|
||||
|
||||
`lcs` to list patch
|
||||
|
||||
++ lusk :: lcs to list patch
|
||||
|* [hel=(list) hev=(list) lcs=(list)]
|
||||
=+ ^= rag
|
||||
^- $% [& p=@ud]
|
||||
[| p=_lcs q=_lcs]
|
||||
==
|
||||
[%& 0]
|
||||
=> .(rag [p=rag q=*(list ,_rag)])
|
||||
=< abet =< main
|
||||
|%
|
||||
++ abet =.(q.rag ?:(=([& 0] p.rag) q.rag [p.rag q.rag]) (flop q.rag))
|
||||
++ done
|
||||
|= new=_p.rag
|
||||
^+ rag
|
||||
?- -.p.rag
|
||||
| ?- -.new
|
||||
| [[%| (weld p.new p.p.rag) (weld q.new q.p.rag)] q.rag]
|
||||
& [new [p.rag q.rag]]
|
||||
==
|
||||
& ?- -.new
|
||||
| [new ?:(=(0 p.p.rag) q.rag [p.rag q.rag])]
|
||||
& [[%& (add p.p.rag p.new)] q.rag]
|
||||
==
|
||||
==
|
||||
::
|
||||
++ main
|
||||
|- ^+ +
|
||||
?~ hel
|
||||
?~ hev
|
||||
?>(?=(~ lcs) +)
|
||||
$(hev t.hev, rag (done %| ~ [i.hev ~]))
|
||||
?~ hev
|
||||
$(hel t.hel, rag (done %| [i.hel ~] ~))
|
||||
?~ lcs
|
||||
+(rag (done %| (flop hel) (flop hev)))
|
||||
?: =(i.hel i.lcs)
|
||||
?: =(i.hev i.lcs)
|
||||
$(lcs t.lcs, hel t.hel, hev t.hev, rag (done %& 1))
|
||||
$(hev t.hev, rag (done %| ~ [i.hev ~]))
|
||||
?: =(i.hev i.lcs)
|
||||
$(hel t.hel, rag (done %| [i.hel ~] ~))
|
||||
$(hel t.hel, hev t.hev, rag (done %| [i.hel ~] [i.hev ~]))
|
||||
--
|
||||
|
||||
Using a common sequence, generate urge from two lists
|
||||
|
||||
~zod/try=> (lusk "hamok" "hasok" "haok")
|
||||
~[[%.y p=2] [%.n p="m" q="s"] [%.y p=2]]
|
||||
~zod/try=> (lusk "hamok" "hasok" "hak")
|
||||
~[[%.y p=2] [%.n p="om" q="os"] [%.y p=1]]
|
||||
~zod/try=> (lusk "telroga" "tesomga" "teoga")
|
||||
~[[%.y p=2] [%.n p="rl" q="s"] [%.y p=1] [%.n p="" q="m"] [%.y p=2]]
|
||||
~zod/try=> (lurk "telroga" `(urge char)`~[[%.y p=2] [%.n p="rl" q="s"] [%.y p=1] [%.n p="" q="m"] [%.y p=2]])
|
||||
"tesomga"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++nude`
|
||||
|
||||
Tree change
|
||||
|
||||
++ nude :: tree change
|
||||
|= [a=* b=*]
|
||||
^- [p=upas q=upas]
|
||||
=< [p=(tred a b) q=(tred b a)]
|
||||
|%
|
||||
++ axes :: locs of nouns
|
||||
|= [a=@ b=*] ^- (map ,* axis)
|
||||
=+ c=*(map ,* axis)
|
||||
|- ^- (map ,* axis)
|
||||
=> .(c (~(put by c) b a))
|
||||
?@ b
|
||||
c
|
||||
%- ~(uni by c)
|
||||
%- ~(uni by $(a (mul 2 a), b -.b))
|
||||
$(a +((mul 2 a)), b +.b)
|
||||
::
|
||||
++ tred :: diff a->b
|
||||
|= [a=* b=*] ^- upas
|
||||
=| c=(unit ,*)
|
||||
=+ d=(axes 1 a)
|
||||
|- ^- upas
|
||||
=> .(c (~(get by d) b))
|
||||
?~ c
|
||||
?@ b
|
||||
[%1 b]
|
||||
=+ e=^-(upas [$(b -.b) $(b +.b)])
|
||||
?- e
|
||||
[[%1 *] [%1 *]] [%1 [p.p.e p.q.e]]
|
||||
* e
|
||||
==
|
||||
[%0 u.c]
|
||||
--
|
||||
|
||||
Generate tree diff from two nouns.
|
||||
|
||||
~zod/try=> (nude 40 20)
|
||||
[p=[%1 p=20] q=[%1 p=40]]
|
||||
~zod/try=> (nude [5 5] 5)
|
||||
[p=[%0 p=3] q=[p=[%0 p=1] q=[%0 p=1]]]
|
||||
~zod/try=> (nude "sam" "sal")
|
||||
[ p=[p=[%1 p=115] q=[p=[%1 p=97] q=[p=[%1 p=108] q=[%0 p=15]]]]
|
||||
q=[p=[%1 p=115] q=[p=[%1 p=97] q=[p=[%1 p=109] q=[%0 p=15]]]]
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,439 +0,0 @@
|
||||
section 2eW, lite number theory
|
||||
===============================
|
||||
|
||||
### `++egcd`
|
||||
|
||||
GCD
|
||||
|
||||
++ egcd :: schneier's egcd
|
||||
|= [a=@ b=@]
|
||||
=+ si
|
||||
=+ [c=(sun a) d=(sun b)]
|
||||
=+ [u=[c=(sun 1) d=--0] v=[c=--0 d=(sun 1)]]
|
||||
|- ^- [d=@ u=@ v=@]
|
||||
?: =(--0 c)
|
||||
[(abs d) d.u d.v]
|
||||
:: ?> ?& =(c (sum (pro (sun a) c.u) (pro (sun b) c.v)))
|
||||
:: =(d (sum (pro (sun a) d.u) (pro (sun b) d.v)))
|
||||
:: ==
|
||||
=+ q=(fra d c)
|
||||
%= $
|
||||
c (dif d (pro q c))
|
||||
d c
|
||||
u [(dif d.u (pro q c.u)) c.u]
|
||||
v [(dif d.v (pro q c.v)) c.v]
|
||||
==
|
||||
::
|
||||
|
||||
Greatest common denominator
|
||||
|
||||
~zod/try=> (egcd 20 15)
|
||||
[d=5 u=2 v=1]
|
||||
~zod/try=> (egcd 24 16)
|
||||
[d=8 u=2 v=1]
|
||||
~zod/try=> (egcd 7 5)
|
||||
[d=1 u=3 v=6]
|
||||
~zod/try=> (egcd (shaf ~ %ham) (shaf ~ %sam))
|
||||
[ d=1
|
||||
u=59.983.396.314.566.203.239.184.568.129.921.874.787
|
||||
v=38.716.650.351.034.402.960.165.718.823.532.275.722
|
||||
]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pram`
|
||||
|
||||
Probable prime
|
||||
|
||||
++ pram :: rabin-miller
|
||||
|= a=@ ^- ?
|
||||
?: ?| =(0 (end 0 1 a))
|
||||
=(1 a)
|
||||
=+ b=1
|
||||
|- ^- ?
|
||||
?: =(512 b)
|
||||
|
|
||||
?|(=+(c=+((mul 2 b)) &(!=(a c) =(a (mul c (div a c))))) $(b +(b)))
|
||||
==
|
||||
|
|
||||
=+ ^= b
|
||||
=+ [s=(dec a) t=0]
|
||||
|- ^- [s=@ t=@]
|
||||
?: =(0 (end 0 1 s))
|
||||
$(s (rsh 0 1 s), t +(t))
|
||||
[s t]
|
||||
?> =((mul s.b (bex t.b)) (dec a))
|
||||
=+ c=0
|
||||
|- ^- ?
|
||||
?: =(c 64)
|
||||
&
|
||||
=+ d=(~(raw og (add c a)) (met 0 a))
|
||||
=+ e=(~(exp fo a) s.b d)
|
||||
?& ?| =(1 e)
|
||||
=+ f=0
|
||||
|- ^- ?
|
||||
?: =(e (dec a))
|
||||
&
|
||||
?: =(f (dec t.b))
|
||||
|
|
||||
$(e (~(pro fo a) e e), f +(f))
|
||||
==
|
||||
$(c +(c))
|
||||
==
|
||||
::
|
||||
|
||||
Probable prime test
|
||||
|
||||
~zod/try=> (pram 31)
|
||||
%.y
|
||||
~zod/try=> =+(a=2 |-(?:(=(a 31) ~ [i=(mod 31 a) t=$(a +(a))])))
|
||||
~[1 1 3 1 1 3 7 4 1 9 7 5 3 1 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1]
|
||||
~zod/try=> =+(a=2 |-(?:(=(a 31) ~ [i=(mod 30 a) t=$(a +(a))])))
|
||||
~[0 0 2 0 0 2 6 3 0 8 6 4 2 0 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0]
|
||||
~zod/try=> (pram 256)
|
||||
%.n
|
||||
~zod/try=> (pram (dec (bex 127)))
|
||||
%.y
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ramp`
|
||||
|
||||
`r-m` prime
|
||||
|
||||
++ ramp :: make r-m prime
|
||||
|= [a=@ b=(list ,@) c=@] ^- @ux :: [bits snags seed]
|
||||
=> .(c (shas %ramp c))
|
||||
=+ d=_@
|
||||
|-
|
||||
?: =((mul 100 a) d)
|
||||
~|(%ar-ramp !!)
|
||||
=+ e=(~(raw og c) a)
|
||||
?: &((levy b |=(f=@ !=(1 (mod e f)))) (pram e))
|
||||
e
|
||||
$(c +(c), d (shax d))
|
||||
::
|
||||
|
||||
Random `a` bit prime, which isn't 1 modulo a list of other numbers,
|
||||
using salt `c`.
|
||||
|
||||
~zod/try=> (ramp 20 ~ %hamelok)
|
||||
0xf.1f0d
|
||||
~zod/try=> (ramp 20 ~ %hameloe)
|
||||
0x2.d341
|
||||
~zod/try=> (ramp 5 ~ %kole)
|
||||
0x1f
|
||||
~zod/try=> (ramp 7 ~ %kole)
|
||||
0x4f
|
||||
~zod/try=> (ramp 7 ~[0x4e] %kole)
|
||||
0x43
|
||||
~zod/try=> `@uw`(ramp 128 ~ %late)
|
||||
0w3y.irKIL.l-pp1.2CkG4.3lsTF
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fo`
|
||||
|
||||
Prime engine
|
||||
|
||||
++ fo :: modulo prime
|
||||
|_ a=@
|
||||
|
||||
XX DO NOT RERUN GET.LS, THERE EXIST ARM COLLISIONS
|
||||
|
||||
Core for performing arithmetic modulo a prime number
|
||||
|
||||
~zod/try=> ~(. fo 79)
|
||||
<7.get [@ud <373.jdd 100.kzl 1.ypj %164>]>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dif`
|
||||
|
||||
Difference
|
||||
|
||||
++ dif
|
||||
|= [b=@ c=@]
|
||||
(sit (sub (add a b) (sit c)))
|
||||
::
|
||||
|
||||
Subtract
|
||||
|
||||
~zod/try=> (~(dif fo 79) 10 5)
|
||||
5
|
||||
~zod/try=> (~(dif fo 79) 5 10)
|
||||
74
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++exp`
|
||||
|
||||
Exponent
|
||||
|
||||
++ exp
|
||||
|= [b=@ c=@]
|
||||
?: =(0 b)
|
||||
1
|
||||
=+ d=$(b (rsh 0 1 b))
|
||||
=+ e=(pro d d)
|
||||
?:(=(0 (end 0 1 b)) e (pro c e))
|
||||
::
|
||||
|
||||
Exponent
|
||||
|
||||
~zod/try=> (~(exp fo 79) 3 5)
|
||||
46
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fra`
|
||||
|
||||
Divide
|
||||
|
||||
++ fra
|
||||
|= [b=@ c=@]
|
||||
(pro b (inv c))
|
||||
::
|
||||
|
||||
Divide
|
||||
|
||||
~zod/try=> (~(fra fo 79) 20 4)
|
||||
5
|
||||
~zod/try=> (~(fra fo 79) 7 11)
|
||||
15
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++inv`
|
||||
|
||||
Inverse
|
||||
|
||||
++ inv
|
||||
|= b=@
|
||||
=+ c=(dul:si u:(egcd b a) a)
|
||||
c
|
||||
::
|
||||
|
||||
Multiplicative inverse
|
||||
|
||||
~zod/try=> (~(inv fo 79) 12)
|
||||
33
|
||||
~zod/try=> (~(pro fo 79) 12 33)
|
||||
1
|
||||
~zod/try=> (~(inv fo 79) 0)
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pro`
|
||||
|
||||
Product
|
||||
|
||||
++ pro
|
||||
|= [b=@ c=@]
|
||||
(sit (mul b c))
|
||||
::
|
||||
|
||||
Product
|
||||
|
||||
~zod/try=> (~(pro fo 79) 5 10)
|
||||
50
|
||||
~zod/try=> (~(pro fo 79) 5 20)
|
||||
21
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sit`
|
||||
|
||||
Bounds
|
||||
|
||||
++ sit
|
||||
|= b=@
|
||||
(mod b a)
|
||||
::
|
||||
|
||||
Bounds check
|
||||
|
||||
~zod/try=> (~(sit fo 79) 9)
|
||||
9
|
||||
~zod/try=> (~(sit fo 79) 99)
|
||||
20
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sum`
|
||||
|
||||
Sum
|
||||
|
||||
++ sum
|
||||
|= [b=@ c=@]
|
||||
(sit (add b c))
|
||||
--
|
||||
|
||||
Add
|
||||
|
||||
~zod/try=> (~(sum fo 79) 9 9)
|
||||
18
|
||||
~zod/try=> (~(sum fo 79) 70 9)
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++ga`
|
||||
|
||||
++ ga :: GF (bex p.a)
|
||||
|= a=[p=@ q=@ r=@] :: dim poly gen
|
||||
=+ si=(bex p.a)
|
||||
=+ ma=(dec si)
|
||||
=> |%
|
||||
|
||||
RSA internals
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dif`
|
||||
|
||||
++ dif :: add and sub
|
||||
|= [b=@ c=@]
|
||||
~| [%dif-ga a]
|
||||
?> &((lth b si) (lth c si))
|
||||
(mix b c)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dub`
|
||||
|
||||
++ dub :: mul by x
|
||||
|= b=@
|
||||
~| [%dub-ga a]
|
||||
?> (lth b si)
|
||||
?: =(1 (cut 0 [(dec p.a) 1] b))
|
||||
(dif (sit q.a) (sit (lsh 0 1 b)))
|
||||
(lsh 0 1 b)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pro`
|
||||
|
||||
++ pro :: slow multiply
|
||||
|= [b=@ c=@]
|
||||
?: =(0 b)
|
||||
0
|
||||
?: =(1 (dis 1 b))
|
||||
(dif c $(b (rsh 0 1 b), c (dub c)))
|
||||
$(b (rsh 0 1 b), c (dub c))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++toe`
|
||||
|
||||
++ toe :: exp/log tables
|
||||
=+ ^= nu
|
||||
|= [b=@ c=@]
|
||||
^- (map ,@ ,@)
|
||||
=+ d=*(map ,@ ,@)
|
||||
|-
|
||||
?: =(0 c)
|
||||
d
|
||||
%= $
|
||||
c (dec c)
|
||||
d (~(put by d) c b)
|
||||
==
|
||||
=+ [p=(nu 0 (bex p.a)) q=(nu ma ma)]
|
||||
=+ [b=1 c=0]
|
||||
|- ^- [p=(map ,@ ,@) q=(map ,@ ,@)]
|
||||
?: =(ma c)
|
||||
[(~(put by p) c b) q]
|
||||
%= $
|
||||
b (pro r.a b)
|
||||
c +(c)
|
||||
p (~(put by p) c b)
|
||||
q (~(put by q) b c)
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++sit`
|
||||
|
||||
++ sit :: reduce
|
||||
|= b=@
|
||||
(mod b (bex p.a))
|
||||
--
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++fra`
|
||||
|
||||
++ fra :: divide
|
||||
|= [b=@ c=@]
|
||||
(pro b (inv c))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++inv`
|
||||
|
||||
++ inv :: invert
|
||||
|= b=@
|
||||
~| [%inv-ga a]
|
||||
=+ c=(~(get by q) b)
|
||||
?~ c !!
|
||||
=+ d=(~(get by p) (sub ma u.c))
|
||||
(need d)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pow`
|
||||
|
||||
++ pow :: exponent
|
||||
|= [b=@ c=@]
|
||||
=+ [d=1 e=c f=0]
|
||||
|-
|
||||
?: =(p.a f)
|
||||
d
|
||||
?: =(1 (cut 0 [f 1] b))
|
||||
$(d (pro d e), e (pro e e), f +(f))
|
||||
$(e (pro e e), f +(f))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++pro`
|
||||
|
||||
++ pro :: multiply
|
||||
|= [b=@ c=@]
|
||||
~| [%pro-ga a]
|
||||
=+ d=(~(get by q) b)
|
||||
?~ d 0
|
||||
=+ e=(~(get by q) c)
|
||||
?~ e 0
|
||||
=+ f=(~(get by p) (mod (add u.d u.e) ma))
|
||||
(need f)
|
||||
--
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,717 +0,0 @@
|
||||
section 2eX, jetted crypto
|
||||
==========================
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++aesc`
|
||||
|
||||
++ aesc :: AES-256
|
||||
~% %aesc + ~
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++en`
|
||||
|
||||
++ en :: ECB enc
|
||||
~/ %en
|
||||
|= [a=@I b=@H] ^- @uxH
|
||||
=+ ahem
|
||||
(be & (ex a) b)
|
||||
|
||||
XX document
|
||||
|
||||
### `++de`
|
||||
|
||||
++ de :: ECB dec
|
||||
~/ %de
|
||||
|= [a=@I b=@H] ^- @uxH
|
||||
=+ ahem
|
||||
(be | (ix (ex a)) b)
|
||||
--
|
||||
|
||||
XX document
|
||||
|
||||
### `++ahem`
|
||||
|
||||
++ ahem :: AES helpers
|
||||
:: XX should be in aesc, isn't for performance reasons
|
||||
=>
|
||||
=+ =+ [gr=(ga 8 0x11b 3) few==>(fe .(a 5))]
|
||||
=+ [pro=pro.gr dif=dif.gr pow=pow.gr ror=ror.few]
|
||||
[pro=pro dif=dif pow=pow ror=ror nnk=8 nnb=4 nnr=14]
|
||||
=> |%
|
||||
|
||||
XX document
|
||||
|
||||
### `++cipa`
|
||||
|
||||
++ cipa :: AES params
|
||||
$_ ^? |%
|
||||
|
||||
XX document
|
||||
|
||||
### `++co`
|
||||
|
||||
++ co [0xe 0xb 0xd 0x9]
|
||||
|
||||
XX document
|
||||
|
||||
### `++ix`
|
||||
|
||||
++ ix :: key expand, inv
|
||||
|= a=@ ^- @
|
||||
=+ [i=1 j=_@ b=_@ c=co:pin]
|
||||
|-
|
||||
?: =(nnr i)
|
||||
a
|
||||
=> .(b (cut 7 [i 1] a))
|
||||
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
|
||||
=> .(j (sub nnr i))
|
||||
%= $
|
||||
i +(i)
|
||||
a
|
||||
%+ can 7
|
||||
:~ [i (cut 7 [0 i] a)]
|
||||
[1 b]
|
||||
[j (cut 7 [+(i) j] a)]
|
||||
==
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ro`
|
||||
|
||||
++ ro [0 3 2 1]
|
||||
|
||||
XX document
|
||||
|
||||
### `++su`
|
||||
|
||||
++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
|
||||
6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
|
||||
ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
|
||||
5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
|
||||
f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
|
||||
1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
|
||||
6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
|
||||
73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
|
||||
6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
|
||||
0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
|
||||
849d.8da7.5746.155e.dab9.edfd.5048.706c.
|
||||
92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
|
||||
25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
|
||||
4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
|
||||
cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
|
||||
fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++pen`
|
||||
|
||||
++ pen :: encrypt
|
||||
^- cipa
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++co`
|
||||
|
||||
++ co [0xe 0xb 0xd 0x9]
|
||||
|
||||
XX document
|
||||
|
||||
### `++ix`
|
||||
|
||||
++ ix :: key expand, inv
|
||||
|= a=@ ^- @
|
||||
=+ [i=1 j=_@ b=_@ c=co:pin]
|
||||
|-
|
||||
?: =(nnr i)
|
||||
a
|
||||
=> .(b (cut 7 [i 1] a))
|
||||
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
|
||||
=> .(j (sub nnr i))
|
||||
%= $
|
||||
i +(i)
|
||||
a
|
||||
%+ can 7
|
||||
:~ [i (cut 7 [0 i] a)]
|
||||
[1 b]
|
||||
[j (cut 7 [+(i) j] a)]
|
||||
==
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ro`
|
||||
|
||||
++ ro [0 3 2 1]
|
||||
|
||||
XX document
|
||||
|
||||
### `++su`
|
||||
|
||||
++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
|
||||
6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
|
||||
ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
|
||||
5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
|
||||
f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
|
||||
1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
|
||||
6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
|
||||
73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
|
||||
6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
|
||||
0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
|
||||
849d.8da7.5746.155e.dab9.edfd.5048.706c.
|
||||
92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
|
||||
25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
|
||||
4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
|
||||
cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
|
||||
fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++pin`
|
||||
|
||||
++ pin :: decrypt
|
||||
^- cipa
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++co`
|
||||
|
||||
++ co [0xe 0xb 0xd 0x9]
|
||||
|
||||
XX document
|
||||
|
||||
### `++ix`
|
||||
|
||||
++ ix :: key expand, inv
|
||||
|= a=@ ^- @
|
||||
=+ [i=1 j=_@ b=_@ c=co:pin]
|
||||
|-
|
||||
?: =(nnr i)
|
||||
a
|
||||
=> .(b (cut 7 [i 1] a))
|
||||
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
|
||||
=> .(j (sub nnr i))
|
||||
%= $
|
||||
i +(i)
|
||||
a
|
||||
%+ can 7
|
||||
:~ [i (cut 7 [0 i] a)]
|
||||
[1 b]
|
||||
[j (cut 7 [+(i) j] a)]
|
||||
==
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ro`
|
||||
|
||||
++ ro [0 3 2 1]
|
||||
|
||||
XX document
|
||||
|
||||
### `++su`
|
||||
|
||||
++ su 0x7d0c.2155.6314.69e1.26d6.77ba.7e04.2b17.
|
||||
6199.5383.3cbb.ebc8.b0f5.2aae.4d3b.e0a0.
|
||||
ef9c.c993.9f7a.e52d.0d4a.b519.a97f.5160.
|
||||
5fec.8027.5910.12b1.31c7.0788.33a8.dd1f.
|
||||
f45a.cd78.fec0.db9a.2079.d2c6.4b3e.56fc.
|
||||
1bbe.18aa.0e62.b76f.89c5.291d.711a.f147.
|
||||
6edf.751c.e837.f9e2.8535.ade7.2274.ac96.
|
||||
73e6.b4f0.cecf.f297.eadc.674f.4111.913a.
|
||||
6b8a.1301.03bd.afc1.020f.3fca.8f1e.2cd0.
|
||||
0645.b3b8.0558.e4f7.0ad3.bc8c.00ab.d890.
|
||||
849d.8da7.5746.155e.dab9.edfd.5048.706c.
|
||||
92b6.655d.cc5c.a4d4.1698.6886.64f6.f872.
|
||||
25d1.8b6d.49a2.5b76.b224.d928.66a1.2e08.
|
||||
4ec3.fa42.0b95.4cee.3d23.c2a6.3294.7b54.
|
||||
cbe9.dec4.4443.8e34.87ff.2f9b.8239.e37c.
|
||||
fbd7.f381.9ea3.40bf.38a5.3630.d56a.0952
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++mcol`
|
||||
|
||||
++ mcol
|
||||
|= [a=(list ,@) b=[p=@ q=@ r=@ s=@]] ^- (list ,@)
|
||||
=+ c=[p=_@ q=_@ r=_@ s=_@]
|
||||
|- ^- (list ,@)
|
||||
?~ a ~
|
||||
=> .(p.c (cut 3 [0 1] i.a))
|
||||
=> .(q.c (cut 3 [1 1] i.a))
|
||||
=> .(r.c (cut 3 [2 1] i.a))
|
||||
=> .(s.c (cut 3 [3 1] i.a))
|
||||
:_ $(a t.a)
|
||||
%+ rep 3
|
||||
%+ turn
|
||||
%- limo
|
||||
:~ [[p.c p.b] [q.c q.b] [r.c r.b] [s.c s.b]]
|
||||
[[p.c s.b] [q.c p.b] [r.c q.b] [s.c r.b]]
|
||||
[[p.c r.b] [q.c s.b] [r.c p.b] [s.c q.b]]
|
||||
[[p.c q.b] [q.c r.b] [r.c s.b] [s.c p.b]]
|
||||
==
|
||||
|= [a=[@ @] b=[@ @] c=[@ @] d=[@ @]]
|
||||
:(dif (pro a) (pro b) (pro c) (pro d))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++pode`
|
||||
|
||||
++ pode :: explode to block
|
||||
|= [a=bloq b=@ c=@] ^- (list ,@)
|
||||
=+ d=(rip a c)
|
||||
=+ m=(met a c)
|
||||
|-
|
||||
?: =(m b)
|
||||
d
|
||||
$(m +(m), d (weld d (limo [0 ~])))
|
||||
|
||||
XX document
|
||||
|
||||
### `++sube`
|
||||
|
||||
++ sube :: s-box word
|
||||
|= [a=@ b=@] ^- @
|
||||
(rep 3 (turn (pode 3 4 a) |=(c=@ (cut 3 [c 1] b))))
|
||||
--
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++be`
|
||||
|
||||
++ be :: block cipher
|
||||
|= [a=? b=@ c=@H] ^- @uxH
|
||||
~| %be-aesc
|
||||
=> %= .
|
||||
+
|
||||
=> +
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++ankh`
|
||||
|
||||
++ ankh
|
||||
|= [a=cipa b=@ c=@]
|
||||
(pode 5 nnb (cut 5 [(mul (ix.a b) nnb) nnb] c))
|
||||
|
||||
XX document
|
||||
|
||||
### `++sark`
|
||||
|
||||
++ sark
|
||||
|= [c=(list ,@) d=(list ,@)] ^- (list ,@)
|
||||
?~ c ~
|
||||
?~ d !!
|
||||
[(mix i.c i.d) $(c t.c, d t.d)]
|
||||
|
||||
XX document
|
||||
|
||||
### `++srow`
|
||||
|
||||
++ srow
|
||||
|= [a=cipa b=(list ,@)] ^- (list ,@)
|
||||
=+ [c=0 d=~ e=ro.a]
|
||||
|-
|
||||
?: =(c nnb)
|
||||
d
|
||||
:_ $(c +(c))
|
||||
%+ rep 3
|
||||
%+ turn
|
||||
(limo [0 p.e] [1 q.e] [2 r.e] [3 s.e] ~)
|
||||
|= [f=@ g=@]
|
||||
(cut 3 [f 1] (snag (mod (add g c) nnb) b))
|
||||
|
||||
XX document
|
||||
|
||||
### `++subs`
|
||||
|
||||
++ subs
|
||||
|= [a=cipa b=(list ,@)] ^- (list ,@)
|
||||
?~ b ~
|
||||
[(sube i.b su.a) $(b t.b)]
|
||||
--
|
||||
==
|
||||
=+ [d=?:(a pen pin) e=(pode 5 nnb c) f=1]
|
||||
=> .(e (sark e (ankh d 0 b)))
|
||||
|-
|
||||
?. =(nnr f)
|
||||
=> .(e (subs d e))
|
||||
=> .(e (srow d e))
|
||||
=> .(e (mcol e co.d))
|
||||
=> .(e (sark e (ankh d f b)))
|
||||
$(f +(f))
|
||||
=> .(e (subs d e))
|
||||
=> .(e (srow d e))
|
||||
=> .(e (sark e (ankh d nnr b)))
|
||||
(rep 5 e)
|
||||
|
||||
XX document
|
||||
|
||||
### `++ex`
|
||||
|
||||
++ ex :: key expand
|
||||
|= a=@I ^- @
|
||||
=+ [b=a c=0 d=su:pen i=nnk]
|
||||
|-
|
||||
?: =(i (mul nnb +(nnr)))
|
||||
b
|
||||
=> .(c (cut 5 [(dec i) 1] b))
|
||||
=> ?: =(0 (mod i nnk))
|
||||
=> .(c (ror 3 1 c))
|
||||
=> .(c (sube c d))
|
||||
.(c (mix c (pow (dec (div i nnk)) 2)))
|
||||
?: &((gth nnk 6) =(4 (mod i nnk)))
|
||||
.(c (sube c d))
|
||||
.
|
||||
=> .(c (mix c (cut 5 [(sub i nnk) 1] b)))
|
||||
=> .(b (can 5 [i b] [1 c] ~))
|
||||
$(i +(i))
|
||||
|
||||
XX document
|
||||
|
||||
### `++ix`
|
||||
|
||||
++ ix :: key expand, inv
|
||||
|= a=@ ^- @
|
||||
=+ [i=1 j=_@ b=_@ c=co:pin]
|
||||
|-
|
||||
?: =(nnr i)
|
||||
a
|
||||
=> .(b (cut 7 [i 1] a))
|
||||
=> .(b (rep 5 (mcol (pode 5 4 b) c)))
|
||||
=> .(j (sub nnr i))
|
||||
%= $
|
||||
i +(i)
|
||||
a
|
||||
%+ can 7
|
||||
:~ [i (cut 7 [0 i] a)]
|
||||
[1 b]
|
||||
[j (cut 7 [+(i) j] a)]
|
||||
==
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++curt`
|
||||
|
||||
++ curt :: curve25519
|
||||
|= [a=@ b=@]
|
||||
=> %= .
|
||||
+
|
||||
=> +
|
||||
=+ =+ [p=486.662 q=(sub (bex 255) 19)]
|
||||
=+ fq=~(. fo q)
|
||||
[p=p q=q fq=fq]
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++cla`
|
||||
|
||||
++ cla
|
||||
|= raw=@
|
||||
=+ low=(dis 248 (cut 3 [0 1] raw))
|
||||
=+ hih=(con 64 (dis 127 (cut 3 [31 1] raw)))
|
||||
=+ mid=(cut 3 [1 30] raw)
|
||||
(can 3 [[1 low] [30 mid] [1 hih] ~])
|
||||
|
||||
XX document
|
||||
|
||||
### `++sqr`
|
||||
|
||||
++ sqr |=(a=@ (mul a a))
|
||||
|
||||
XX document
|
||||
|
||||
### `++inv`
|
||||
|
||||
++ inv |=(a=@ (~(exp fo q) (sub q 2) a))
|
||||
|
||||
XX document
|
||||
|
||||
### `++cad`
|
||||
|
||||
++ cad
|
||||
|= [n=[x=@ z=@] m=[x=@ z=@] d=[x=@ z=@]]
|
||||
=+ ^= xx
|
||||
;: mul 4 z.d
|
||||
%- sqr %- abs:si
|
||||
%+ dif:si
|
||||
(sun:si (mul x.m x.n))
|
||||
(sun:si (mul z.m z.n))
|
||||
==
|
||||
=+ ^= zz
|
||||
;: mul 4 x.d
|
||||
%- sqr %- abs:si
|
||||
%+ dif:si
|
||||
(sun:si (mul x.m z.n))
|
||||
(sun:si (mul z.m x.n))
|
||||
==
|
||||
[(sit.fq xx) (sit.fq zz)]
|
||||
|
||||
XX document
|
||||
|
||||
### `++cub`
|
||||
|
||||
++ cub
|
||||
|= [x=@ z=@]
|
||||
=+ ^= xx
|
||||
%+ mul
|
||||
%- sqr %- abs:si
|
||||
(dif:si (sun:si x) (sun:si z))
|
||||
(sqr (add x z))
|
||||
=+ ^= zz
|
||||
;: mul 4 x z
|
||||
:(add (sqr x) :(mul p x z) (sqr z))
|
||||
==
|
||||
[(sit.fq xx) (sit.fq zz)]
|
||||
--
|
||||
==
|
||||
=+ one=[b 1]
|
||||
=+ i=253
|
||||
=+ r=one
|
||||
=+ s=(cub one)
|
||||
|-
|
||||
?: =(i 0)
|
||||
=+ x=(cub r)
|
||||
(sit.fq (mul -.x (inv +.x)))
|
||||
=+ m=(rsh 0 i a)
|
||||
?: =(0 (mod m 2))
|
||||
$(i (dec i), s (cad r s one), r (cub r))
|
||||
$(i (dec i), r (cad r s one), s (cub s))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ed`
|
||||
|
||||
++ ed :: ed25519
|
||||
=>
|
||||
=+ =+ [b=256 q=(sub (bex 255) 19)]
|
||||
=+ fq=~(. fo q)
|
||||
=+ ^= l
|
||||
%+ add
|
||||
(bex 252)
|
||||
27.742.317.777.372.353.535.851.937.790.883.648.493
|
||||
=+ d=(dif.fq 0 (fra.fq 121.665 121.666))
|
||||
=+ ii=(exp.fq (div (dec q) 4) 2)
|
||||
[b=b q=q fq=fq l=l d=d ii=ii]
|
||||
~% %coed +> ~
|
||||
|%
|
||||
|
||||
### `++norm`
|
||||
|
||||
++ norm |=(x=@ ?:(=(0 (mod x 2)) x (sub q x)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++xrec`
|
||||
|
||||
++ xrec :: recover x-coord
|
||||
|= y=@ ^- @
|
||||
=+ ^= xx
|
||||
%+ mul (dif.fq (mul y y) 1)
|
||||
(inv.fq +(:(mul d y y)))
|
||||
=+ x=(exp.fq (div (add 3 q) 8) xx)
|
||||
?: !=(0 (dif.fq (mul x x) (sit.fq xx)))
|
||||
(norm (pro.fq x ii))
|
||||
(norm x)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ward`
|
||||
|
||||
++ ward :: edwards multiply
|
||||
|= [pp=[@ @] qq=[@ @]] ^- [@ @]
|
||||
=+ dp=:(pro.fq d -.pp -.qq +.pp +.qq)
|
||||
=+ ^= xt
|
||||
%+ pro.fq
|
||||
%+ sum.fq
|
||||
(pro.fq -.pp +.qq)
|
||||
(pro.fq -.qq +.pp)
|
||||
(inv.fq (sum.fq 1 dp))
|
||||
=+ ^= yt
|
||||
%+ pro.fq
|
||||
%+ sum.fq
|
||||
(pro.fq +.pp +.qq)
|
||||
(pro.fq -.pp -.qq)
|
||||
(inv.fq (dif.fq 1 dp))
|
||||
[xt yt]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++scam`
|
||||
|
||||
++ scam :: scalar multiply
|
||||
|= [pp=[@ @] e=@] ^- [@ @]
|
||||
?: =(0 e)
|
||||
[0 1]
|
||||
=+ qq=$(e (div e 2))
|
||||
=> .(qq (ward qq qq))
|
||||
?: =(1 (dis 1 e))
|
||||
(ward qq pp)
|
||||
qq
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++etch`
|
||||
|
||||
++ etch :: encode point
|
||||
|= pp=[@ @] ^- @
|
||||
(can 0 ~[[(sub b 1) +.pp] [1 (dis 1 -.pp)]])
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++curv`
|
||||
|
||||
++ curv :: point on curve?
|
||||
|= [x=@ y=@] ^- ?
|
||||
.= 0
|
||||
%+ dif.fq
|
||||
%+ sum.fq
|
||||
(pro.fq (sub q (sit.fq x)) x)
|
||||
(pro.fq y y)
|
||||
(sum.fq 1 :(pro.fq d x x y y))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++deco`
|
||||
|
||||
++ deco :: decode point
|
||||
|= s=@ ^- (unit ,[@ @])
|
||||
=+ y=(cut 0 [0 (dec b)] s)
|
||||
=+ si=(cut 0 [(dec b) 1] s)
|
||||
=+ x=(xrec y)
|
||||
=> .(x ?:(!=(si (dis 1 x)) (sub q x) x))
|
||||
=+ pp=[x y]
|
||||
?. (curv pp)
|
||||
~
|
||||
[~ pp]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++bb`
|
||||
|
||||
++ bb
|
||||
=+ bby=(pro.fq 4 (inv.fq 5))
|
||||
[(xrec bby) bby]
|
||||
::
|
||||
--
|
||||
~% %ed + ~
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++puck`
|
||||
|
||||
++ puck :: public key
|
||||
~/ %puck
|
||||
|= sk=@I ^- @
|
||||
?: (gth (met 3 sk) 32) !!
|
||||
=+ h=(shal (rsh 0 3 b) sk)
|
||||
=+ ^= a
|
||||
%+ add
|
||||
(bex (sub b 2))
|
||||
(lsh 0 3 (cut 0 [3 (sub b 5)] h))
|
||||
=+ aa=(scam bb a)
|
||||
(etch aa)
|
||||
|
||||
XX document
|
||||
|
||||
### `++suck`
|
||||
|
||||
++ suck :: keypair from seed
|
||||
|= se=@I ^- @uJ
|
||||
=+ pu=(puck se)
|
||||
(can 0 ~[[b se] [b pu]])
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++sign`
|
||||
|
||||
++ sign :: certify
|
||||
~/ %sign
|
||||
|= [m=@ se=@] ^- @
|
||||
=+ sk=(suck se)
|
||||
=+ pk=(cut 0 [b b] sk)
|
||||
=+ h=(shal (rsh 0 3 b) sk)
|
||||
=+ ^= a
|
||||
%+ add
|
||||
(bex (sub b 2))
|
||||
(lsh 0 3 (cut 0 [3 (sub b 5)] h))
|
||||
=+ ^= r
|
||||
=+ hm=(cut 0 [b b] h)
|
||||
=+ ^= i
|
||||
%+ can 0
|
||||
:~ [b hm]
|
||||
[(met 0 m) m]
|
||||
==
|
||||
(shaz i)
|
||||
=+ rr=(scam bb r)
|
||||
=+ ^= ss
|
||||
=+ er=(etch rr)
|
||||
=+ ^= ha
|
||||
%+ can 0
|
||||
:~ [b er]
|
||||
[b pk]
|
||||
[(met 0 m) m]
|
||||
==
|
||||
(~(sit fo l) (add r (mul (shaz ha) a)))
|
||||
(can 0 ~[[b (etch rr)] [b ss]])
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++veri`
|
||||
|
||||
++ veri :: validate
|
||||
~/ %veri
|
||||
|= [s=@ m=@ pk=@] ^- ?
|
||||
?: (gth (div b 4) (met 3 s)) |
|
||||
?: (gth (div b 8) (met 3 pk)) |
|
||||
=+ cb=(rsh 0 3 b)
|
||||
=+ rr=(deco (cut 0 [0 b] s))
|
||||
?~ rr |
|
||||
=+ aa=(deco pk)
|
||||
?~ aa |
|
||||
=+ ss=(cut 0 [b b] s)
|
||||
=+ ha=(can 3 ~[[cb (etch u.rr)] [cb pk] [(met 3 m) m]])
|
||||
=+ h=(shaz ha)
|
||||
=((scam bb ss) (ward u.rr (scam u.aa h)))
|
||||
::
|
||||
--
|
||||
::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,399 +0,0 @@
|
||||
section 2eY, SHA-256
|
||||
====================
|
||||
|
||||
### `++shad`
|
||||
|
||||
++ shad |=(ruz=@ (shax (shax ruz))) :: double sha-256
|
||||
|
||||
XX document
|
||||
|
||||
### `++shaf`
|
||||
|
||||
++ shaf :: half sha-256
|
||||
|= [sal=@ ruz=@]
|
||||
=+ haz=(shas sal ruz)
|
||||
(mix (end 7 1 haz) (rsh 7 1 haz))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++shak`
|
||||
|
||||
++ shak :: XX shd be PBKDF
|
||||
|= [who=@p wud=@]
|
||||
(shas (mix %shak who) wud)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++sham`
|
||||
|
||||
++ sham :: noun hash
|
||||
|= yux=* ^- @uvH ^- @
|
||||
?@ yux
|
||||
(shaf %mash yux)
|
||||
(shaf %sham (jam yux))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++shas`
|
||||
|
||||
++ shas :: salted hash
|
||||
|= [sal=@ ruz=@]
|
||||
(shax (mix sal (shax ruz)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++shax`
|
||||
|
||||
++ shax :: sha-256
|
||||
~/ %shax
|
||||
|= ruz=@ ^- @
|
||||
~| %sha
|
||||
=+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
|
||||
=+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
|
||||
=+ ral=(lsh 0 3 (met 3 ruz))
|
||||
=+ ^= ful
|
||||
%+ can 0
|
||||
:~ [ral ruz]
|
||||
[8 128]
|
||||
[(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
|
||||
[64 (~(net fe 6) ral)]
|
||||
==
|
||||
=+ lex=(met 9 ful)
|
||||
=+ ^= kbx 0xc671.78f2.bef9.a3f7.a450.6ceb.90be.fffa.
|
||||
8cc7.0208.84c8.7814.78a5.636f.748f.82ee.
|
||||
682e.6ff3.5b9c.ca4f.4ed8.aa4a.391c.0cb3.
|
||||
34b0.bcb5.2748.774c.1e37.6c08.19a4.c116.
|
||||
106a.a070.f40e.3585.d699.0624.d192.e819.
|
||||
c76c.51a3.c24b.8b70.a81a.664b.a2bf.e8a1.
|
||||
9272.2c85.81c2.c92e.766a.0abb.650a.7354.
|
||||
5338.0d13.4d2c.6dfc.2e1b.2138.27b7.0a85.
|
||||
1429.2967.06ca.6351.d5a7.9147.c6e0.0bf3.
|
||||
bf59.7fc7.b003.27c8.a831.c66d.983e.5152.
|
||||
76f9.88da.5cb0.a9dc.4a74.84aa.2de9.2c6f.
|
||||
240c.a1cc.0fc1.9dc6.efbe.4786.e49b.69c1.
|
||||
c19b.f174.9bdc.06a7.80de.b1fe.72be.5d74.
|
||||
550c.7dc3.2431.85be.1283.5b01.d807.aa98.
|
||||
ab1c.5ed5.923f.82a4.59f1.11f1.3956.c25b.
|
||||
e9b5.dba5.b5c0.fbcf.7137.4491.428a.2f98
|
||||
=+ ^= hax 0x5be0.cd19.1f83.d9ab.9b05.688c.510e.527f.
|
||||
a54f.f53a.3c6e.f372.bb67.ae85.6a09.e667
|
||||
=+ i=0
|
||||
|- ^- @
|
||||
?: =(i lex)
|
||||
(rep 5 (turn (rip 5 hax) net))
|
||||
=+ ^= wox
|
||||
=+ dux=(cut 9 [i 1] ful)
|
||||
=+ wox=(rep 5 (turn (rip 5 dux) net))
|
||||
=+ j=16
|
||||
|- ^- @
|
||||
?: =(64 j)
|
||||
wox
|
||||
=+ :* l=(wac (sub j 15) wox)
|
||||
m=(wac (sub j 2) wox)
|
||||
n=(wac (sub j 16) wox)
|
||||
o=(wac (sub j 7) wox)
|
||||
==
|
||||
=+ x=:(mix (ror 0 7 l) (ror 0 18 l) (rsh 0 3 l))
|
||||
=+ y=:(mix (ror 0 17 m) (ror 0 19 m) (rsh 0 10 m))
|
||||
=+ z=:(sum n x o y)
|
||||
$(wox (con (lsh 5 j z) wox), j +(j))
|
||||
=+ j=0
|
||||
=+ :* a=(wac 0 hax)
|
||||
b=(wac 1 hax)
|
||||
c=(wac 2 hax)
|
||||
d=(wac 3 hax)
|
||||
e=(wac 4 hax)
|
||||
f=(wac 5 hax)
|
||||
g=(wac 6 hax)
|
||||
h=(wac 7 hax)
|
||||
==
|
||||
|- ^- @
|
||||
?: =(64 j)
|
||||
%= ^$
|
||||
i +(i)
|
||||
hax %+ rep 5
|
||||
:~ (sum a (wac 0 hax))
|
||||
(sum b (wac 1 hax))
|
||||
(sum c (wac 2 hax))
|
||||
(sum d (wac 3 hax))
|
||||
(sum e (wac 4 hax))
|
||||
(sum f (wac 5 hax))
|
||||
(sum g (wac 6 hax))
|
||||
(sum h (wac 7 hax))
|
||||
==
|
||||
==
|
||||
=+ l=:(mix (ror 0 2 a) (ror 0 13 a) (ror 0 22 a)) :: s0
|
||||
=+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
|
||||
=+ n=(sum l m) :: t2
|
||||
=+ o=:(mix (ror 0 6 e) (ror 0 11 e) (ror 0 25 e)) :: s1
|
||||
=+ p=(mix (dis e f) (dis (inv e) g)) :: ch
|
||||
=+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
|
||||
$(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++shaw`
|
||||
|
||||
++ shaw :: hash to nbits
|
||||
|= [sal=@ len=@ ruz=@]
|
||||
(~(raw og (shas sal (mix len ruz))) len)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++og`
|
||||
|
||||
++ og :: shax-powered rng
|
||||
~/ %og
|
||||
|_ a=@
|
||||
|
||||
XX document
|
||||
|
||||
### `++rad`
|
||||
|
||||
++ rad :: random in range
|
||||
|= b=@ ^- @
|
||||
=+ c=(raw (met 0 b))
|
||||
?:((lth c b) c $(a +(a)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++rads`
|
||||
|
||||
++ rads :: random continuation
|
||||
|= b=@
|
||||
=+ r=(rad b)
|
||||
[r +>.$(a (shas %og-s r))]
|
||||
|
||||
XX document
|
||||
|
||||
### `++raw`
|
||||
|
||||
++ raw :: random bits
|
||||
~/ %raw
|
||||
|= b=@ ^- @
|
||||
%+ can
|
||||
0
|
||||
=+ c=(shas %og-a (mix b a))
|
||||
|- ^- (list ,[@ @])
|
||||
?: =(0 b)
|
||||
~
|
||||
=+ d=(shas %og-b (mix b (mix a c)))
|
||||
?: (lth b 256)
|
||||
[[b (end 0 b d)] ~]
|
||||
[[256 d] $(c d, b (sub b 256))]
|
||||
|
||||
XX document
|
||||
|
||||
### `++raws`
|
||||
|
||||
++ raws :: random bits continuation
|
||||
|= b=@
|
||||
=+ r=(raw b)
|
||||
[r +>.$(a (shas %og-s r))]
|
||||
--
|
||||
|
||||
XX document
|
||||
|
||||
### `++shaz`
|
||||
|
||||
++ shaz :: sha-512
|
||||
|= ruz=@ ^- @
|
||||
(shal [(met 3 ruz) ruz])
|
||||
|
||||
XX document
|
||||
|
||||
### `++shal`
|
||||
|
||||
++ shal :: sha-512 with length
|
||||
~/ %shal
|
||||
|= [len=@ ruz=@] ^- @
|
||||
=> .(ruz (cut 3 [0 len] ruz))
|
||||
=+ [few==>(fe .(a 6)) wac=|=([a=@ b=@] (cut 6 [a 1] b))]
|
||||
=+ [sum=sum.few ror=ror.few net=net.few inv=inv.few]
|
||||
=+ ral=(lsh 0 3 len)
|
||||
=+ ^= ful
|
||||
%+ can 0
|
||||
:~ [ral ruz]
|
||||
[8 128]
|
||||
[(mod (sub 1.920 (mod (add 8 ral) 1.024)) 1.024) 0]
|
||||
[128 (~(net fe 7) ral)]
|
||||
==
|
||||
=+ lex=(met 10 ful)
|
||||
=+ ^= kbx 0x6c44.198c.4a47.5817.5fcb.6fab.3ad6.faec.
|
||||
597f.299c.fc65.7e2a.4cc5.d4be.cb3e.42b6.
|
||||
431d.67c4.9c10.0d4c.3c9e.be0a.15c9.bebc.
|
||||
32ca.ab7b.40c7.2493.28db.77f5.2304.7d84.
|
||||
1b71.0b35.131c.471b.113f.9804.bef9.0dae.
|
||||
0a63.7dc5.a2c8.98a6.06f0.67aa.7217.6fba.
|
||||
f57d.4f7f.ee6e.d178.eada.7dd6.cde0.eb1e.
|
||||
d186.b8c7.21c0.c207.ca27.3ece.ea26.619c.
|
||||
c671.78f2.e372.532b.bef9.a3f7.b2c6.7915.
|
||||
a450.6ceb.de82.bde9.90be.fffa.2363.1e28.
|
||||
8cc7.0208.1a64.39ec.84c8.7814.a1f0.ab72.
|
||||
78a5.636f.4317.2f60.748f.82ee.5def.b2fc.
|
||||
682e.6ff3.d6b2.b8a3.5b9c.ca4f.7763.e373.
|
||||
4ed8.aa4a.e341.8acb.391c.0cb3.c5c9.5a63.
|
||||
34b0.bcb5.e19b.48a8.2748.774c.df8e.eb99.
|
||||
1e37.6c08.5141.ab53.19a4.c116.b8d2.d0c8.
|
||||
106a.a070.32bb.d1b8.f40e.3585.5771.202a.
|
||||
d699.0624.5565.a910.d192.e819.d6ef.5218.
|
||||
c76c.51a3.0654.be30.c24b.8b70.d0f8.9791.
|
||||
a81a.664b.bc42.3001.a2bf.e8a1.4cf1.0364.
|
||||
9272.2c85.1482.353b.81c2.c92e.47ed.aee6.
|
||||
766a.0abb.3c77.b2a8.650a.7354.8baf.63de.
|
||||
5338.0d13.9d95.b3df.4d2c.6dfc.5ac4.2aed.
|
||||
2e1b.2138.5c26.c926.27b7.0a85.46d2.2ffc.
|
||||
1429.2967.0a0e.6e70.06ca.6351.e003.826f.
|
||||
d5a7.9147.930a.a725.c6e0.0bf3.3da8.8fc2.
|
||||
bf59.7fc7.beef.0ee4.b003.27c8.98fb.213f.
|
||||
a831.c66d.2db4.3210.983e.5152.ee66.dfab.
|
||||
76f9.88da.8311.53b5.5cb0.a9dc.bd41.fbd4.
|
||||
4a74.84aa.6ea6.e483.2de9.2c6f.592b.0275.
|
||||
240c.a1cc.77ac.9c65.0fc1.9dc6.8b8c.d5b5.
|
||||
efbe.4786.384f.25e3.e49b.69c1.9ef1.4ad2.
|
||||
c19b.f174.cf69.2694.9bdc.06a7.25c7.1235.
|
||||
80de.b1fe.3b16.96b1.72be.5d74.f27b.896f.
|
||||
550c.7dc3.d5ff.b4e2.2431.85be.4ee4.b28c.
|
||||
1283.5b01.4570.6fbe.d807.aa98.a303.0242.
|
||||
ab1c.5ed5.da6d.8118.923f.82a4.af19.4f9b.
|
||||
59f1.11f1.b605.d019.3956.c25b.f348.b538.
|
||||
e9b5.dba5.8189.dbbc.b5c0.fbcf.ec4d.3b2f.
|
||||
7137.4491.23ef.65cd.428a.2f98.d728.ae22
|
||||
=+ ^= hax 0x5be0.cd19.137e.2179.1f83.d9ab.fb41.bd6b.
|
||||
9b05.688c.2b3e.6c1f.510e.527f.ade6.82d1.
|
||||
a54f.f53a.5f1d.36f1.3c6e.f372.fe94.f82b.
|
||||
bb67.ae85.84ca.a73b.6a09.e667.f3bc.c908
|
||||
=+ i=0
|
||||
|- ^- @
|
||||
?: =(i lex)
|
||||
(rep 6 (turn (rip 6 hax) net))
|
||||
=+ ^= wox
|
||||
=+ dux=(cut 10 [i 1] ful)
|
||||
=+ wox=(rep 6 (turn (rip 6 dux) net))
|
||||
=+ j=16
|
||||
|- ^- @
|
||||
?: =(80 j)
|
||||
wox
|
||||
=+ :* l=(wac (sub j 15) wox)
|
||||
m=(wac (sub j 2) wox)
|
||||
n=(wac (sub j 16) wox)
|
||||
o=(wac (sub j 7) wox)
|
||||
==
|
||||
=+ x=:(mix (ror 0 1 l) (ror 0 8 l) (rsh 0 7 l))
|
||||
=+ y=:(mix (ror 0 19 m) (ror 0 61 m) (rsh 0 6 m))
|
||||
=+ z=:(sum n x o y)
|
||||
$(wox (con (lsh 6 j z) wox), j +(j))
|
||||
=+ j=0
|
||||
=+ :* a=(wac 0 hax)
|
||||
b=(wac 1 hax)
|
||||
c=(wac 2 hax)
|
||||
d=(wac 3 hax)
|
||||
e=(wac 4 hax)
|
||||
f=(wac 5 hax)
|
||||
g=(wac 6 hax)
|
||||
h=(wac 7 hax)
|
||||
==
|
||||
|- ^- @
|
||||
?: =(80 j)
|
||||
%= ^$
|
||||
i +(i)
|
||||
hax %+ rep 6
|
||||
:~ (sum a (wac 0 hax))
|
||||
(sum b (wac 1 hax))
|
||||
(sum c (wac 2 hax))
|
||||
(sum d (wac 3 hax))
|
||||
(sum e (wac 4 hax))
|
||||
(sum f (wac 5 hax))
|
||||
(sum g (wac 6 hax))
|
||||
(sum h (wac 7 hax))
|
||||
==
|
||||
==
|
||||
=+ l=:(mix (ror 0 28 a) (ror 0 34 a) (ror 0 39 a)) :: S0
|
||||
=+ m=:(mix (dis a b) (dis a c) (dis b c)) :: maj
|
||||
=+ n=(sum l m) :: t2
|
||||
=+ o=:(mix (ror 0 14 e) (ror 0 18 e) (ror 0 41 e)) :: S1
|
||||
=+ p=(mix (dis e f) (dis (inv e) g)) :: ch
|
||||
=+ q=:(sum h o p (wac j kbx) (wac j wox)) :: t1
|
||||
$(j +(j), a (sum q n), b a, c b, d c, e (sum d q), f e, g f, h g)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++shan`
|
||||
|
||||
++ shan :: sha-1 (deprecated)
|
||||
|= ruz=@
|
||||
=+ [few==>(fe .(a 5)) wac=|=([a=@ b=@] (cut 5 [a 1] b))]
|
||||
=+ [sum=sum.few ror=ror.few rol=rol.few net=net.few inv=inv.few]
|
||||
=+ ral=(lsh 0 3 (met 3 ruz))
|
||||
=+ ^= ful
|
||||
%+ can 0
|
||||
:~ [ral ruz]
|
||||
[8 128]
|
||||
[(mod (sub 960 (mod (add 8 ral) 512)) 512) 0]
|
||||
[64 (~(net fe 6) ral)]
|
||||
==
|
||||
=+ lex=(met 9 ful)
|
||||
=+ kbx=0xca62.c1d6.8f1b.bcdc.6ed9.eba1.5a82.7999
|
||||
=+ hax=0xc3d2.e1f0.1032.5476.98ba.dcfe.efcd.ab89.6745.2301
|
||||
=+ i=0
|
||||
|-
|
||||
?: =(i lex)
|
||||
(rep 5 (flop (rip 5 hax)))
|
||||
=+ ^= wox
|
||||
=+ dux=(cut 9 [i 1] ful)
|
||||
=+ wox=(rep 5 (turn (rip 5 dux) net))
|
||||
=+ j=16
|
||||
|- ^- @
|
||||
?: =(80 j)
|
||||
wox
|
||||
=+ :* l=(wac (sub j 3) wox)
|
||||
m=(wac (sub j 8) wox)
|
||||
n=(wac (sub j 14) wox)
|
||||
o=(wac (sub j 16) wox)
|
||||
==
|
||||
=+ z=(rol 0 1 :(mix l m n o))
|
||||
$(wox (con (lsh 5 j z) wox), j +(j))
|
||||
=+ j=0
|
||||
=+ :* a=(wac 0 hax)
|
||||
b=(wac 1 hax)
|
||||
c=(wac 2 hax)
|
||||
d=(wac 3 hax)
|
||||
e=(wac 4 hax)
|
||||
==
|
||||
|- ^- @
|
||||
?: =(80 j)
|
||||
%= ^$
|
||||
i +(i)
|
||||
hax %+ rep 5
|
||||
:~
|
||||
(sum a (wac 0 hax))
|
||||
(sum b (wac 1 hax))
|
||||
(sum c (wac 2 hax))
|
||||
(sum d (wac 3 hax))
|
||||
(sum e (wac 4 hax))
|
||||
==
|
||||
==
|
||||
=+ fx=(con (dis b c) (dis (not 5 1 b) d))
|
||||
=+ fy=:(mix b c d)
|
||||
=+ fz=:(con (dis b c) (dis b d) (dis c d))
|
||||
=+ ^= tem
|
||||
?: &((gte j 0) (lte j 19))
|
||||
:(sum (rol 0 5 a) fx e (wac 0 kbx) (wac j wox))
|
||||
?: &((gte j 20) (lte j 39))
|
||||
:(sum (rol 0 5 a) fy e (wac 1 kbx) (wac j wox))
|
||||
?: &((gte j 40) (lte j 59))
|
||||
:(sum (rol 0 5 a) fz e (wac 2 kbx) (wac j wox))
|
||||
:(sum (rol 0 5 a) fy e (wac 3 kbx) (wac j wox))
|
||||
$(j +(j), a tem, b a, c (rol 0 30 b), d c, e d)
|
||||
|
||||
XX document
|
||||
|
||||
--
|
@ -1,250 +0,0 @@
|
||||
section 2eZ, OLD rendering
|
||||
==========================
|
||||
|
||||
### `++show`
|
||||
|
||||
++ show :: XX deprecated, use type
|
||||
|= vem=*
|
||||
|^ ^- tank
|
||||
?: ?=(@ vem)
|
||||
[%leaf (mesc (trip vem))]
|
||||
?- vem
|
||||
[s=~ c=*]
|
||||
[%leaf '\'' (weld (mesc (tape +.vem)) `tape`['\'' ~])]
|
||||
::
|
||||
[s=%a c=@] [%leaf (mesc (trip c.vem))]
|
||||
[s=%b c=*] (shop c.vem |=(a=@ ~(rub at a)))
|
||||
[s=[%c p=@] c=*]
|
||||
:+ %palm
|
||||
[['.' ~] ['-' ~] ~ ~]
|
||||
[[%leaf (mesc (trip p.s.vem))] $(vem c.vem) ~]
|
||||
::
|
||||
[s=%d c=*] (shop c.vem |=(a=@ ~(rud at a)))
|
||||
[s=%k c=*] (tank c.vem)
|
||||
[s=%h c=*]
|
||||
?: =(0 c.vem) :: XX remove after 220
|
||||
[%leaf '#' ~]
|
||||
:+ %rose
|
||||
[['/' ~] ['/' ~] ~]
|
||||
=+ yol=((list ,@ta) c.vem)
|
||||
(turn yol |=(a=@ta [%leaf (trip a)]))
|
||||
::
|
||||
[s=%o c=*]
|
||||
%= $
|
||||
vem
|
||||
:- [%m '%h:<[%d %d].[%d %d]>']
|
||||
[-.c.vem +<-.c.vem +<+.c.vem +>-.c.vem +>+.c.vem ~]
|
||||
==
|
||||
::
|
||||
[s=%p c=*] (shop c.vem |=(a=@ ~(rup at a)))
|
||||
[s=%q c=*] (shop c.vem |=(a=@ ~(r at a)))
|
||||
[s=%r c=*] $(vem [[%r ' ' '{' '}'] c.vem])
|
||||
[s=%t c=*] (shop c.vem |=(a=@ ~(rt at a)))
|
||||
[s=%v c=*] (shop c.vem |=(a=@ ~(ruv at a)))
|
||||
[s=%x c=*] (shop c.vem |=(a=@ ~(rux at a)))
|
||||
[s=[%m p=@] c=*] (shep p.s.vem c.vem)
|
||||
[s=[%r p=@] c=*]
|
||||
$(vem [[%r ' ' (cut 3 [0 1] p.s.vem) (cut 3 [1 1] p.s.vem)] c.vem])
|
||||
::
|
||||
[s=[%r p=@ q=@ r=@] c=*]
|
||||
:+ %rose
|
||||
:* p=(mesc (trip p.s.vem))
|
||||
q=(mesc (trip q.s.vem))
|
||||
r=(mesc (trip r.s.vem))
|
||||
==
|
||||
|- ^- (list tank)
|
||||
?@ c.vem
|
||||
~
|
||||
[^$(vem -.c.vem) $(c.vem +.c.vem)]
|
||||
::
|
||||
[s=%z c=*] $(vem [[%r %$ %$ %$] c.vem])
|
||||
* !!
|
||||
==
|
||||
|
||||
XX document
|
||||
|
||||
### `++shep`
|
||||
|
||||
++ shep
|
||||
|= [fom=@ gar=*]
|
||||
^- tank
|
||||
=+ l=(met 3 fom)
|
||||
=+ i=0
|
||||
:- %leaf
|
||||
|- ^- tape
|
||||
?: (gte i l)
|
||||
~
|
||||
=+ c=(cut 3 [i 1] fom)
|
||||
?. =(37 c)
|
||||
(weld (mesc [c ~]) $(i +(i)))
|
||||
=+ d=(cut 3 [+(i) 1] fom)
|
||||
?. .?(gar)
|
||||
['\\' '#' $(i (add 2 i))]
|
||||
(weld ~(ram re (show d -.gar)) $(i (add 2 i), gar +.gar))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++shop`
|
||||
|
||||
++ shop
|
||||
|= [aug=* vel=$+(a=@ tape)]
|
||||
^- tank
|
||||
?: ?=(@ aug)
|
||||
[%leaf (vel aug)]
|
||||
:+ %rose
|
||||
[[' ' ~] ['[' ~] [']' ~]]
|
||||
=> .(aug `*`aug)
|
||||
|- ^- (list tank)
|
||||
?: ?=(@ aug)
|
||||
[^$ ~]
|
||||
[^$(aug -.aug) $(aug +.aug)]
|
||||
--
|
||||
|
||||
XX document
|
||||
|
||||
### `++at`
|
||||
|
||||
++ at
|
||||
|_ a=@
|
||||
|
||||
XX document
|
||||
|
||||
### `++r`
|
||||
|
||||
++ r
|
||||
?: ?& (gte (met 3 a) 2)
|
||||
|-
|
||||
?: =(0 a)
|
||||
&
|
||||
=+ vis=(end 3 1 a)
|
||||
?& ?|(=('-' vis) ?&((gte vis 'a') (lte vis 'z')))
|
||||
$(a (rsh 3 1 a))
|
||||
==
|
||||
==
|
||||
rtam
|
||||
?: (lte (met 3 a) 2)
|
||||
rud
|
||||
rux
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++rf`
|
||||
|
||||
++ rf `tape`[?-(a & '&', | '|', * !!) ~]
|
||||
|
||||
XX document
|
||||
|
||||
### `++rn`
|
||||
|
||||
++ rn `tape`[?>(=(0 a) '~') ~]
|
||||
|
||||
XX document
|
||||
|
||||
### `++rt`
|
||||
|
||||
++ rt `tape`['\'' (weld (mesc (trip a)) `tape`['\'' ~])]
|
||||
|
||||
XX document
|
||||
|
||||
### `++rta`
|
||||
|
||||
++ rta rt
|
||||
|
||||
XX document
|
||||
|
||||
### `++rtam`
|
||||
|
||||
++ rtam `tape`['%' (trip a)]
|
||||
|
||||
XX document
|
||||
|
||||
### `++rub`
|
||||
|
||||
++ rub `tape`['0' 'b' (rum 2 ~ |=(b=@ (add '0' b)))]
|
||||
|
||||
XX document
|
||||
|
||||
### `++rud`
|
||||
|
||||
++ rud (rum 10 ~ |=(b=@ (add '0' b)))
|
||||
|
||||
XX document
|
||||
|
||||
### `++rum`
|
||||
|
||||
++ rum
|
||||
|= [b=@ c=tape d=$+(@ @)]
|
||||
^- tape
|
||||
?: =(0 a)
|
||||
[(d 0) c]
|
||||
=+ e=0
|
||||
|- ^- tape
|
||||
?: =(0 a)
|
||||
c
|
||||
=+ f=&(!=(0 e) =(0 (mod e ?:(=(10 b) 3 4))))
|
||||
%= $
|
||||
a (div a b)
|
||||
c [(d (mod a b)) ?:(f [?:(=(10 b) ',' '-') c] c)]
|
||||
e +(e)
|
||||
==
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++rup`
|
||||
|
||||
++ rup
|
||||
=+ b=(met 3 a)
|
||||
^- tape
|
||||
:- '-'
|
||||
|- ^- tape
|
||||
?: (gth (met 5 a) 1)
|
||||
%+ weld
|
||||
$(a (rsh 5 1 a), b (sub b 4))
|
||||
`tape`['-' '-' $(a (end 5 1 a), b 4)]
|
||||
?: =(0 b)
|
||||
['~' ~]
|
||||
?: (lte b 1)
|
||||
(trip (tos:po a))
|
||||
|- ^- tape
|
||||
?: =(2 b)
|
||||
=+ c=(rsh 3 1 a)
|
||||
=+ d=(end 3 1 a)
|
||||
(weld (trip (tod:po c)) (trip (tos:po (mix c d))))
|
||||
=+ c=(rsh 3 2 a)
|
||||
=+ d=(end 3 2 a)
|
||||
(weld ^$(a c, b (met 3 c)) `tape`['-' $(a (mix c d), b 2)])
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ruv`
|
||||
|
||||
++ ruv
|
||||
^- tape
|
||||
:+ '0'
|
||||
'v'
|
||||
%^ rum
|
||||
64
|
||||
~
|
||||
|= b=@
|
||||
?: =(63 b)
|
||||
'+'
|
||||
?: =(62 b)
|
||||
'-'
|
||||
?:((lth b 26) (add 65 b) ?:((lth b 52) (add 71 b) (sub b 4)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++rux`
|
||||
|
||||
++ rux `tape`['0' 'x' (rum 16 ~ |=(b=@ (add b ?:((lth b 10) 48 87))))]
|
||||
--
|
||||
:::::::::::::::::::::::::::::::::::::::::::::::::::::: ::
|
||||
|
||||
XX document
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,67 +0,0 @@
|
||||
section 3bA, lite number theory
|
||||
===============================
|
||||
|
||||
### `++fu`
|
||||
|
||||
++ fu :: modulo (mul p q)
|
||||
|= a=[p=@ q=@]
|
||||
=+ b=?:(=([0 0] a) 0 (~(inv fo p.a) (~(sit fo p.a) q.a)))
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++dif`
|
||||
|
||||
++ dif
|
||||
|= [c=[@ @] d=[@ @]]
|
||||
[(~(dif fo p.a) -.c -.d) (~(dif fo q.a) +.c +.d)]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++exp`
|
||||
|
||||
++ exp
|
||||
|= [c=@ d=[@ @]]
|
||||
:- (~(exp fo p.a) (mod c (dec p.a)) -.d)
|
||||
(~(exp fo q.a) (mod c (dec q.a)) +.d)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++out`
|
||||
|
||||
++ out :: garner's formula
|
||||
|= c=[@ @]
|
||||
%+ add
|
||||
+.c
|
||||
(mul q.a (~(pro fo p.a) b (~(dif fo p.a) -.c (~(sit fo p.a) +.c))))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++pro`
|
||||
|
||||
++ pro
|
||||
|= [c=[@ @] d=[@ @]]
|
||||
[(~(pro fo p.a) -.c -.d) (~(pro fo q.a) +.c +.d)]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++sum`
|
||||
|
||||
++ sum
|
||||
|= [c=[@ @] d=[@ @]]
|
||||
[(~(sum fo p.a) -.c -.d) (~(sum fo q.a) +.c +.d)]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++sit`
|
||||
|
||||
++ sit
|
||||
|= c=@
|
||||
[(mod c p.a) (mod c q.a)]
|
||||
|
||||
XX document
|
@ -1,600 +0,0 @@
|
||||
section 3bB, cryptosuites
|
||||
=========================
|
||||
|
||||
### `++crua`
|
||||
|
||||
++ crua !: :: cryptosuite A (RSA)
|
||||
^- acru
|
||||
=| [mos=@ pon=(unit ,[p=@ q=@ r=[p=@ q=@] s=_*fu])]
|
||||
=> |%
|
||||
|
||||
XX document
|
||||
|
||||
### `++mx`
|
||||
|
||||
++ mx (dec (met 0 mos)) :: bit length
|
||||
|
||||
XX document
|
||||
|
||||
### `++dap`
|
||||
|
||||
++ dap :: OEAP decode
|
||||
|= [wid=@ xar=@ dog=@] ^- [p=@ q=@]
|
||||
=+ pav=(sub wid xar)
|
||||
=+ qoy=(cut 0 [xar pav] dog)
|
||||
=+ dez=(mix (end 0 xar dog) (shaw %pad-b xar qoy))
|
||||
[dez (mix qoy (shaw %pad-a pav dez))]
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++pad`
|
||||
|
||||
++ pad :: OEAP encode
|
||||
|= [wid=@ rax=[p=@ q=@] meg=@] ^- @
|
||||
=+ pav=(sub wid p.rax)
|
||||
?> (gte pav (met 0 meg))
|
||||
^- @
|
||||
=+ qoy=(mix meg (shaw %pad-a pav q.rax))
|
||||
=+ dez=(mix q.rax (shaw %pad-b p.rax qoy))
|
||||
(can 0 [p.rax dez] [pav qoy] ~)
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++pull`
|
||||
|
||||
++ pull |=(a=@ (~(exp fo mos) 3 a))
|
||||
|
||||
XX document
|
||||
|
||||
### `++push`
|
||||
|
||||
++ push |=(a=@ (~(exp fo mos) 5 a))
|
||||
|
||||
XX document
|
||||
|
||||
### `++pump`
|
||||
|
||||
++ pump
|
||||
|= a=@ ^- @
|
||||
?~ pon !!
|
||||
(out.s.u.pon (exp.s.u.pon p.r.u.pon (sit.s.u.pon a)))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++punt`
|
||||
|
||||
++ punt
|
||||
|= a=@ ^- @
|
||||
?~ pon !!
|
||||
(out.s.u.pon (exp.s.u.pon q.r.u.pon (sit.s.u.pon a)))
|
||||
|%
|
||||
|
||||
XX document
|
||||
|
||||
### `++as`
|
||||
|
||||
++ as
|
||||
=> |%
|
||||
|
||||
XX document
|
||||
|
||||
### `++haul`
|
||||
|
||||
++ haul :: revealing haul
|
||||
|= a=pass
|
||||
!!
|
||||
^?
|
||||
|% ++ seal
|
||||
|= [a=pass b=@ c=@]
|
||||
^- @
|
||||
!!
|
||||
|
||||
XX document
|
||||
|
||||
### `++seal`
|
||||
|
||||
|
||||
XX document
|
||||
|
||||
###++sign
|
||||
|
||||
```
|
||||
++ sign
|
||||
|= [a=@ b=@] ^- @
|
||||
!!
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++sure
|
||||
|
||||
```
|
||||
++ sure
|
||||
|= [a=@ b=@]
|
||||
^- (unit ,@)
|
||||
!!
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++tear
|
||||
|
||||
```
|
||||
++ tear
|
||||
|= [a=pass b=@]
|
||||
^- (unit ,[p=@ q=@])
|
||||
!!
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++de
|
||||
|
||||
```
|
||||
++ de
|
||||
|+ [key=@ cep=@] ^- (unit ,@)
|
||||
!!
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++dy
|
||||
|
||||
```
|
||||
++ dy
|
||||
|+ [a=@ b=@] ^- @
|
||||
!!
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++en
|
||||
|
||||
```
|
||||
++ en
|
||||
|+ [key=@ msg=@] ^- @ux
|
||||
!!
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++ex
|
||||
|
||||
```
|
||||
++ ex ^?
|
||||
|% ++ fig ^- @uvH (shaf %bfig puc)
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++fig
|
||||
|
||||
XX document
|
||||
|
||||
### `++pac`
|
||||
|
||||
++ pac ^- @uvG (end 6 1 (shaf %acod sec))
|
||||
|
||||
XX document
|
||||
|
||||
### `++pub`
|
||||
|
||||
++ pub ^- pass (cat 3 'b' puc)
|
||||
|
||||
XX document
|
||||
|
||||
### `++sec`
|
||||
|
||||
++ sec ^- ring sed
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++nu`
|
||||
|
||||
++ nu
|
||||
^?
|
||||
|% ++ com
|
||||
|= a=@
|
||||
^+ ^?(..nu)
|
||||
..nu(sed ~, puc a)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++elcm`
|
||||
|
||||
++ elcm
|
||||
|= [a=@ b=@]
|
||||
(div (mul a b) d:(egcd a b))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++eldm`
|
||||
|
||||
++ eldm
|
||||
|= [a=@ b=@ c=@]
|
||||
(~(inv fo (elcm (dec b) (dec c))) a)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ersa`
|
||||
|
||||
++ ersa
|
||||
|= [a=@ b=@]
|
||||
[a b [(eldm 3 a b) (eldm 5 a b)] (fu a b)]
|
||||
^?
|
||||
|% ++ com
|
||||
|= a=@
|
||||
^+ ^?(..nu)
|
||||
..nu(mos a, pon ~)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++com`
|
||||
|
||||
|
||||
XX document
|
||||
|
||||
###++pit
|
||||
|
||||
```
|
||||
++ pit
|
||||
|= [a=@ b=@]
|
||||
^+ ^?(..nu)
|
||||
..nu(sed b, puc (puck:ed b))
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++nol
|
||||
|
||||
```
|
||||
++ nol
|
||||
|= a=@
|
||||
^+ ^?(..nu)
|
||||
..nu(sed a, puc (puck:ed a))
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++bruw
|
||||
|
||||
```
|
||||
++ bruw :: create keypair
|
||||
|= [a=@ b=@] :: width seed
|
||||
^- acru
|
||||
(pit:nu:crua a b)
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++haul
|
||||
|
||||
```
|
||||
++ haul :: revealing haul
|
||||
|= a=pass
|
||||
!!
|
||||
^?
|
||||
|% ++ seal
|
||||
|= [a=pass b=@ c=@]
|
||||
^- @
|
||||
!!
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++weur
|
||||
|
||||
```
|
||||
++ weur :: activate secret key
|
||||
|= a=ring
|
||||
^- acru
|
||||
=+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
|
||||
?> =('A' mag)
|
||||
(nol:nu:crua bod)
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++trua
|
||||
|
||||
```
|
||||
++ trua :: test rsa
|
||||
|= msg=@tas
|
||||
^- @
|
||||
=+ ali=(bruw 1.024 (shax 'ali'))
|
||||
=+ bob=(bruw 1.024 (shax 'bob'))
|
||||
=+ tef=(sign:as.ali [0 msg])
|
||||
=+ lov=(sure:as.ali [0 tef])
|
||||
?. &(?=(^ lov) =(msg u.lov))
|
||||
~|(%test-fail-sign !!)
|
||||
=+ key=(shax (shax (shax msg)))
|
||||
=+ sax=(seal:as.ali pub:ex.bob key msg)
|
||||
=+ tin=(tear:as.bob pub:ex.ali sax)
|
||||
?. &(?=(^ tin) =(key p.u.tin) =(msg q.u.tin))
|
||||
~|(%test-fail-seal !!)
|
||||
msg
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++crub
|
||||
|
||||
```
|
||||
++ crub :: cryptosuite B (Ed)
|
||||
^- acru
|
||||
=| [puc=pass sed=ring]
|
||||
=> |%
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++dap
|
||||
|
||||
```
|
||||
++ dap :: OEAP decode
|
||||
|= [wid=@ xar=@ dog=@] ^- [p=@ q=@]
|
||||
=+ pav=(sub wid xar)
|
||||
=+ qoy=(cut 0 [xar pav] dog)
|
||||
=+ dez=(mix (end 0 xar dog) (shaw %pad-b xar qoy))
|
||||
[dez (mix qoy (shaw %pad-a pav dez))]
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++pad
|
||||
|
||||
```
|
||||
++ pad :: OEAP encode
|
||||
|= [wid=@ rax=[p=@ q=@] meg=@] ^- @
|
||||
=+ pav=(sub wid p.rax)
|
||||
?> (gte pav (met 0 meg))
|
||||
^- @
|
||||
=+ qoy=(mix meg (shaw %pad-a pav q.rax))
|
||||
=+ dez=(mix q.rax (shaw %pad-b p.rax qoy))
|
||||
(can 0 [p.rax dez] [pav qoy] ~)
|
||||
|%
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++as
|
||||
|
||||
```
|
||||
++ as
|
||||
=> |%
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++haul
|
||||
|
||||
```
|
||||
++ haul :: revealing haul
|
||||
|= a=pass
|
||||
!!
|
||||
^?
|
||||
|% ++ seal
|
||||
|= [a=pass b=@ c=@]
|
||||
^- @
|
||||
!!
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++seal
|
||||
|
||||
XX document
|
||||
|
||||
### `++sign`
|
||||
|
||||
++ sign
|
||||
|= [a=@ b=@] ^- @
|
||||
!!
|
||||
|
||||
XX document
|
||||
|
||||
### `++sure`
|
||||
|
||||
++ sure
|
||||
|= [a=@ b=@]
|
||||
^- (unit ,@)
|
||||
!!
|
||||
|
||||
XX document
|
||||
|
||||
### `++tear`
|
||||
|
||||
++ tear
|
||||
|= [a=pass b=@]
|
||||
^- (unit ,[p=@ q=@])
|
||||
!!
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++de`
|
||||
|
||||
++ de
|
||||
|+ [key=@ cep=@] ^- (unit ,@)
|
||||
!!
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++dy`
|
||||
|
||||
++ dy
|
||||
|+ [a=@ b=@] ^- @
|
||||
!!
|
||||
|
||||
XX document
|
||||
|
||||
### `++en`
|
||||
|
||||
++ en
|
||||
|+ [key=@ msg=@] ^- @ux
|
||||
!!
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++ex`
|
||||
|
||||
++ ex ^?
|
||||
|% ++ fig ^- @uvH (shaf %bfig puc)
|
||||
|
||||
XX document
|
||||
|
||||
### `++fig`
|
||||
|
||||
|
||||
XX document
|
||||
|
||||
###++pac
|
||||
|
||||
```
|
||||
++ pac ^- @uvG (end 6 1 (shaf %acod sec))
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++pub
|
||||
|
||||
```
|
||||
++ pub ^- pass (cat 3 'b' puc)
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++sec
|
||||
|
||||
```
|
||||
++ sec ^- ring sed
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++nu
|
||||
|
||||
```
|
||||
++ nu
|
||||
^?
|
||||
|% ++ com
|
||||
|= a=@
|
||||
^+ ^?(..nu)
|
||||
..nu(sed ~, puc a)
|
||||
::
|
||||
```
|
||||
|
||||
XX document
|
||||
|
||||
###++com
|
||||
|
||||
XX document
|
||||
|
||||
### `++pit`
|
||||
|
||||
++ pit
|
||||
|= [a=@ b=@]
|
||||
^+ ^?(..nu)
|
||||
..nu(sed b, puc (puck:ed b))
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++nol`
|
||||
|
||||
++ nol
|
||||
|= a=@
|
||||
^+ ^?(..nu)
|
||||
..nu(sed a, puc (puck:ed a))
|
||||
|
||||
XX document
|
||||
|
||||
### `++brew`
|
||||
|
||||
++ brew :: create keypair
|
||||
|= [a=@ b=@] :: width seed
|
||||
^- acru
|
||||
(pit:nu:crub a b)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++hail`
|
||||
|
||||
++ hail :: activate public key
|
||||
|= a=pass
|
||||
^- acru
|
||||
=+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
|
||||
?> =('b' mag)
|
||||
(com:nu:crub bod)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++wear`
|
||||
|
||||
++ wear :: activate secret key
|
||||
|= a=ring
|
||||
^- acru
|
||||
=+ [mag=(end 3 1 a) bod=(rsh 3 1 a)]
|
||||
?> =('b' mag)
|
||||
(nol:nu:crub bod)
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++trub`
|
||||
|
||||
++ trub :: test ed
|
||||
|= msg=@tas
|
||||
^- @
|
||||
=+ ali=(brew 1.024 (shax 'ali'))
|
||||
=+ bob=(brew 1.024 (shax 'bob'))
|
||||
=+ tef=(sign:as.ali [0 msg])
|
||||
=+ lov=(sure:as.ali [0 tef])
|
||||
?. &(?=(^ lov) =(msg u.lov))
|
||||
~|(%test-fail-sign !!)
|
||||
=+ key=(shax (shax (shax msg)))
|
||||
=+ sax=(seal:as.ali pub:ex.bob key msg)
|
||||
=+ tin=(tear:as.bob pub:ex.ali sax)
|
||||
?. &(?=(^ tin) =(key p.u.tin) =(msg q.u.tin))
|
||||
~|(%test-fail-seal !!)
|
||||
msg
|
||||
::
|
||||
|
||||
XX document
|
||||
|
||||
### `++hmac`
|
||||
|
||||
++ hmac :: HMAC-SHA1
|
||||
|= [key=@ mes=@]
|
||||
=+ ip=(fil 3 64 0x36)
|
||||
=+ op=(fil 3 64 0x5c)
|
||||
=+ ^= kex
|
||||
?: (gth (met 3 key) 64)
|
||||
(lsh 3 44 (shan (swap 3 key)))
|
||||
(lsh 3 (sub 64 (met 3 key)) (swap 3 key))
|
||||
=+ inn=(shan (swap 3 (cat 3 (swap 3 mes) (mix ip kex))))
|
||||
(shan (swap 3 (cat 3 inn (mix op kex))))
|
||||
::
|
||||
|
||||
XX document
|
@ -1,382 +0,0 @@
|
||||
section 3bC, Gregorian UTC
|
||||
==========================
|
||||
|
||||
### `++dawn`
|
||||
|
||||
Weekday of Jan 1
|
||||
|
||||
++ dawn :: weekday of jan 1
|
||||
|= yer=@ud
|
||||
=+ yet=(sub yer 1)
|
||||
%- mod :_ 7
|
||||
:(add 1 (mul 5 (mod yet 4)) (mul 4 (mod yet 100)) (mul 6 (mod yet 400)))
|
||||
::
|
||||
|
||||
Computes which day of the week January 1st falls on for a year `yer`,
|
||||
producing an atom. Weeks are zero-indexed beginning on Sunday.
|
||||
|
||||
`yer` is an unsigned decimal, [`@ud`]().
|
||||
|
||||
~zod/try=> (dawn 2.015)
|
||||
4
|
||||
~zod/try=> (dawn 1)
|
||||
1
|
||||
~zod/try=> (dawn 0)
|
||||
! subtract-underflow
|
||||
! exit
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++daws`
|
||||
|
||||
Weekday of date
|
||||
|
||||
++ daws :: weekday of date
|
||||
|= yed=date
|
||||
%- mod :_ 7
|
||||
(add (dawn y.yed) (sub (yawn [y.yed m.yed d.t.yed]) (yawn y.yed 1 1)))
|
||||
::
|
||||
|
||||
Produces the day of the week of a given date `yed` as an atom. Weeks are
|
||||
zero-indexed beginning on Sunday.
|
||||
|
||||
`yed` is a [`date`]().
|
||||
|
||||
~zod/try=> (daws [[a=%.y y=2.014] m=6 t=[d=6 h=21 m=9 s=15 f=~[0xa16]]])
|
||||
5
|
||||
~zod/try=> (daws (yore -<-))
|
||||
2
|
||||
|
||||
(second example always returns the current date).
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++deal`
|
||||
|
||||
Add leap seconds
|
||||
|
||||
++ deal :: to leap sec time
|
||||
|= yer=@da
|
||||
=+ n=0
|
||||
=+ yud=(yore yer)
|
||||
|- ^- date
|
||||
?: (gte yer (add (snag n lef:yu) ~s1))
|
||||
(yore (year yud(s.t (add n s.t.yud))))
|
||||
?: &((gte yer (snag n lef:yu)) (lth yer (add (snag n lef:yu) ~s1)))
|
||||
yud(s.t (add +(n) s.t.yud))
|
||||
?: =(+(n) (lent lef:yu))
|
||||
(yore (year yud(s.t (add +(n) s.t.yud))))
|
||||
$(n +(n))
|
||||
::
|
||||
|
||||
Produces a [`date`]() with the 25 leap seconds added.
|
||||
|
||||
`yer` is an absolute date, [`@da`]().
|
||||
|
||||
~zod/try=> (yore (bex 127))
|
||||
[[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=8 f=~]]
|
||||
~zod/try=> (deal `@da`(bex 127))
|
||||
[[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=33 f=~]]
|
||||
~zod/try=> (yore (bex 126))
|
||||
[[a=%.n y=146.138.512.088] m=6 t=[d=19 h=7 m=45 s=4 f=~]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lead`
|
||||
|
||||
Subtract leap seconds
|
||||
|
||||
++ lead :: from leap sec time
|
||||
|= ley=date
|
||||
=+ ler=(year ley)
|
||||
=+ n=0
|
||||
|- ^- @da
|
||||
=+ led=(sub ler (mul n ~s1))
|
||||
?: (gte ler (add (snag n les:yu) ~s1))
|
||||
led
|
||||
?: &((gte ler (snag n les:yu)) (lth ler (add (snag n les:yu) ~s1)))
|
||||
?: =(s.t.ley 60)
|
||||
(sub led ~s1)
|
||||
led
|
||||
?: =(+(n) (lent les:yu))
|
||||
(sub led ~s1)
|
||||
$(n +(n))
|
||||
::
|
||||
|
||||
Produces an absolute date ([`@ud`]()) with the 25 leap seconds
|
||||
subtracted.
|
||||
|
||||
`ley` is a [`date`]().
|
||||
|
||||
~zod/try=> (yore `@da`(bex 127))
|
||||
[[a=%.y y=226] m=12 t=[d=5 h=15 m=30 s=8 f=~]]
|
||||
~zod/try=> (lead (yore `@da`(bex 127)))
|
||||
~226.12.5..15.29.43
|
||||
~zod/try=> (lead (yore `@da`(bex 126)))
|
||||
~146138512088-.6.19..07.44.39
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++dust`
|
||||
|
||||
Print UTC format
|
||||
|
||||
++ dust :: print UTC format
|
||||
|= yed=date
|
||||
^- tape
|
||||
=+ wey=(daws yed)
|
||||
;: weld
|
||||
`tape`(snag wey (turn wik:yu |=(a=tape (scag 3 a))))
|
||||
", " ~(rud at d.t.yed) " "
|
||||
`tape`(snag (dec m.yed) (turn mon:yu |=(a=tape (scag 3 a))))
|
||||
" " (scag 1 ~(rud at y.yed)) (slag 2 ~(rud at y.yed)) " "
|
||||
~(rud at h.t.yed) ":" ~(rud at m.t.yed) ":" ~(rud at s.t.yed)
|
||||
" " "+0000"
|
||||
==
|
||||
::
|
||||
|
||||
Produces a [tape]() of the date in UTC format.
|
||||
|
||||
`yed` is a [`date`]().
|
||||
|
||||
~zod/try=> (dust (yore ->-))
|
||||
"Tue, 21 Oct 2014 21:35:12 +0000"
|
||||
~zod/try=> (dust [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]])
|
||||
"Fri, 11 Oct 2002 12:20:55 +0000"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++stud`
|
||||
|
||||
Parse UTC format
|
||||
|
||||
++ stud :: parse UTC format
|
||||
|= cud=tape
|
||||
^- (unit date)
|
||||
=- ?~ tud ~
|
||||
`[[%.y &3.u.tud] &2.u.tud &1.u.tud &4.u.tud &5.u.tud &6.u.tud ~]
|
||||
^= tud
|
||||
%+ rust cud
|
||||
;~ plug
|
||||
;~(pfix (stun [5 5] next) dim:ag)
|
||||
::
|
||||
%+ cook
|
||||
|= a=tape
|
||||
=+ b=0
|
||||
|- ^- @
|
||||
?: =(a (snag b (turn mon:yu |=(a=tape (scag 3 a)))))
|
||||
+(b)
|
||||
$(b +(b))
|
||||
(ifix [ace ace] (star alf))
|
||||
::
|
||||
;~(sfix dim:ag ace)
|
||||
;~(sfix dim:ag col)
|
||||
;~(sfix dim:ag col)
|
||||
dim:ag
|
||||
(cold ~ (star next))
|
||||
==
|
||||
::
|
||||
|
||||
Accepts a [tape]() containing a date in UTC format and produces the
|
||||
[unit]() of a [`date`]().
|
||||
|
||||
~zod/try=> (stud "Tue, 21 Oct 2014 21:21:55 +0000")
|
||||
[~ [[a=%.y y=2.014] m=10 t=[d=21 h=21 m=21 s=55 f=~]]]
|
||||
~zod/try=> (stud "Wed, 11 Oct 2002 12:20:55 +0000")
|
||||
[~ [[a=%.y y=2.002] m=10 t=[d=11 h=12 m=20 s=55 f=~]]]
|
||||
~zod/try=> (stud "Wed, 11 Oct 2002")
|
||||
~
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++unt`
|
||||
|
||||
UGT to UTC time
|
||||
|
||||
++ unt :: UGT to UTC time
|
||||
|= a=@da
|
||||
(div (sub a ~1970.1.1) (bex 64))
|
||||
::
|
||||
|
||||
~zod/try=/hom> (unt -<-)
|
||||
1.413.927.704
|
||||
~zod/try=> (unt ~20014.1.1)
|
||||
569.413.670.400
|
||||
~zod/try=> (unt ~2014.1.1)
|
||||
1.388.534.400
|
||||
|
||||
Transforms Urbit Galactic Time to UTC time, producing an atom.
|
||||
|
||||
`a` is an [atom]().
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++yu`
|
||||
|
||||
UTC format constants
|
||||
|
||||
++ yu :: UTC format constants
|
||||
|%
|
||||
|
||||
~zod/try=/hom> yu
|
||||
<4.pgn 250.tmw 41.cmo 414.rvm 101.jzo 1.ypj %164>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++mon`
|
||||
|
||||
Months
|
||||
|
||||
++ mon ^- (list tape)
|
||||
:~ "January" "February" "March" "April" "May" "June" "July"
|
||||
"August" "September" "October" "November" "December"
|
||||
==
|
||||
::
|
||||
|
||||
Produces a list of [tapes]() containing the 12 months of the year.
|
||||
|
||||
~zod/try=/hom> mon:yu
|
||||
<<
|
||||
"January"
|
||||
"February"
|
||||
"March"
|
||||
"April"
|
||||
"May"
|
||||
"June"
|
||||
"July"
|
||||
"August"
|
||||
"September"
|
||||
"October"
|
||||
"November"
|
||||
"December"
|
||||
>>
|
||||
~zod/try=/hom> (snag 1 mon:yu)
|
||||
"February"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++wik`
|
||||
|
||||
Weeks
|
||||
|
||||
++ wik ^- (list tape)
|
||||
:~ "Sunday" "Monday" "Tuesday" "Wednesday" "Thursday"
|
||||
"Friday" "Saturday"
|
||||
==
|
||||
::
|
||||
|
||||
Produces a list of [tapes]() containing the 7 days of the week,
|
||||
beginning with Sunday.
|
||||
|
||||
~zod/try=/hom> wik:yu
|
||||
<<"Sunday" "Monday" "Tuesday" "Wednesday" "Thursday" "Friday" "Saturday">>
|
||||
~zod/try=/hom> (snag 2 wik:yu)
|
||||
"Tuesday"
|
||||
~zod/try=/hom> (snag (daws (yore -<-)) wik:yu)
|
||||
"Tuesday"
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++les`
|
||||
|
||||
Leap second dates
|
||||
|
||||
++ les ^- (list ,@da)
|
||||
:~ ~2015.7.1 ~2012.7.1 ~2009.1.1 ~2006.1.1 ~1999.1.1 ~1997.7.1
|
||||
~1996.1.1 ~1994.7.1 ~1993.7.1 ~1992.7.1 ~1991.1.1 ~1990.1.1
|
||||
~1988.1.1 ~1985.7.1 ~1983.7.1 ~1982.7.1 ~1981.7.1 ~1980.1.1
|
||||
~1979.1.1 ~1978.1.1 ~1977.1.1 ~1976.1.1 ~1975.1.1 ~1974.1.1
|
||||
~1973.1.1 ~1972.7.1
|
||||
==
|
||||
|
||||
Produces a list of the (absolute) dates ([`@da`]) of the 25 leap seconds
|
||||
|
||||
~zod/try=/hom> les:yu
|
||||
~[
|
||||
~2015.7.1
|
||||
~2012.7.1
|
||||
~2009.1.1
|
||||
~2006.1.1
|
||||
~1999.1.1
|
||||
~1997.7.1
|
||||
~1996.1.1
|
||||
~1994.7.1
|
||||
~1993.7.1
|
||||
~1992.7.1
|
||||
~1991.1.1
|
||||
~1990.1.1
|
||||
~1988.1.1
|
||||
~1985.7.1
|
||||
~1983.7.1
|
||||
~1982.7.1
|
||||
~1981.7.1
|
||||
~1980.1.1
|
||||
~1979.1.1
|
||||
~1978.1.1
|
||||
~1977.1.1
|
||||
~1976.1.1
|
||||
~1975.1.1
|
||||
~1974.1.1
|
||||
~1973.1.1
|
||||
~1972.7.1
|
||||
]
|
||||
~zod/try=/hom> (snag 2 les:yu)
|
||||
~2006.1.1
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### `++lef`
|
||||
|
||||
Back-shifted leap second dates
|
||||
|
||||
++ lef ^- (list ,@da)
|
||||
:~ ~2015.6.30..23.59.59 ~2012.6.30..23.59.59
|
||||
~2008.12.31..23.59.58 ~2005.12.31..23.59.57
|
||||
~1998.12.31..23.59.56 ~1997.6.30..23.59.55
|
||||
~1995.12.31..23.59.54 ~1994.6.30..23.59.53
|
||||
~1993.6.30..23.59.52 ~1992.6.30..23.59.51
|
||||
~1990.12.31..23.59.50 ~1989.12.31..23.59.49
|
||||
~1987.12.31..23.59.48 ~1985.6.30..23.59.47
|
||||
~1983.6.30..23.59.46 ~1982.6.30..23.59.45
|
||||
~1981.6.30..23.59.44 ~1979.12.31..23.59.43
|
||||
~1978.12.31..23.59.42 ~1977.12.31..23.59.41
|
||||
~1976.12.31..23.59.40 ~1975.12.31..23.59.39
|
||||
~1974.12.31..23.59.38 ~1973.12.31..23.59.37
|
||||
~1972.12.31..23.59.36 ~1972.6.30..23.59.35
|
||||
==
|
||||
::
|
||||
|
||||
Produces a list of absolute dates ([`@da`]()) that represent the Urbit
|
||||
Galactc Time equivalents of the UTC leap second dates in [`++les`](/doc/hoon/library/3bc#++les).
|
||||
|
||||
~zod/try=/hom> lef:yu
|
||||
~[
|
||||
~2015.6.30..23.59.59
|
||||
~2012.6.30..23.59.59
|
||||
~2008.12.31..23.59.58
|
||||
~2005.12.31..23.59.57
|
||||
~1998.12.31..23.59.56
|
||||
~1997.6.30..23.59.55
|
||||
~1995.12.31..23.59.54
|
||||
~1994.6.30..23.59.53
|
||||
~1993.6.30..23.59.52
|
||||
~1992.6.30..23.59.51
|
||||
~1990.12.31..23.59.50
|
||||
~1989.12.31..23.59.49
|
||||
~1987.12.31..23.59.48
|
||||
~1985.6.30..23.59.47
|
||||
~1983.6.30..23.59.46
|
||||
~1982.6.30..23.59.45
|
||||
~1981.6.30..23.59.44
|
||||
~1979.12.31..23.59.43
|
||||
~1978.12.31..23.59.42
|
||||
~1977.12.31..23.59.41
|
||||
~1976.12.31..23.59.40
|
||||
~1975.12.31..23.59.39
|
||||
~1974.12.31..23.59.38
|
||||
~1973.12.31..23.59.37
|
||||
~1972.12.31..23.59.36
|
||||
~1972.6.30..23.59.35
|
||||
]
|
||||
~zod/try=/hom> (snag 2 lef:yu)
|
||||
~2005.12.31..23.59.57
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,267 +0,0 @@
|
||||
section 3bF, filesystem interface
|
||||
=================================
|
||||
|
||||
### `++feel`
|
||||
|
||||
Generate file diff
|
||||
|
||||
++ feel :: simple file write
|
||||
|= [pax=path val=*]
|
||||
^- miso
|
||||
=+ dir=((hard arch) .^(%cy pax))
|
||||
?~ q.dir [%ins val]
|
||||
:- %mut
|
||||
^- udon
|
||||
[%a %a .^(%cx pax) val]
|
||||
::
|
||||
|
||||
Generates a diff between a file located at `pax` and an input value
|
||||
`val`.
|
||||
|
||||
`pax` is a [`++path`]().
|
||||
|
||||
`val` is a value as a [noun]().
|
||||
|
||||
~zod/try=> + %/mel 'test'
|
||||
+ /~zod/try/2/mel
|
||||
~zod/try=> (feel %/mel 'tesh?')
|
||||
[%mut p=[p=%a q=[%a p=44.903.392.628 q=272.335.332.724]]]
|
||||
~zod/try=> `@t`44.903.392.628
|
||||
'''
|
||||
test
|
||||
'''
|
||||
~zod/try=> `@t`272.335.332.724
|
||||
'tesh?'
|
||||
|
||||
### `++file`
|
||||
|
||||
Simple file load
|
||||
|
||||
++ file :: simple file load
|
||||
|= pax=path
|
||||
^- (unit)
|
||||
=+ dir=((hard arch) .^(%cy pax))
|
||||
?~(q.dir ~ [~ .^(%cx pax)])
|
||||
::
|
||||
|
||||
Reads the value of a file located at `pax` and renders it as a
|
||||
[`++unit`]().
|
||||
|
||||
`pax` is a [`++path`]().
|
||||
|
||||
~zod/try=> %/zak
|
||||
~zod/try=/zak> :ls %
|
||||
~zod/try=/zak> + %/mop 20
|
||||
+ /~zod/try/3/zak/mop
|
||||
~zod/try=/zak> :ls %
|
||||
mop
|
||||
~zod/try=/zak> (file %/mop)
|
||||
[~ 20]
|
||||
~zod/try=/zak> (file %/lak)
|
||||
~
|
||||
~zod/try=/zak> (file /==2%/mop)
|
||||
~
|
||||
|
||||
### `++foal`
|
||||
|
||||
Write high-level change
|
||||
|
||||
++ foal :: high-level write
|
||||
|= [pax=path val=*]
|
||||
^- toro
|
||||
?> ?=([* * * *] pax)
|
||||
[i.t.pax [%& [*cart [[t.t.t.pax (feel pax val)] ~]]]]
|
||||
::
|
||||
|
||||
Produces a [`++toro`](), a change intended for whatever file is located
|
||||
at `pax`. Handled by `%clay`.
|
||||
|
||||
`pax` is a [`++path`]().
|
||||
|
||||
`val` is a value as a [noun]().
|
||||
|
||||
~zod/try=> + %/mek 'a'
|
||||
+ /~zod/try/4/mek
|
||||
~zod/try=> (foal %/mek 'b')
|
||||
[ p=~.try
|
||||
q
|
||||
[%.y q=[p=[p=0v0 q=0v0] q=~[[p=/mek q=[%mut p=[p=%a q=[%a p=97 q=98]]]]]]]
|
||||
]
|
||||
~zod/try=> (feel %/mek 'b')
|
||||
[%mut p=[p=%a q=[%a p=97 q=98]]]
|
||||
|
||||
### `++fray`
|
||||
|
||||
High-level delete
|
||||
|
||||
++ fray :: high-level delete
|
||||
|= pax=path
|
||||
^- toro
|
||||
?> ?=([* * * *] pax)
|
||||
[i.t.pax [%& [*cart [[t.t.t.pax [%del .^(%cx pax)]] ~]]]]
|
||||
::
|
||||
|
||||
Produces a deletion [`++toro`]() for a file located at path `pax`.
|
||||
Handled by `%clay`.
|
||||
|
||||
`pax` is a [`++path`]().
|
||||
|
||||
~zod/try=> + %/mek 'a'
|
||||
+ /~zod/try/4/mek
|
||||
~zod/try=> (fray %/mek)
|
||||
[p=~.try q=[%.y q=[p=[p=0v0 q=0v0] q=~[[p=/mek q=[%del p=97]]]]]]
|
||||
~zod/try=> `@t`97
|
||||
'a'
|
||||
|
||||
### `++furl`
|
||||
|
||||
Unify changes
|
||||
|
||||
++ furl :: unify changes
|
||||
|= [one=toro two=toro]
|
||||
^- toro
|
||||
~| %furl
|
||||
?> ?& =(p.one p.two) :: same path
|
||||
&(?=(& -.q.one) ?=(& -.q.two)) :: both deltas
|
||||
==
|
||||
[p.one [%& [*cart (weld q.q.q.one q.q.q.two)]]]
|
||||
::
|
||||
|
||||
Merge two [`++toro`]()s `one` and `two` that are in the same [`desk`]()
|
||||
and pointed at the same [`++path`]().
|
||||
|
||||
`one` is a [`++toro`]().
|
||||
|
||||
`two` is a [`++toro`]().
|
||||
|
||||
~zod/try=> %/zak
|
||||
~zod/try=/zak> :ls %
|
||||
mop
|
||||
~zod/try=/zak> (furl (fray %/mop) (foal %/mok 'hi'))
|
||||
[ p=~.try
|
||||
q
|
||||
[ %.y
|
||||
q
|
||||
[ p=[p=0v0 q=0v0]
|
||||
q=~[[p=/zak/mop q=[%del p=20]] [p=/zak/mok q=[%ins p=26.984]]]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
### `++meat`
|
||||
|
||||
Kite to .\^ path
|
||||
|
||||
++ meat :: kite to .^ path
|
||||
|= kit=kite
|
||||
^- path
|
||||
[(cat 3 'c' p.kit) (scot %p r.kit) s.kit (scot `dime`q.kit) t.kit]
|
||||
::
|
||||
|
||||
Converts a type request name to a [`++path`]().
|
||||
|
||||
`kit` is a [`++kite`]().
|
||||
|
||||
zod/try=/zop> `kite`[%x ud/1 ~zod %main /sur/down/gate/hook]
|
||||
[p=%x q=[%ud p=1] r=~zod s=%main t=/sur/down/gate/hook]
|
||||
~zod/try=/zop> (meat [%x ud/1 ~zod %main /sur/down/gate/hook])
|
||||
/cx/~zod/main/1/sur/down/gate/hook
|
||||
~zod/try=/zop> .^((meat [%x ud/1 ~zod %main /sur/down/gate/hook]))
|
||||
8.024.240.839.827.090.233.853.057.929.619.452.695.436.878.709.611.140.677.
|
||||
745.908.646.440.925.885.935.296.374.867.974.972.908.054.571.544.099.882.490.
|
||||
677.391.983.737.511.220.072.391.888.081.664.570
|
||||
~zod/try=/zop> (,@t .^((meat [%x ud/1 ~zod %main /sur/down/gate/hook])))
|
||||
'''
|
||||
::
|
||||
:::: /hoon/gate/down/sur
|
||||
::
|
||||
/? 314
|
||||
/- *markdown
|
||||
down
|
||||
|
||||
'''
|
||||
|
||||
### `++tame`
|
||||
|
||||
Parse kite path
|
||||
|
||||
++ tame :: parse kite path
|
||||
|= hap=path
|
||||
^- (unit kite)
|
||||
?. ?=([@ @ @ @ *] hap) ~
|
||||
=+ :* hyr=(slay i.hap)
|
||||
fal=(slay i.t.hap)
|
||||
dyc=(slay i.t.t.hap)
|
||||
ved=(slay i.t.t.t.hap)
|
||||
:: ved=(slay i.t.hap)
|
||||
:: fal=(slay i.t.t.hap)
|
||||
:: dyc=(slay i.t.t.t.hap)
|
||||
tyl=t.t.t.t.hap
|
||||
==
|
||||
?. ?=([~ %$ %tas @] hyr) ~
|
||||
?. ?=([~ %$ %p @] fal) ~
|
||||
?. ?=([~ %$ %tas @] dyc) ~
|
||||
?. ?=([~ %$ case] ved) ~
|
||||
=+ his=`@p`q.p.u.fal
|
||||
=+ [dis=(end 3 1 q.p.u.hyr) rem=(rsh 3 1 q.p.u.hyr)]
|
||||
?. ?&(?=(%c dis) ?=(?(%v %w %x %y %z) rem)) ~
|
||||
[~ rem p.u.ved q.p.u.fal q.p.u.dyc tyl]
|
||||
::
|
||||
|
||||
Parses a clay [.\^]()
|
||||
[`++path` ]()to request details. Produces the [`++unit`]() of a [`++kite`]().
|
||||
|
||||
`hap` is a [`++path`]().
|
||||
|
||||
~zod/try=/zop> (tame /cx/~zod/main/1/sur/down/gate/hook)
|
||||
[~ [p=%x q=[%ud p=1] r=~zod s=%main t=/sur/down/gate/hook]]
|
||||
~zod/try=/zop> (tame /cx/0/main/1/sur/down/gate/hook)
|
||||
~
|
||||
~zod/try=/zop> (tame /~zod/main/0x12/sur/down/gate/hook)
|
||||
~
|
||||
|
||||
### `++tome`
|
||||
|
||||
Parse path to beam
|
||||
|
||||
++ tome :: parse path to beam
|
||||
|= pax=path
|
||||
^- (unit beam)
|
||||
?. ?=([* * * *] pax) ~
|
||||
%+ biff (slaw %p i.pax)
|
||||
|= who=ship
|
||||
%+ biff (slaw %tas i.t.pax)
|
||||
|= dex=desk
|
||||
%+ biff (slay i.t.t.pax)
|
||||
|= cis=coin
|
||||
?. ?=([%$ case] cis) ~
|
||||
`(unit beam)`[~ [who dex `case`p.cis] (flop t.t.t.pax)]
|
||||
::
|
||||
|
||||
Parses a [`++path`]() `pax` to a [\`++beam](), a well-typed location.
|
||||
|
||||
~zod/try=/zop> (tome /~fyr/try/2/for/me)
|
||||
[~ [[p=~fyr q=%try r=[%ud p=2]] s=/me/for]]
|
||||
~zod/try=/zop> (tome /~zod/main/1)
|
||||
[~ [[p=~zod q=%main r=[%ud p=1]] s=/]]
|
||||
~zod/try=/zop> (tome /0/main/1)
|
||||
~
|
||||
~zod/try=/zop> (tome /~zod/main/0x12)
|
||||
~
|
||||
|
||||
### `++tope :: beam to path`
|
||||
|
||||
Parse beam to path
|
||||
|
||||
|= bem=beam
|
||||
^- path
|
||||
[(scot %p p.bem) q.bem (scot r.bem) (flop s.bem)]
|
||||
|
||||
Parses a [`++beam`]() to a [`++path`](/doc/hoon/library/1#++path).
|
||||
|
||||
~zod/try=/zop> (tope [~zod %main ud/1] /hook/down/sur)
|
||||
/~zod/main/1/sur/down/hook
|
||||
~zod/try=/zop> (tope [~fyr %try da/~2015.1.1] /txt/test)
|
||||
/~fyr/try/~2015.1.1/test/txt
|
||||
~zod/try=/zop> (tope [~doznec %try da/-<-] /txt/test)
|
||||
/~doznec/try/~2014.10.30..00.32.48..3ae4/test/txt
|
@ -1,943 +0,0 @@
|
||||
section 3bG, URL handling
|
||||
=========================
|
||||
|
||||
### `++deft`
|
||||
|
||||
Import URL path
|
||||
|
||||
++ deft :: import url path
|
||||
|= rax=(list ,@t)
|
||||
|- ^- pork
|
||||
?~ rax
|
||||
[~ ~]
|
||||
?~ t.rax
|
||||
=+ den=(trip i.rax)
|
||||
=+ ^= vex
|
||||
%- %- full
|
||||
;~(plug sym ;~(pose (stag ~ ;~(pfix dot sym)) (easy ~)))
|
||||
[[1 1] (trip i.rax)]
|
||||
?~ q.vex
|
||||
[~ [i.rax ~]]
|
||||
[+.p.u.q.vex [-.p.u.q.vex ~]]
|
||||
=+ pok=$(rax t.rax)
|
||||
:- p.pok
|
||||
[i.rax q.pok]
|
||||
::
|
||||
|
||||
Parse the extension the from last element of url, which is delimited
|
||||
either by a `.` or a `/`.
|
||||
|
||||
`rax` is a [`++list`]() of [`@t`]().
|
||||
|
||||
~zod/try=> (deft /foo/bar/'baz.txt')
|
||||
[p=[~ ~.txt] q=<|foo bar baz|>]
|
||||
~zod/try=> (deft /foo/bar/baz)
|
||||
[p=~ q=<|foo bar baz|>]
|
||||
|
||||
### `++fain`
|
||||
|
||||
Restructure path
|
||||
|
||||
++ fain :: path restructure
|
||||
|= [hom=path raw=path]
|
||||
=+ bem=(need (tome raw))
|
||||
=+ [mer=(flop s.bem) moh=(flop hom)]
|
||||
|- ^- (pair beam path)
|
||||
?~ moh
|
||||
[bem(s hom) (flop mer)]
|
||||
?> &(?=(^ mer) =(i.mer i.moh))
|
||||
$(mer t.mer, moh t.moh)
|
||||
::
|
||||
|
||||
Splits a concrete
|
||||
[`++spur`]() out of a full `++path`, producing a location [`++beam`]() and a remainder [`++path`]().
|
||||
|
||||
`hom` is a [`++path`]()
|
||||
|
||||
~zod/try=> (fain / %)
|
||||
[p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.07.17..c835]] s=/] q=/]
|
||||
~zod/try=> (fain /lok %)
|
||||
! exit
|
||||
~zod/try=> (fain / %/mer/lok/tem)
|
||||
[ p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.08.03..bfdf]] s=/]
|
||||
q=/tem/lok/mer
|
||||
]
|
||||
~zod/try=> (fain /mer %/mer/lok/tem)
|
||||
[p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.08.15..4da0]] s=/mer] q=/tem/lok]
|
||||
~zod/try=> (fain /lok/mer %/mer/lok/tem)
|
||||
[p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.08.24..4d9e]] s=/lok/mer] q=/tem]
|
||||
~zod/try=> (fain /lok/mer %/mer)
|
||||
! exit
|
||||
~zod/try=> (fain /hook/hymn/tor %/tor/hymn/hook/'._req_1234__')
|
||||
[ p=[[p=~zod q=%try r=[%da p=~2014.11.1..00.09.25..c321]] s=/hook/hymn/tor]
|
||||
q=/._req_1234__
|
||||
]
|
||||
|
||||
### `++fuel`
|
||||
|
||||
Parse fcgi
|
||||
|
||||
++ fuel :: parse fcgi
|
||||
|= [bem=beam but=path]
|
||||
^- epic
|
||||
?> ?=([%web @ *] but)
|
||||
=+ dyb=(slay i.t.but)
|
||||
?> ?& ?=([~ %many *] dyb)
|
||||
?=([* * *] p.u.dyb)
|
||||
:: ?=([%$ %tas *] i.p.u.dyb)
|
||||
?=([%many *] i.p.u.dyb)
|
||||
?=([%blob *] i.t.p.u.dyb)
|
||||
==
|
||||
=+ ced=((hard cred) p.i.t.p.u.dyb)
|
||||
:: =+ nep=q.p.i.p.u.dyb
|
||||
=+ ^= nyp ^- path
|
||||
%+ turn p.i.p.u.dyb
|
||||
|= a=coin ^- @ta
|
||||
?> ?=([%$ %ta @] a)
|
||||
?>(((sane %ta) q.p.a) q.p.a)
|
||||
=+ ^= gut ^- (list ,@t)
|
||||
%+ turn t.t.p.u.dyb
|
||||
|= a=coin ^- @t
|
||||
?> ?=([%$ %t @] a)
|
||||
?>(((sane %t) q.p.a) q.p.a)
|
||||
=+ ^= quy
|
||||
|- ^- (list ,[p=@t q=@t])
|
||||
?~ gut ~
|
||||
?> ?=(^ t.gut)
|
||||
[[i.gut i.t.gut] $(gut t.t.gut)]
|
||||
:* (~(gas by *(map cord cord)) quy)
|
||||
ced
|
||||
bem
|
||||
t.t.but
|
||||
nyp
|
||||
==
|
||||
::
|
||||
|
||||
Retrieieves the %eyre FCGI, producing a [`++epic`](). Used primarily in
|
||||
[`/hook`]() files. See the [`%eyre`]() doc for more detail.
|
||||
|
||||
`bem` is a [`++beam`]().
|
||||
|
||||
`but` is a [`++path`]().
|
||||
|
||||
~zod/main=> (fuel [[p=~zod q=%try r=[%ud p=2]] s=/psal] /web/'._.~-~~~~.gen~-~-_~~05vg0001v09f0n30fbh7dn6ab2jakmmspdq04nef5h70qbd5lh6atr4c5j2qrbldpp62q1df1in0sr1ding0c3qgt7kclj74qb65lm6atrkc5k2qpr5e1mmispdchin4p3fegmiqrjpdlo62p1dchsn4p39comn8pbcehgmsbbef5p7crrifr3o035dhgfrk2b5__')
|
||||
[ qix={}
|
||||
ced
|
||||
[ hut=[p=%.y q=[~ 8.445] r=[%.n p=.0.0.0.0]]
|
||||
aut={[p=%$ q={'~rovryn-natlet-fidryd-dapmyn--todred-simpeg-hatwel-firfet'}]}
|
||||
orx='laspex-harnum-fadweb-mipbyn'
|
||||
acl=[~ 'en-US,en;q=0.8']
|
||||
cip=[%.y p=.127.0.0.1]
|
||||
cum={}
|
||||
]
|
||||
bem=[[p=~zod q=%try r=[%ud p=2]] s=/psal]
|
||||
but=/
|
||||
nyp=/gen
|
||||
]
|
||||
|
||||
### `++sifo`
|
||||
|
||||
64-bit encode
|
||||
|
||||
++ sifo :: 64-bit encode
|
||||
|= tig=@
|
||||
^- tape
|
||||
=+ poc=(~(dif fo 3) 0 (met 3 tig))
|
||||
=+ pad=(lsh 3 poc (swap 3 tig))
|
||||
=+ ^= cha
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'
|
||||
=+ ^= sif
|
||||
|- ^- tape
|
||||
?~ pad
|
||||
~
|
||||
=+ d=(end 0 6 pad)
|
||||
[(cut 3 [d 1] cha) $(pad (rsh 0 6 pad))]
|
||||
(weld (flop (slag poc sif)) (trip (fil 3 poc '=')))
|
||||
::
|
||||
|
||||
Encodes an atom to MIME base64, producing a [`++tape`]().
|
||||
|
||||
~zod/main=> (sifo 'foobar')
|
||||
"Zm9vYmFy"
|
||||
~zod/main=> (sifo 1)
|
||||
"Q=="
|
||||
~zod/main=> (sifo (shax %hi))
|
||||
"j0NDRmSPa5bfid2pAcUXaxCm2Dlh3TwayItZstwyeqQ="
|
||||
|
||||
### `++urle`
|
||||
|
||||
Encode URL
|
||||
|
||||
++ urle :: URL encode
|
||||
|= tep=tape
|
||||
^- tape
|
||||
%- zing
|
||||
%+ turn tep
|
||||
|= tap=char
|
||||
=+ xen=|=(tig=@ ?:((gte tig 10) (add tig 55) (add tig '0')))
|
||||
?: ?| &((gte tap 'a') (lte tap 'z'))
|
||||
&((gte tap 'A') (lte tap 'Z'))
|
||||
&((gte tap '0') (lte tap '9'))
|
||||
=('.' tap)
|
||||
=('-' tap)
|
||||
=('~' tap)
|
||||
=('_' tap)
|
||||
==
|
||||
[tap ~]
|
||||
['%' (xen (rsh 0 4 tap)) (xen (end 0 4 tap)) ~]
|
||||
::
|
||||
|
||||
The inverse of [`++urld`](). Accepts a tape `tep` and replaces all
|
||||
characters other than alphanumerics and `.`, `-`, `~`, and `_`, with URL
|
||||
escape sequences.
|
||||
|
||||
~zod/main=> (urle "hello")
|
||||
"hello"
|
||||
~zod/main=> (urle "hello dear")
|
||||
"hello%20dear"
|
||||
~zod/main=> (urle "hello-my?=me !")
|
||||
"hello-my%3F%3Dme%20%20%21"
|
||||
|
||||
### `++urld`
|
||||
|
||||
Decode URL
|
||||
|
||||
++ urld :: URL decode
|
||||
|= tep=tape
|
||||
^- (unit tape)
|
||||
?~ tep [~ ~]
|
||||
?: =('%' i.tep)
|
||||
?. ?=([@ @ *] t.tep) ~
|
||||
=+ nag=(mix i.t.tep (lsh 3 1 i.t.t.tep))
|
||||
=+ val=(rush nag hex:ag)
|
||||
?~ val ~
|
||||
=+ nex=$(tep t.t.t.tep)
|
||||
?~(nex ~ [~ [`@`u.val u.nex]])
|
||||
=+ nex=$(tep t.tep)
|
||||
?~(nex ~ [~ i.tep u.nex])
|
||||
::
|
||||
|
||||
The inverse of [`++urle`](). Parses a URL escaped tape to the
|
||||
[`++unit`]() of an unescaped `++tape`.
|
||||
|
||||
`tep` is a [`++tape`]().
|
||||
|
||||
~zod/main=> (urld "hello")
|
||||
[~ "hello"]
|
||||
~zod/main=> (urld "hello%20dear")
|
||||
[~ "hello dear"]
|
||||
~zod/main=> (urld "hello-my%3F%3Dme%20%20%21")
|
||||
[~ "hello-my?=me !"]
|
||||
~zod/main=> (urld "hello-my%3F%3Dme%20%2%21")
|
||||
~
|
||||
|
||||
### `++earl`
|
||||
|
||||
Localize purl
|
||||
|
||||
++ earl :: localize purl
|
||||
|= [who=@p pul=purl]
|
||||
^- purl
|
||||
pul(q.q [(rsh 3 1 (scot %p who)) q.q.pul])
|
||||
::
|
||||
|
||||
Prepends a ship name to the spur of a [`++purl`]().
|
||||
|
||||
`who` is a [`@p`](), a ship name.
|
||||
|
||||
`pul` is a [`++purl`]().
|
||||
|
||||
~zod/main=> (need (epur 'http://123.1.1.1/me.ham'))
|
||||
[p=[p=%.n q=~ r=[%.n p=.123.1.1.1]] q=[p=[~ ~.ham] q=<|me|>] r=~]
|
||||
~zod/main=> (earl ~zod (need (epur 'http://123.1.1.1/me.ham')))
|
||||
[p=[p=%.n q=~ r=[%.n p=.123.1.1.1]] q=[p=[~ ~.ham] q=<|zod me|>] r=~]
|
||||
~zod/main=> (earl ~pittyp (need (epur 'http://123.1.1.1/me.ham')))
|
||||
[p=[p=%.n q=~ r=[%.n p=.123.1.1.1]] q=[p=[~ ~.ham] q=<|pittyp me|>] r=~]
|
||||
~zod/main=> (earn (earl ~pittyp (need (epur 'http://123.1.1.1/me.ham'))))
|
||||
"http://123.1.1.1/pittyp/me"
|
||||
|
||||
### `++earn`
|
||||
|
||||
Purl to tape
|
||||
|
||||
++ earn :: purl to tape
|
||||
|^ |= pul=purl
|
||||
^- tape
|
||||
:(weld (head p.pul) "/" (body q.pul) (tail r.pul))
|
||||
::
|
||||
|
||||
Parses a `++purl` `pul` to a [`++tape`]().
|
||||
|
||||
`pul` is a [`++purl`]().
|
||||
|
||||
~zod/main=> (earn [| ~ [%| .127.0.0.1]] [~ ~] ~)
|
||||
"http://127.0.0.1/"
|
||||
~zod/main=> (earn [| ~ `/com/google/www] [~ ~] ~)
|
||||
"http://www.google.com/"
|
||||
~zod/main=> (earn [& ~ `/com/google/www] [~ ~] ~)
|
||||
"https://www.google.com/"
|
||||
~zod/main=> (earn [& `200 `/com/google/www] [~ ~] ~)
|
||||
"https://www.google.com:200/"
|
||||
~zod/main=> (earn [& `200 `/com/google/www] [~ /search] ~)
|
||||
"https://www.google.com:200/search"
|
||||
~zod/main=> (earn [& ~ `/com/google/www] [`%html /search] ~)
|
||||
"https://www.google.com/search"
|
||||
~zod/main=> (earn [& ~ `/com/google/www] [~ /search] [%q 'urbit'] ~)
|
||||
"https://www.google.com/search?q=urbit"
|
||||
~zod/main=> (earn [& ~ `/com/google/www] [~ /search] [%q 'urbit escaping?'] ~)
|
||||
"https://www.google.com/search?q=urbit%20escaping%3F"
|
||||
|
||||
### `++body`
|
||||
|
||||
Render URL path
|
||||
|
||||
++ body
|
||||
|= pok=pork ^- tape
|
||||
?~ q.pok ~
|
||||
|-
|
||||
=+ seg=(trip i.q.pok)
|
||||
?~ t.q.pok
|
||||
?~(p.pok seg (welp seg '.' (trip u.p.pok)))
|
||||
(welp seg '/' $(q.pok t.q.pok))
|
||||
::
|
||||
|
||||
|
||||
Renders URL path `pok` as a [`++tape`]().
|
||||
|
||||
~zod/main=> (body:earn ~ /foo/mol/lok)
|
||||
"foo/mol/lok"
|
||||
~zod/main=> (body:earn `%htm /foo/mol/lok)
|
||||
"foo/mol/lok.htm"
|
||||
~zod/main=> (body:earn `%htm /)
|
||||
""
|
||||
|
||||
### `++head`
|
||||
|
||||
Render URL beginning
|
||||
|
||||
++ head
|
||||
|= har=hart
|
||||
^- tape
|
||||
;: weld
|
||||
?:(&(p.har !=([& /localhost] r.har)) "https://" "http://")
|
||||
::
|
||||
?- -.r.har
|
||||
| (trip (rsh 3 1 (scot %if p.r.har)))
|
||||
& =+ rit=(flop p.r.har)
|
||||
|- ^- tape
|
||||
?~(rit ~ (weld (trip i.rit) ?~(t.rit "" `tape`['.' $(rit t.rit)])))
|
||||
==
|
||||
::
|
||||
?~(q.har ~ `tape`[':' (trip (rsh 3 2 (scot %ui u.q.har)))])
|
||||
==
|
||||
::
|
||||
|
||||
Renders a `++hart`, usually the beginning of a URL, as the [`++tape`]()
|
||||
of a traditional URL.
|
||||
|
||||
~zod/main=> (head:earn | ~ %| .127.0.0.1)
|
||||
"http://127.0.0.1"
|
||||
~zod/main=> (head:earn & ~ %| .127.0.0.1)
|
||||
"https://127.0.0.1"
|
||||
~zod/main=> (head:earn & [~ 8.080] %| .127.0.0.1)
|
||||
"https://127.0.0.1:8080"
|
||||
~zod/main=> (head:earn & [~ 8.080] %& /com/google/www)
|
||||
"https://www.google.com:8080"
|
||||
|
||||
### `++tail`
|
||||
|
||||
Render query string
|
||||
|
||||
++ tail
|
||||
|= kay=quay
|
||||
^- tape
|
||||
?: =(~ kay) ~
|
||||
:- '?'
|
||||
|- ^- tape
|
||||
?~ kay ~
|
||||
;: weld
|
||||
(urle (trip p.i.kay))
|
||||
"="
|
||||
(urle (trip q.i.kay))
|
||||
?~(t.kay ~ `tape`['&' $(kay t.kay)])
|
||||
==
|
||||
--
|
||||
::
|
||||
|
||||
Renders a `quay`, a query string in hoon, to the [`++tape`]() of a
|
||||
traditional query string.
|
||||
|
||||
`kay` is a [`++quay`]().
|
||||
|
||||
~zod/main=> (tail:earn ~)
|
||||
""
|
||||
~zod/main=> (tail:earn [%ask 'bid'] ~)
|
||||
"?ask=bid"
|
||||
~zod/main=> (tail:earn [%ask 'bid'] [%make 'well'] ~)
|
||||
"?ask=bid&make=well"
|
||||
|
||||
### `++epur`
|
||||
|
||||
Top-level URL parser
|
||||
|
||||
++ epur :: url/header parser
|
||||
=< |=(a=cord (rush a auri))
|
||||
|%
|
||||
|
||||
Toplevel URL parser.
|
||||
|
||||
`a` is a [`++cord`](/doc/hoon/library/1#++cord).
|
||||
|
||||
~zod/main=> (epur 'http://127.0.0.1/')
|
||||
[~ [p=[p=%.n q=~ r=[%.n p=.127.0.0.1]] q=[p=~ q=<||>] r=~]]
|
||||
~zod/main=> (epur 'http://www.google.com/')
|
||||
[~ [p=[p=%.n q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]]
|
||||
~zod/main=> (epur 'https://www.google.com/')
|
||||
[~ [p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]]
|
||||
~zod/main=> (epur 'https//www.google.com/')
|
||||
~
|
||||
~zod/main=> (epur 'https://www.google.com:200/')
|
||||
[~ [p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]]
|
||||
~zod/main=> (epur 'https://www.google.com:200/search')
|
||||
[ ~
|
||||
[p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~]
|
||||
]
|
||||
~zod/main=> (epur 'https://www.google.com/search')
|
||||
[~ [p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~]]
|
||||
~zod/main=> (epur 'https://www.google.com/search?q=urbit')
|
||||
[ ~
|
||||
[ p=[p=%.y q=~ r=[%.y p=<|com google www|>]]
|
||||
q=[p=~ q=<|search|>]
|
||||
r=~[[p='q' q='urbit']]
|
||||
]
|
||||
]
|
||||
~zod/main=> (epur 'https://www.google.com/search?q=urb it')
|
||||
~
|
||||
~zod/main=> (epur 'https://www.google.com/search?q=urb%20it')
|
||||
[ ~
|
||||
[ p=[p=%.y q=~ r=[%.y p=<|com google www|>]]
|
||||
q=[p=~ q=<|search|>]
|
||||
r=~[[p='q' q='urb it']]
|
||||
]
|
||||
]
|
||||
~zod/main=> (epur 'https://www.google.com/search?q=urbit%20escaping%3F')
|
||||
[ ~
|
||||
[ p=[p=%.y q=~ r=[%.y p=<|com google www|>]]
|
||||
q=[p=~ q=<|search|>]
|
||||
r=~[[p='q' q='urbit escaping?']]
|
||||
]
|
||||
]
|
||||
|
||||
### `++apat`
|
||||
|
||||
++ apat :: 2396 abs_path
|
||||
%+ cook deft
|
||||
(ifix [fas ;~(pose fas (easy ~))] (more fas smeg))
|
||||
|
||||
URL path as ++pork
|
||||
|
||||
~zod/try=> (scan "/foo/mol/lok" apat:epur)
|
||||
[p=~ q=<|foo mol lok|>]
|
||||
~zod/try=> (scan "/foo/mol/lok.htm" apat:epur)
|
||||
[p=[~ ~.htm] q=<|foo mol lok|>]
|
||||
|
||||
### `++auri`
|
||||
|
||||
++ auri
|
||||
%+ cook
|
||||
|= a=purl
|
||||
?.(=([& /localhost] r.p.a) a a(p.p &))
|
||||
;~ plug
|
||||
;~ plug
|
||||
%+ sear
|
||||
|= a=@t
|
||||
^- (unit ,?)
|
||||
?+(a ~ %http [~ %|], %https [~ %&])
|
||||
;~(sfix scem ;~(plug col fas fas))
|
||||
thor
|
||||
==
|
||||
;~(plug ;~(pose apat (easy *pork)) yque)
|
||||
==
|
||||
|
||||
URL parsing rule
|
||||
|
||||
~zod/main=> (auri:epur [1 1] "http://127.0.0.1/")
|
||||
[ p=[p=1 q=18]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.n q=~ r=[%.n p=.127.0.0.1]] q=[p=~ q=<||>] r=~]
|
||||
q=[p=[p=1 q=18] q=""]
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "http://www.google.com/")
|
||||
[ p=[p=1 q=23]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.n q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]
|
||||
q=[p=[p=1 q=23] q=""]
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com/")
|
||||
[ p=[p=1 q=24]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~]
|
||||
q=[p=[p=1 q=24] q=""]
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https//www.google.com/")
|
||||
[ p=[p=1 q=6] q=~]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com:200/")
|
||||
[ p=[p=1 q=28]
|
||||
q=[~ u=[p=[p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<||>] r=~] q=[p=[p=1 q=28] q=""]]]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com:200/search")
|
||||
[ p=[p=1 q=34]
|
||||
q=[~ u=[p=[p=[p=%.y q=[~ 200] r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~] q=[p=[p=1 q=34] q=""]]]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com/search")
|
||||
[ p=[p=1 q=30]
|
||||
q=[~ u=[p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~] q=[p=[p=1 q=30] q=""]]]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urbit")
|
||||
[ p=[p=1 q=38]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urbit']]]
|
||||
q=[p=[p=1 q=38] q=""]
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urb it")
|
||||
[ p=[p=1 q=36]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urb']]]
|
||||
q=[p=[p=1 q=36] q=" it"]
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urb%20it")
|
||||
[ p=[p=1 q=41]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urb it']]]
|
||||
q=[p=[p=1 q=41] q=""]
|
||||
]
|
||||
]
|
||||
]
|
||||
~zod/main=> (auri:epur [1 1] "https://www.google.com/search?q=urbit%20escaping%3F")
|
||||
[ p=[p=1 q=52]
|
||||
q
|
||||
[ ~
|
||||
u
|
||||
[ p=[p=[p=%.y q=~ r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='urbit escaping?']]]
|
||||
q=[p=[p=1 q=52] q=""]
|
||||
]
|
||||
]
|
||||
]
|
||||
|
||||
### `++cock`
|
||||
|
||||
++ cock :: cookie
|
||||
(most ;~(plug sem ace) ;~(plug toke ;~(pfix tis tosk)))
|
||||
|
||||
HTTP cookies, results in associative list of cord to cord.
|
||||
|
||||
~zod/try=> (scan "sam=lop" cock:epur)
|
||||
[['sam' 'lop'] ~]
|
||||
~zod/try=> (scan "sam=lop; res=\"salo don -keg!mo\"" cock:epur)
|
||||
[['sam' 'lop'] ~[['res' 'salo don -keg!mo']]]
|
||||
~zod/try=> (scan "sam=lop; res=\"salo don -keg!mo\"; so" cock:epur)
|
||||
! {1 34}
|
||||
! exit
|
||||
|
||||
### `++dlab`
|
||||
|
||||
++ dlab :: 2396 domainlabel
|
||||
%+ sear
|
||||
|= a=@ta
|
||||
?.(=('-' (rsh 3 (dec (met 3 a)) a)) [~ u=a] ~)
|
||||
%+ cook cass
|
||||
;~(plug aln (star alp))
|
||||
::
|
||||
|
||||
Domain label: alphanumeric, with `-` allowed in middle.
|
||||
|
||||
~zod/try=> (scan "google" dlab:epur)
|
||||
~.google
|
||||
~zod/try=> (scan "lera2" dlab:epur)
|
||||
~.lera2
|
||||
~zod/try=> (scan "gor-tem" dlab:epur)
|
||||
~.gor-tem
|
||||
~zod/try=> (scan "gortem-" dlab:epur)
|
||||
! {1 8}
|
||||
! exit
|
||||
|
||||
### `++fque`
|
||||
|
||||
++ fque (cook crip (plus pquo)) :: normal query field
|
||||
|
||||
One or more query string characters
|
||||
|
||||
~zod/try=> (scan "%20" fque:epur)
|
||||
' '
|
||||
~zod/try=> (scan "sam" fque:epur)
|
||||
'sam'
|
||||
~zod/try=> (scan "les+tor" fque:epur)
|
||||
'les tor'
|
||||
~zod/try=> (scan "sore-%22mek%22" fque:epur)
|
||||
'sore-"mek"'
|
||||
~zod/try=> (scan "" fque:epur)
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
### `++fquu`
|
||||
|
||||
++ fquu (cook crip (star pquo)) :: optional field
|
||||
|
||||
Zero or more query string characters
|
||||
|
||||
~zod/try=> (scan "%20" fquu:epur)
|
||||
' '
|
||||
~zod/try=> (scan "sam" fquu:epur)
|
||||
'sam'
|
||||
~zod/try=> (scan "les+tor" fquu:epur)
|
||||
'les tor'
|
||||
~zod/try=> (scan "sore-%22mek%22" fquu:epur)
|
||||
'sore-"mek"'
|
||||
~zod/try=> (scan "" fquu:epur)
|
||||
''
|
||||
|
||||
### `++pcar`
|
||||
|
||||
++ pcar ;~(pose pure pesc psub col pat) :: 2396 path char
|
||||
|
||||
Single URL path character: literal, `%` escape, subpath delimiter, `:`
|
||||
or `@`
|
||||
|
||||
~zod/try=> (scan "a" pcar:epur)
|
||||
~~a
|
||||
~zod/try=> (scan "ab" pcar:epur)
|
||||
! {1 2}
|
||||
! exit
|
||||
~zod/try=> (scan "-" pcar:epur)
|
||||
~~-
|
||||
~zod/try=> (scan "." pcar:epur)
|
||||
~~~.
|
||||
~zod/try=> (scan "%20" pcar:epur)
|
||||
~~.
|
||||
~zod/try=> (scan "!" pcar:epur)
|
||||
~~~21.
|
||||
|
||||
### `++pcok`
|
||||
|
||||
++ pcok ;~(less bas sem com doq prn) :: cookie char
|
||||
|
||||
Cookie character
|
||||
|
||||
~zod/try=> (scan "a" pcok:epur)
|
||||
~~a
|
||||
~zod/try=> (scan "ab" pcok:epur)
|
||||
! {1 2}
|
||||
! exit
|
||||
~zod/try=> (scan "!" pcok:epur)
|
||||
~~~21.
|
||||
~zod/try=> (scan ";" pcok:epur)
|
||||
! {1 2}
|
||||
! exit
|
||||
|
||||
### `++pesc`
|
||||
|
||||
++ pesc ;~(pfix cen mes) :: 2396 escaped
|
||||
|
||||
URL `%` escape, by two hex characters.
|
||||
|
||||
~zod/try=> `@t`(scan "%22" pesc:epur)
|
||||
'"'
|
||||
~zod/try=> `@t`(scan "%20" pesc:epur)
|
||||
' '
|
||||
|
||||
### `++pold`
|
||||
|
||||
++ pold (cold ' ' (just '+')) :: old space code
|
||||
|
||||
Old URL `' '` escape
|
||||
|
||||
~zod/try=> `@t`(scan "+" pold:epur)
|
||||
' '
|
||||
~zod/try=> `@t`(scan " " pold:epur)
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
### `++pque`
|
||||
|
||||
++ pque ;~(pose pcar fas wut) :: 3986 query char
|
||||
|
||||
Irregular query string character.
|
||||
|
||||
~zod/try=> `@t`(scan "a" pque:epur)
|
||||
'a'
|
||||
~zod/try=> `@t`(scan "?" pque:epur)
|
||||
'?'
|
||||
~zod/try=> `@t`(scan "%20" pque:epur)
|
||||
' '
|
||||
~zod/try=> `@t`(scan "+" pque:epur)
|
||||
'+'
|
||||
|
||||
### `++pquo`
|
||||
|
||||
++ pquo ;~(pose pure pesc pold) :: normal query char
|
||||
|
||||
Character in query string key/value
|
||||
|
||||
~zod/try=> (scan "a" pquo:epur)
|
||||
'a'
|
||||
~zod/try=> (scan "ab" pquo:epur)
|
||||
! {1 2}
|
||||
! exit
|
||||
~zod/try=> (scan "%22" pquo:epur)
|
||||
'"'
|
||||
~zod/try=> (scan "%20" pquo:epur)
|
||||
' '
|
||||
~zod/try=> (scan "+" pquo:epur)
|
||||
' '
|
||||
|
||||
### `++pure`
|
||||
|
||||
++ pure ;~(pose aln hep dot cab sig) :: 2396 unreserved
|
||||
|
||||
URL-safe character
|
||||
|
||||
~zod/try=> (scan "a" pure:epur)
|
||||
~~a
|
||||
~zod/try=> (scan "%20" pure:epur)
|
||||
! {1 1}
|
||||
! exit
|
||||
~zod/try=> (scan "." pure:epur)
|
||||
~~~.
|
||||
~zod/try=> (scan "-" pure:epur)
|
||||
~~-
|
||||
|
||||
### `++psub`
|
||||
|
||||
++ psub ;~ pose :: 3986 sub-delims
|
||||
zap buc pam soq pel per
|
||||
tar lus com sem tis
|
||||
==
|
||||
|
||||
URL path subdelimeter
|
||||
|
||||
~zod/try=> `@t`(scan "+" psub:epur)
|
||||
'+'
|
||||
~zod/try=> `@t`(scan "(" psub:epur)
|
||||
'('
|
||||
~zod/try=> `@t`(scan "$" psub:epur)
|
||||
'$'
|
||||
~zod/try=> `@t`(scan "a" psub:epur)
|
||||
! {1 1}
|
||||
! exit
|
||||
|
||||
### `++ptok`
|
||||
|
||||
++ ptok ;~ pose :: 2616 token
|
||||
aln zap hax buc cen pam soq tar lus
|
||||
hep dot ket cab tec bar sig
|
||||
==
|
||||
|
||||
Character valid in HTTP token
|
||||
|
||||
~zod/try=> `tape`(murn =+(a=' ' |-(`tape`?:(=(0x7f a) ~ [a $(a +(a))]))) (curr rush ptok):epur)
|
||||
"!#$%&'*+-.0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ^_`abcdefghijklmnopqrstuvwxyz|~"
|
||||
~zod/try=> `tape`(skim =+(a=' ' |-(`tape`?:(=(0x7f a) ~ [a $(a +(a))]))) |=(a=char ?=(~ (rush a ptok:epur))))
|
||||
" "(),/:;<=>?@[\]{}"
|
||||
|
||||
### `++scem`
|
||||
|
||||
++ scem :: 2396 scheme
|
||||
%+ cook cass
|
||||
;~(plug alf (star ;~(pose aln lus hep dot)))
|
||||
::
|
||||
|
||||
URI scheme: alphabetic character, followed by any number of
|
||||
alphanumeric, `+` `-` or `.`
|
||||
|
||||
~zod/try=> `@t`(scan "http" scem:epur)
|
||||
'http'
|
||||
~zod/try=> `@t`(scan "https" scem:epur)
|
||||
'https'
|
||||
~zod/try=> `@t`(scan "chrome-extension" scem:epur)
|
||||
'chrome-extension'
|
||||
|
||||
### `++smeg`
|
||||
|
||||
++ smeg (cook crip (plus pcar)) :: 2396 segment
|
||||
|
||||
URL path segment
|
||||
|
||||
~zod/try=> (scan "foo" smeg:epur)
|
||||
'foo'
|
||||
~zod/try=> (scan "bar%20baz-bam" smeg:epur)
|
||||
'bar baz-bam'
|
||||
|
||||
### `++tock`
|
||||
|
||||
++ tock (cook crip (plus pcok)) :: 6265 cookie-value
|
||||
|
||||
HTTP cookie value
|
||||
|
||||
~zod/try=> (rush 'sam' tock:epur)
|
||||
[~ 'sam']
|
||||
~zod/try=> (rush 'las!tore' tock:epur)
|
||||
[~ 'las!tore']
|
||||
~zod/try=> (rush '"sop""les"tor' tock:epur)
|
||||
~
|
||||
~zod/try=> (rush '"zemug"' tock:epur)
|
||||
~
|
||||
|
||||
### `++tosk`
|
||||
|
||||
++ tosk ;~(pose tock (ifix [doq doq] tock)) :: 6265 cookie-value
|
||||
|
||||
Possibly quoted HTTP cookie value
|
||||
|
||||
~zod/try=> (rush 'sam' tosk:epur)
|
||||
[~ 'sam']
|
||||
~zod/try=> (rush 'las!tore' tosk:epur)
|
||||
[~ 'las!tore']
|
||||
~zod/try=> (rush '"sop""les"tor' tosk:epur)
|
||||
~
|
||||
~zod/try=> (rush '"zemug"' tosk:epur)
|
||||
[~ 'zemug']
|
||||
|
||||
### `++toke`
|
||||
|
||||
++ toke (cook crip (plus ptok)) :: 2616 token
|
||||
|
||||
HTTP cookie name
|
||||
|
||||
~zod/try=> (rush 'sam' toke:epur)
|
||||
[~ 'sam']
|
||||
~zod/try=> (rush 'las!tore' toke:epur)
|
||||
[~ 'las!tore']
|
||||
~zod/try=> (rush 'sop""les"tor' toke:epur)
|
||||
~
|
||||
~zod/try=> (rush '"zemug"' toke:epur)
|
||||
~
|
||||
|
||||
### `++thor`
|
||||
|
||||
++ thor :: 2396 host/port
|
||||
%+ cook |*(a=[* *] [+.a -.a])
|
||||
;~ plug
|
||||
thos
|
||||
;~(pose (stag ~ ;~(pfix col dim:ag)) (easy ~))
|
||||
==
|
||||
|
||||
Parse ++host and unit `@ui` port.
|
||||
|
||||
~zod/try=> (scan "localhost" thor:epur)
|
||||
[~ [%.y i='localhost' t=~]]
|
||||
~zod/try=> (scan "localhost:8080" thor:epur)
|
||||
[[~ q=8.080] [%.y i='localhost' t=~]]
|
||||
~zod/try=> (scan "192.168.0.1:8080" thor:epur)
|
||||
[[~ q=8.080] [%.n q=3.232.235.521]]
|
||||
~zod/try=> (scan "www.google.com" thor:epur)
|
||||
[~ [%.y i='com' t=~['google' 'www']]]
|
||||
|
||||
### `++thos`
|
||||
|
||||
++ thos :: 2396 host, no local
|
||||
;~ plug
|
||||
;~ pose
|
||||
%+ stag %&
|
||||
%+ sear :: LL parser weak here
|
||||
|= a=(list ,@t)
|
||||
=+ b=(flop a)
|
||||
?> ?=(^ b)
|
||||
=+ c=(end 3 1 i.b)
|
||||
?.(&((gte c 'a') (lte c 'z')) ~ [~ u=b])
|
||||
(most dot dlab)
|
||||
::
|
||||
%+ stag %|
|
||||
=+ tod=(ape:ag ted:ab)
|
||||
%+ bass 256
|
||||
;~(plug tod (stun [3 3] ;~(pfix dot tod)))
|
||||
==
|
||||
==
|
||||
|
||||
URI host: dot-separated segments, or IP address.
|
||||
|
||||
~zod/try=> (scan "localhost" thos:epur)
|
||||
[%.y i='localhost' t=~]
|
||||
~zod/try=> (scan "192.168.0.1" thos:epur)
|
||||
[%.n q=3.232.235.521]
|
||||
~zod/try=> (scan "192.168.0.1:80" thos:epur)
|
||||
! {1 12}
|
||||
! exit
|
||||
~zod/try=> (scan "www.google.com" thos:epur)
|
||||
[%.y i='com' t=~['google' 'www']]
|
||||
|
||||
### `++yque`
|
||||
|
||||
++ yque :: query ending
|
||||
;~ pose
|
||||
;~(pfix wut yquy)
|
||||
(easy ~)
|
||||
==
|
||||
|
||||
Parses query string, or lack thereof. Result type ++quay
|
||||
|
||||
~zod/try=> (scan "?sar=tok" yque:epur)
|
||||
[['sar' 'tok'] ~]
|
||||
~zod/try=> (scan "?les=urbit%20sep&met=kam" yque:epur)
|
||||
[['les' 'urbit sep'] ~[['met' 'kam']]]
|
||||
~zod/try=> (scan "" yque:epur)
|
||||
~
|
||||
|
||||
### `++yquy`
|
||||
|
||||
++ yquy :: query
|
||||
;~ pose :: proper query
|
||||
%+ more
|
||||
;~(pose pam sem)
|
||||
;~(plug fque ;~(pose ;~(pfix tis fquu) (easy '')))
|
||||
::
|
||||
%+ cook :: funky query
|
||||
|=(a=tape [[%$ (crip a)] ~])
|
||||
(star pque)
|
||||
==
|
||||
|
||||
Parse query string after `?`
|
||||
|
||||
~zod/try=> (scan "sar=tok" yquy:epur)
|
||||
[['sar' 'tok'] ~]
|
||||
~zod/try=> (scan "les=urbit%20sep&met=kam" yquy:epur)
|
||||
[['les' 'urbit sep'] ~[['met' 'kam']]]
|
||||
~zod/try=> (scan "" yquy:epur)
|
||||
~
|
||||
|
||||
### `++zest`
|
||||
|
||||
++ zest :: 2616 request-uri
|
||||
;~ pose
|
||||
(stag %& (cook |=(a=purl a) auri))
|
||||
(stag %| ;~(plug apat yque))
|
||||
==
|
||||
--
|
||||
|
||||
Parse ++quri absolute or relative request path
|
||||
|
||||
~zod/try=> (scan "http://www.google.com:80/search?q=foo" zest:epur)
|
||||
[%.y p=[p=%.n q=[~ 80] r=[%.y p=<|com google www|>]] q=[p=~ q=<|search|>] r=~[[p='q' q='foo']]]
|
||||
~zod/try=> (scan "/rel/bat" zest:epur)
|
||||
[%.n [p=~ q=<|rel bat|>] ~]
|
@ -1,479 +0,0 @@
|
||||
section 3bH, names etc
|
||||
======================
|
||||
|
||||
### `++clan`
|
||||
|
||||
++ clan :: ship to rank
|
||||
|= who=ship ^- rank
|
||||
=+ wid=(met 3 who)
|
||||
?: (lte wid 1) %czar
|
||||
?: =(2 wid) %king
|
||||
?: (lte wid 4) %duke
|
||||
?: (lte wid 8) %earl
|
||||
?> (lte wid 16) %pawn
|
||||
::
|
||||
|
||||
Ship class
|
||||
|
||||
~zod/main=> (clan ~zod)
|
||||
%czar
|
||||
~zod/main=> (clan ~tyr)
|
||||
%czar
|
||||
~zod/main=> (clan ~doznec)
|
||||
%king
|
||||
~zod/main=> (clan ~tasfyn-partyv)
|
||||
%duke
|
||||
|
||||
### `++glam`
|
||||
|
||||
++ glam
|
||||
|= zar=@pD ^- tape
|
||||
%+ snag zar
|
||||
^- (list tape)
|
||||
:~ "Tianming" "Pepin the Short" "Haile Selassie" "Alfred the Great"
|
||||
"Tamerlane" "Pericles" "Talleyrand" "Yongle" "Seleucus"
|
||||
"Uther Pendragon" "Louis XVI" "Ahmad Shāh Durrānī" "Constantine"
|
||||
"Wilhelm I" "Akbar" "Louis XIV" "Nobunaga" "Alexander VI"
|
||||
"Philippe II" "Julius II" "David" "Niall Noígíallach" "Kublai Khan"
|
||||
"Öz Beg Khan" "Ozymandias" "Ögedei Khan" "Jiang Jieshi" "Darius"
|
||||
"Shivaji" "Qianlong" "Bolesław I Chrobry" "Tigranes" "Han Wudi"
|
||||
"Charles X" "Naresuan" "Frederick II" "Simeon" "Kangxi"
|
||||
"Suleiman the Magnificent" "Pedro II" "Genghis Khan" "Laozi"
|
||||
"Porfirio Díaz" "Pakal" "Wu Zetian" "Garibaldi" "Matthias Corvinus"
|
||||
"Leopold II" "Leonidas" "Sitting Bull" "Nebuchadnezzar II"
|
||||
"Rhodes" "Henry VIII" "Attila" "Catherine II" "Chulalongkorn"
|
||||
"Uthmān" "Augustus" "Faustin" "Chongde" "Justinian"
|
||||
"Afonso de Albuquerque" "Antoninus Pius" "Cromwell" "Innocent X"
|
||||
"Fidel" "Frederick the Great" "Canute" "Vytautas" "Amina"
|
||||
"Hammurabi" "Suharto" "Victoria" "Hiawatha" "Paul V" "Shaka"
|
||||
"Lê Thánh Tông" "Ivan Asen II" "Tiridates" "Nefertiti" "Gwangmu"
|
||||
"Ferdinand & Isabella" "Askia" "Xuande" "Boris Godunov" "Gilgamesh"
|
||||
"Maximillian I" "Mao" "Charlemagne" "Narai" "Hanno" "Charles I & V"
|
||||
"Alexander II" "Mansa Musa" "Zoe Porphyrogenita" "Metternich"
|
||||
"Robert the Bruce" "Pachacutec" "Jefferson" "Solomon" "Nicholas I"
|
||||
"Barbarossa" "FDR" "Pius X" "Gwanggaeto" "Abbas I" "Julius Caesar"
|
||||
"Lee Kuan Yew" "Ranavalona I" "Go-Daigo" "Zenobia" "Henry V"
|
||||
"Bảo Đại" "Casimir III" "Cyrus" "Charles the Wise" "Sandrokottos"
|
||||
"Agamemnon" "Clement VII" "Suppiluliuma" "Deng Xiaoping"
|
||||
"Victor Emmanuel" "Ajatasatru" "Jan Sobieski" "Huangdi" "Xuantong"
|
||||
"Narmer" "Cosimo de' Medici" "Möngke Khan" "Stephen Dušan" "Henri IV"
|
||||
"Mehmed Fatih" "Conn Cétchathach" "Francisco Franco" "Leo X"
|
||||
"Kammu" "Krishnadevaraya" "Elizabeth I" "Norton I" "Washington"
|
||||
"Meiji" "Umar" "TR" "Peter the Great" "Agustin I" "Ashoka"
|
||||
"William the Conqueror" "Kongolo Mwamba" "Song Taizu"
|
||||
"Ivan the Terrible" "Yao" "Vercingetorix" "Geronimo" "Rurik"
|
||||
"Urban VIII" "Alexios Komnenos" "Maria I" "Tamar" "Bismarck"
|
||||
"Arthur" "Jimmu" "Gustavus Adolphus" "Suiko" "Basil I" "Montezuma"
|
||||
"Santa Anna" "Xerxes" "Beyazıt Yıldırım" "Samudragupta" "James I"
|
||||
"George III" "Kamehameha" "Francesco Sforza" "Trajan"
|
||||
"Rajendra Chola" "Hideyoshi" "Cleopatra" "Alexander"
|
||||
"Ashurbanipal" "Paul III" "Vespasian" "Tecumseh" "Narasimhavarman"
|
||||
"Suryavarman II" "Bokassa I" "Charles Canning" "Theodosius"
|
||||
"Francis II" "Zhou Wen" "William Jardine" "Ahmad al-Mansur"
|
||||
"Lajos Nagy" "Theodora" "Mussolini" "Samuil" "Osman Gazi"
|
||||
"Kim Il-sung" "Maria Theresa" "Lenin" "Tokugawa" "Marcus Aurelius"
|
||||
"Nzinga Mbande" "Edward III" "Joseph II" "Pulakesi II" "Priam"
|
||||
"Qin Shi Huang" "Shah Jahan" "Sejong" "Sui Wendi" "Otto I"
|
||||
"Napoleon III" "Prester John" "Dido" "Joao I" "Gregory I"
|
||||
"Gajah Mada" "Abd-ar Rahmān III" "Taizong" "Franz Josef I"
|
||||
"Nicholas II" "Gandhi" "Chandragupta II" "Peter III"
|
||||
"Oba Ewuare" "Louis IX" "Napoleon" "Selim Yavuz" "Shun"
|
||||
"Hayam Wuruk" "Jagiełło" "Nicaule" "Sargon" "Saladin" "Charles II"
|
||||
"Brian Boru" "Da Yu" "Antiochus III" "Charles I"
|
||||
"Jan Pieterszoon Coen" "Hongwu" "Mithridates" "Hadrian" "Ptolemy"
|
||||
"Benito Juarez" "Sun Yat-sen" "Raja Raja Chola" "Bolivar" "Pius VII"
|
||||
"Shapur II" "Taksin" "Ram Khamhaeng" "Hatshepsut" "Alī" "Matilda"
|
||||
"Ataturk"
|
||||
==
|
||||
::
|
||||
|
||||
Retrieve carrier name.
|
||||
|
||||
~zod/main=> (glam ~zod)
|
||||
"Tianming"
|
||||
~zod/main=> (glam ~fyr)
|
||||
"Bolivar"
|
||||
|
||||
### `++glon`
|
||||
|
||||
++ glon
|
||||
|= lag=lang
|
||||
^- (unit tape)
|
||||
?+ lag ~
|
||||
%aa [~ "Afar"]
|
||||
%ab [~ "Abkhazian"]
|
||||
%ae [~ "Avestan"]
|
||||
%af [~ "Afrikaans"]
|
||||
%ak [~ "Akan"]
|
||||
%am [~ "Amharic"]
|
||||
%an [~ "Aragonese"]
|
||||
%ar [~ "Arabic"]
|
||||
%as [~ "Assamese"]
|
||||
%av [~ "Avaric"]
|
||||
%ay [~ "Aymara"]
|
||||
%az [~ "Azerbaijani"]
|
||||
%ba [~ "Bashkir"]
|
||||
%be [~ "Belarusian"]
|
||||
%bg [~ "Bulgarian"]
|
||||
%bh [~ "Bihari"]
|
||||
%bi [~ "Bislama"]
|
||||
%bm [~ "Bambara"]
|
||||
%bn [~ "Bengali"]
|
||||
%bo [~ "Tibetan"]
|
||||
%br [~ "Breton"]
|
||||
%bs [~ "Bosnian"]
|
||||
%ca [~ "Catalan"]
|
||||
%ce [~ "Chechen"]
|
||||
%ch [~ "Chamorro"]
|
||||
%co [~ "Corsican"]
|
||||
%cr [~ "Cree"]
|
||||
%cs [~ "Czech"]
|
||||
%cu [~ "Slavonic"]
|
||||
%cv [~ "Chuvash"]
|
||||
%cy [~ "Welsh"]
|
||||
%da [~ "Danish"]
|
||||
%de [~ "German"]
|
||||
%dv [~ "Maldivian"]
|
||||
%dz [~ "Dzongkha"]
|
||||
%ee [~ "Ewe"]
|
||||
%el [~ "Greek"]
|
||||
%en [~ "English"]
|
||||
%eo [~ "Esperanto"]
|
||||
%es [~ "Spanish"]
|
||||
%et [~ "Estonian"]
|
||||
%eu [~ "Basque"]
|
||||
%fa [~ "Persian"]
|
||||
%ff [~ "Fulah"]
|
||||
%fi [~ "Finnish"]
|
||||
%fj [~ "Fijian"]
|
||||
%fo [~ "Faroese"]
|
||||
%fr [~ "French"]
|
||||
%fy [~ "Frisian"]
|
||||
%ga [~ "Irish Gaelic"]
|
||||
%gd [~ "Scottish Gaelic"]
|
||||
%gl [~ "Galician"]
|
||||
%gn [~ "Guarani"]
|
||||
%gu [~ "Gujarati"]
|
||||
%gv [~ "Manx"]
|
||||
%ha [~ "Hausa"]
|
||||
%he [~ "Hebrew"]
|
||||
%hi [~ "Hindi"]
|
||||
%ho [~ "Hiri Motu"]
|
||||
%hr [~ "Croatian"]
|
||||
%ht [~ "Haitian Creole"]
|
||||
%hu [~ "Hungarian"]
|
||||
%hy [~ "Armenian"]
|
||||
%hz [~ "Herero"]
|
||||
%ia [~ "Interlingua"]
|
||||
%id [~ "Indonesian"]
|
||||
%ie [~ "Occidental"]
|
||||
%ig [~ "Igbo"]
|
||||
%ii [~ "Nuosu"]
|
||||
%ik [~ "Inupiaq"]
|
||||
%io [~ "Ido"]
|
||||
%is [~ "Icelandic"]
|
||||
%it [~ "Italian"]
|
||||
%iu [~ "Inuktitut"]
|
||||
%ja [~ "Japanese"]
|
||||
%jv [~ "Javanese"]
|
||||
%ka [~ "Georgian"]
|
||||
%kg [~ "Kongo"]
|
||||
%ki [~ "Kikuyu"]
|
||||
%kj [~ "Kwanyama"]
|
||||
%kk [~ "Kazakh"]
|
||||
%kl [~ "Kalaallisut"]
|
||||
%km [~ "Central Khmer"]
|
||||
%kn [~ "Kannada"]
|
||||
%ko [~ "Korean"]
|
||||
%kr [~ "Kanuri"]
|
||||
%ks [~ "Kashmiri"]
|
||||
%ku [~ "Kurdish"]
|
||||
%kv [~ "Komi"]
|
||||
%kw [~ "Cornish"]
|
||||
%ky [~ "Kyrgyz"]
|
||||
%la [~ "Latin"]
|
||||
%lb [~ "Luxembourgish"]
|
||||
%lg [~ "Ganda"]
|
||||
%li [~ "Limburgish"]
|
||||
%ln [~ "Lingala"]
|
||||
%lo [~ "Lao"]
|
||||
%lt [~ "Lithuanian"]
|
||||
%lu [~ "Luba-Katanga"]
|
||||
%lv [~ "Latvian"]
|
||||
%mg [~ "Malagasy"]
|
||||
%mh [~ "Marshallese"]
|
||||
%mi [~ "Maori"]
|
||||
%mk [~ "Macedonian"]
|
||||
%ml [~ "Malayalam"]
|
||||
%mn [~ "Mongolian"]
|
||||
%mr [~ "Marathi"]
|
||||
%ms [~ "Malay"]
|
||||
%mt [~ "Maltese"]
|
||||
%my [~ "Burmese"]
|
||||
%na [~ "Nauru"]
|
||||
%nb [~ "Norwegian Bokmål"]
|
||||
%nd [~ "North Ndebele"]
|
||||
%ne [~ "Nepali"]
|
||||
%ng [~ "Ndonga"]
|
||||
%nl [~ "Dutch"]
|
||||
%nn [~ "Norwegian Nynorsk"]
|
||||
%no [~ "Norwegian"]
|
||||
%nr [~ "South Ndebele"]
|
||||
%nv [~ "Navajo"]
|
||||
%ny [~ "Chichewa"]
|
||||
%oc [~ "Occitan"]
|
||||
%oj [~ "Ojibwa"]
|
||||
%om [~ "Oromo"]
|
||||
%or [~ "Oriya"]
|
||||
%os [~ "Ossetian"]
|
||||
%pa [~ "Punjabi"]
|
||||
%pi [~ "Pali"]
|
||||
%pl [~ "Polish"]
|
||||
%ps [~ "Pashto"]
|
||||
%pt [~ "Portuguese"]
|
||||
%qu [~ "Quechua"]
|
||||
%rm [~ "Romansh"]
|
||||
%rn [~ "Rundi"]
|
||||
%ro [~ "Romanian"]
|
||||
%ru [~ "Russian"]
|
||||
%rw [~ "Kinyarwanda"]
|
||||
%sa [~ "Sanskrit"]
|
||||
%sc [~ "Sardinian"]
|
||||
%sd [~ "Sindhi"]
|
||||
%se [~ "Northern Sami"]
|
||||
%sg [~ "Sango"]
|
||||
%si [~ "Sinhala"]
|
||||
%sk [~ "Slovak"]
|
||||
%sl [~ "Slovenian"]
|
||||
%sm [~ "Samoan"]
|
||||
%sn [~ "Shona"]
|
||||
%so [~ "Somali"]
|
||||
%sq [~ "Albanian"]
|
||||
%sr [~ "Serbian"]
|
||||
%ss [~ "Swati"]
|
||||
%st [~ "Sotho"]
|
||||
%su [~ "Sundanese"]
|
||||
%sv [~ "Swedish"]
|
||||
%sw [~ "Swahili"]
|
||||
%ta [~ "Tamil"]
|
||||
%te [~ "Telugu"]
|
||||
%tg [~ "Tajik"]
|
||||
%th [~ "Thai"]
|
||||
%ti [~ "Tigrinya"]
|
||||
%tk [~ "Turkmen"]
|
||||
%tl [~ "Tagalog"]
|
||||
%tn [~ "Tswana"]
|
||||
%to [~ "Tonga"]
|
||||
%tr [~ "Turkish"]
|
||||
%ts [~ "Tsonga"]
|
||||
%tt [~ "Tatar"]
|
||||
%tw [~ "Twi"]
|
||||
%ty [~ "Tahitian"]
|
||||
%ug [~ "Uighur"]
|
||||
%uk [~ "Ukrainian"]
|
||||
%ur [~ "Urdu"]
|
||||
%uz [~ "Uzbek"]
|
||||
%ve [~ "Venda"]
|
||||
%vi [~ "Vietnamese"]
|
||||
%vo [~ "Volapük"]
|
||||
%wa [~ "Walloon"]
|
||||
%wo [~ "Wolof"]
|
||||
%xh [~ "Xhosa"]
|
||||
%yi [~ "Yiddish"]
|
||||
%yo [~ "Yoruba"]
|
||||
%za [~ "Zhuang"]
|
||||
%zh [~ "Chinese"]
|
||||
%zu [~ "Zulu"]
|
||||
==
|
||||
::
|
||||
|
||||
ISO language code
|
||||
|
||||
~zod/main=> (glon %cs)
|
||||
[~ "Czech"]
|
||||
~zod/main=> (glon %en)
|
||||
[~ "English"]
|
||||
~zod/main=> (glon %mz)
|
||||
~
|
||||
|
||||
### `++gnom`
|
||||
|
||||
++ gnom :: ship display name
|
||||
|= [[our=@p now=@da] him=@p] ^- @t
|
||||
=+ yow=(scot %p him)
|
||||
=+ pax=[(scot %p our) %name (scot %da now) yow ~]
|
||||
=+ woy=((hard ,@t) .^(%a pax))
|
||||
?: =(%$ woy) yow
|
||||
(rap 3 yow ' ' woy ~)
|
||||
::
|
||||
|
||||
Fetch display name from %ames
|
||||
|
||||
~zod/main=> (gnom [->-< -<-] ~zod)
|
||||
'~zod |Tianming|'
|
||||
~zod/main=> (gnom [->-< -<-] ~doznec)
|
||||
'~doznec ~doznec'
|
||||
~zod/main=> (gnom [->-< -<-] ~tug)
|
||||
'~tug |Go-Daigo|'
|
||||
|
||||
### `++gnow`
|
||||
|
||||
++ gnow
|
||||
|= [who=@p gos=gcos] ^- @t
|
||||
?- -.gos
|
||||
%czar (rap 3 '|' (rap 3 (glam who)) '|' ~)
|
||||
%king (rap 3 '_' p.gos '_' ~)
|
||||
%earl (rap 3 ':' p.gos ':' ~)
|
||||
%pawn ?~(p.gos %$ (rap 3 '.' u.p.gos '.' ~))
|
||||
%duke
|
||||
?: ?=(%anon -.p.gos) %$
|
||||
%+ rap 3
|
||||
^- (list ,@)
|
||||
?- -.p.gos
|
||||
%punk ~['"' q.p.gos '"']
|
||||
?(%lord %lady)
|
||||
=+ ^= nad
|
||||
=+ nam=`name`s.p.p.gos
|
||||
%+ rap 3
|
||||
:~ p.nam
|
||||
?~(q.nam 0 (cat 3 ' ' u.q.nam))
|
||||
?~(r.nam 0 (rap 3 ' (' u.r.nam ')' ~))
|
||||
' '
|
||||
s.nam
|
||||
==
|
||||
?:(=(%lord -.p.gos) ~['[' nad ']'] ~['(' nad ')'])
|
||||
==
|
||||
==
|
||||
::
|
||||
|
||||
XX Document
|
||||
|
||||
### `++hunt`
|
||||
|
||||
++ hunt :: first of unit dates
|
||||
|= [one=(unit ,@da) two=(unit ,@da)]
|
||||
^- (unit ,@da)
|
||||
?~ one two
|
||||
?~ two one
|
||||
?:((lth u.one u.two) one two)
|
||||
::
|
||||
|
||||
XX Document
|
||||
|
||||
### `++mojo`
|
||||
|
||||
++ mojo :: compiling load
|
||||
|= [pax=path src=*]
|
||||
^- (each twig (list tank))
|
||||
?. ?=(@ src)
|
||||
[%| ~[[leaf/"musk: malformed: {<pax>}"]]]
|
||||
=+ ^= mud
|
||||
%- mule |.
|
||||
((full vest) [1 1] (trip src))
|
||||
?: ?=(| -.mud) mud
|
||||
?~ q.p.mud
|
||||
:~ %|
|
||||
leaf/"musk: syntax error: {<pax>}"
|
||||
leaf/"musk: line {<p.p.p.mud>}, column {<q.p.p.mud>}"
|
||||
==
|
||||
[%& p.u.q.p.mud]
|
||||
::
|
||||
|
||||
XX Document
|
||||
|
||||
### `++mole`
|
||||
|
||||
++ mole :: new to old sky
|
||||
|= ska=$+(* (unit (unit)))
|
||||
|= a=*
|
||||
^- (unit)
|
||||
=+ b=(ska a)
|
||||
?~ b ~
|
||||
?~ u.b ~
|
||||
[~ u.u.b]
|
||||
::
|
||||
|
||||
XX Document
|
||||
|
||||
### `++much`
|
||||
|
||||
++ much :: constructing load
|
||||
|= [pax=path src=*]
|
||||
^- gank
|
||||
=+ moj=(mojo pax src)
|
||||
?: ?=(| -.moj) moj
|
||||
(mule |.((slap !>(+>.$) `twig`p.moj)))
|
||||
::
|
||||
|
||||
XX Document
|
||||
|
||||
### `++musk`
|
||||
|
||||
++ musk :: compiling apply
|
||||
|= [pax=path src=* sam=vase]
|
||||
^- gank
|
||||
=+ mud=(much pax src)
|
||||
?: ?=(| -.mud) mud
|
||||
(mule |.((slam p.mud sam)))
|
||||
::
|
||||
|
||||
XX Document
|
||||
|
||||
### `++saxo`
|
||||
|
||||
++ saxo :: autocanon
|
||||
|= who=ship
|
||||
^- (list ship)
|
||||
?: (lth who 256) [who ~]
|
||||
[who $(who (sein who))]
|
||||
::
|
||||
|
||||
Compute list of ancestors
|
||||
|
||||
~zod/main=> (saxo ~pittyp-pittyp)
|
||||
~[~pittyp-pittyp ~dalnel ~del]
|
||||
~zod/main=> (saxo ~tasfyn-partyv)
|
||||
~[~tasfyn-partyv ~doznec ~zod]
|
||||
~zod/main=> (saxo ~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet)
|
||||
~[~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet ~zod]
|
||||
|
||||
### `++sein`
|
||||
|
||||
++ sein :: autoboss
|
||||
|= who=ship ^- ship
|
||||
=+ mir=(clan who)
|
||||
?- mir
|
||||
%czar who
|
||||
%king (end 3 1 who)
|
||||
%duke (end 4 1 who)
|
||||
%earl (end 5 1 who)
|
||||
%pawn `@p`0
|
||||
==
|
||||
|
||||
Compute direct senior.
|
||||
|
||||
~zod/main=> (sein ~tasfyn-partyv)
|
||||
~doznec
|
||||
~zod/main=> (sein ~doznec)
|
||||
~zod
|
||||
~zod/main=> (sein ~zod)
|
||||
~zod
|
||||
~zod/main=> (sein ~pittyp-pittyp)
|
||||
~dalnel
|
||||
~zod/main=> (sein ~dalnel)
|
||||
~del
|
||||
~zod/main=> (sein ~ractul-fodsug-sibryg-modsyl--difrun-mirfun-filrec-patmet)
|
||||
~zod
|
||||
|
||||
Compute Phonemic base.
|
||||
|
||||
~zod/main=> (saxo ~rabdec-monfer)
|
||||
~[~rabdec-monfer ~dalnel ~del]
|
||||
~zod/main=> `@rd`~rabdec-monfer
|
||||
0x5fd25
|
||||
[%rlyd 0x5.fd25]
|
||||
0b1.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000.0000
|
||||
~zod/main=> `@p`0x5.fd25
|
||||
~rabdec-monfer
|
||||
|
||||
For `@rd` and `@p` see the [odors](../reference/odors) reference
|
File diff suppressed because it is too large
Load Diff
@ -1,18 +0,0 @@
|
||||
---
|
||||
logo: black
|
||||
sort: 2
|
||||
title: Hoon 101
|
||||
---
|
||||
|
||||
Welcome to Hoon 101!
|
||||
|
||||
Ideally, you've installed an Urbit planet (if you have a ticket)
|
||||
or comet (if you don't). See the [user doc](../../user). We
|
||||
recommend opening up the dojo and just typing the examples; you
|
||||
don't know a language until you know it in your fingers.
|
||||
|
||||
Hoon 101 is still under construction; new chapters are posted
|
||||
roughly once a week. So far:
|
||||
|
||||
<list></list>
|
||||
|
@ -1,286 +0,0 @@
|
||||
---
|
||||
next: true
|
||||
sort: 0
|
||||
spam: true
|
||||
title: Hoon 101.0: nouns, spans, and molds
|
||||
---
|
||||
|
||||
# Hoon 101.0: nouns, spans and molds
|
||||
|
||||
Hoon is a strict, higher-order typed pure-functional language.
|
||||
|
||||
Why Hoon? Typed functional languages are known for a pleasant
|
||||
phenomenon: once your code compiles, it's quite likely to work.
|
||||
But most typed functional languages are conceptually dependent on
|
||||
abstract advanced math, and difficult to understand without it.
|
||||
|
||||
Hoon is a typed FP language for the common street programmer.
|
||||
Well-written Hoon is as concrete and data-oriented as possible.
|
||||
The less functional magic you use, the better. But the magic is
|
||||
there, mostly, if you need it.
|
||||
|
||||
The main disadvantage of Hoon is that its syntax and semantics
|
||||
are unfamiliar. The syntax will remind too many of Perl, but
|
||||
like most human languages (and unlike Perl) it combines a regular
|
||||
core structure with irregular variations. And Hoon's semantic
|
||||
complexity is bounded by the size of the compiler: type inference plus code
|
||||
generation are 2000 lines of Hoon. Most peoples' experience is that the
|
||||
language is much easier to learn than it looks.
|
||||
|
||||
> The name "Hoon" is from the Wallace Stevens poem, _Tea at the
|
||||
Palaz of Hoon_. It also means "hooligan" in Australian.
|
||||
|
||||
## How to use this tutorial
|
||||
|
||||
Ideally, you've installed an Urbit planet (if you have a ticket)
|
||||
or comet (if you don't). See the [user doc](../../../user). We
|
||||
recommend opening up the dojo and just typing the examples; you
|
||||
don't know a language until you know it in your fingers.
|
||||
|
||||
## Nouns: data made boring
|
||||
|
||||
A noun is an atom or a cell. An atom is any unsigned integer. A
|
||||
cell is an ordered pair of nouns.
|
||||
|
||||
Nouns are trees; they have no cycles. Noun comparison is always
|
||||
by value (the programmer can't test pointer equality). Nouns are
|
||||
strict; there is no such thing as an infinite noun. And nouns are
|
||||
immutable. There's just no way to have any real fun with nouns.
|
||||
|
||||
> Nouns are Lisp's S-expressions, minus a lot of hacks, tricks,
|
||||
and features that made sense 50 years ago. In particular,
|
||||
because atoms are not tagged (an atom can encode a string, for
|
||||
instance), nouns depend on a static type system at a higher
|
||||
layer. How do you print an atom if you don't know whether it's a
|
||||
string or a number?
|
||||
|
||||
## A type system for nouns
|
||||
|
||||
One obstacle to learning Hoon is that it has two quite distinct
|
||||
concepts that might equally be called a "type." Worse, most
|
||||
other typed functional languages are mathy and share a basically
|
||||
mathematical concept of "type." Hoon does not have this concept
|
||||
at all. We can't avoid using the T-word occasionally, but it has
|
||||
no precise meaning in Hoon and can be extremely confusing.
|
||||
|
||||
Hoon's two kinds of "type" are `span` and `mold`. A span is both
|
||||
a constructively defined set of nouns, and a semantic convention
|
||||
for users in that set. A `mold` is a function whose range is
|
||||
some useful span. A mold is always idempotent (for any noun `x`,
|
||||
`f(x)` equals `f(f(x))`), and its domain is any noun.
|
||||
|
||||
One way to explain this is that while a span is what most
|
||||
languages call a "type," Hoon has no syntax for the programmer to
|
||||
define a span directly. Instead, we use inference to define it
|
||||
as the range of a mold function. This mold can also be used to
|
||||
validate or normalize untrusted, untyped data -- a common problem
|
||||
in modern programming, because networks.
|
||||
|
||||
> Sending a noun over the network is a good example of why Hoon
|
||||
is different. In a normal modern language, you serialize and
|
||||
deserialize a data type by extending your type to implement a
|
||||
serialization interface. A really good language can process your
|
||||
type definition and automatically generate this code. In Hoon,
|
||||
we have one function `jam` that converts any noun to an atom,
|
||||
and another `cue` that inverts `jam`. To validate, the receiver
|
||||
applies its own mold to the cued noun, and we've sent typed data
|
||||
over the network without any attack surface (except `jam` and
|
||||
`cue`, which fit on a page). No custom serialization code,
|
||||
manual or generated, is required. The mold itself is not sent;
|
||||
protocol agreement is out of band.
|
||||
|
||||
Hoon's inference algorithm is dumber than the unification
|
||||
algorithms (Hindley-Milner) used in most typed functional
|
||||
languages. Hoon thinks only forward, not backward. Eg, Haskell
|
||||
can infer the result type of a function from its argument
|
||||
(forward), or the argument type from the result (backward).
|
||||
Hoon can do the first but not the second.
|
||||
|
||||
So Hoon needs more manual annotations, which you usually want
|
||||
anyway for prosaic software-engineering reasons. Otherwise its
|
||||
typesystem solves more or less the same job, including
|
||||
pattern-matching, genericity / typeclasses, etc.
|
||||
|
||||
> A good test of a static higher-order typesystem is whether it can
|
||||
infer the product type of a grammar defined as a combinator
|
||||
parser. The Hoon parser passes this test; when it typechecks,
|
||||
the parser's range nests within the span of the expression mold.
|
||||
|
||||
## Let's make some nouns
|
||||
|
||||
Let's make a noun:
|
||||
```
|
||||
~tasfyn-partyv:dojo> 42
|
||||
```
|
||||
You'll see the expression you entered, then the result:
|
||||
```
|
||||
> 42
|
||||
42
|
||||
```
|
||||
Let's try a different noun. Or is it different?
|
||||
```
|
||||
~tasfyn-partyv:dojo> 0x2a
|
||||
```
|
||||
You'll see:
|
||||
```
|
||||
> 0x2a
|
||||
0x2a
|
||||
```
|
||||
`42` and `0x2a` are actually *the same noun*, because they're the
|
||||
same number. But we don't just have the noun to print - we have
|
||||
a `[span noun]` cell (sometimes called a `vase`).
|
||||
|
||||
As you recall, a span defines a set of nouns and a semantic
|
||||
interpretation. As sets, both spans here are "any number". But
|
||||
semantically, `42` has a decimal span and `0x2a` hexadecimal, so
|
||||
they print differently.
|
||||
|
||||
> It's important to remember that Hoon is a statically typed language.
|
||||
We don't work with vases unless we're dynamically compiling code,
|
||||
which is of course what we're doing here in the dojo. In Hoon,
|
||||
dynamic type equals static type plus runtime compilation.
|
||||
|
||||
Let's make some cells. Try these on your own urbit:
|
||||
```
|
||||
~tasfyn-partyv:dojo> [42 0x2a]
|
||||
~tasfyn-partyv:dojo> [42 [0x2a 420]]
|
||||
~tasfyn-partyv:dojo> [42 0x2a 420]
|
||||
```
|
||||
We observe that cells associate right: `[a b c]` is just another
|
||||
way of writing `[a [b c]]`.
|
||||
|
||||
Lisp masters beware: Hoon `[a b]` is Lisp `(a . b)`, Lisp
|
||||
`(a b)` is Hoon `[a b ~]`. `~` means nil, with value zero. Lisp
|
||||
and Hoon are both pair-oriented languages down below, but Lisp
|
||||
has a layer of sugar that makes it look list-oriented. Hoon
|
||||
loves its "improper lists," ie, tuples.
|
||||
|
||||
## Looking at spans
|
||||
|
||||
What are these mysterious spans? We can see them with the `?`
|
||||
prefix, which prints the span along with the result. Moving to
|
||||
a more compact example format:
|
||||
```
|
||||
~tasfyn-partyv:dojo> ? 42
|
||||
@ud
|
||||
42
|
||||
~tasfyn-partyv:dojo> ? 0x2a
|
||||
@ux
|
||||
0x2a
|
||||
```
|
||||
`@ud` and `@ux` stand for "unsigned decimal" and "unsigned hex,"
|
||||
obviously.
|
||||
|
||||
> What is this span syntax? We only derive spans through
|
||||
inference. So there's no parsing grammar for a span. We have to
|
||||
be able to print spans, if only for debugging and diagnostics,
|
||||
but the syntax is output-only. As in this case, it often looks
|
||||
like the `mold` syntax, but the two are at opposite ends of the
|
||||
type food chain.
|
||||
|
||||
## Looking at spans, part 2
|
||||
|
||||
Usually, good style in Hoon is concrete style. When a Hoon
|
||||
programmer defines an abstract semantic value in terms of a noun,
|
||||
we rarely put a conceptual layer of abstraction between value and
|
||||
noun. We think of the value as an interpretation of the noun.
|
||||
We don't think of the noun as an implementation of the noun.
|
||||
|
||||
But rules are made to be broken. With the `?` command, we *do*
|
||||
use an abstract layer, by printing our span noun in that custom
|
||||
syntax. But we can also look at the span noun directly, with the
|
||||
`??` command. As we'll see, `??` is mainly for newbies, but
|
||||
newbies love it.
|
||||
|
||||
```
|
||||
~tasfyn-partyv:dojo> ?? 42
|
||||
[%atom %ud]
|
||||
42
|
||||
~tasfyn-partyv:dojo> ?? [42 0x2a]
|
||||
[%cell [%atom %ud] [%atom %ux]]
|
||||
[42 0x2a]
|
||||
```
|
||||
What is this `%atom` syntax? Is it a real noun? Can anyone
|
||||
make one?
|
||||
```
|
||||
~tasfyn-partyv:dojo> %atom
|
||||
%atom
|
||||
~tasfyn-partyv:dojo> %foo
|
||||
%foo
|
||||
~tasfyn-partyv:dojo> [%foo %bar]
|
||||
[%foo %bar]
|
||||
```
|
||||
What's the span of one of these symbols?
|
||||
```
|
||||
~tasfyn-partyv:dojo> ? %foo
|
||||
%foo
|
||||
%foo
|
||||
~tasfyn-partyv:dojo> ?? %foo
|
||||
[%cube 7.303.014 [%atom %tas]]
|
||||
%foo
|
||||
```
|
||||
This takes a little bit of explaining. `7.303.014` is just the
|
||||
Urbit (and German) way of writing the English number `7,303,014`,
|
||||
or the Urbit hex number `0x6f.6f66`, or the string "foo" as an
|
||||
unsigned integer with least-significant byte first.
|
||||
|
||||
A `%cube` span is a constant -- a set of one noun, the atom
|
||||
`7.303.014`. But we still need to know how to print that noun.
|
||||
In this case, it's an `[%atom %tas]`, ie, a text symbol.
|
||||
|
||||
Cubes don't have to be symbols -- in fact, we can take the
|
||||
numbers we've just been using, and make them constants:
|
||||
```
|
||||
~tasfyn-partyv:dojo> %42
|
||||
%42
|
||||
~tasfyn-partyv:dojo> ? %42
|
||||
%42
|
||||
%42
|
||||
~tasfyn-partyv:dojo> ?? %42
|
||||
[%cube 42 [%atom %ud]]
|
||||
%42
|
||||
```
|
||||
|
||||
> Why `??`? Spans are an exception to concrete style, because they
|
||||
use "manual laziness" to define logically recursive structures.
|
||||
A recursive span contains Hoon code which is evaluated to apply
|
||||
it. In practice, this noun often contains the entire Urbit
|
||||
kernel, so you wouldn't want to try to print it in the dojo. If
|
||||
you find `??` taking a weirdly long time, this may have happened;
|
||||
press ^C.
|
||||
|
||||
## Our first mold
|
||||
|
||||
After seeing a few span examples, are we ready to describe the
|
||||
set of all spans with a Hoon mold? Well, no, but let's try it
|
||||
anyway. Ignore the syntax (which we'll explain later; this is a
|
||||
tutorial, not a reference manual), and you'll get the idea:
|
||||
```
|
||||
++ span
|
||||
$% [%atom p=@tas]
|
||||
[%cell p=span q=span]
|
||||
[%cube p=* q=span]
|
||||
==
|
||||
```
|
||||
This mold is not the entire definition of `span`, just the cases
|
||||
we've seen so far. In English, a valid span is either:
|
||||
|
||||
- a cell with head `%atom`, and tail some symbol.
|
||||
- a cell with head `%cell`, and tail some pair of spans.
|
||||
- a cell with head `%cube`, and tail a noun-span pair.
|
||||
|
||||
The head of a span is essentially the tag in a variant record,
|
||||
a pattern every programming language has. To use the span, we
|
||||
look at the head and then decide what to do with the tail.
|
||||
|
||||
> A conventional naming strategy for simple, self-explaining
|
||||
structures is to name the legs of a tuple `p`, `q`, `r`, `s` and
|
||||
`t`. If you get all the way to `t`, your noun is probably not
|
||||
simple or self-explaining; meaningful names are recommended.
|
||||
|
||||
## Progress
|
||||
|
||||
Believe it or not, at this point we understand nouns completely.
|
||||
We don't understand spans and molds completely, but we get the
|
||||
basics. In the [next chapter](1-twigs), we'll see how Hoon
|
||||
expressions (twigs) turn one noun into another.
|
@ -1,286 +0,0 @@
|
||||
---
|
||||
next: true
|
||||
sort: 1
|
||||
spam: true
|
||||
title: Hoon 101.1: twigs and legs
|
||||
---
|
||||
# Hoon 101.1: twigs and legs
|
||||
|
||||
In the [last chapter](0-nouns), we learned how to make nouns. In
|
||||
this chapter we'll get into Hoon expressions, or *twigs*.
|
||||
|
||||
## How to use this tutorial
|
||||
|
||||
Ideally, you've installed an Urbit planet (if you have a ticket)
|
||||
or comet (if you don't). See the [user doc](../../../user).
|
||||
|
||||
We recommend opening up the dojo and just typing the examples;
|
||||
you don't know a language until you know it in your fingers.
|
||||
Also, make sure you've worked through the chapters in order.
|
||||
|
||||
## Nock for Hoon programmers
|
||||
|
||||
Hoon compiles itself to a pico-interpreter called
|
||||
[Nock](../../nock), a combinator algebra defined in 200 words. This
|
||||
isn't the place to explain Nock (which relates to Hoon much as
|
||||
assembly language relates to C), but Nock is just a way to
|
||||
express a function as a noun.
|
||||
|
||||
Nock is a Turing-complete interpreter shaped like (pseudocode):
|
||||
```
|
||||
Nock(problem) => product
|
||||
```
|
||||
The `problem` is always a cell `[subject formula]`. The
|
||||
function is the `formula`. The input to the function is the
|
||||
`subject`. The output is the `product`.
|
||||
|
||||
## From Hoon to Nock
|
||||
|
||||
The Hoon parser turns an source expression (even one as simple as
|
||||
`42` from the last chapter) into a noun called a `twig`. If you
|
||||
know what an AST is, a twig is an AST. (If you don't know what
|
||||
an AST is, it's not necessarily worth the student loans.)
|
||||
|
||||
To simplify slightly, the Hoon compiler is shaped like:
|
||||
```
|
||||
Hoon(subject-span function-twig) => [product-span formula-nock]
|
||||
```
|
||||
Hoon, like Nock, is a *subject-oriented* language. Your code is
|
||||
always executed against one input noun, the subject. For any
|
||||
subject noun in `subject-span` (ie, argument type), the compiler
|
||||
produces a Nock formula that computes `function-twig` on that
|
||||
subject, and a `product-span` that is the span of the product
|
||||
(ie, result type).
|
||||
|
||||
> This is really a nontrivial difference. In a normal,
|
||||
non-subject-oriented language, your code executes against a
|
||||
scope, stack, environment, or other variable context, probably
|
||||
not even a regular user-level value. For ordinary coders,
|
||||
"subject-oriented programming" is one of the hardest things to
|
||||
understand about Hoon; for some reason, your brain keeps wanting
|
||||
the interpreter state to be more interesting.
|
||||
|
||||
## From constants to twigs
|
||||
|
||||
In the last chapter we were entering degenerate twigs like `42`.
|
||||
Obviously a numeric constant doesn't use the subject at all, so
|
||||
it's not a very interesting example.
|
||||
|
||||
Let's save a test subject as a dojo variable:
|
||||
```
|
||||
~tasfyn-partyv:dojo> =test [[[8 9] 5] [6 7]]
|
||||
```
|
||||
The `=test` command tells the dojo to rearrange its stock subject
|
||||
to include this `test` noun. Let's check that it's there:
|
||||
```
|
||||
~tasfyn-partyv:dojo> test
|
||||
[[[8 9] 5] 6 7]
|
||||
```
|
||||
> If you're wondering why `[6 7]` got printed as `6 7`, remember
|
||||
that `[]` associates to the right. Also, `=test` is not in any
|
||||
way Hoon syntax; it's dojo syntax. Every Hoon twig is a valid
|
||||
dojo command, but not vice versa.
|
||||
|
||||
We want to use `test`, this harmless little noun, as the subject
|
||||
for some equally harmless twigs. We can do this with the `:`
|
||||
syntax, which composes twigs in the functional sense. The twig
|
||||
`a:b` uses the product of twig `b` as the subject of twig `a`.
|
||||
Trivial cases:
|
||||
```
|
||||
~tasfyn-partyv:dojo> 42:test
|
||||
42
|
||||
~tasfyn-partyv:dojo> 42:420
|
||||
42
|
||||
```
|
||||
|
||||
## Tree addressing
|
||||
|
||||
The simplest twigs produce a subtree, or "leg", of the subject.
|
||||
A cell, of course, is a binary tree. The very simplest twig is
|
||||
`.`, which produces the root of the tree - the whole subject:
|
||||
```
|
||||
~tasfyn-partyv:dojo> .:test
|
||||
[[[8 9] 5] 6 7]
|
||||
```
|
||||
Like human languages, Hoon is full of irregular abbreviations.
|
||||
The `.` syntax is a shorthand for `+1`:
|
||||
```
|
||||
~tasfyn-partyv:dojo> +1:test
|
||||
[[[8 9] 5] 6 7]
|
||||
```
|
||||
Hoon has a simple tree addressing scheme (inherited from Nock):
|
||||
the root is `1`, the head of `n` is `2n`, the tail is `2n+1`.
|
||||
The twig syntax for a tree address is `+n`.
|
||||
|
||||
In our example noun, each leaf is its own tree address:
|
||||
```
|
||||
~tasfyn-partyv:dojo> +2:test
|
||||
[[8 9] 5]
|
||||
~tasfyn-partyv:dojo> +3:test
|
||||
[6 7]
|
||||
~tasfyn-partyv:dojo> +4:test
|
||||
[8 9]
|
||||
~tasfyn-partyv:dojo> +5:test
|
||||
5
|
||||
~tasfyn-partyv:dojo> +6:test
|
||||
6
|
||||
~tasfyn-partyv:dojo> +7:test
|
||||
7
|
||||
```
|
||||
> An instinct for binary tree geometry develops over time as you
|
||||
use the system, rather the way most programmers learn to do
|
||||
binary math. No, really.
|
||||
|
||||
## Lark syntax
|
||||
|
||||
This alternative syntax for a tree address maps noun geometry
|
||||
directly to a glyph. Lark syntax creates a recognizable
|
||||
geometric shape by alternating between two head/tail pairs, read
|
||||
left to right: `-` and `+`, `<` and `>`.
|
||||
|
||||
Thus `-` is `+2`, `+` is `+3`, `+<` is `+6`, `->` is `+5`, `-<+`
|
||||
is `+9`, etc.
|
||||
|
||||
> Why lark syntax? Code full of numbers is ugly and distracting,
|
||||
and looks like hardcoded constants. We actually almost never use
|
||||
the `+` syntax.
|
||||
|
||||
## Simple faces
|
||||
|
||||
Tree addressing is cool, but it would be pretty tough to program
|
||||
in Hoon if it was the only way of getting data out of a subject.
|
||||
|
||||
Let's introduce some new syntax:
|
||||
```
|
||||
~tasfyn-partyv:dojo> foo=42
|
||||
foo=42
|
||||
~tasfyn-partyv:dojo> ? foo=42
|
||||
foo=@ud
|
||||
foo=42
|
||||
~tasfyn-partyv:dojo> ?? foo=42
|
||||
[%face %foo [%atom %ud]]
|
||||
foo=42
|
||||
```
|
||||
To extend our `++span` mold from the last chapter:
|
||||
```
|
||||
++ span
|
||||
$% [%atom p=@tas]
|
||||
[%cell p=span p=span]
|
||||
[%cube p=* q=span]
|
||||
[%face p=@tas q=span]
|
||||
==
|
||||
```
|
||||
The `%face` span wraps a label around a noun. Then we can
|
||||
get a leg by name. Let's make a new dojo variable:
|
||||
```
|
||||
~tasfyn-partyv:dojo> =test [[[8 9] 5] foo=[6 7]]
|
||||
```
|
||||
The syntax is what you might expect:
|
||||
```
|
||||
~tasfyn-partyv:dojo> test
|
||||
[[[8 9] 5] foo=[6 7]]
|
||||
~tasfyn-partyv:dojo> foo:test
|
||||
[6 7]
|
||||
```
|
||||
Does this do what you expect it to do?
|
||||
```
|
||||
~tasfyn-partyv:dojo> +3:test
|
||||
foo=[6 7]
|
||||
~tasfyn-partyv:dojo> ? +3:test
|
||||
foo=[@ud @ud]
|
||||
foo=[6 7]
|
||||
~tasfyn-partyv:dojo> ?? +3:test
|
||||
[%face %foo [%cell [%atom %ud] [%atom %ud]]]
|
||||
foo=[6 7]
|
||||
```
|
||||
|
||||
## Interesting faces; wings
|
||||
|
||||
Let's look at a few more interesting face cases. First, suppose
|
||||
we have two cases of `foo`?
|
||||
```
|
||||
~tasfyn-partyv:dojo> =test [[foo=[8 9] 5] foo=[6 7]]
|
||||
~tasfyn-partyv:dojo> foo:test
|
||||
[8 9]
|
||||
```
|
||||
In the tree search, the head wins. We can overcome this with a
|
||||
`^` prefix, which tells the search to skip its first hit:
|
||||
```
|
||||
~tasfyn-partyv:dojo> ^foo:test
|
||||
[6 7]
|
||||
```
|
||||
`^^foo` will skip two foos, `^^^foo` three, *ad infinitum*.
|
||||
But what about nested labels?
|
||||
```
|
||||
~tasfyn-partyv:dojo> =test [[[8 9] 5] foo=[6 bar=7]]
|
||||
~tasfyn-partyv:dojo> bar:test
|
||||
/~tasfyn-partyv/home/~2015.11.7..21.40.21..1aec:<[1 1].[1 9]>
|
||||
-find-limb.bar
|
||||
find-none
|
||||
```
|
||||
We can't search *through* a label. If we want to get our `bar`
|
||||
out, we need to search *into* it:
|
||||
```
|
||||
~tasfyn-partyv:dojo> bar.foo:test
|
||||
7
|
||||
```
|
||||
`bar.foo` is what we call a `wing`, a search path in a noun.
|
||||
Note that the wing runs from left to right, ie, the opposite of
|
||||
most languages: `bar.foo` means "bar within foo."
|
||||
|
||||
Each step in a wing is a `limb`. (Most languages use metaphors;
|
||||
Hoon abuses them.) A limb can be a tree address, like `+3` or
|
||||
`.`, or a label like `foo`. We can combine them in one wing:
|
||||
```
|
||||
~tasfyn-partyv:dojo> bar.foo.+3:test
|
||||
7
|
||||
```
|
||||
It's important to note the difference between `bar.foo:test`
|
||||
and `bar:foo:test`, even though they produce the same product:
|
||||
```
|
||||
~tasfyn-partyv:dojo> bar:foo:test
|
||||
7
|
||||
```
|
||||
`bar.foo` is one twig, which we run on the product of `test`.
|
||||
That's different from running `bar` on the product of `foo` on
|
||||
the product of `test`.
|
||||
|
||||
> You're probably used to name resolution in variable scopes
|
||||
and flat records, but not in trees. Partly this is because the
|
||||
tradition in language design is to prefer semantics that make it
|
||||
easy to build simple symbol tables, because linear search of a
|
||||
nontrivial tree is a bad idea on '80s hardware.
|
||||
|
||||
## Mutation
|
||||
|
||||
Mutation? Well, not really. We can't modify nouns; the concept
|
||||
doesn't even make sense in Hoon (or Nock).
|
||||
|
||||
Rather, we build new nouns which are copies of old ones, but
|
||||
with mutations. Let's build a "mutated" copy of our test noun:
|
||||
```
|
||||
~tasfyn-partyv:dojo> test
|
||||
[[[8 9] 5] foo=[6 bar=7]]
|
||||
~tasfyn-partyv:dojo> test(foo 42)
|
||||
[[[8 9] 5] foo=42]
|
||||
~tasfyn-partyv:dojo> test(+8 %eight, bar.foo [%hello %world])
|
||||
[[[%eight 9] 5] foo=[6 [%hello %world]]]
|
||||
```
|
||||
As we see, there's no need for the mutant noun to be shaped
|
||||
anything like the old noun. They're different nouns.
|
||||
|
||||
A mutation, like `+8 %eight`, specifies a wing and a twig.
|
||||
The wing, like `+8` or `bar.foo`, defines a leg to replace.
|
||||
The twig runs against the original subject.
|
||||
|
||||
Can we use mutation to build a cyclical noun? Nice try, but no:
|
||||
```
|
||||
~tasfyn-partyv:dojo> test(+8 test)
|
||||
[[[[[[8 9] 5] foo=[6 bar=7]] 9] 5] foo=[6 bar=7]]
|
||||
```
|
||||
|
||||
## Progress
|
||||
|
||||
Now, not only can you build a noun, you can get data out of it and
|
||||
even evolve new, related nouns. We've still seen only two very
|
||||
restricted kinds of twigs: constants and legs. In the [next chapter](2-syntax), we'll actually write some interesting expressions.
|
@ -1,475 +0,0 @@
|
||||
---
|
||||
next: false
|
||||
sort: 2
|
||||
spam: true
|
||||
title: Hoon 101.2: syntax
|
||||
---
|
||||
# Hoon 101.2: full-contact syntax
|
||||
|
||||
In [chapter 0](0-nouns), we read about nouns. In [chapter 1](1-twigs),
|
||||
we discovered twigs and legs.
|
||||
|
||||
Up till now, we've done everything in the dojo, Hoon's shell /
|
||||
REPL. Now it's time to actually write a real Hoon source file,
|
||||
and get a bit deeper into the syntax.
|
||||
|
||||
## How to use this tutorial
|
||||
|
||||
Ideally, you've installed an Urbit planet (if you have a ticket)
|
||||
or comet (if you don't). See the [user doc](../../../user).
|
||||
|
||||
We recommend opening up the dojo and just typing the examples;
|
||||
you don't know a language until you know it in your fingers.
|
||||
Also, make sure you've worked through the chapters in order.
|
||||
|
||||
## Building a simple generator
|
||||
|
||||
In Urbit there's a variety of source file roles, distinguished by
|
||||
the magic paths they're loaded from: `/gen` for generators,
|
||||
`/ape` for appliances, `/lib` for libraries, etc.
|
||||
|
||||
We'll start with a generator, the simplest kind of Urbit program.
|
||||
|
||||
### Create a sandbox desk
|
||||
|
||||
A desk is the Urbit equivalent of a `git` branch. We're just
|
||||
playing around here and don't intend to soil our `%home` desk with
|
||||
test files. So let's make a sandbox:
|
||||
```
|
||||
|sync %sandbox our %home
|
||||
```
|
||||
|
||||
You just merged the `%home` desk on your own ship into a new
|
||||
`%sandbox` desk. `%sandbox` has everything in `%home`, but we'll
|
||||
add more. Future changes in `%home` (such as our over-the-air
|
||||
updates) will also propagate into `%sandbox`.
|
||||
|
||||
> Desks are always born in merges; it makes no sense to create an
|
||||
empty desk, because anything you do in a desk depends on other
|
||||
files in the desk. For instance, your file types (marks) are
|
||||
defined by source files in the same desk.
|
||||
|
||||
### Mount the sandbox from Unix
|
||||
|
||||
Run the command
|
||||
```
|
||||
~tasfyn-partyv:dojo> |mount /=sandbox=/gen %gen
|
||||
```
|
||||
This mounts the `/gen` folder from the `%sandbox` desk in your Unix
|
||||
directory `~/tasfyn-partyv/gen`.
|
||||
|
||||
The mount is a two-way sync, "Dropbox style." When you edit a
|
||||
Unix file and save, your edit is automatically committed as a
|
||||
change in the `%sandbox` desk. If you change `%sandbox` files
|
||||
from Urbit, these changes will also propagate to Unix.
|
||||
|
||||
### Execute from the sandbox
|
||||
|
||||
Let's set the dojo desk to `%sandbox`:
|
||||
```
|
||||
~tasfyn-partyv:dojo> =dir /=sandbox=
|
||||
=% /~tasfyn-partyv/sandbox/~2015.11.13..02.49.37..9e6c/
|
||||
```
|
||||
Your prompt will change to:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox
|
||||
```
|
||||
|
||||
### Write hello, world
|
||||
|
||||
Let's build the simplest possible kind of generator, a builder.
|
||||
|
||||
First, configure your favorite Unix text editor to work with
|
||||
Hoon. There are Hoon modes for vim, emacs and Sublime in the
|
||||
`extras/` directory of the github repo.
|
||||
|
||||
Second, create the file `~/tasfyn-partyv/gen/test.hoon`.
|
||||
Paste this text into it:
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
[%hello %world]
|
||||
```
|
||||
Get the spaces exactly right, please. Hoon is not in general a
|
||||
whitespace-sensitive language, but the difference between one space and
|
||||
two-or-more matters. And for the moment, think of
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
```
|
||||
as gibberish boilerplate, like `#include "stdio.h"` at the start of a C
|
||||
program.
|
||||
|
||||
Now, run your builder:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> +test
|
||||
[%hello %world]
|
||||
```
|
||||
This is your first Hoon *program* per se. Congrats!
|
||||
|
||||
## Hoon syntax 101
|
||||
|
||||
But what's up with this syntax?
|
||||
|
||||
### Some syntactic relatives
|
||||
|
||||
The relationship between ASCII and human programming languages
|
||||
is like the relationship between the electric guitar and
|
||||
rock-and-roll. If it doesn't have a guitar, it's not rock.
|
||||
If it doesn't use ASCII, it's not a programming language.
|
||||
|
||||
Some great rock guitarists play three chords, like Johnny Ramone;
|
||||
some shred it up, like Jimmy Page. If Lisp is the Ramones of
|
||||
syntax, Perl or APL is Led Zeppelin. No one has any right to rag
|
||||
on Perl or APL, but Hoon is a "metalhead" language that shreds
|
||||
its ASCII very differently.
|
||||
|
||||
### The case for heavy metal
|
||||
|
||||
The philosophical case for a metalhead language is threefold.
|
||||
One, human beings are much better at associating meaning with
|
||||
symbols than they think they are. Two, a programming language is
|
||||
a professional tool and not a plastic beach shovel.
|
||||
|
||||
> "There's a guitar player, a harp player, a double-bass player,
|
||||
all holding up their blisters. Imagine if you downloaded a
|
||||
library off the internet... and it gave you blisters! Right? The
|
||||
horror! And yet... every musician has overcome a barrier to entry
|
||||
similar to this." — Rich Hickey
|
||||
|
||||
And three, the alternative to heavy metal is keywords. When you
|
||||
use a keyword language, not only are you forcing the programmer
|
||||
to tiptoe around a ridiculous maze of reserved words. You're
|
||||
expressing your program through two translation steps:
|
||||
symbol->English and English->computation.
|
||||
|
||||
When you shred, you are going direct: symbol->computation. A
|
||||
pure-functional language with syntax on the metalhead principle
|
||||
creates a sense of "seeing the function" which no keyword
|
||||
language can quite duplicate. Also, all the words you see on the
|
||||
screen are actually meaningful terms in the program.
|
||||
|
||||
But a great metalhead language should *not* be user-extensible.
|
||||
That way lies King Crimson. (Maybe Haskell is King Crimson: the
|
||||
prog-rock of programming languages.) A language is a standard;
|
||||
if users can do whatever with ASCII, there is no standard. If a
|
||||
metal language can work, it's only by rigorous consistency and
|
||||
predictability. No macros, operator overloading, etc, etc.
|
||||
|
||||
### A glyphic bestiary
|
||||
|
||||
Any metalhead language you don't yet know is line noise. Let's
|
||||
get you up to speed as fast as possible.
|
||||
|
||||
A programming language needs to be not just read but said. But
|
||||
no one wants to say "ampersand." Therefore, we've taken the
|
||||
liberty of assigning three-letter names to all ASCII glyphs.
|
||||
|
||||
Some of these bindings are obvious and some aren't. You'll be
|
||||
genuinely surprised at how easy they are to remember:
|
||||
```
|
||||
ace [1 space] gal < pel (
|
||||
bar | gap [>1 space, nl] per )
|
||||
bas \ gar > sel [
|
||||
buc $ hax # sem ;
|
||||
cab _ hep - ser ]
|
||||
cen % kel { soq '
|
||||
col : ker } tar *
|
||||
com , ket ^ tec `
|
||||
doq " lus + tis =
|
||||
dot . pam & wut ?
|
||||
fas / pat @ zap !
|
||||
```
|
||||
It's fun to confuse the muggles by using these outside Urbit.
|
||||
|
||||
Hoon is not whitespace-sensitive, except that its grammar defines
|
||||
two distinct whitespace tokens: `ace`, a single space, and `gap`,
|
||||
anything else. `\t`, `\r`, and `\l` choke the parser and should
|
||||
not appear in your file.
|
||||
|
||||
A few digraphs also have irregular sounds:
|
||||
```
|
||||
== stet
|
||||
-- shed
|
||||
++ slus
|
||||
-> lark
|
||||
-< lush
|
||||
+> dark
|
||||
+< dish
|
||||
```
|
||||
|
||||
You might remember wondering where the "lark syntax" of chapter 1
|
||||
got its name. Lark syntax is read in digraphs from the left, so
|
||||
`+>+` is `darklus`.
|
||||
|
||||
> `+>+` is of course `cdddr` in Lisp.
|
||||
|
||||
### The shape of a twig
|
||||
|
||||
As we learned in chapter 1, a twig - the parsed form of a Hoon
|
||||
expression - is a noun. As usual in Hoon, the easiest way to
|
||||
explain both the syntax that compiles into that noun, and the
|
||||
semantic meaning of the noun, is the noun's physical structure.
|
||||
|
||||
#### Autocons
|
||||
|
||||
A twig is always a cell, and any cell of twigs is a twig
|
||||
producing a cell. As an homage to Lisp, we call this
|
||||
"autocons."
|
||||
|
||||
Where you'd write `(cons a b)` in Lisp, you write `[a b]` in
|
||||
Hoon. The Lisp expression, in Hoon syntax, would be `[%cons a b
|
||||
~]`. But the Hoon twig is just `[a b]`.
|
||||
|
||||
The `???` prefix prints a twig as a noun instead of running it.
|
||||
Let's see autocons in action:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> ??? 42
|
||||
[%dtzy p=%ud q=42]
|
||||
~tasfyn-partyv:dojo/sandbox> ??? 0x2a
|
||||
[%dtzy p=%ux q=42]
|
||||
~tasfyn-partyv:dojo/sandbox> ??? [42 0xa]
|
||||
[[%dtzy p=%ud q=42] [%dtzy p=%ux q=42]]
|
||||
```
|
||||
|
||||
#### The stem-bulb pattern
|
||||
|
||||
If the head of your twig is a cell, it's an autocons. If the
|
||||
head is an atom, it's an unpronounceable four-letter symbol like
|
||||
the `%dtzy` above.
|
||||
|
||||
Except for the funny autocons case, twigs have the same shape
|
||||
we see in the `span` mold, which we met in chapter 0. It's
|
||||
essentially a variant record, the most common data structure
|
||||
ever. In Hoon it's called a *kelp*.
|
||||
|
||||
The head of a kelp (like `%dtzy` above) is called the *stem*.
|
||||
The tail (like `[%ux 42]`) is the *bulb*.
|
||||
|
||||
> Think about how to encode tagged data in a noun. It seems
|
||||
obvious that the noun is a cell, where the head of the cell is
|
||||
the tag (stem) and the tail is the data (bulb). Then, all these
|
||||
nouns are cells whose head is an atom. This leaves two noun
|
||||
shapes "out of band": atoms, and cells whose head is a cell.
|
||||
|
||||
> Since no twig is an atom, a cell `[twig twig]` is always a cell
|
||||
whose head is a cell. So we can distinguish "autocons" from all
|
||||
stem-bulb nouns, and assign it specific semantics.
|
||||
|
||||
#### Runes and stems
|
||||
|
||||
A *rune* is a digraph - a sequence of two ASCII glyphs. If you
|
||||
know C, you know digraphs like `!=` and `?:` and are used to
|
||||
reading them as single characters.
|
||||
|
||||
In Hoon you can *say* runes as words: "zaptis" and "wutcol"
|
||||
respectively. If we had to say "exclamation point equals" and
|
||||
"question-colon" all the time, we'd just die.
|
||||
|
||||
Most twig stems are made from runes, by concatenating the glyph
|
||||
names and removing the vowels. For example, the rune `=+`,
|
||||
pronounced "tislus," becomes the stem `%tsls`. (Note that in
|
||||
most noun implementations, this is a 31-bit direct value.)
|
||||
|
||||
> Some twig stems (like `%dtzy`) are not runes, simply because
|
||||
they don't have regular-form syntax and don't need to use
|
||||
precious ASCII real estate. They are otherwise no different.
|
||||
|
||||
An important point to note about runes: they're organized. The
|
||||
first glyph in the rune defines a category. For instance, runes
|
||||
starting with `.` compute intrinsics; runes starting with `|`
|
||||
produce cores; etc.
|
||||
|
||||
Another important point about runes: they come in two flavors,
|
||||
"natural" (stems interpreted directly by the compiler) and
|
||||
"synthetic" (macros, essentially).
|
||||
|
||||
> Language food fight warning: one advantage of Hoon over Lisp
|
||||
is no gensyms. All Hoon macros are perfectly hygienic. Another
|
||||
advantage is that Hoon has no (user-level) macros. In Hoon
|
||||
terms, nobody gets to invent their own runes, because that way
|
||||
lies DSL write-only chaos. But if we had user-level macros,
|
||||
they'd be perfectly hygienic as well.
|
||||
|
||||
#### Tall and wide regular forms
|
||||
|
||||
A good rune example is the simple rune `=+`, pronounced "tislus",
|
||||
which becomes the stem `%tsls`. A `%tsls` twig has the mold
|
||||
`[%tsls p=twig q=twig]`.
|
||||
|
||||
The very elegance of functional languages creates a visual
|
||||
problem that imperative languages lack. An imperative language
|
||||
has distinct statements (with side effects) and (usually pure)
|
||||
expressions; it's natural that in most well-formatted code,
|
||||
statements flow vertically down the screen, and expressions grow
|
||||
horizontally across this. This interplay creates a natural and
|
||||
relaxing shape on your screen.
|
||||
|
||||
In a functional language, there's no difference. The trivial
|
||||
functional syntax is Lisp's, which has two major problems. One:
|
||||
piles of expression terminators build up at the bottom of complex
|
||||
functions. Two: the natural shape of code is diagonal. The more
|
||||
complex a function, the more it wants to besiege the right
|
||||
margin. The children of a node have to start to the right of its
|
||||
parent, so the right margin bounds the tree depth.
|
||||
|
||||
Hoon does not completely solve these problems, but alleviates
|
||||
them. In Hoon, there are actually two regular syntax forms for
|
||||
most twig cases: "tall" and "wide" form. Tall twigs can contain
|
||||
wide twigs, but not vice versa, so the visual shape of a program
|
||||
is very like that of a statements-and-expressions language.
|
||||
|
||||
Also, in tall mode, most runes don't need terminators. Take
|
||||
`=+`, for example. Since the parser knows to expect exactly
|
||||
two twigs after the `=+` rune, it doesn't need any extra syntax
|
||||
to tell it that it's done.
|
||||
|
||||
Let's try a wide `=+` in the dojo:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> =+(planet=%world [%hello planet])
|
||||
[%hello %world]
|
||||
```
|
||||
(`=+` seems to be some sort of variable declaration? Let's not
|
||||
worry about it right now. We're on syntax.)
|
||||
|
||||
The wide syntax for a `=+` twig, or any binary rune: `(`, the
|
||||
first subtwig, one space, the second subtwig, and `)`). To read
|
||||
this twig out loud, you'd say:
|
||||
```
|
||||
tislus pel planet tis cen world ace sel cen hello ace planet ser per
|
||||
```
|
||||
> Various colloquialisms inevitably creep into this usage. "tis" not
|
||||
in a rune gets contracted to "is"; "ace" is often just assumed; etc.
|
||||
|
||||
Let's try a tall `=+` in `test.hoon`:
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
=+ planet=%world
|
||||
[%hello planet]
|
||||
```
|
||||
The tall syntax for a `=+` twig, or any binary rune: the rune, at
|
||||
least two spaces or one newline, the first subtwig, at least two
|
||||
spaces or one newline, the second subtwig. Again, tall subtwigs
|
||||
can be tall or wide; wide subtwigs have to be wide.
|
||||
|
||||
(Note that our boilerplate line is a bunch of tall runes on one
|
||||
line, with two-space gaps. This is unusual but quite legal, and
|
||||
not to be confused with the actual wide form.)
|
||||
|
||||
To read this twig out loud, you'd say:
|
||||
```
|
||||
tislus gap planet is cen world gap nep cen hello ace planet pen
|
||||
```
|
||||
#### Layout conventions
|
||||
|
||||
Should you use wide twigs or tall twigs? When? How? What
|
||||
should your code look like? You're the artist. Except for the
|
||||
difference between one space (`ace`) and more space (`gap`), the
|
||||
parser doesn't care how you format your code. Hoon is not Go --
|
||||
there are no fixed rules for doing it right.
|
||||
|
||||
> Keep lines under 80 characters, though. The parser doesn't
|
||||
enforce this yet. But it will, so watch out!
|
||||
|
||||
#### Backstep indentation
|
||||
|
||||
Note that the "variable declaration" metaphor of `=+` works
|
||||
perfectly here. Because `[%hello planet]` -- despite being a
|
||||
subtree of the the `=+` twig -- is at the same indent level. A
|
||||
variable declaration shouldn't add indent depth. And `=+`
|
||||
doesn't. Our code flows down the screen, not down and to the
|
||||
right, and of course there are no superfluous terminators.
|
||||
|
||||
Another example, using a ternary rune with a strange resemblance
|
||||
to C:
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
=+ planet=%world
|
||||
?: =(%world planet)
|
||||
[%hello planet]
|
||||
[%goodbye planet]
|
||||
```
|
||||
This is called "backstep" indentation. Not all the children of
|
||||
`?:` ("wutcol", `%wtcl`) are at the same indent as the parent;
|
||||
but one of them is.
|
||||
|
||||
It's not always the case when backstepping that the largest
|
||||
subtwig is at the bottom and loses no indent, but it often is.
|
||||
And we do a lot to help you maintain this.
|
||||
|
||||
For instance, `=+` ("tislus") is a binary rune: `=+(a b)`. In
|
||||
most cases of `=+` the heavy twig is `b`, but sometimes it's `a`.
|
||||
So we can use its friend the `=-` rune ("tishep") to get the same
|
||||
semantics with the right shape: `=-(b a)`. Similarly, instead of
|
||||
`?:(a b c)`, we can write `?.(a c b)`.
|
||||
|
||||
Not all runes have tuple structure; some are n-ary, and use
|
||||
the `==` terminator (again, pronounced "stet"):
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
=+ planet=%world
|
||||
?+ planet
|
||||
[%unknown planet]
|
||||
%world [%hello planet]
|
||||
%ocean [%goodbye planet]
|
||||
==
|
||||
```
|
||||
So we occasionally lose right-margin as we descend a deep twig.
|
||||
But we can keep this lossage low with good layout design.
|
||||
|
||||
#### Irregular forms
|
||||
|
||||
There are more regular forms than we've shown above, but not a
|
||||
lot more. Hoon would be quite easy to learn if it was only its
|
||||
regular forms. It wouldn't be as easy to read or use, though.
|
||||
The learning curve is important, but not all-important.
|
||||
|
||||
Some stems (like the `%dtzy` constants above) obviously don't and
|
||||
can't have any kind of regular form (which is why `%dtzy` is not
|
||||
a real digraph rune). Many of the true runes have only regular
|
||||
forms. But some have irregular forms. Irregular forms are
|
||||
always wide, but there is no other constraint on their syntax.
|
||||
|
||||
We've already encountered one of the irregular forms: `foo=42`
|
||||
from the last chapter, and `planet=%world` here. Let's unpack
|
||||
this twig:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> ?? %world
|
||||
[%cube 431.316.168.567 %atom %tas]
|
||||
%world
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> ??? %world
|
||||
[%dtzz %tas 431.316.168.567]
|
||||
```
|
||||
Clearly, `%dtzz` is one of our non-regulars. But we can wrap it
|
||||
with our irregular form:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> ?? planet=%world
|
||||
[%face %planet [%cube 431.316.168.567 %atom %tas]]
|
||||
planet=%world
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> ??? planet=%world
|
||||
[%ktts %planet %dtzz %tas 431.316.168.567]
|
||||
```
|
||||
Since `%ktts` is "kettis", ie, `^=`, this has to be the irregular
|
||||
form of
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> ^=(planet %world)
|
||||
planet=world
|
||||
```
|
||||
So if we wrote our example without this irregular form, it'd be
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
=+ ^=(planet %world)
|
||||
[%hello planet]
|
||||
```
|
||||
Or with a gratuitous use of tall form:
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
=+ ^= planet %world
|
||||
[%hello planet]
|
||||
```
|
||||
## Progress
|
||||
|
||||
Now you know how to read Hoon! For fun, try to pronounce more of
|
||||
the code on this page. Please don't laugh too hard at yourself.
|
||||
|
||||
In the [next chapter](3-program), we'll actually write a real program...
|
@ -1,350 +0,0 @@
|
||||
---
|
||||
next: false
|
||||
sort: 3
|
||||
spam: true
|
||||
title: Hoon 101.3: an algorithm
|
||||
---
|
||||
# Hoon 101.3: an algorithm
|
||||
|
||||
In [chapter 0](0-nouns), we read about nouns. In [chapter 1](1-twigs),
|
||||
we discovered twigs and legs. In [chapter 2](2-syntax), we learned
|
||||
Hoon syntax and created our first source file.
|
||||
|
||||
Now it's time for an actual, meaningful *algorithm*.
|
||||
|
||||
## How to use this tutorial
|
||||
|
||||
Ideally, you've installed an Urbit planet (if you have a ticket)
|
||||
or comet (if you don't). See the [user doc](../../../user).
|
||||
|
||||
We recommend opening up the dojo and just typing the examples;
|
||||
you don't know a language until you know it in your fingers.
|
||||
Also, make sure you've worked through the chapters in order.
|
||||
|
||||
## Goal: a decrement generator
|
||||
|
||||
Our algorithm is the classic Urbit example: decrement.
|
||||
|
||||
If you learned [Nock](../../nock) before Hoon, you've already
|
||||
written decrement. If not, all you need to know is that the only
|
||||
built-in arithmetic operator in Nock is increment. To decrement,
|
||||
we need to count up to the result with a simple loop.
|
||||
|
||||
## A practical subject
|
||||
|
||||
As we've seen, Hoon works by running a twig against a subject.
|
||||
In chapter 1, we made a simple test subject that was just a few
|
||||
constants, and applied some simple twigs to it.
|
||||
|
||||
This time, we'll actually put useful working data in the subject,
|
||||
building up more and more complex subjects as we go.
|
||||
|
||||
## Subject: nil
|
||||
|
||||
We'll start with the empty subject `~`:
|
||||
```
|
||||
:- %say |= * :- %noun
|
||||
=> ~
|
||||
[%hello %world]
|
||||
```
|
||||
The `=>` rune ("tisgar", `%tsgr`)), for `=>(p q)` executes `p`
|
||||
against the subject, then uses that product as the subject of
|
||||
`q`.
|
||||
|
||||
> We've already used an irregular form of `=>`, or to be more
|
||||
precise its mirror `=<` ("tisgal", `%tsgl`). In chapter 1, when we wrote
|
||||
`+3:test`, we meant `=>(test +3)` or `=<(+3 test)`.
|
||||
|
||||
What is `~`? It's Hoon `nil`, a zero atom:
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> ?? ~
|
||||
[%cube 0 [%atom %n]]
|
||||
~
|
||||
```
|
||||
We use `~` for list terminators and the like. Obviously, since
|
||||
`[%hello %world]` is just a constant, a nil subject works as
|
||||
well as any:
|
||||
|
||||
```
|
||||
~tasfyn-partyv:dojo/sandbox> +test
|
||||
[%hello %world]
|
||||
```
|
||||
|
||||
## Subject: `arg=@`
|
||||
|
||||
Above, we used an empty subject to avoid the very complex,
|
||||
interesting subject your generator twig gets by default.
|
||||
|
||||
But a decrement generator needs to get an argument from the
|
||||
command line -- the number we're trying to decrement.
|
||||
|
||||
This involves changing the `test.hoon` boilerplate a little.
|
||||
Again, don't worry about the boilerplate line just yet:
|
||||
```
|
||||
:- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=> arg=arg
|
||||
[%hello arg]
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
[%hello 42]
|
||||
```
|
||||
> `=> arg=arg` looks a little odd. We wouldn't ordinarily do
|
||||
this; we're just trying to keep the subject simple.
|
||||
|
||||
In case there's any doubt about the subject (remember from
|
||||
chapter 1 that `.` means `+1`, the whole subject):
|
||||
```
|
||||
:- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=> arg=arg
|
||||
.
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
arg=42
|
||||
```
|
||||
|
||||
## An increment generator
|
||||
|
||||
We can even write a trivial increment generator using `.+`,
|
||||
or even better its irregular form `+`:
|
||||
```
|
||||
:- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=> arg=arg
|
||||
+(arg)
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
43
|
||||
```
|
||||
We'll assume these same first two lines for the rest of the
|
||||
examples in this chapter.
|
||||
|
||||
## Cores: one more kind of span
|
||||
|
||||
To decrement, we need a loop. To write a loop, we need yet
|
||||
another kind of noun: the *core*. Briefly, a core is a `[code
|
||||
data]` pair. Our new `span` mold:
|
||||
```
|
||||
++ span
|
||||
$% [%atom p=@tas]
|
||||
[%cell p=span p=span]
|
||||
[%core p=span q=(map ,@tas twig)]
|
||||
[%cube p=* q=span]
|
||||
[%face p=@tas q=span]
|
||||
==
|
||||
```
|
||||
|
||||
### Structure of a core
|
||||
|
||||
The core is a cell `[battery payload]`. The payload is data, the
|
||||
battery is code -- a tree of Nock formulas.
|
||||
|
||||
In the `%core` span, the payload is described by an arbitrary
|
||||
span. The battery is described by a map of symbol to twig.
|
||||
|
||||
> Yes, the span contains the complete AST of the whole core.
|
||||
This is a very different approach from most typed languages,
|
||||
which compute function signatures. To infer the product of an
|
||||
arm, we retrace the code in theory, but cache in practice.
|
||||
|
||||
### Arms are computed attributes
|
||||
|
||||
How do we use a core? Remember that Nock is a function
|
||||
```
|
||||
Nock(subject formula) -> product
|
||||
```
|
||||
To activate a core, we pull one formula from the battery, and
|
||||
execute with the whole core as the subject. Coincidentally,
|
||||
Nock has one macro instruction, `9`, that does just this.
|
||||
|
||||
So the formula defines an arbitrary function on the core. The
|
||||
name of this function (as defined in the twig map) is a computed
|
||||
attribute, or *arm*.
|
||||
|
||||
> Is a core an object? Not quite, because an arm is not a method.
|
||||
Methods in an OO language have arguments. Arms are functions
|
||||
only of the payload. (A method in Hoon is an arm that produces a
|
||||
gate, which is another core -- but we're getting too far ahead.)
|
||||
However, the battery does look a lot like a classic "vtable."
|
||||
|
||||
### Arms and wing resolution
|
||||
|
||||
It might be a good time to brush up on your [chapter 1](1-twigs).
|
||||
The wing resolution algorithm gets a little more complicated.
|
||||
|
||||
Hoon overloads computed attributes (arms) and literal attributes
|
||||
(legs) in the same namespace. A label in a wing may refer to
|
||||
either. when searching a core, we look for a matching arm. If
|
||||
we find it we're done. If we don't, or if a `^` mark makes us
|
||||
skip, we search into the payload.
|
||||
|
||||
Only the last limb in the wing can activate an arm. If a name
|
||||
resolves to a core arm, but it's not the last limb in the wing,
|
||||
the arm produces the core itself. Similarly, when the wing is
|
||||
not an access but a mutation, the arm refers to the core. Only
|
||||
the end of the wing is activated.
|
||||
|
||||
> Suppose `foo` is a core. `bar` is an arm on foo. Then `bar.foo`
|
||||
computes the `bar` arm. Perhaps the product is another core.
|
||||
Even if `moo` is an arm in this new core, `bar.foo`, the wing
|
||||
`moo.bar.foo` does not compute `moo` on the core `bar.foo`.
|
||||
Instead, it looks for `moo` within the payload of the core `foo`.
|
||||
(You're looking for `moo:bar.foo`, ie, `=>(bar.foo moo)`.)
|
||||
|
||||
Does this sound too tricky? Hopefully not, but it's about the
|
||||
most complicated semantic rule you'll find in Hoon.
|
||||
|
||||
## Increment with a core
|
||||
|
||||
Keeping our two-line boilerplate, let's increment with a core:
|
||||
```
|
||||
=< inc
|
||||
|%
|
||||
++ inc
|
||||
+(arg)
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
43
|
||||
```
|
||||
What's going on? We used the `|%` rune ("barcen") to produce a
|
||||
core. (There are a lot of runes which create cores; they all
|
||||
start with `|`, and are basically macros that turn into `|%`.)
|
||||
|
||||
The payload of a core produced with `|%` is the subject with
|
||||
which `|%` is compiled. We might say that `|%` wraps a core
|
||||
around its subject. In this case, the subject of the `|%`,
|
||||
and thus payload, is our `arg=@ud` argument.
|
||||
|
||||
Then we used this core as the subject of the simple wing `inc`.
|
||||
|
||||
> Remember that `=<(a b)` is just `=>(b a)`. The core is heavy
|
||||
and `inc` is light, so we use `=<` to put the heavy part last.
|
||||
|
||||
The prettyprinter can even print a core, sort of. Take out the
|
||||
`=< inc`:
|
||||
```
|
||||
|%
|
||||
++ inc
|
||||
+(arg)
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
<1.bgq arg=42>
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> ? +test 42
|
||||
<1.bgq arg=@ud>
|
||||
<1.bgq arg=42>
|
||||
```
|
||||
In this notation, `1` means the number of arms in the core, `bgq`
|
||||
is a very short fingerprint, and `arg=42` is the payload (and
|
||||
`arg=@ud` is the payload span).
|
||||
|
||||
> Cores can be large and complex, and we obviously can't render all
|
||||
the data in them, either when printing a type or a value. At
|
||||
some point, you'll probably make the mistake of printing a big
|
||||
core, maybe even the whole kernel, as an untyped noun. Just
|
||||
press ^C.
|
||||
|
||||
## Adding a counter
|
||||
|
||||
To decrement, we need to count up to the argument. So we need a
|
||||
counter in our subject, because where else would it go?
|
||||
|
||||
Let's change the subject to add a counter, `pre`:
|
||||
```
|
||||
=> [pre=0 .]
|
||||
=< inc
|
||||
|%
|
||||
++ inc
|
||||
+(arg)
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
43
|
||||
```
|
||||
Once again, `.` is the whole subject, so we're wrapping it in a
|
||||
cell whose head is `pre=0`. This doesn't change the way we use
|
||||
`arg`, even though it's one level deeper in the subject tree.
|
||||
Let's look at the subject again:
|
||||
```
|
||||
=> [pre=0 .]
|
||||
.
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
[pre=0 arg=42]
|
||||
~tasfyn-partyv:dojo/sandbox> ? +test 42
|
||||
[pre=@ud arg=@ud]
|
||||
[pre=0 arg=42]
|
||||
```
|
||||
There's a less cluttered way to write `=>([a .] b)`. In wide
|
||||
mode, `=+(a b)`. A tall example:
|
||||
```
|
||||
=+ pre=0
|
||||
.
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
[pre=0 arg=42]
|
||||
```
|
||||
This rune `=+`, "tislus", `%tsls`, is of course the "variable
|
||||
declaration" we saw in chapter 2.
|
||||
|
||||
## We actually decrement
|
||||
|
||||
Now we can write our actual decrement program, combining the
|
||||
features we've explored above:
|
||||
```
|
||||
=+ pre=0
|
||||
=< dec
|
||||
|%
|
||||
++ dec
|
||||
?: =(arg +(pre))
|
||||
pre
|
||||
dec(pre +(pre))
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
41
|
||||
```
|
||||
`=(a b)` is an irregular form of `.=(a b)`, ie, "dottis" or the
|
||||
noun `[%dtts a b]`. Likewise, `+(a)` is `.+(a)`, ie, "dotlus"
|
||||
or `[%dtls a]`.
|
||||
|
||||
`?:`, "wuttis", `%wtts`, does exactly what it does in C.
|
||||
|
||||
The real action is in `dec(pre +(pre))`. We saw this same
|
||||
mutation form in chapter 1. It's an irregular form of the `%=`
|
||||
rune, "centis", `%cnts`.
|
||||
|
||||
Here, of course, we're computing an arm of a mutated core. We're
|
||||
recomputing the loop arm, `dec`, against a new core with an
|
||||
incremented `pre` leg. Basically, everything interesting in Hoon
|
||||
happens when you compute an arm of a mutated core.
|
||||
|
||||
The whole program, using only regular forms, wide and tall:
|
||||
```
|
||||
=+ ^=(pre 0)
|
||||
=< dec
|
||||
|%
|
||||
++ dec
|
||||
?: .=(arg .+(pre))
|
||||
pre
|
||||
%= dec
|
||||
pre .+(pre)
|
||||
==
|
||||
--
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
41
|
||||
```
|
||||
A good illustration of why we need irregular forms.
|
||||
|
||||
## Progress
|
||||
|
||||
Now we've actually done something useful. Well, if you count
|
||||
O(n) decrement as something useful.
|
||||
|
||||
We've actually seen most of the major tools in Hoon's toolbox,
|
||||
just in a super-minimalist selection. But we'll need a few more
|
||||
runes to get to something that looks like real programming.
|
||||
|
||||
For instance, we have a decrement algorithm, but we don't have a
|
||||
decrement *function* - in the Hoon sense of the word, anyway. We
|
||||
don't see `(dec arg)` in this code. That'll be the next chapter.
|
@ -1,327 +0,0 @@
|
||||
---
|
||||
next: false
|
||||
sort: 4
|
||||
spam: true
|
||||
title: Hoon 101.4: functions
|
||||
---
|
||||
# Hoon 4: toward actual functions
|
||||
|
||||
In [chapter 0](0-nouns), we read about nouns. In [chapter 1](1-twigs),
|
||||
we discovered twigs and legs. In [chapter 2](2-syntax), we learned
|
||||
Hoon syntax and created our first source file. In [chapter 3](3-algorithm)
|
||||
we wrote an actual algorithm.
|
||||
|
||||
Now we'll go a step farther and actually define a *function*.
|
||||
|
||||
## Goal: `(decrement arg)`
|
||||
|
||||
Of course, Hoon is a functional language and every twig defines a
|
||||
function of the subject. But we haven't seen the Hoon equivalent
|
||||
of a function *declaration*. Where is Lisp `defun`?
|
||||
|
||||
Also, the Hoon equivalent of a normal function call can't just
|
||||
involve compiling the function into a Nock formula, whose subject
|
||||
is the function's argument. As Einstein said, everything must be
|
||||
as simple as possible, but no simpler.
|
||||
|
||||
A function that worked this way would, by definition, have no
|
||||
access to data or code other than the argument. Where would the
|
||||
standard library go? Would we have to pass it in the argument?
|
||||
|
||||
## Form of the solution
|
||||
|
||||
Let's get the boilerplate out of the way. We'll keep the same
|
||||
external generator interface, but our solution will look like:
|
||||
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
(decrement arg)
|
||||
=> ~
|
||||
!!
|
||||
```
|
||||
In place of the `!!`, we'll put a core, effectively a library,
|
||||
that exports a function `decrement`. We'll then call that
|
||||
function with `(decrement arg)`, an irregular form of
|
||||
`%-(decrement arg)`. Again, this core uses `=> ~` to clear
|
||||
the subject, so we can't cheat and call `(dec arg)`.
|
||||
|
||||
> `!!`, or "zapzap" or `[%zpzp ~]`, is a twig that
|
||||
always crashes. Because it produces the empty span (`%void`), it
|
||||
doesn't cause type inference problems.
|
||||
|
||||
## Not quite a function call
|
||||
|
||||
As usual, we'll get to our goal gradually. A first try:
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=+ gat=decrement
|
||||
=<(run gat(sam arg))
|
||||
=> ~
|
||||
|%
|
||||
++ decrement
|
||||
=+ sam=0
|
||||
=+ pre=0
|
||||
|%
|
||||
++ run
|
||||
?: =(sam +(pre))
|
||||
pre
|
||||
run(pre +(pre))
|
||||
--
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
41
|
||||
```
|
||||
This works, but it's hardly concise or pretty. We'll get there.
|
||||
|
||||
We replaced the `!!` with a `|%` twig that produces a library
|
||||
core. The payload of our library core is `~`, because that's the
|
||||
subject we sent in. The battery contains one arm, `decrement`.
|
||||
|
||||
The `decrement` arm produces an inner core. The payload of this
|
||||
inner core is `[pre=0 sam=0 +>]`, where `+>` is the library core.
|
||||
The battery of the inner core has one arm, `run`, which computes
|
||||
our algorithm from the last chapter.
|
||||
|
||||
To run our algorithm, we put the core that `decrement` produces
|
||||
into a new leg, `gat`. Mutating this core to set `sam` to our
|
||||
argument `arg`, we evaluate the `run` arm.
|
||||
|
||||
> Why do we need this `gat` leg? Why can't we just write `=<(run
|
||||
decrement(sam arg))`? Remember our `moo:bar.foo` problem from
|
||||
the previous chapter. `decrement(sam arg)` mutates not the
|
||||
*product* of the decrement arm, but the core that computes it.
|
||||
There's no `sam` in that subject, so the twig won't compile.
|
||||
|
||||
## Better is worse
|
||||
|
||||
To make this code look simpler, we need to make it more complex.
|
||||
Our next try uses not two nested cores, but *three*:
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=+ gat=decrement
|
||||
=<(run gat(sam arg))
|
||||
=> ~
|
||||
|%
|
||||
++ decrement
|
||||
=+ sam=0
|
||||
|%
|
||||
++ run
|
||||
=+ pre=0
|
||||
=< loop
|
||||
|%
|
||||
++ loop
|
||||
?: =(sam +(pre))
|
||||
pre
|
||||
loop(pre +(pre))
|
||||
--
|
||||
--
|
||||
--
|
||||
```
|
||||
This is actually the final structure of our function, but uses
|
||||
none of the syntactic tricks we'll use to make it pretty.
|
||||
|
||||
> Why do we need to make the code more complex? Because we need
|
||||
it to use the regular form that our synthetic runes, ie macros,
|
||||
use to express function definitions and calls.
|
||||
|
||||
## Loop sugar
|
||||
|
||||
Look at little `loop`. It works just like our old `run`. But
|
||||
there's something nice about it: we don't use the symbol `loop`
|
||||
anywhere outside these 7 lines of code. It's not exported.
|
||||
|
||||
Therefore, the `loop` name is useless and redundant. Making up
|
||||
names is one of the hard problems in computer science, so why
|
||||
solve it for no reason?
|
||||
|
||||
So Hoon has an *empty name*: `$`. As a constant, `$` is a
|
||||
zero-length symbol (`%$` instead of `%foo`) As a limb is the
|
||||
`buc` symbol (`$`).
|
||||
|
||||
Replacing `loop` with `$`, our loop becomes:
|
||||
```
|
||||
=< $
|
||||
|%
|
||||
++ $
|
||||
?: =(sam +(pre))
|
||||
pre
|
||||
$(sam +(run))
|
||||
--
|
||||
```
|
||||
|
||||
This may not seem like a huge improvement. It's not. But it
|
||||
lets us match and move to the synthetic rune `|-`, "barhep":
|
||||
```
|
||||
|- ?: =(sam +(pre))
|
||||
pre
|
||||
$(pre +(pre))
|
||||
```
|
||||
`|-` is simply the canonical Hoon loop. All we've done to use a
|
||||
core as a loop is to name our arm `$`, and evaluate it on the
|
||||
core we just made.
|
||||
|
||||
Our program now:
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=+ gat=decrement
|
||||
=<(run gat(sam arg))
|
||||
=> ~
|
||||
|%
|
||||
++ decrement
|
||||
=+ sam=0
|
||||
|%
|
||||
++ run
|
||||
=+ pre=0
|
||||
|- ?: =(sam +(pre))
|
||||
pre
|
||||
$(pre +(pre))
|
||||
--
|
||||
--
|
||||
```
|
||||
|
||||
## Almost to lambda
|
||||
|
||||
Could we use `$` for `++run`? It certainly sounds like the same
|
||||
kind of thing as `++loop`. The word "run" just means "do it".
|
||||
Why should we be saying "do it" all the time?
|
||||
|
||||
Our third try, with this change:
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=+ gat=decrement
|
||||
=<($ gat(sam arg))
|
||||
=> ~
|
||||
|%
|
||||
++ decrement
|
||||
=| sam=@ud
|
||||
|%
|
||||
++ $
|
||||
=+ pre=0
|
||||
|- ?: =(sam +(pre))
|
||||
pre
|
||||
$(pre +(pre))
|
||||
--
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
41
|
||||
```
|
||||
> Besides `run` to `$`, we changed `=+ sam=0` to `=| sam=@ud`.
|
||||
This is some mold magic we'll explain in the next chapter, but
|
||||
it basically does the same thing: pushes a leg named `sam`, whose
|
||||
value is a number we'll later overwrite.
|
||||
|
||||
This use of `$` in a core, very similar to the way we used `$` in
|
||||
our `|-` loop, smells like it too should have a rune. It does:
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=+ gat=decrement
|
||||
=<($ gat(sam arg))
|
||||
=> ~
|
||||
|%
|
||||
++ decrement
|
||||
|= sam=@ud
|
||||
=+ pre=0
|
||||
|- ?: =(sam +(pre))
|
||||
pre
|
||||
$(pre +(pre))
|
||||
--
|
||||
|
||||
~tasfyn-partyv:dojo/sandbox> +test 42
|
||||
41
|
||||
```
|
||||
Doesn't `decrement` look like a function? Indeed, we're done with
|
||||
the `decrement` arm. This is what it should look like.
|
||||
|
||||
> If you squint a little, `|=` ("bartis") might even be a strange,
|
||||
deformed ASCII-art lambda.
|
||||
|
||||
Since it's doing something simple, we might well even compress
|
||||
the whole body of `decrement` into one wide-form line:
|
||||
```
|
||||
=+(pre=0 |-(?:(=(sam +(pre)) pre $(pre +(pre)))))
|
||||
```
|
||||
This is a bit tight for most. But we can get really compact by
|
||||
dropping the labels and going to full geometry:
|
||||
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
=+ gat=decrement
|
||||
=<($ gat(sam arg))
|
||||
=> ~
|
||||
|%
|
||||
++ decrement |=(@ud =+(0 |-(?:(=(+>+< +<) +< $(+< +(+<))))))
|
||||
--
|
||||
```
|
||||
> It's not a good idea to actually program this way. But it does
|
||||
strengthen your Hoon tree-geometry muscles. To use tree
|
||||
geometry, you have to really know the shape of your subject.
|
||||
|
||||
## Structure of a gate
|
||||
|
||||
What is the noun produced by `decrement`? In true Hoonese it's
|
||||
a *gate*, but nobody will hate you for saying "function." And
|
||||
while we *slam* our gates, you can feel free to just "call" them.
|
||||
|
||||
Every gate is a core; not every core is a gate. All cores are
|
||||
shaped like `[battery payload]`. A core is a gate if its payload
|
||||
is a cell, and its battery has one arm, `$`. So a gate is shaped
|
||||
like `[formula [sample context]]`.
|
||||
|
||||
To slam (call) a gate, you replace its sample (`+6` or `+<`,
|
||||
"lusgal" or "dish") with your argument. "Multiple arguments" are
|
||||
a single sample that's a tuple. So our code should actually read
|
||||
```
|
||||
=+ gat=decrement
|
||||
=<($ gat(+< arg))
|
||||
```
|
||||
This `=+` sequence remains ugly. Once again, `decrement(+< arg)`
|
||||
is not a mutation to the product of `decrement`, but a mutation
|
||||
to the core that produces `decrement`. Fortunately, there's a
|
||||
sugary rune that combines the semantics of both these lines:
|
||||
```
|
||||
%*($ decrement +< arg))
|
||||
```
|
||||
This mutates the product of `decrement` as specified. (`+< arg`
|
||||
in the wide form of `$*` is just the first of n comma-separated
|
||||
pairs; we could write `%*($ decrement +< arg, +> foo, moo 42)`.
|
||||
|
||||
> Arguably, %* is oversweetened; $:(decrement +< arg)
|
||||
would be simpler and better. Hoon isn't perfect.
|
||||
|
||||
## Slamming the gate
|
||||
|
||||
Anyway, it shouldn't come as a surprise that a synonym for
|
||||
`%*($ function +< argument)` is `%-(function argument)`. And an
|
||||
irregular form of this is just `(function argument)`.
|
||||
|
||||
The irregular syntax constructs multiple-argument syntax as a
|
||||
tuple; `(add 2 2)` is `(add [2 2])`, `(rsh 3 1 5)` is `(rsh [3 1 5])`.
|
||||
If there are no arguments, `(function)`, this means `$:function`,
|
||||
ie, `=>(function $)`.
|
||||
|
||||
We can also take the `=> ~` out, since we now know what we're
|
||||
doing. The final program:
|
||||
```
|
||||
=< :- %say |= [* [[arg=@ud ~] ~]] :- %noun
|
||||
(decrement arg)
|
||||
|%
|
||||
++ decrement
|
||||
|= sam=@ud
|
||||
=+ pre=0
|
||||
|- ?: =(sam +(pre))
|
||||
pre
|
||||
$(pre +(pre))
|
||||
--
|
||||
```
|
||||
## Progress
|
||||
|
||||
In most functional languages, a function is a primitive. In Hoon
|
||||
it's a macro, and a pretty complex macro at that. We spent four
|
||||
chapters building the concept up out of much smaller pieces.
|
||||
|
||||
Fortunately, once you have functions you can do anything. We
|
||||
still have a fair bit to learn, but we've now seen all the
|
||||
fundamental building blocks of programming in Hoon. In the next
|
||||
chapter, we'll get back into molds and spans.
|
@ -1,7 +0,0 @@
|
||||
References
|
||||
==========
|
||||
|
||||
Aside from the runes and standard library there are a few things worth
|
||||
knowing about the hoon language. You can find those here.
|
||||
|
||||
<list></list>
|
@ -1,686 +0,0 @@
|
||||
Odors
|
||||
=====
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Since Everything in Hoon is a natural number, the interpreter needs to
|
||||
know both how to render them and subject them to type enforcement.
|
||||
Odors, which are just ASCII spans beginning with a `@`, carry all of the
|
||||
information necessary for the interpreter to do this. For instance, the
|
||||
interpreter knows to render an atom of odor `@t` as UTF-8 text.
|
||||
|
||||
The span composing the Odor consists of two parts: a lowercase prefix
|
||||
carrying type information, and an upper-case suffix containing
|
||||
information about its size. The prefix is a taxonomy that grows more
|
||||
specific to the right. For example, atoms of the odor `@ta` are URL-safe
|
||||
ASCII text, and Atoms of the odor `@tas` are the more specific subset of
|
||||
ASCII text that is acceptable in hoon.
|
||||
|
||||
The general principle of type enforcement is that atoms change freely
|
||||
either up or down the taxonomy, but not across. You can treat a `@tas`
|
||||
as a `@t`, as in a strong type system; but you can also treat a `@t` as
|
||||
a `@tas`, or an `@` as anything. However, passing a `@t` to a function
|
||||
that expects an `@ux` is a type error.
|
||||
|
||||
XXDIAGRAMXX
|
||||
|
||||
For example, you can cast a `@t` to a `@tas`, or vice-versa:
|
||||
|
||||
~zod/try=> =a `@t`'permitted'
|
||||
~zod/try=> a
|
||||
'permitted'
|
||||
~zod/try=> `@tas`a
|
||||
%permitted
|
||||
|
||||
However, you cannot pass a `@ux` to a function that expects a `@t`
|
||||
without casting it to a `@` first:
|
||||
|
||||
~zod/try=> (|=(a=@t [%foo a]) 0x20)
|
||||
! type-fail
|
||||
! exit
|
||||
~zod/try=> =a 0x21
|
||||
~zod/try=> (|=(a=@t [%foo a]) `@t`a)
|
||||
[%foo '!']
|
||||
|
||||
Note that when explicitly casting a `@ux` to a `@t`, the interpreter
|
||||
automatically casts the `@ux` to a `@` first.
|
||||
|
||||
Comprehensive list of the Hoon Odors
|
||||
------------------------------------
|
||||
|
||||
@c UTF-32 codepoint
|
||||
@d date
|
||||
@da absolute date
|
||||
@dr relative date (ie, timespan)
|
||||
@f yes or no (inverse boolean)
|
||||
@n nil
|
||||
@p phonemic base
|
||||
@r IEEE floating-point
|
||||
@rd double precision (64 bits)
|
||||
@rh half precision (16 bits)
|
||||
@rq quad precision (128 bits)
|
||||
@rs single precision (32 bits)
|
||||
@s signed integer, sign bit low
|
||||
@sb signed binary
|
||||
@sd signed decimal
|
||||
@sv signed base32
|
||||
@sw signed base64
|
||||
@sx signed hexadecimal
|
||||
@t UTF-8 text (cord)
|
||||
@ta ASCII text (span)
|
||||
@tas ASCII symbol (term)
|
||||
@u unsigned integer
|
||||
@ub unsigned binary
|
||||
@ud unsigned decimal
|
||||
@uv unsigned base32
|
||||
@uw unsigned base64
|
||||
@ux unsigned hexadecimal
|
||||
|
||||
Odor Size Suffixes
|
||||
------------------
|
||||
|
||||
The suffix of an odor, if present, is a single upper-case character A-Z
|
||||
`c`, which indicates the size of an atom. This is possible, because in
|
||||
Hoon, a letter maps to an ASCII code number, thus a number.
|
||||
|
||||
Size is specified in bits in the form of `1 << (c - 'A')` resp. `2^c`,
|
||||
since most data aligns to the power of 2 or can be composed of such
|
||||
blocks.
|
||||
|
||||
The size of a block of size `N` can be calculated for example using
|
||||
`(bex (sub 'N' 'A'))` in bits or `(div (bex (sub 'N' 'A')) 8)` in bytes.
|
||||
|
||||
Thus, `@tD` is one UTF-8 byte (whatever that means) and `@tN` is 1
|
||||
kilobyte or less of UTF-8.
|
||||
|
||||
For reference:
|
||||
|
||||
A 1 bit
|
||||
B 2 bits
|
||||
C 4 bits
|
||||
D 1 byte
|
||||
E 2 bytes
|
||||
F 4 bytes
|
||||
G 8 bytes
|
||||
H 16 bytes
|
||||
I 32 bytes
|
||||
J 64 bytes
|
||||
K 128 bytes
|
||||
L 256 bytes
|
||||
M 512 bytes
|
||||
N 1K
|
||||
O 2K
|
||||
P 4K
|
||||
Q 8K
|
||||
R 16K
|
||||
S 32K
|
||||
T 64K
|
||||
U 128K
|
||||
V 256K
|
||||
W 512K
|
||||
X 1MB
|
||||
Y 2MB
|
||||
Z 4MB
|
||||
|
||||
It is possible to construct an atom bigger than 4Mb in size, but the
|
||||
type system would not be able to express an odor size for it.
|
||||
|
||||
There is also the datatype `++bloq` to hold a to-the-power-of block size
|
||||
(though it is just an alias for `@`).
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @c
|
||||
|
||||
UTF-32 codepoint
|
||||
|
||||
Atoms of the odor `@c` represent Unicode text, constructed with a UTF-32
|
||||
bytestream, with the lowest-significant bit first. Although we usually
|
||||
use a UTF-8 bytestream, sometimes it's useful to build atoms of one or
|
||||
more UTF-32 words.
|
||||
|
||||
##### Forms
|
||||
|
||||
`~-[text]`
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> :type; ~-foo
|
||||
~-foo
|
||||
@c
|
||||
~zod/try=> ~-i~2764.u
|
||||
~-i~2764.u
|
||||
~zod/try=> (tuft ~-i~2764.u)
|
||||
'i❤u'
|
||||
~zod/try=> `@ux`~-foo
|
||||
0x6f.0000.006f.0000.0066
|
||||
~zod/try=> `@ux`~-i~2764.u
|
||||
0x75.0000.2764.0000.0069
|
||||
~zod/try=> `@ux`(tuft ~-i~2764.u)
|
||||
0x75.a49d.e269
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @d
|
||||
|
||||
Date
|
||||
|
||||
#### @da
|
||||
|
||||
Absolute date
|
||||
|
||||
Atoms of the odor `@da` represent absolute Urbit dates. Urbit dates
|
||||
represent 128-bit chronological time, with 2\^64 seconds from the start
|
||||
of the universe. For example, 2\^127 is 3:30:08 PM on December 5, AD
|
||||
226. The time of day and/or second fragment is optional. As the last
|
||||
example shows, BC times are also possible.
|
||||
|
||||
##### Forms
|
||||
|
||||
`~~[year].[month].[date]..[hour].[minute].[second]..[millisecond]`
|
||||
|
||||
Note: the time of day and/or millisecond fragment is optional.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> ~2014.1.1
|
||||
~2014.1.1
|
||||
~zod/try=> :type; ~2014.1.1
|
||||
~2014.1.1
|
||||
@da
|
||||
~zod/try=> ~2014.1.1..01.01.01
|
||||
~2014.1.1..01.01.01
|
||||
~zod/try=> :type; ~2014.1.1..01.01.01
|
||||
~2014.1.1..01.01.01
|
||||
@da
|
||||
~zod/try=> ~2014.1.1..01.01.01..1234
|
||||
~2014.1.1..01.01.01..1234
|
||||
~zod/try=> `@da`(bex 127)
|
||||
~226.12.5..15.30.08
|
||||
~zod/try=> `@da`(dec (bex 127))
|
||||
~226.12.5..15.30.07..ffff.ffff.ffff.ffff
|
||||
~zod/try=> `@ux`~2013.12.7
|
||||
0x8000.000d.2140.7280.0000.0000.0000.0000
|
||||
~zod/try=> `@ux`~2013.12.7..15.30.07
|
||||
0x8000.000d.2141.4c7f.0000.0000.0000.0000
|
||||
~zod/try=> `@ux`~2013.12.7..15.30.07..1234
|
||||
0x8000.000d.2141.4c7f.1234.0000.0000.0000
|
||||
~zod/try=> `@ux`~2013.12.7..15.30.07..1234
|
||||
0x8000.000d.2141.4c7f.1234.0000.0000.0000
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @dr
|
||||
|
||||
Relative date (ie, timespan)
|
||||
|
||||
Atoms of the odor `@dr` atoms represent basic time intervals in
|
||||
milliseconds. There are no `@dr` intervals under a second or over a day
|
||||
in length.
|
||||
|
||||
##### Forms
|
||||
|
||||
`~d[day].h[hour]m[minute].s[second]..[fractionals]`
|
||||
|
||||
Note: Every measurement is optional, so long as those that are present
|
||||
are in order. The largest measurement is preceded by a `~`.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> ~d1.h19.m5.s29
|
||||
~d1.h19.m5.s29
|
||||
~zod/try=> :type; ~d1.h19.m5.s29
|
||||
~d1.h19.m5.s29
|
||||
@dr
|
||||
~zod/try=> `@dr`(div ~s1 1.000)
|
||||
~.s0..0041.8937.4bc6.a7ef
|
||||
~zod/try=> ~d1.h19.m5.s29..0041
|
||||
~d1.h19.m5.s29..0041
|
||||
~zod/try=> `@ux`~s1
|
||||
0x1.0000.0000.0000.0000
|
||||
~zod/try=> `@ux`~m1
|
||||
0x3c.0000.0000.0000.0000
|
||||
~zod/try=> `@dr`(div ~d1 5)
|
||||
~h4.m48
|
||||
~zod/try=> (div ~m1 ~s1)
|
||||
60
|
||||
~zod/try=> (div ~h1 ~m1)
|
||||
60
|
||||
~zod/try=> (div ~h1 ~s1)
|
||||
3.600
|
||||
~zod/try=> (div ~d1 ~h1)
|
||||
24
|
||||
~zod/try=> `@da`(add ~2013.11.30 ~d1)
|
||||
~2013.12.1
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @f
|
||||
|
||||
Loobean(inverse boolean)
|
||||
|
||||
Atoms of the odor `@f` represent loobeans, where `0` is yes and `1` is
|
||||
no. Loobeans are often represented in their cubic and runic forms shown
|
||||
below.
|
||||
|
||||
##### Forms
|
||||
|
||||
`0`, `1` as numbers. `%.y`, `%.n` as [`%cube`]()s. `&`, `|` as short
|
||||
forms.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> `@ud`.y
|
||||
0
|
||||
~zod/try=> :type; .y
|
||||
%.y
|
||||
{%.y %.n}
|
||||
~zod/try=> `@ud`.n
|
||||
1
|
||||
~zod/try=> .y
|
||||
%.y
|
||||
~zod/try=> &
|
||||
%.y
|
||||
~zod/try=> |
|
||||
%.n
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @n
|
||||
|
||||
Nil
|
||||
|
||||
Atoms of the odor `@n` indicate an absence of information, as in a list
|
||||
terminator. The only value is `~`, which is just `0`.
|
||||
|
||||
~zod/try=> :type; ~
|
||||
~
|
||||
%~
|
||||
~zod/try=> `@ud`%~
|
||||
0
|
||||
~zod/try=> `@ud`~
|
||||
0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @p
|
||||
|
||||
Phonemic base
|
||||
|
||||
Atoms of `@p` are primarily used to represent ships names, but they can
|
||||
be used to optimize any short number for memorability. For example, it
|
||||
is great for checksums.
|
||||
|
||||
##### Forms
|
||||
|
||||
`~[phonemic]`
|
||||
|
||||
Every syllable is a byte. Pairs of two bytes are separated by `-`, and
|
||||
phrases of four pairs are separated by `--`.
|
||||
|
||||
~zod/try=> ~pasnut
|
||||
~pasnut
|
||||
~zod/try=> :type; ~pasnut
|
||||
~pasnut
|
||||
@p
|
||||
~zod/try=> `@p`0x4321
|
||||
~pasnut
|
||||
~zod/try=> `@p`0x8765.4321
|
||||
~famsyr-dirwes
|
||||
~zod/try=> `@p`0x8766.4321
|
||||
~lidlug-maprec
|
||||
~zod/try=> `@p`(shaf %foo %bar)
|
||||
~ralnyl-panned-tinmul-winpex--togtux-ralsem-lanrus-pagrup
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @r
|
||||
|
||||
IEEE floating-points
|
||||
|
||||
Hoon does not yet support floating point, so these syntaxes don't work
|
||||
yet. But the syntax for a single-precision float is the normal English
|
||||
syntax, with a `.` prefix:
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @s
|
||||
|
||||
Signed integer, sign bit low
|
||||
|
||||
Without finite-sized integers, the sign extension trick obviously does
|
||||
not work. A signed integer in Hoon is a different way to use atoms than
|
||||
an unsigned integer; even for positive numbers, the signed integer
|
||||
cannot equal the unsigned.
|
||||
|
||||
The prefix for a negative signed integer is a single `-` before the
|
||||
unsigned syntax. The prefix for a positive signed integer is `--`. The
|
||||
least significant represents the sign. The representation is similar to
|
||||
a folded number line.
|
||||
|
||||
#### @sb
|
||||
|
||||
Signed binary
|
||||
|
||||
Atoms of the odor `@sb` represent signed binary numbers.
|
||||
|
||||
#### Forms
|
||||
|
||||
`-0b[negative_binary]` `--0b[postive_binary]`
|
||||
|
||||
#### Examples
|
||||
|
||||
~zod/try=> :type; -0b1
|
||||
-0b1
|
||||
@sb
|
||||
~zod/try=> `@sd`-0b1
|
||||
-1
|
||||
~zod/try=> `@sd`--0b1
|
||||
--1
|
||||
~zod/try=> `@sd`--0b11
|
||||
--3
|
||||
~zod/try=> `@sb`(sum:si -0b10 -0b10)
|
||||
-0b100
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @sd
|
||||
|
||||
Signed decimal
|
||||
|
||||
Atoms of odor `@sd` represent signed decimal numbers.
|
||||
|
||||
#### Forms
|
||||
|
||||
`-[negative[decimal]()]` `--[postive_[decimal]()]`
|
||||
|
||||
#### Examples
|
||||
|
||||
~zod/try=> -234
|
||||
-234
|
||||
~zod/try=> :type; -234
|
||||
-234
|
||||
@sd
|
||||
~zod/try=> :type; --234
|
||||
--234
|
||||
@sd
|
||||
~zod/try=> (sum:si -234 --234)
|
||||
--0
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @sv
|
||||
|
||||
Signed base32
|
||||
|
||||
Atoms of odor `@sv` represent signed base32 numbers.
|
||||
|
||||
##### Forms
|
||||
|
||||
`-0v[negative_base32]` The digits are, in order, `0-9`, `a-v`.
|
||||
`--0v[positive_base32]`
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> -0vv
|
||||
-0vv
|
||||
~zod/try=> :type; -0vv
|
||||
-0vv
|
||||
@sv
|
||||
~zod/try=> --0vb
|
||||
--0vb
|
||||
~zod/try=> `@sd`-0vv
|
||||
-31
|
||||
~zod/try=> `@sd`--0vb
|
||||
--11
|
||||
~zod/try=> `@sd`(sum:si -0vv --0vb)
|
||||
-20
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @sw
|
||||
|
||||
Signed base64
|
||||
|
||||
Atoms of odor `@sw` represent base64 numbers.
|
||||
|
||||
##### Forms
|
||||
|
||||
`-0w[negative_base64]` The digits are, in order, `0-9`, `a-z`,
|
||||
`A-Z`,`-`, and `~`. `--0w[positive_base64]` The digits are, in order,
|
||||
`0-9`
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> -0w--
|
||||
-0w--
|
||||
~zod/try=> :type; -0w--
|
||||
-0w--
|
||||
@sw
|
||||
~zod/try=> `@sd`(sum:si -0w-A -0w--)
|
||||
-8.034
|
||||
|
||||
#### @sx
|
||||
|
||||
Signed hexadecimal
|
||||
|
||||
Atoms of odor `@sx` represent signed hexadecimal numbers.
|
||||
|
||||
##### Forms
|
||||
|
||||
`-[negative_hexadecimal]` `--[positive_hexadecimal]`
|
||||
|
||||
##### Examples
|
||||
|
||||
~~zod/try=> -0x0
|
||||
--0x0
|
||||
~zod/try=> `@sd`--0x17
|
||||
--23
|
||||
~zod/try=> `@ux`(bex 20)
|
||||
0x10.0000
|
||||
~zod/try=> 0x10. 0000
|
||||
0x10.0000
|
||||
~zod/try=> `@sd`(sum:si --0x17 -0x0)
|
||||
--23
|
||||
~zod/try=> `@sd`(sum:si --0x17 -0xa)
|
||||
--13
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @t
|
||||
|
||||
UTF-8 text (cord)
|
||||
|
||||
Atoms of the odor `@t` represent a
|
||||
[cord](http://en.wikipedia.org/wiki/Rope_data_structure), sequence of
|
||||
UTF-8 bytes, LSB first. It is sometimes called a cord.
|
||||
|
||||
##### Forms
|
||||
|
||||
`~~[text]` `'[text]'`
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> ~~foo
|
||||
'foo'
|
||||
~zod/try=> :type; 'foo'
|
||||
'foo'
|
||||
@t
|
||||
~zod/try=> :type; ~~foo
|
||||
'foo'
|
||||
@t
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @ta
|
||||
|
||||
ASCII text (span)
|
||||
|
||||
Atoms of the odor `@ta` represent the ASCII text subset used in hoon
|
||||
literals: `a-z`, `0-9`, `~`, `-`, `.`, `_`.
|
||||
|
||||
##### Forms
|
||||
|
||||
`~.[text]` There are no escape sequences.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> ~..asdf
|
||||
~..asdf
|
||||
~zod/try=> :type; ~.asdf
|
||||
~.asdf
|
||||
@ta
|
||||
~zod/try=> `@t`~.asdf
|
||||
'asdf'
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @tas
|
||||
|
||||
ASCII symbol (term)
|
||||
|
||||
Atoms of `@tas` represent [`++term`]()s, the most exclusive text odor.
|
||||
The only characters permitted are lowercase ASCII, except as the first
|
||||
or last character, and 0-9, except as the first character.
|
||||
|
||||
##### Forms
|
||||
|
||||
`%[text]` This means a term is always [cubical]().
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> %dead-fish9
|
||||
%dead-fish9
|
||||
~zod/try=> -:!>(%dead-fish9)
|
||||
[%cube p=271.101.667.197.767.630.546.276 q=[%atom p=%tas]]
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
### @u
|
||||
|
||||
Unsigned integer
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @ub
|
||||
|
||||
Unsigned binary
|
||||
|
||||
Atoms of the odor `@ub` represent unsigned binary numbers.
|
||||
|
||||
#### Forms
|
||||
|
||||
`0b[number]` Numbers are least-significant bit first.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> `@`0b1
|
||||
1
|
||||
~zod/try=> :type; 0b1
|
||||
0b1
|
||||
@ub
|
||||
~zod/try=> `@`0b10
|
||||
2
|
||||
~zod/try=> `@`0b100
|
||||
4
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @ud
|
||||
|
||||
Unsigned decimal
|
||||
|
||||
Atoms of `@ud` represent unsigned decimal numbers. It is the default
|
||||
print format for both `@u` and and `@u`, namely unsigned numbers with no
|
||||
printing preference, as well as opaque atoms.
|
||||
|
||||
##### Forms
|
||||
|
||||
Numbers of more than three digits must be delimited by `.`s. Whitespace
|
||||
and linebreaks can appear between the dot and the next group.
|
||||
|
||||
~zod/try=> 0
|
||||
0
|
||||
~zod/try=> 19
|
||||
19
|
||||
~zod/try=> :type; 19
|
||||
19
|
||||
@ud
|
||||
~zod/try=> 1.024
|
||||
1.024
|
||||
~zod/try=> 65.536
|
||||
65.536
|
||||
~zod/try=> (bex 20)
|
||||
1.048.576
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @uv
|
||||
|
||||
Unsigned base32
|
||||
|
||||
Atoms of the odor `@uv` represent unsigned base64 numbers.
|
||||
|
||||
##### Forms
|
||||
|
||||
`0v[number]` The digits are, in order, `0-9`, `a-v`.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> `@ud`0vv
|
||||
31
|
||||
~zod/try=> :type; 0vv
|
||||
0vv
|
||||
@uv
|
||||
~zod/try=> `@ud`(add 0vv 0v9)
|
||||
40
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @uw
|
||||
|
||||
Unsigned base64
|
||||
|
||||
##### Forms
|
||||
|
||||
`ow[number]` The digits are, in order, `0-9`, `a-z`, `A-Z`,`-`, and `~`.
|
||||
|
||||
##### Examples
|
||||
|
||||
~zod/try=> 0w~
|
||||
0w~
|
||||
~zod/try=> :type; 0w~
|
||||
0w~
|
||||
@uw
|
||||
~zod/try=> `@uv`(add 0w~ 0wZ)
|
||||
0v3s
|
||||
~zod/try=> `@ud``@uv`(add 0w~ 0wZ)
|
||||
124
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
#### @ux
|
||||
|
||||
Unsigned hexadecimal
|
||||
|
||||
Atoms of the odor `@ux` represent hexadecimal numbers.
|
||||
|
||||
##### Forms
|
||||
|
||||
`0x`number. Numbers with more than four digits must be delimited by
|
||||
`.`s. Hex digits are lowercase only.
|
||||
|
||||
~zod/try=> 0x0
|
||||
0x0
|
||||
~zod/try=> :type; 0x0
|
||||
0x0
|
||||
@ux
|
||||
~zod/try=> `@ud`0x17
|
||||
23
|
||||
~zod/try=> `@ux`(bex 20)
|
||||
0x10.0000
|
||||
~zod/try=> 0x10. 0000
|
||||
0x10.0000
|
||||
|
||||
------------------------------------------------------------------------
|
@ -1,68 +0,0 @@
|
||||
Pronunciation
|
||||
=============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
Hoon is a reserved-word-free
|
||||
language - any text in the program is part of the program.
|
||||
|
||||
We use so many of these ASCII glyphs that we like to be able
|
||||
to read them out loud. A language is meant to be _said_. The
|
||||
squiggles have conventional names, sort of, some of them easy to
|
||||
say, others not so much. So we've renamed them:
|
||||
|
||||
ace space
|
||||
bar |
|
||||
bas \
|
||||
buc $
|
||||
cab _
|
||||
cen %
|
||||
col :
|
||||
com ,
|
||||
doq "
|
||||
dot .
|
||||
fas /
|
||||
gal <
|
||||
gar >
|
||||
hax #
|
||||
hep -
|
||||
kel {
|
||||
ker }
|
||||
ket ^
|
||||
lus +
|
||||
pam &
|
||||
pat @
|
||||
pel (
|
||||
per )
|
||||
sel [
|
||||
sem ;
|
||||
ser ]
|
||||
sig ~
|
||||
soq '
|
||||
tar *
|
||||
tec `
|
||||
tis =
|
||||
wut ?
|
||||
zap !
|
||||
|
||||
Memorizing these names seems like a burden, but it actually makes
|
||||
communicating about hoon code a lot faster and easier. `bartis`
|
||||
sounds a lot better than 'bar equals'.
|
||||
|
||||
To pronounce a rune, concatenate the glyph names, stressing the
|
||||
first syllable and softening the second vowel into a "schwa."
|
||||
Hence, to say `~.`, say "sigdot." To say `|=`, say "bartis."
|
||||
Which has an inevitable tendency to turn into "barts" - a sin
|
||||
to be encouraged.
|
||||
|
||||
There are a few runes with irregular special pronunciations:
|
||||
|
||||
-- hephep phep
|
||||
+- lushep slep
|
||||
++ luslus slus
|
||||
== tistis stet
|
||||
+< lusgal glus
|
||||
+> lusgar gras
|
||||
-< hepgal gelp
|
||||
-> hepgar garp
|
@ -1,132 +0,0 @@
|
||||
<div class="short">
|
||||
|
||||
Runes
|
||||
=====
|
||||
|
||||
In Hoon there are no reserved words. Instead, [`++twigs`]() (abstract
|
||||
syntax trees), are formed using a diagraph of two ASCII symbols, which
|
||||
is called a rune.
|
||||
|
||||
Runes are loosely divided into categories by their first character. To
|
||||
find documentation on each individual category, follow these links:
|
||||
|
||||
<list></list>
|
||||
|
||||
<search/>
|
||||
|
||||
</div>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
For example, the rune `?:`, pronounced "wutcol", is a rune that accepts
|
||||
three `++twig` expressions to form an "if-then-else statement," where
|
||||
`p` is the predicate, `q` is the "then" statement, and `r` is the "else"
|
||||
statement:
|
||||
|
||||
[%wtcl p=twig q=twig r=twig]
|
||||
|
||||
In a program, it is used like so:
|
||||
|
||||
++ add
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: =(0 a) b
|
||||
$(a (dec a), b +(b))
|
||||
|
||||
Here the `=(0 a)` is `p`, the `b` is `q`, and the bottom line is the
|
||||
`r`.
|
||||
|
||||
There are several benefits to using runes in lieu of reserved words.
|
||||
First, it prevents the programmer from accidentally misusing a reserved
|
||||
word as a variable name, which also allows her to be sure that any word
|
||||
in her progam is an identifier. Next, as the first ASCII symbol of the
|
||||
rune digraphs bears semantic significance, the programmer can look at
|
||||
any rune and immediately have a basic, intuitive understanding as to
|
||||
what it does.
|
||||
|
||||
Next, rune syntax addresses several issues that arise in other
|
||||
languages. First, it produces cleaner, less verbose code that
|
||||
conveniently flows downward. To highlight the verbosity Hoon avoids by
|
||||
implementing runes, here is the C equivalent of the `++add` source code
|
||||
printed above:
|
||||
|
||||
attribute add {
|
||||
function(left-operand: atom, right-operand: atom)
|
||||
produce atom
|
||||
if equals(0, left-operand) {
|
||||
right-operand
|
||||
} else {
|
||||
recurse(left-operand (decrement left-operand)),
|
||||
right-operand (increment right-operand))
|
||||
}
|
||||
}
|
||||
|
||||
What is more, Hoon solves two problems that arise in functional
|
||||
programming languages with very deep expression trees: first, the
|
||||
collection of huge piles of closing parens at the end of large blocks;
|
||||
and second, the fact that the depth of expression trees are thus bounded
|
||||
by the width of the text box, as subexpressions tend to be indented.
|
||||
Some languages solve the bracket-terminator problem by parsing
|
||||
whitespace in order to use indentation to express tree depth:
|
||||
|
||||
?:
|
||||
&
|
||||
47
|
||||
52
|
||||
|
||||
While this is actually valid Hoon, it does not solve the width problem.
|
||||
|
||||
To address this problem, most Hoon `++twigs` have a short, fixed
|
||||
fan-out. Thus, the parser does not need significant whitespace nor a
|
||||
terminator to determine how many twigs follow a `?:`--it already knows
|
||||
that the answer is three. A smart parser allows the Hoon programmer to
|
||||
format her code using a [backstep pattern]() that allows her to descend
|
||||
into a deep tree without losing right margin.
|
||||
|
||||
Lastly, but perhaps most significantly, code is meant to be seen, and
|
||||
not read. Anyone who has even slight experience coding Hoon will tell
|
||||
you that they can understand and connect with properly formatted Hoon
|
||||
code on a deeper, more intuitive level that cannot be explained but must
|
||||
be experienced. One doesn't read `++add`, she sees it.
|
||||
|
||||
Names and Categories
|
||||
--------------------
|
||||
|
||||
While the second glyph in a rune means little or nothing, the first
|
||||
defines a rough semantic category:
|
||||
|
||||
| bar Core construction
|
||||
$ buc Tile construction
|
||||
% cen Invocations
|
||||
: col Tuple construction
|
||||
. dot Nock operations
|
||||
# hax Pretty printing
|
||||
^ ket Type conversions
|
||||
; sem Composers (and XML generators)
|
||||
~ sig Hints
|
||||
= tis Subject modifiers
|
||||
? wut Conditionals, booleans, and tests
|
||||
! zap Special operations
|
||||
|
||||
As shown above, each glyph has its own monosyllabic name, designed to be
|
||||
pronounced quickly in combination with another glyph to form a rune
|
||||
name. As languages are often read-aloud, this saves the programmer from
|
||||
having to say "dollar sign, question mark"--"bucwut" is much more
|
||||
compact.
|
||||
|
||||
Irregular pronuncations
|
||||
-----------------------
|
||||
|
||||
To avoid a few tongue-twisters, some runes have irregular pronunciations
|
||||
that should be noted:
|
||||
|
||||
-- hephep phep
|
||||
+- lushep slep
|
||||
++ luslus slus
|
||||
== tistis stet
|
||||
|
||||
Note: these runes are not members of any of the categories above, but
|
||||
are mostly used to....
|
@ -1,49 +0,0 @@
|
||||
<div class="short">
|
||||
|
||||
`buc $ %buc`
|
||||
============
|
||||
|
||||
Tile construction
|
||||
-----------------
|
||||
|
||||
The `$` runes construct [`++tile`]()s. [`++tile`]()s are one of our
|
||||
primary building blocks in hoon, they define how we reduce our ASTs into
|
||||
well typed nouns that nock can compute. You can think of a [`++tile`]()
|
||||
sort of like a typeclass in Haskell.
|
||||
|
||||
</div>
|
||||
|
||||
#### Forks
|
||||
|
||||
##### [`++tile`]()s that can be one of multiple cases.
|
||||
|
||||
[`$?`]() Non-empty list of cases.
|
||||
|
||||
[`$|`]() Fork between atom and cell.
|
||||
|
||||
[`$&`]() Fork between cells whose head is a cell and cells whose head is
|
||||
an atom.
|
||||
|
||||
<hr></hr>
|
||||
|
||||
#### Tuples
|
||||
|
||||
[`$:`]() Unlabelled arrays.
|
||||
|
||||
[`$=`]() Tuple with [`++face`]()s.
|
||||
|
||||
<hr> </hr>
|
||||
|
||||
#### Reductions
|
||||
|
||||
##### Important convenience methods for working with tiles, and are very broadly used.
|
||||
|
||||
[`$*`]() [bunt]()
|
||||
|
||||
[`$,`]() [clam]()
|
||||
|
||||
[`$@`]() [whip]()
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<kids></kids>
|
@ -1,52 +0,0 @@
|
||||
bucbar `$|` %bcbr
|
||||
=================
|
||||
|
||||
<div class="short">
|
||||
|
||||
Atom or cell
|
||||
------------
|
||||
|
||||
`$|` is a tile rune that produces a [`%reed`](), a tile whose [icon]()
|
||||
is a [fork]() between two nouns: an [atom]() of `tile` `p` and a cell of
|
||||
`tile` `q`. `$|` is similar to [`$?`](), but is more strict in that in
|
||||
only contains one atom tile and one cell tile.
|
||||
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
</hr>
|
||||
### Produces
|
||||
|
||||
[`Tile`](): `[%reed p=tile q=tile]`
|
||||
|
||||
### Sample
|
||||
|
||||
`p` is a [`tile`]() `q` is a [`tile`]()
|
||||
|
||||
### Tall form
|
||||
|
||||
$| p
|
||||
q
|
||||
|
||||
### Wide form
|
||||
|
||||
$|(p q)
|
||||
|
||||
### Irregular form
|
||||
|
||||
None
|
||||
|
||||
### Examples
|
||||
|
||||
~zod/try=> *$|(~ [~ u=@])
|
||||
~
|
||||
~zod/try=> :type; *$|(~ [~ u=@])
|
||||
~
|
||||
u(@)
|
||||
|
||||
++ list |* a=_,* :: null-terminated list
|
||||
$|(~ [i=a t=(list a)]) ::
|
||||
|
||||
In `++list`, `$|` specifies that every element in a noun that can be
|
||||
cast to a `++list` is either the atom `~` or the cell
|
||||
`[i=a t=(list a)]`.
|
@ -1,43 +0,0 @@
|
||||
buccab `$_` %bccb
|
||||
==========================
|
||||
|
||||
Default value
|
||||
|
||||
`$_` produces a tile-by-example, called a `%weed`. A `%weed` contains
|
||||
the twig used to make the example.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Tile: `[%weed p=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$_ p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
$_(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
_p
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> *_12
|
||||
12
|
||||
~zod/try=> :type; *_12
|
||||
12
|
||||
@ud
|
||||
~zod/try=> ^-(_(add 2 2) 'a')
|
||||
97
|
@ -1,44 +0,0 @@
|
||||
buccol `$:` %bccl
|
||||
==========================
|
||||
|
||||
Tile autocons
|
||||
|
||||
`$:` is a tile rune that constructs the tile of a tuple from a tuple of
|
||||
tiles.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Tile](): `[p=tile q=tile]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile](). `q` is a [tile]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$: p
|
||||
q
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
$:(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
[p q]
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> *[1 2]
|
||||
[%1 %2]
|
||||
~zod/try=> (,[1 2] "ham")
|
||||
[%1 %2]
|
||||
~zod/try=> (,[@ 2] "ham")
|
||||
[104 %2]
|
@ -1,61 +0,0 @@
|
||||
buccom `$,` %bccm
|
||||
==========================
|
||||
|
||||
Normalizing gate, `%clam`
|
||||
|
||||
`$,` is a synthetic rune that produces a `%leaf`, a normalizing gate or
|
||||
[clam]() for `p`. `$,` is used to ensure an input value fits a certain
|
||||
type: if it does match, the value is produced. If it doesn't, the
|
||||
default value for the desired type is produced.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Twig](): `[%bccm p=tile]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile]()
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$, p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
,p
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
++ cord ,@t :: text atom (UTF-8)
|
||||
|
||||
In `++cord`, `,` creates a gate that validates atoms of the odor
|
||||
[`@t`]().
|
||||
|
||||
~zod/try=> (,[1 2] "ham")
|
||||
[%1 %2]
|
||||
~zod/try=> (,[@ 2] "ham")
|
||||
[104 %2]
|
||||
~zod/try=> (,~ %foo)
|
||||
~
|
||||
~zod/try=> (,~ [%ba %r])
|
||||
~
|
||||
~zod/try=> (,$%([%a @] [%b ^]) [%b 5])
|
||||
[%b 0 0]
|
||||
~zod/try=> (,$%([%a @] [%b ^]) [%a 5])
|
||||
[%a 5]
|
||||
~zod/try=> (,$%([%a @] [%b ^]) [%a 6 7])
|
||||
[%a 0]
|
||||
~zod/try=> (,$%([%a @] [%b ^]) [%b ~])
|
||||
[%b 0 0]
|
||||
~zod/try=> (,$%([%a @] [%b ^]) [%b "ame"])
|
||||
[%b 97 [109 101 0]]
|
@ -1,64 +0,0 @@
|
||||
buccen `$%` %bccn
|
||||
==========================
|
||||
|
||||
Tagged union
|
||||
|
||||
`$%` is a tile rune that produces a [`%kelp`](), the tile of the
|
||||
discriminated union. `$%` takes a list of lines which are labeled cases,
|
||||
called fronds, closed by `==`. Commonly used for pattern matching.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Twig](): `[%kelp p=[i=line t=(list line)]]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`++list`]() of [`++line`]()s.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$% p
|
||||
q
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> $%([%& @p] [%| @t])
|
||||
<1.dhe [* @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
|
||||
~zod/try=> *$%([%& @p] [%| @t])
|
||||
[%.y ~zod]
|
||||
~zod/try=> :type; *$%([%& @p] [%| @t])
|
||||
[%.y ~zod]
|
||||
{[%.y @p] [%.n @t]}
|
||||
~zod/try=> :type; *(each ,@p ,@t)
|
||||
[%.y p=~zod]
|
||||
{[%.y p=@p] [%.n p=@t]}
|
||||
~zod/try=> $%(~ [%a 1])
|
||||
~ <syntax error at [1 13]>
|
||||
~zod/try=> $%([%~ ~] [%a 1])
|
||||
<1.yck [* @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
|
||||
~zod/try=> *$%([%~ ~] [%a 1])
|
||||
[~ ~]
|
||||
|
||||
++ foot $% [%ash p=twig] :: dry, geometric
|
||||
[%elm p=twig] :: wet, generic
|
||||
[%oak ~] :: XX not used
|
||||
[%yew p=(map term foot)] :: XX not used
|
||||
==
|
||||
|
||||
In `++foot`, `$%` creates a list of possible cases. That is, a `++foot`
|
||||
can be either `%ash`, `%elm`, `%oak` or `%yew`.
|
@ -1,49 +0,0 @@
|
||||
bucket `$^` %bckt
|
||||
==========================
|
||||
|
||||
Normalizing gate, `%herb`
|
||||
|
||||
`$^`, is a tile rune that declares an [`%herb`](). An `%herb` is a gate,
|
||||
accepting a sample of \* and normalizing it as you choose. If you use a
|
||||
twig as a tile, it's treated as an herb.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Tile: `[%herb p=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$^ p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
$^(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> *$^(cord)
|
||||
''
|
||||
~zod/try=> *$^(|=(a=* ?^(a a [~ a])))
|
||||
[~ 0]
|
||||
~zod/try=> `$^(|=(a=* ?^(a a [~ a])))`1
|
||||
! type-fail
|
||||
! exit
|
||||
~zod/try=> `$^(|=(a=* ?^(a a [~ a])))`[1 2]
|
||||
[1 2]
|
||||
~zod/try=> :type; *$^(|=(a=* ?^(a a [~ a])))
|
||||
[~ 0]
|
||||
{[%~ @] [* *]}
|
@ -1,62 +0,0 @@
|
||||
buclus `$+` %bcls
|
||||
==========================
|
||||
|
||||
Signature
|
||||
|
||||
`$+` a tile for a gate which accepts `p` and produces `q`. `$+` is
|
||||
similar to a function signature. `$+(p q)` is a `%bark` of a `%weed`, or
|
||||
`$_(|+(p _q))`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Tile: `$_(|+(p _q))`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile]() `q` is a [tile]()
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$+ p q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
$+(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
++ sort :: quicksort
|
||||
~/ %sort
|
||||
!:
|
||||
|* [a=(list) b=$+([* *] ?)]
|
||||
=> .(a ^.(homo a))
|
||||
|- ^+ a
|
||||
?~ a ~
|
||||
%+ weld
|
||||
$(a (skim t.a |=(c=_i.a (b c i.a))))
|
||||
^+ t.a
|
||||
[i.a $(a (skim t.a |=(c=_i.a !(b c i.a))))]
|
||||
|
||||
In ++sort, `$+` is a tile for a comparator gate, which takes two nouns
|
||||
and produces a loobean.
|
||||
|
||||
~zod/try=> |=(a=@ (add 2 a))
|
||||
<1.sgg [a=@ [[@da @ta] [@p @ta] *''] @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
|
||||
~zod/try=> `$+(@ @)`|=(a=@ (add 2 a))
|
||||
<1|crm [@ [[@da @ta] [@p @ta] *''] @n <246.qra 41.uuw 374.glo 100.rip 1.ypj %164>]>
|
||||
~zod/try=> +<:|=(a=@ (add 2 a))
|
||||
a=0
|
||||
~zod/try=> +<:`$+(@ @)`|=(a=@ (add 2 a))
|
||||
! -axis.6
|
||||
! peek-park
|
||||
! exit
|
@ -1,39 +0,0 @@
|
||||
bucpam `$&` %bcpm
|
||||
==========================
|
||||
|
||||
Pair / tag
|
||||
|
||||
`$&` is a tile rune that produces a `%bush`. A `%bush` is a tile whose
|
||||
[icon]() is a [fork]() between two different kinds of nouns: cells whose
|
||||
head is a cell and cells whose head is an atom `(tile q)`. Its default
|
||||
value is the value of `q`. One important use of `$&` is to implement
|
||||
autocons in [`++twig`]() and [`++tile`]().
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Tile](): `[%bush p=tile q=tile]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$& p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
$&(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
@ -1,37 +0,0 @@
|
||||
bucpat `$@` %bcpt
|
||||
==========================
|
||||
|
||||
Wing to tile
|
||||
|
||||
`$@` is a natural rune that whips (normalizes) wing `p` into tile `q`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Tile: `[%bcpt p=wing q=tile]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`++wing`](). `q` is a [tile]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
p@q
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> =+(a=97 a@cord)
|
||||
'a'
|
@ -1,38 +0,0 @@
|
||||
buctar `$*` %bctr
|
||||
==========================
|
||||
|
||||
Default value
|
||||
|
||||
`$*`, is a synthetic rune that produces the [bunt]() (default value) of
|
||||
a tile as a compile-time constant if possible. If it is not possible,
|
||||
then it is produced dynamically.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Twig](): `[%bctr p=tile]`
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$* p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
$*(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
*p
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> *@t
|
||||
''
|
||||
~zod/try=> *[@p @ux]
|
||||
[~zod 0x0]
|
||||
~zod/try=> *(list ,@)
|
||||
~
|
@ -1,53 +0,0 @@
|
||||
buctis `$=` %bcts
|
||||
==========================
|
||||
|
||||
Face for tile
|
||||
|
||||
`$=` is a tile rune that produces a `%bark`. A `%bark` is a tile that
|
||||
wraps a [face]() around another tile. Used primarily to add faces to
|
||||
[nouns]().
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Tile](): `[%bark p=term q=tile]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [term]().
|
||||
|
||||
`q` is a [tile]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$= p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
`a=*` parses as `[%bark %a %noun]`.
|
||||
|
||||
~zod/try=> *$=(a @)
|
||||
a=0
|
||||
~zod/try=> :type; *$=(a @)
|
||||
a=0
|
||||
a=@
|
||||
~zod/try=> :type; *a=@
|
||||
a=0
|
||||
a=@
|
||||
~zod/try=> :type; *a=[1 2]
|
||||
a=[%1 %2]
|
||||
a=[%1 %2]
|
@ -1,48 +0,0 @@
|
||||
bucwut `$?` %bcwt
|
||||
==========================
|
||||
|
||||
Fork
|
||||
|
||||
`$?` produces a fork, called a `%fern`. A `%fern` is a non-empty list of
|
||||
cases.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Tile](): `[%fern p=[i=tile t=(list tile)]]`.
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [list]() of [tiles]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
$? p
|
||||
q
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
?(p q)
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
++ base ?([%atom p=odor] %noun %cell %bean %null) :: axils, @ * ^ ? ~
|
||||
|
||||
`++base`, `?` (the irregular form of `$?`) specifies a list of
|
||||
orthoganal cases for the `%axil` tile.
|
||||
|
||||
~zod/try=> *?(%a %b %c)
|
||||
%a
|
||||
~zod/try=> :type; *?(%a %b %c)
|
||||
%a
|
||||
{%a %b %c}
|
@ -1,40 +0,0 @@
|
||||
buczap `$!` %bczp
|
||||
==========================
|
||||
|
||||
Axil bunt
|
||||
|
||||
`$!` is an synthetic internal twig that produces the [bunt]() (default
|
||||
value) for `[%axil p]`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
[Twig](): `[%bczp p=base]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [base]() [axil]() type.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> (ream '~')
|
||||
[%bczp p=%null]
|
||||
~zod/try=> (make '~')
|
||||
[%1 p=0]
|
@ -1,47 +0,0 @@
|
||||
<div class="short">
|
||||
|
||||
`bar | %bar`
|
||||
============
|
||||
|
||||
Core construction
|
||||
-----------------
|
||||
|
||||
The `|` runes construct [core]()s. In the broadest case you can think of
|
||||
a core as similar to an object with named properties that can contain
|
||||
either functions or data.
|
||||
|
||||
The `|` runes accept an associative array of names ([++term]()) to
|
||||
([++foot]()), each pair of which are called an [++arm](), producing one
|
||||
of the three basic categories of core.
|
||||
|
||||
</div>
|
||||
|
||||
#### The natural, generic core:
|
||||
|
||||
[`|%`]() Generic core, with [++arms] generally containing [++twig]()s
|
||||
|
||||
<hr></hr>
|
||||
|
||||
#### Doors, generic core with a sample:
|
||||
|
||||
##### Gates:
|
||||
|
||||
Cores with one arm [`$`], the empty name and which takes a sample
|
||||
`p`. The closest thing in Hoon to a function.
|
||||
|
||||
[`|=`]() [`dry`]() gate, where the [sample]() is typechecked at compile
|
||||
time. [`|*`]() [`wet`]() gate, where the sample is typechecked at
|
||||
runtime against its product type.
|
||||
|
||||
##### Traps:
|
||||
|
||||
Traps reduce to a `|%` with one arm `$`, the empty name. A trap is just
|
||||
some computation that has been put inside of a wrapper so that it may be
|
||||
passed around.
|
||||
|
||||
[`|.`]() Generic trap. [`|-`]() Trap automatically [kick]ed (called)
|
||||
after construction.
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<kids></kids>
|
@ -1,118 +0,0 @@
|
||||
barcab, `|_`, %brcb
|
||||
============================
|
||||
|
||||
Door: core with sample
|
||||
|
||||
`|_` is a synthetic rune that produces a [`%gold`]() [door]() with
|
||||
sample `p` and [arms]() `q`. The list must be closed with a `--`.
|
||||
|
||||
`|_` is similar to `|%`, but defines a sample for the set of arms it
|
||||
contains. Moreover, `|_` only accepts [dry or `%elm`]() arms. Put
|
||||
simply, type checking on these arms is performed on the input before
|
||||
computation. For more on variance, see the [glossary entry]() and the
|
||||
examples below.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
[barcen, `|%`, `%brcn`]() [barfas, `|/`, `%brfs`]()
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brcb p=tile q=(map term foot)]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile](). `q` is a [`map`]() with [`++term`]() keys and
|
||||
[`++foot`]() values.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|_ p
|
||||
++ p.n.q
|
||||
q.n.q
|
||||
--
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> =mol
|
||||
|_ a=@ud
|
||||
++ succ +(a)
|
||||
++ prev (dec a)
|
||||
--
|
||||
/~zod/try=> ~(succ mol 1)
|
||||
2
|
||||
/~zod/try=> ~(succ mol ~(succ mol ~(prev mol 5)))
|
||||
6
|
||||
|
||||
In this example we create a door `mol` that operates on a [`@ud`](),
|
||||
`a`. We add two arms to our door, `++succ` and `++prev`, and invoke them
|
||||
with the irregular form of [`%~`](). Doors are commonly invoked with
|
||||
`%~`, irregular form `~(arm door sample)`, which replaces the door's
|
||||
sample and pulls the specified arm.
|
||||
|
||||
/~zod/try=> =kom
|
||||
|_ a=(list)
|
||||
++ hed -.a
|
||||
++ tal +.a
|
||||
--
|
||||
new var %kom
|
||||
/~zod/try=> =kot
|
||||
|/ a=(list)
|
||||
+- hed -.a
|
||||
+- tal +.a
|
||||
--
|
||||
new var %kot
|
||||
/~zod/try=> ~(tal kom "abc")
|
||||
t=~[98 99]
|
||||
/~zod/try=> ~(tal kot "abc")
|
||||
t="bc"
|
||||
/~zod/try=> ~(tal kot [1 2 3 ~])
|
||||
[2 3 ~]
|
||||
/~zod/try=> ~(tal kom [1 2 3 ~])
|
||||
t=~[2 3]
|
||||
|
||||
Here we're demonstrating the difference between `|_` and `|/`. We create
|
||||
a nearly identical door using both runes, each with an arm that produces
|
||||
the tail of the sample, `a`. You can see that our wet gates use the
|
||||
sample as a tile to produce well-typed output.
|
||||
|
||||
++ ne
|
||||
|_ tig=@
|
||||
++ d (add tig '0')
|
||||
++ x ?:((gte tig 10) (add tig 87) d)
|
||||
++ v ?:((gte tig 10) (add tig 87) d)
|
||||
++ w ?:(=(tig 63) '~' ?:(=(tig 62) '-' ?:((gte tig 36) (add tig 29) x)))
|
||||
--
|
||||
::
|
||||
|
||||
`++ne` is used to print a single digit in base 10, 16, 32, or 64 and is
|
||||
a part of the hoon standard library. You can find it in `hoon.hoon`.
|
||||
`|_` is very commonly used throughout our standard library for groups of
|
||||
arms who all take the same sample.
|
||||
|
||||
~zod/try=> ~(x ne 12)
|
||||
99
|
||||
~zod/try=> `@t`~(x ne 12)
|
||||
'c'
|
||||
~zod/try=> `@ux`12
|
||||
0xc
|
||||
|
||||
Here we put `++ne` to work a bit. Our first call renders 12 in base 16.
|
||||
Since `99` is within the ASCII character range, we can cast it to a
|
||||
[`@t`]() and get `'c'`. Conveniently, casting `12` to a [`@ux`]()
|
||||
results in `0xc`.
|
@ -1,135 +0,0 @@
|
||||
barcen, `|%`, %brcn
|
||||
============================
|
||||
|
||||
Build Core
|
||||
|
||||
`|%` is a natural rune that produces a [core](). `|%` takes a list of
|
||||
[arm]()s . The list must be closed with a `--`.
|
||||
|
||||
The product of `|%` is similar to an object with named properties
|
||||
containing either functions or data. A `|%` accepts both [dry or
|
||||
`%elm`]() and [wet or `%ash`]() arms. For more about variance, see the
|
||||
[glossary]().
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
[barcab, `|_`, `%brcb`]() [barfas, `|/`, `%brfs`]()
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brcn p=(map term foot)]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`map`]() with [`++term`]() keys and [`++foot`]() values, which
|
||||
are called arms.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|%
|
||||
++ p.n.q
|
||||
q.n.q
|
||||
+- p.n.l.q
|
||||
q.n.l.q
|
||||
--
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=>
|
||||
=a |%
|
||||
++ n 100
|
||||
++ g |= b=@
|
||||
(add b n)
|
||||
--
|
||||
new var %a
|
||||
/~zod/try=>
|
||||
(g.a 1)
|
||||
101
|
||||
|
||||
Here we create a core with two arms `n`, a constant and `g`, a simple
|
||||
function. `g` adds our constant `n` to whatever is passed to it.
|
||||
|
||||
/~zod/try=>
|
||||
=a |%
|
||||
++ l |%
|
||||
++ r 100
|
||||
++ s 4
|
||||
--
|
||||
++ g |= b=@
|
||||
(div (add b r:l) s:l)
|
||||
--
|
||||
changed %a
|
||||
/~zod/try=>
|
||||
(g.a 4)
|
||||
26
|
||||
|
||||
Extending our previous example a bit, we nest a core inside our arm `l`
|
||||
and make our [gate]() `g` a bit more complicated. `g` now computes the
|
||||
sum of its argument and the arm `r` inside `l`, and divides that by `s`
|
||||
inside `l`.
|
||||
|
||||
++ yo
|
||||
|% ++ cet 36.524 :: (add 24 (mul 100 365))
|
||||
++ day 86.400 :: (mul 24 hor)
|
||||
++ era 146.097 :: (add 1 (mul 4 cet))
|
||||
++ hor 3.600 :: (mul 60 mit)
|
||||
++ jes 106.751.991.084.417 :: (mul 730.692.561 era)
|
||||
++ mit 60
|
||||
++ moh `(list ,@ud)`[31 28 31 30 31 30 31 31 30 31 30 31 ~]
|
||||
++ moy `(list ,@ud)`[31 29 31 30 31 30 31 31 30 31 30 31 ~]
|
||||
++ qad 126.144.001 :: (add 1 (mul 4 yer))
|
||||
++ yer 31.536.000 :: (mul 365 day)
|
||||
--
|
||||
|
||||
[`++yo`](), found in `hoon.hoon`, uses `|%` to create a core whose arms
|
||||
contain constant data for calculating time. As the following examples
|
||||
shows, `|%` is also used to encapsulate arms that perform calculations.
|
||||
|
||||
++ si :: signed integer
|
||||
|%
|
||||
++ abs |=(a=@s (add (end 0 1 a) (rsh 0 1 a)))
|
||||
++ dif |=([a=@s b=@s] (sum a (new !(syn b) (abs b))))
|
||||
++ dul |=([a=@s b=@] =+(c=(old a) ?:(-.c (mod +.c b) (sub b +.c))))
|
||||
++ fra |= [a=@s b=@s]
|
||||
(new =(0 (mix (syn a) (syn b))) (div (abs a) (abs b)))
|
||||
++ new |=([a=? b=@] `@s`?:(a (mul 2 b) ?:(=(0 b) 0 +((mul 2 (dec b))))))
|
||||
++ old |=(a=@s [(syn a) (abs a)])
|
||||
++ pro |= [a=@s b=@s]
|
||||
(new =(0 (mix (syn a) (syn b))) (mul (abs a) (abs b)))
|
||||
++ rem |=([a=@s b=@s] (dif a (pro b (fra a b))))
|
||||
++ sum |= [a=@s b=@s]
|
||||
~| %si-sum
|
||||
=+ [c=(old a) d=(old b)]
|
||||
?: -.c
|
||||
?: -.d
|
||||
(new & (add +.c +.d))
|
||||
?: (gte +.c +.d)
|
||||
(new & (sub +.c +.d))
|
||||
(new | (sub +.d +.c))
|
||||
?: -.d
|
||||
?: (gte +.c +.d)
|
||||
(new | (sub +.c +.d))
|
||||
(new & (sub +.d +.c))
|
||||
(new | (add +.c +.d))
|
||||
++ sun |=(a=@u (mul 2 a))
|
||||
++ syn |=(a=@s =(0 (end 0 1 a)))
|
||||
--
|
||||
|
||||
[`++si`](), found in `hoon.hoon`, uses `|%` to create a core whose arms
|
||||
contain gates used to calculate with signed integers, [`@s`](). In this
|
||||
case our core is made up entirely of gates.
|
@ -1,114 +0,0 @@
|
||||
bardot, `|.`, %brdt
|
||||
============================
|
||||
|
||||
Trap
|
||||
|
||||
`|.`, is a synthetic rune that produces a [dry]() [`%gold`]() trap. A
|
||||
trap is a [`door`]() with one only arm [`$`](), the empty name.
|
||||
|
||||
The default action performed on a trap is kicking it by pulling the arm
|
||||
`$`. `|.` is similar to `|=` with no arguments. You can think of `|.` as
|
||||
a function that takes no inputs.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
barhep, `|-`, %brhp](#brhp) [bartis, `|=`, %brts
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brdt p=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`++twig`]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|. p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
|.(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=>
|
||||
=a |.(42)
|
||||
changed %a
|
||||
/~zod/try=>
|
||||
a
|
||||
< 1.yln
|
||||
[ a
|
||||
< 2.yqy
|
||||
[ a
|
||||
< 3.kii
|
||||
[ a
|
||||
< 2.wvx
|
||||
[ a=<2.kqf 2.hng 250.qyy 41.raw 414.hhh 100.xkc 1.ypj %164>
|
||||
<2.hng 250.qyy 41.raw 414.hhh 100.xkc 1.ypj %164>
|
||||
]
|
||||
>
|
||||
<2.hng 250.qyy 41.raw 414.hhh 100.xkc 1.ypj %164>
|
||||
]
|
||||
>
|
||||
<2.hng 250.qyy 41.raw 414.hhh 100.xkc 1.ypj %164>
|
||||
]
|
||||
>
|
||||
<2.hng 250.qyy 41.raw 414.hhh 100.xkc 1.ypj %164>
|
||||
]
|
||||
>
|
||||
/~zod/try=>
|
||||
(a)
|
||||
42
|
||||
/~zod/try=>
|
||||
$:a
|
||||
42
|
||||
|
||||
This is a simple example. We assign a shell variable `a` to be a trap
|
||||
that simply produces the atom `42`. Printing `a` prints the core and its
|
||||
context. Calling `a` using `(`, the irregular form of [`%-`](), produces
|
||||
its value. As does pulling the arm `$` from inside it using `$:a`.
|
||||
|
||||
/~zod/try=>
|
||||
=a 10
|
||||
changed %a
|
||||
/~zod/try=>
|
||||
=b |. (add a 2)
|
||||
changed %b
|
||||
/~zod/try=>
|
||||
(b)
|
||||
12
|
||||
|
||||
In this case we assign a variable `a` to be `10`, and create a trap `b`
|
||||
to add `2` to it. This is a trivial example, but is meant to show that
|
||||
traps are useful when you need a gate that only operates on values that
|
||||
are already in its context.
|
||||
|
||||
/~zod/try=>
|
||||
=loop =+ reps=10
|
||||
=+ step=0
|
||||
=+ outp=0
|
||||
|.
|
||||
?: =(step reps)
|
||||
outp
|
||||
$(outp (add outp 2), step +(step))
|
||||
changed %loop
|
||||
/~zod/try=> (loop)
|
||||
20
|
||||
|
||||
Expanding on our previous example, we create a trap with three local
|
||||
variables, `reps`, `step`, and `outp`. We use a trap to create a loop,
|
||||
testing each time if `step` is equal to `reps`, if so producing `outp`
|
||||
otherwise calling our trap again with `outp` replaced with `outp+2`, and
|
||||
`step` incremented.
|
@ -1,105 +0,0 @@
|
||||
barfas, `|/`, %brfs
|
||||
============================
|
||||
|
||||
Door with tile
|
||||
|
||||
`|/` is a synthetic rune that produces a [`%gold`]() [door]() with
|
||||
sample `[%bctr p]` and list of [arm]()s `q`. The list of arms must be
|
||||
closed with a `--`.
|
||||
|
||||
`|/` is similar to `|_` in that it accepts a sample for the set of arms
|
||||
, but differs in that it accepts [wet or `%ash`]() arms.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
[barcab, `|_`, `%brcb`]() [barcen, `|%`, `%brcn`]()
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brfs p=tile q=(map term foot)]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a tile. `q` is a [`map`]() with [`++term`]() keys and
|
||||
[`++foot`]() values.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|/ p
|
||||
+- p.n.q
|
||||
q.n.q
|
||||
--
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> =fas |/
|
||||
a=@
|
||||
+- two (mul a 2)
|
||||
+- for (div a 2)
|
||||
--
|
||||
new var %fas
|
||||
/~zod/try=> ~(two fas 2)
|
||||
4
|
||||
/~zod/try=> ~(for fas ~(for fas ~(two fas 12)))
|
||||
6
|
||||
|
||||
In this simple example we're creating a door with two arms. One arm
|
||||
divides our sample by two, the other divides by two.
|
||||
|
||||
/~zod/try=> =kom
|
||||
|_ a=(list)
|
||||
++ hed -.a
|
||||
++ tal +.a
|
||||
--
|
||||
new var %kom
|
||||
/~zod/try=> =kot
|
||||
|/ a=(list)
|
||||
+- hed -.a
|
||||
+- tal +.a
|
||||
--
|
||||
new var %kot
|
||||
/~zod/try=> ~(tal kom "abc")
|
||||
t=~[98 99]
|
||||
/~zod/try=> ~(tal kot "abc")
|
||||
t="bc"
|
||||
/~zod/try=> ~(tal kot [1 2 3 ~])
|
||||
[2 3 ~]
|
||||
/~zod/try=> ~(tal kom [1 2 3 ~])
|
||||
t=~[2 3]
|
||||
|
||||
Here we're demonstrating the difference between `|_` and `|/`. We create
|
||||
a nearly identical door using both runes, each with an arm that produces
|
||||
the tail of the sample, `a`. You can see that our wet gates use the
|
||||
sample as a tile to produce well-typed output.
|
||||
|
||||
++ by :: map engine
|
||||
~/ %by
|
||||
|/ a=(map)
|
||||
::
|
||||
+- all
|
||||
~/ %all
|
||||
|* b=$+(* ?)
|
||||
|- ^- ?
|
||||
?@ a
|
||||
&
|
||||
?&((b q.n.a) $(a l.a) $(a r.a))
|
||||
|
||||
All of the container engines in `hoon.hoon` use `|/` to set up the tile
|
||||
for their operations. In `++by`, the map engine, `|/` creates a door
|
||||
that takes a map that is passed to its arms. See more about using `++by`
|
||||
in the [library]().
|
@ -1,78 +0,0 @@
|
||||
barhep, `|-`, %brhp
|
||||
============================
|
||||
|
||||
Kicked trap
|
||||
|
||||
`|-` is a synthetic rune that produces a dry [`%gold`]() trap and
|
||||
[kicks]() it. You can think of a trap like a 'trap door', since `|-` is
|
||||
a [`door`]() with only one arm [`$`](), the empty name.
|
||||
|
||||
`|-` is different from `|.` in that it is kicked by default. `|-` is
|
||||
similar to creating and calling an anonymous function and is quite
|
||||
commonly used for loops or recursion.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
bardot, `|.`, %brdt
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brhp p=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a twig
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|- p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
|-(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> |-(42)
|
||||
42
|
||||
|
||||
In contrast to our `|.` example, `|-` is kicked by default, so its
|
||||
internals are produced immediately.
|
||||
|
||||
/~zod/try=> =+ a=`*`~[41 42]
|
||||
|-
|
||||
?~ a
|
||||
~
|
||||
[-.a %m $(a +.a)]
|
||||
[41 %m [42 %m ~]]
|
||||
|
||||
In this case we use `|-` for one of its most common applications, a
|
||||
loop. Here we walk across `a` by calling `$` with `a` replaced by `+.a`,
|
||||
producing a nested tuple.
|
||||
|
||||
++ dec :: decrement
|
||||
~/ %dec
|
||||
|= a=@
|
||||
~| %decrement-underflow
|
||||
?< =(0 a)
|
||||
=+ b=0
|
||||
|- ^- @
|
||||
?: =(a +(b))
|
||||
b
|
||||
$(b +(b))
|
||||
|
||||
In `++dec`, found in `hoon.hoon`, `|-` creates a trap that contains the
|
||||
test and looping semantics. Essentially, we count up to `a-1` by
|
||||
incrementing `b`. Using `|-` inside an existing core as we do here is
|
||||
its most common use.
|
@ -1,103 +0,0 @@
|
||||
barket, `|^`, %brkt
|
||||
============================
|
||||
|
||||
Kicked book
|
||||
|
||||
`|^` is a synthetic rune that produces and then kicks a [`%gold`]()
|
||||
[book]() with sample `p` as a [`%$(p)`](), and a list of [arm]()s `q`.
|
||||
The list must be closed with a `--`.
|
||||
|
||||
`|^` is similar to `|-`, but differs in that it can contain internal
|
||||
arms.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
barhep, `|-`, %brhp](#brhp) [barcab, `|_`, %brcb
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brkt p=twig q=(map term foot)]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](). `q` is a [`map`]() with [`++term`]() keys and
|
||||
[`++foot`]() values, which are called arms.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|^ p
|
||||
++ p.n.q
|
||||
q.n.q
|
||||
--
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
None
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> =+ a=21
|
||||
|^ [square double]
|
||||
++ square (mul a a)
|
||||
++ double (mul 2 a)
|
||||
--
|
||||
[441 42]
|
||||
|
||||
Here `|^` computes a result by calling its helper arms `++square` and
|
||||
`++double`. Notice that `a` is also in the context. `|^` is most
|
||||
commonly used inside another gate or core.
|
||||
|
||||
++ mum :: mug with murmur3
|
||||
~/ %mum
|
||||
|= a=*
|
||||
|^ (trim ?@(a a (mix $(a -.a) (mix 0x7fff.ffff $(a +.a)))))
|
||||
++ spec :: standard murmur3
|
||||
|= [syd=@ key=@]
|
||||
?> (lte (met 5 syd) 1)
|
||||
=+ ^= row
|
||||
|= [a=@ b=@]
|
||||
(con (end 5 1 (lsh 0 a b)) (rsh 0 (sub 32 a) b))
|
||||
=+ mow=|=([a=@ b=@] (end 5 1 (mul a b)))
|
||||
=+ len=(met 5 key)
|
||||
=- =. goc (mix goc len)
|
||||
=. goc (mix goc (rsh 4 1 goc))
|
||||
=. goc (mow goc 0x85eb.ca6b)
|
||||
=. goc (mix goc (rsh 0 13 goc))
|
||||
=. goc (mow goc 0xc2b2.ae35)
|
||||
(mix goc (rsh 4 1 goc))
|
||||
^= goc
|
||||
=+ [inx=0 goc=syd]
|
||||
|- ^- @
|
||||
?: =(inx len) goc
|
||||
=+ kop=(cut 5 [inx 1] key)
|
||||
=. kop (mow kop 0xcc9e.2d51)
|
||||
=. kop (row 15 kop)
|
||||
=. kop (mow kop 0x1b87.3593)
|
||||
=. goc (mix kop goc)
|
||||
=. goc (row 13 goc)
|
||||
=. goc (end 5 1 (add 0xe654.6b64 (mul 5 goc)))
|
||||
$(inx +(inx))
|
||||
::
|
||||
++ trim :: 31-bit nonzero
|
||||
|= key=@
|
||||
=+ syd=0xcafe.babe
|
||||
|- ^- @
|
||||
=+ haz=(spec syd key)
|
||||
=+ ham=(mix (rsh 0 31 haz) (end 0 31 haz))
|
||||
?.(=(0 ham) ham $(syd +(syd)))
|
||||
--
|
||||
::
|
||||
|
||||
[`++mum`]() is a hashing gate, which uses two helper arms to computes
|
||||
its results. The `|^` at the top performs the computation.
|
@ -1,63 +0,0 @@
|
||||
barlus, `|+`, %brls
|
||||
============================
|
||||
|
||||
`%iron` gate
|
||||
|
||||
`|+` is a synthetic rune that produces a [dry]() [`%iron`]() [gate]()
|
||||
with sample [`$*(p)`]() and [arm]()s `q`. `|+` is similar to `|=`, but
|
||||
differs in that its sample cannot be read. It can be thought of as
|
||||
similar to a private function.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
bartis, `|=`, %brts
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brls p=tile q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile](). `q` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|+ p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
|+(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> +<:|+(a=@ a)
|
||||
! -axis.6
|
||||
! peek-park
|
||||
! exit
|
||||
~zod/try=> +<:|=(a=@ a)
|
||||
a=0
|
||||
|
||||
Here we're trying to read the sample, using `+<` of two different kinds
|
||||
of gates. With `|+` you can see we cause an error, whereas with `|=` our
|
||||
default sample is `a=0`.
|
||||
|
||||
~zod/try=> %.(20 |+(a=@ a))
|
||||
20
|
||||
~zod/try=> %.(20 |=(a=@ a))
|
||||
20
|
||||
~zod/try=> %.(20 |+(a=@ (add a 12)))
|
||||
32
|
||||
|
||||
Kicking a `|+` gate, however, is the same as `|=`.
|
@ -1,73 +0,0 @@
|
||||
bartar, `|*`, %brtr
|
||||
============================
|
||||
|
||||
Wet gate
|
||||
|
||||
`|*` is a synthetic rune that produces a [wet]() [gate]() with sample
|
||||
[`$*(p)`](), arm `q`. A gate is a core with one arm, [`$`](), the empty
|
||||
name.
|
||||
|
||||
`|*` is similar to a function in the same way that `|=` is, but differs
|
||||
in that it does type checking at runtime. With `|*`, the product type is
|
||||
checked to be the same as the input type, rather than the sample tile.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
bartis, `|=`, %brts
|
||||
============================
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brtr p=tile q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile](). `q` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|* p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
|*(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> %.('c' |*(a=@ a))
|
||||
'c'
|
||||
~zod/try=> %.('c' |=(a=@ a))
|
||||
99
|
||||
|
||||
This is a concise way of understanding the difference between `|*` and
|
||||
`|=`. We use `%.` in both cases to slam each gate with the sample `'c'`.
|
||||
`|=` uses its tile `a=@` to cast `'c'` to an atom (`99` is the ASCII
|
||||
code for `'c'`). `|*` simply ensures that the product type matches the
|
||||
input sample type.
|
||||
|
||||
++ flop :: reverse
|
||||
~/ %flop
|
||||
|* a=(list)
|
||||
=> .(a (homo a))
|
||||
^+ a
|
||||
=+ b=`_a`~
|
||||
|-
|
||||
?@ a
|
||||
b
|
||||
$(a t.a, b [i.a b])
|
||||
|
||||
In [`++flop`](), `|*` is used so the type information within the passed
|
||||
in list is maintained. Without a `|*`, any cords would be cast to nouns
|
||||
as in our previous example.
|
@ -1,71 +0,0 @@
|
||||
bartis, `|=`, %brts
|
||||
============================
|
||||
|
||||
Dry gate
|
||||
|
||||
`|=`, is a synthetic rune that produces a [dry]() [`%gold`]() gate with
|
||||
sample [`$*(p)`](), arm `q`. A gate is a core with one arm, [`$`](), the
|
||||
empty name. `|=` checks its input sample against its tile, `p`.
|
||||
|
||||
`|=` is similar to a function that takes a defined input and produces
|
||||
the result of some computation. `|=` differs from `|*` in that its
|
||||
typechecking occurs at compile-time to ensure that all inputs match its
|
||||
sample tile.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
bartar, `|*`, %brtr
|
||||
============================
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brts p=tile q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [tile](). `q` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|= p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
|=(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> =inc |=(a=@ +(a))
|
||||
~zod/try=> (inc 20)
|
||||
21
|
||||
|
||||
Here we create a very simple gate that increments its sample, `a`. You
|
||||
can think of `|=` as similar to a straightforward function that takes
|
||||
arguments.
|
||||
|
||||
++ add :: add
|
||||
~/ %add
|
||||
|= [a=@ b=@]
|
||||
^- @
|
||||
?: =(0 a)
|
||||
b
|
||||
$(a (dec a), b +(b))
|
||||
|
||||
In [++add](), from `hoon.hoon`, `|=` creates a gate whose sample takes
|
||||
two atoms labeled `a` and `b`, and whose arm evaluates an expression
|
||||
that produces the sum of the atoms by decrementing `a` until it is `0`
|
||||
and incrementing `b` at each step. Here, `$` is used for recursion,
|
||||
calling the gate produced by `|=` with `a` replaced by `(dec a)` and `b`
|
||||
replaced by `+(b)`.
|
@ -1,54 +0,0 @@
|
||||
barwut, `|?`, %brwt
|
||||
============================
|
||||
|
||||
`%lead` trap
|
||||
|
||||
`|?` is a synthetic rune that produces a dry [`%lead`]() trap. `%lead`
|
||||
traps are used when we want to pass one core to another core, as both
|
||||
the sample and context of the core being passed must must be hidden in
|
||||
order to avoid type conflicts with a core that has a different sample
|
||||
and context.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%brwt q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`q` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
|? p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
|?(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> |?(20)
|
||||
< 1?lld
|
||||
[[[@da @ta] [@p @ta] *''] @n <250.yum 41.int 414.hhh 100.xkc 1.ypj %164>]
|
||||
>
|
||||
~zod/try=> +:|?(20)
|
||||
! -axis.3
|
||||
! peek-park
|
||||
! exit
|
||||
~zod/try=> +:|.(20)
|
||||
[ [[~2014.10.22..19.39.41..0440 ~.~2014.10.22..19.39.41..0440] [~zod ~.~zod] <||>]
|
||||
~
|
||||
<250.yum 41.int 414.hhh 100.xkc 1.ypj %164>
|
||||
]
|
||||
|
||||
A lead core's payload cannot be read or written.
|
@ -1,44 +0,0 @@
|
||||
<div class="short">
|
||||
|
||||
`col : %col`
|
||||
============
|
||||
|
||||
Tuples
|
||||
------
|
||||
|
||||
The `:` runes construct [tuples]().
|
||||
|
||||
There is no natural `:` rune. Instead, all of them derive from the
|
||||
autocons property of `++twig`, as show below.
|
||||
|
||||
++ twig $& [p=twig q=twig]
|
||||
|
||||
Namely, a cell of two twigs is a twig producing a cell of the results of
|
||||
the two original sub-twigs.
|
||||
|
||||
The `:` runes produce one of three categories of tuples
|
||||
|
||||
</div>
|
||||
|
||||
#### Tuples of determinate size:
|
||||
|
||||
[`:-`]() Tuples of two elements, `p` and `q`. [`:_`]() Tuples of two
|
||||
reversed elements, `q` and `p`. Used to ensure vertical code flow.\
|
||||
|
||||
[`:+`]() Tuples of three elements `p`, `q`, and `r`. [`:^`]() Tuples of
|
||||
four elements `p`, `q`, `r`, and `s`.
|
||||
|
||||
<hr></hr>
|
||||
|
||||
#### Tuples of indeterminate size:
|
||||
|
||||
[`:*`]() Tuples of n elements. [`:~`]() Null-terminated tuples of n
|
||||
elements.
|
||||
|
||||
#### Tuples used for interpolation:
|
||||
|
||||
[`:/`]() Tuple designed to be interpolated into an XML structure.
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<kids></kids>
|
@ -1,56 +0,0 @@
|
||||
colcab, `:_`, %clcb
|
||||
============================
|
||||
|
||||
Cell, backwards
|
||||
|
||||
`:_`, `colcab`, `[%clcb p=twig q=twig]` is a synthetic rune that
|
||||
produces the cell `[q p]`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%clcb p=twig q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](). `q` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
:_ p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:_(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
undefined
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> :_(1 2)
|
||||
[2 1]
|
||||
|
||||
A simple example. `:_` produces the cell of any two twigs, but in
|
||||
reverse order.
|
||||
|
||||
~zod/try=> `tape`:_(~ 'a')
|
||||
"a"
|
||||
|
||||
Since a [`++tape`]() is a null-terminated list of characters, casting
|
||||
the result of `:_(~ 'a')` to a `tape` produces `"a"`.
|
||||
|
||||
/~zod/try=>
|
||||
:_ (add 2 2)
|
||||
|- (div 4 2)
|
||||
[2 4]
|
||||
|
||||
Most commonly `:_` helps to organize code, allowing you to produce a
|
||||
cell from nested computation.
|
@ -1,47 +0,0 @@
|
||||
colfas, `:/`, %clfs
|
||||
============================
|
||||
|
||||
Internal interpolation
|
||||
|
||||
`:/`, `colfas`, is a synthetic rune that produces `[%$ [%$ p ~] ~]`,
|
||||
i.e., `[0 [0 p 0] 0]`.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
[`++manx`]() [`%smdq`](#smdq)
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%clfs p=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig]()
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
:/ p
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:/(p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
undefined
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> :/(20)
|
||||
[[%~. [%~. 20] ~] ~]
|
||||
~zod/try=> :/(add 2 2)
|
||||
[[%~. [%~. 4] ~] ~]
|
||||
|
||||
Wraps twig in `[%$ [%$ .] ~]~`, used for interpolation.
|
@ -1,85 +0,0 @@
|
||||
colhep, `:-`, %clhp
|
||||
============================
|
||||
|
||||
Cell
|
||||
|
||||
`:-`, `colhep`, `[%clhp p=twig q=twig]` is a synthetic rune that
|
||||
produces the cell `[p q]`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%clhp p=twig q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](). `q` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
:- p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:-(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
[p q]
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
~zod/try=> :-(1 2)
|
||||
[1 2]
|
||||
~zod/try=> :- 'a'
|
||||
%b
|
||||
['a' %b]
|
||||
|
||||
This is the most straightforward case of `:-`, producing a cell of
|
||||
static data in either tall or wide form.
|
||||
|
||||
/~zod/try=>
|
||||
:- (add 2 2)
|
||||
|- (div 4 2)
|
||||
[4 2]
|
||||
|
||||
Most commonly `:-` helps to organize code, allowing you to produce a
|
||||
cell from nested computation.
|
||||
|
||||
Some obscure `:-` irregular forms.
|
||||
==================================
|
||||
|
||||
Moveme: irregular form doc
|
||||
|
||||
### Infix `^`
|
||||
|
||||
~zod/main=/app> 1^2^3
|
||||
[1 2 3]
|
||||
|
||||
`a^b` is equivalent to `:- a b`
|
||||
|
||||
### Infix `/`
|
||||
|
||||
~zod/main=/app> a/1
|
||||
[%a 1]
|
||||
~zod/main=/app> a/'twig'
|
||||
[%a 'twig']
|
||||
|
||||
Like `^`, but first item must be a term, and is cubed. Used to construct
|
||||
paths and fronds.
|
||||
|
||||
### Prefix `` ` ``, postfix `~`
|
||||
|
||||
~zod/main=/app> ````20
|
||||
[~ ~ ~ ~ 20]
|
||||
~zod/main=/app> [42 30]~
|
||||
[[42 30] ~]
|
||||
|
||||
Complimenting each other, these construct pairs with nil in the head and
|
||||
tail respectively. Multiple postfix `~` do not work for unknown reasons.
|
@ -1,68 +0,0 @@
|
||||
colket, `:^`, %clkt
|
||||
============================
|
||||
|
||||
Tuple of four
|
||||
|
||||
`:^` is a synthetic rune that produces a cell `[p q r s]`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%clkt p=twig q=twig r=twig s=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](). `q` is a [twig](). `r` is a [twig](). `s` is a
|
||||
[twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
Kingside:
|
||||
|
||||
:^ p
|
||||
q
|
||||
r
|
||||
s
|
||||
|
||||
Queenside:
|
||||
|
||||
:^ p q
|
||||
r
|
||||
s
|
||||
|
||||
:^ p q r
|
||||
s
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:^(p q r s)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
undefined
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> :^(1 2 3 4)
|
||||
[1 2 3 4]
|
||||
/~zod/try=> :^ 5 6
|
||||
7
|
||||
8
|
||||
[5 6 7 8]
|
||||
|
||||
This is the most straightforward case of `:^`, producing a tuple of four
|
||||
values in both tall and wide form.
|
||||
|
||||
/~zod/try=>
|
||||
:^ (add 2 4) (add 2 6)
|
||||
|- (div 4 2)
|
||||
~
|
||||
[6 8 2 ~]
|
||||
|
||||
Most commonly `:^` helps to organize code, allowing you to produce a
|
||||
cell from nested computation.
|
@ -1,61 +0,0 @@
|
||||
collus, `:+`, %clls
|
||||
============================
|
||||
|
||||
Tuple of three
|
||||
|
||||
`:+` is a synthetic rune that produces a cell `[p q r]`.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%clls p=twig q=twig r=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](). `q` is a [twig](). `r` is a [twig]().
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
Kingside:
|
||||
|
||||
:+ p
|
||||
q
|
||||
r
|
||||
|
||||
Queenside:
|
||||
|
||||
:+ p q
|
||||
r
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:+(p q r)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
undefined
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> :+ 1
|
||||
2
|
||||
3
|
||||
[1 2 3]
|
||||
/~zod/try=> :+(%a ~ 'b')
|
||||
[%a ~ 'b']
|
||||
|
||||
This is the most straightforward case of `:+`, producing a tuple of four
|
||||
values in both tall and wide form.
|
||||
|
||||
/~zod/try=>
|
||||
:+ (add 2 4) (add 2 6)
|
||||
|- (div 4 2)
|
||||
[6 8 2]
|
||||
|
||||
Most commonly `:+` helps to organize code, allowing you to produce a
|
||||
cell from nested computation.
|
@ -1,69 +0,0 @@
|
||||
colsig, `:~`, %clsg
|
||||
============================
|
||||
|
||||
Null-terminated tuple
|
||||
|
||||
`:~`, `colsig`, `[%clsg p=tusk]` is a synthetic rune that produces a
|
||||
null-terminated tuple.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%clsg p=tusk]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`++tusk`](), a list of twigs.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
:~ i.p
|
||||
i.t.p
|
||||
i.t.t.p
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:~(i.p i.t.p i.t.t.p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
~[i.p i.t.p i.t.t.p]
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> :~(5 3 4 2 1)
|
||||
[5 3 4 2 1 ~]
|
||||
/~zod/try=> ~[5 3 4 2 1]
|
||||
[5 3 4 2 1 ~]
|
||||
/~zod/try=> :~ 5
|
||||
3
|
||||
4
|
||||
2
|
||||
1
|
||||
==
|
||||
[5 3 4 2 1 ~]
|
||||
|
||||
This is the most straightforward case of `:~`, producing a tuple of four
|
||||
values in wide, irregular and tall form.
|
||||
|
||||
/~zod/try=> %- flop
|
||||
%- limo
|
||||
:~ 5
|
||||
3
|
||||
4
|
||||
2
|
||||
1
|
||||
==
|
||||
~[1 2 4 3 5]
|
||||
|
||||
In this example we use `%-` to pass the results of our previous example
|
||||
to [`++limo`](), which creates a [`++list`](), and [`++flop`](), which
|
||||
reverses its order. This example shows how `:~` is commonly useful.
|
||||
Null-terminated tuples are easily converted to lists, which are
|
||||
frequently encountered in hoon.
|
@ -1,57 +0,0 @@
|
||||
coltar, `:*`, %cltr
|
||||
============================
|
||||
|
||||
Tuple
|
||||
|
||||
`:*`, `coltar`, `[%cltr p=tusk]` is a synthetic rune that produces a
|
||||
tuple.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cltr p=tusk]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`++tusk`](), a list of twigs.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
:~ i.p
|
||||
i.t.p
|
||||
i.t.t.p
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
:*(i.p i.t.p i.t.t.p)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
[i.p i.t.p i.t.t.p]
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> :*(5 3 4 1 4 9 0 ~ 'a')
|
||||
[5 3 4 1 4 9 0 ~ 'a']
|
||||
/~zod/try=> [5 3 4 1 4 9 0 ~ 'a']
|
||||
[5 3 4 1 4 9 0 ~ 'a']
|
||||
/~zod/try=> :* 5
|
||||
3
|
||||
4
|
||||
1
|
||||
4
|
||||
9
|
||||
0
|
||||
~
|
||||
'a'
|
||||
==
|
||||
[5 3 4 1 4 9 0 ~ 'a']
|
||||
|
||||
This is the most straightforward case of `:*`, producing a tuple of n
|
||||
values in wide, irregular and tall form.
|
@ -1,41 +0,0 @@
|
||||
<div class="short">
|
||||
|
||||
`cen % %cen`
|
||||
============
|
||||
|
||||
Pulling
|
||||
-------
|
||||
|
||||
The `%` runes [pull]() [`++arms`]() and [`++wings`]() from the
|
||||
[subject](), often modifying their values. The `%` runes are similar to
|
||||
function calls, or execution tools. We use them to either compute some
|
||||
code with changes in the subject, or produce the output from a core.
|
||||
|
||||
There are two categories of `%` runes.
|
||||
|
||||
</div>
|
||||
|
||||
#### Pull with changes:
|
||||
|
||||
[`%=`]() The natural `%` rune. Evaluates `p` with the changes specified
|
||||
in `q`.
|
||||
|
||||
[`%_`]() Evaluates `p` with the changes specified in `q`, then
|
||||
casts the product back to the type of `p`.
|
||||
|
||||
[`%*`]() Evaluates `p` from a [door]() `q` with changes `r`.Terminated by `==`.
|
||||
|
||||
<hr></hr>
|
||||
|
||||
### Pull the empty arm `$`, similar to calling a function:
|
||||
|
||||
[`%-`]() [slams]() a core with one argument.
|
||||
|
||||
[`%+`]() slams a core with two arguments.
|
||||
|
||||
[`%^`]() slams a core with three arguments.
|
||||
|
||||
|
||||
<hr></hr>
|
||||
|
||||
<kids></kids>
|
@ -1,74 +0,0 @@
|
||||
cencab, `%_`, %cncb
|
||||
============================
|
||||
|
||||
Evaluate with changes, cast
|
||||
|
||||
`%_` is a synthetic rune that evaluates `p` with the changes specified
|
||||
in `q`, then casts the product back to the type of `p`. `%_` is used to
|
||||
change a batch of [`++wing`]()s all at once, ensuring that the resulting
|
||||
product is type checked.
|
||||
|
||||
See also
|
||||
--------
|
||||
|
||||
[`%=`](#cnts) is similar, but without type-checking.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cncb p=wing q=tram]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [`++wing`](), a list of [`++limb`]()s. `q` is a [`++tram`](), a
|
||||
list of [`++wing`]()s and twigs.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
%_ p
|
||||
p.i.q q.i.q
|
||||
p.i.t.q q.i.t.q
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
%_(p p.i.q q.i.q, p.i.t.q q.i.t.q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> =a [b=1 c=2 d=3]
|
||||
new var %a
|
||||
/~zod/try=> %_(a b (add 3 b.a), c (add 3 c.a), d (add 3 d.a))
|
||||
[b=4 c=5 d=6]
|
||||
|
||||
Here we're using `%_` to add 3 to all of the values inside of our shell
|
||||
variable `a`.
|
||||
|
||||
/~zod/try=> =a [b='odors' c='twigs' d='tiles']
|
||||
changed %a
|
||||
/~zod/try=> %_(a b c.a, c d.a, d b.a)
|
||||
[b='twigs' c='tiles' d='odors']
|
||||
|
||||
In this case we're using `%_` to swap the values of the faces in `a`.
|
||||
|
||||
/~zod/try=> =+ a=1
|
||||
=+ z=|=(b=@ (add a b))
|
||||
(z 1)
|
||||
2
|
||||
/~zod/try=> =+ a=1
|
||||
=+ z=|=(b=@ (add a b))
|
||||
(%_(z a 100) 1)
|
||||
101
|
||||
|
||||
At first we set up a simple gate `z` with a variable, `a` in its
|
||||
context. Subsequently we use `%_` to change the value of `a` within the
|
||||
context of `z` and compute the output again.
|
@ -1,55 +0,0 @@
|
||||
cencol, `%:`, %cncl
|
||||
============================
|
||||
|
||||
Slam, one argument
|
||||
|
||||
`%:` is a synthetic rune that that [pull]()s [`$`]() from the [door]()
|
||||
`p` with its sample set to `q`. `%:` in the most common case simply
|
||||
[slam]()s `p` with `q`, similar to a function call with one argument.
|
||||
Unlike its close relative `%-`, `%:` is designed for [gate]()s who take
|
||||
a single value as their sample.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cncl p=twig q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](), most commonly a [gate]() `q` is a [twig]()
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
%: p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
%:(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> %:(dec 42)
|
||||
41
|
||||
|
||||
Here we use `%:` in its most straightforward form, to call an arm that
|
||||
takes one argument.
|
||||
|
||||
/~zod/try=> %: dec
|
||||
%+ add 2
|
||||
%+ mul 2 20
|
||||
41
|
||||
|
||||
Here we call [`++dec`]() with the sum of `2` and the product of `2` and
|
||||
`20` using `%:`. As you can see, `%:` is most useful for code
|
||||
organization, when you need to compute intermediate products for your
|
||||
final result
|
@ -1,62 +0,0 @@
|
||||
cendot, `%.`, %cndt
|
||||
============================
|
||||
|
||||
Slam, reverse order
|
||||
|
||||
`%.` is a synthetic rune that reverses the order of [`%-`](). `%.`
|
||||
exists primarily for code readability and organization, see the [style
|
||||
guide]().
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cndt p=twig q=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` and `q` are [twig]()s.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
%. p
|
||||
q
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
%.(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> (dec 42)
|
||||
41
|
||||
~zod/try=> %.(42 dec)
|
||||
41
|
||||
|
||||
In the most straightforward case `%.` allows us to reverse the order of
|
||||
arm and arguments.
|
||||
|
||||
/~zod/try=> %.
|
||||
%+ add
|
||||
%+ mul 2 20
|
||||
2
|
||||
dec
|
||||
41
|
||||
|
||||
Here we add `2` to the product of `2` and `20`, and use `%.` to
|
||||
decrement our result. As you can see, `%.` is most useful for code
|
||||
organization, when you need to compute intermediate products for your
|
||||
final result.
|
||||
|
||||
Equivalent to
|
||||
-------------
|
||||
|
||||
%-(q p)
|
@ -1,39 +0,0 @@
|
||||
cenhep, `%-`, %cnhp
|
||||
============================
|
||||
|
||||
Slam, n-arguments
|
||||
|
||||
Slam, 1 (or n) argument(s)
|
||||
|
||||
%- is a synthetic rune that that pulls $ from the door p with its sample set to [%cltr q]. %- in both its tall and wide forms is like a function call with one argument. However, %-is most commonly used in its irregular form, where p and q are enclosed within () where q is a list of n arguments.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cnhp p=twig q=tusk]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](), most commonly a [gate]() `q` is a [tusk](), a list of
|
||||
twigs
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
%- p
|
||||
q
|
||||
==
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
%-(p q)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
(p q)
|
||||
|
||||
Examples
|
||||
--------
|
@ -1,46 +0,0 @@
|
||||
cenket, `%^`, %cnkt
|
||||
============================
|
||||
|
||||
Slam, three arguments
|
||||
|
||||
`%^` is a synthetic rune that that [pull]()s [`$`]() from the [door]()
|
||||
`p` with its sample set to `[%cntr q r s]`. `%^` in the most common case
|
||||
simply [slam]()s `p` with `q`, `r` and `s`, similar to a function call
|
||||
with three arguments.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cnkt p=twig q=twig r=twig s=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](), most commonly a [gate](). `q`, `r` and `s` are
|
||||
[twig]()s.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
%^ p
|
||||
q
|
||||
r
|
||||
s
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
%^(p q r s)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
Equivalent to
|
||||
-------------
|
||||
|
||||
%-(p [q r s])
|
@ -1,59 +0,0 @@
|
||||
cenlus, `%+`, %cnls
|
||||
============================
|
||||
|
||||
Slam, two arguments
|
||||
|
||||
`%+` is a synthetic rune that that [pull]()s [`$`] from the [door]() `p`
|
||||
with its sample set to `[%cntr q r]`. `%+` in the most common case
|
||||
simply [slam]()s `p` with `q` and `r`, similar to a function call with
|
||||
two arguments.
|
||||
|
||||
Produces
|
||||
--------
|
||||
|
||||
Twig: `[%cnls p=twig q=twig r=twig]`
|
||||
|
||||
Sample
|
||||
------
|
||||
|
||||
`p` is a [twig](), most commonly a [gate](). `q` and `r` are [twig]()s.
|
||||
|
||||
Tall form
|
||||
---------
|
||||
|
||||
%+ p
|
||||
q
|
||||
r
|
||||
|
||||
Wide form
|
||||
---------
|
||||
|
||||
%+(p q r)
|
||||
|
||||
Irregular form
|
||||
--------------
|
||||
|
||||
None
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
/~zod/try=> =a |= [b=@ c=@]
|
||||
(add b c)
|
||||
new var %a
|
||||
/~zod/try=> %+ a
|
||||
2
|
||||
1
|
||||
3
|
||||
/~zod/try=> %+(a 2 3)
|
||||
5
|
||||
|
||||
First we set a shell variable `a` to be a gate that takes two arguments
|
||||
and produces their sum. Then we use `%+` to pass values to our gate.
|
||||
`%+` is most useful for code organization, when you need to compute
|
||||
intermediate products for your final computation.
|
||||
|
||||
Equivalent to
|
||||
-------------
|
||||
|
||||
%-(p [q r])
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user