mirror of
https://github.com/urbit/shrub.git
synced 2024-12-21 01:41:37 +03:00
commit
03f4bd35bb
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:9d131da321b891c126f62cc587c5e27c257695ff9ae15e502356159fba7f9bf3
|
||||
size 1234415
|
||||
oid sha256:df9ab46632f1a6727837eb03ddf5d37c8f415d89b3205fbc2005891fd3e8921e
|
||||
size 1234585
|
||||
|
@ -1,3 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:ecfe53c9e00d8cba244c85eb0ec0ed3b4e8ac07737bb0c6a7aa57d6c52f52c85
|
||||
size 15993675
|
||||
oid sha256:50a06217c5354abe42baec10072ddba8e0129c20806fc8173529989724397836
|
||||
size 12874302
|
||||
|
@ -2133,7 +2133,12 @@
|
||||
:: 3f: scrambling ::
|
||||
:: 3g: molds and mold builders ::
|
||||
:: ::
|
||||
~% %tri + ~
|
||||
~% %tri +
|
||||
==
|
||||
%year year
|
||||
%yore yore
|
||||
%ob ob
|
||||
==
|
||||
|%
|
||||
::
|
||||
:::: 3a: signed and modular ints ::
|
||||
@ -3810,13 +3815,20 @@
|
||||
--
|
||||
::
|
||||
++ ob
|
||||
~% %ob ..ob
|
||||
==
|
||||
%fein fein
|
||||
%fynd fynd
|
||||
==
|
||||
|%
|
||||
::
|
||||
:: +fein: conceal structure, v3.
|
||||
::
|
||||
:: +fein conceals planet-sized atoms. The idea is that it should not be
|
||||
:: trivial to tell which planet a star has spawned under.
|
||||
::
|
||||
++ fein
|
||||
~/ %fein
|
||||
|= pyn/@ ^- @
|
||||
?: &((gte pyn 0x1.0000) (lte pyn 0xffff.ffff))
|
||||
(add 0x1.0000 (feis (sub pyn 0x1.0000)))
|
||||
@ -3832,6 +3844,7 @@
|
||||
:: Restores obfuscated values that have been enciphered with +fein.
|
||||
::
|
||||
++ fynd
|
||||
~/ %fynd
|
||||
|= cry/@ ^- @
|
||||
?: &((gte cry 0x1.0000) (lte cry 0xffff.ffff))
|
||||
(add 0x1.0000 (tail (sub cry 0x1.0000)))
|
||||
@ -3841,7 +3854,6 @@
|
||||
%+ con hi
|
||||
$(cry lo)
|
||||
cry
|
||||
::
|
||||
:: +feis: a four-round generalised Feistel cipher over the domain
|
||||
:: [0, 2^32 - 2^16 - 1].
|
||||
::
|
||||
|
@ -5,7 +5,9 @@
|
||||
/** Tier 1.
|
||||
**/
|
||||
u3_noun u3ka_add(u3_noun a, u3_noun b);
|
||||
u3_noun u3ka_div(u3_noun a, u3_noun b);
|
||||
u3_noun u3ka_sub(u3_noun a, u3_noun b);
|
||||
u3_noun u3ka_mod(u3_noun a, u3_noun b);
|
||||
u3_noun u3ka_mul(u3_noun a, u3_noun b);
|
||||
u3_noun u3ka_gth(u3_noun a, u3_noun b);
|
||||
u3_noun u3ka_lte(u3_noun a, u3_noun b);
|
||||
@ -18,6 +20,10 @@
|
||||
|
||||
/* u3kc: tier 3 functions
|
||||
*/
|
||||
u3_noun
|
||||
u3kc_con(u3_noun a,
|
||||
u3_noun b);
|
||||
|
||||
/* u3kc_mix(): binary xor.
|
||||
*/
|
||||
u3_noun
|
||||
|
@ -70,6 +70,11 @@
|
||||
u3_noun u3qc_swp(u3_atom, u3_atom);
|
||||
u3_noun u3qc_sqt(u3_atom);
|
||||
|
||||
u3_noun u3_po_find_prefix(c3_y one, c3_y two, c3_y three);
|
||||
u3_noun u3_po_find_suffix(c3_y one, c3_y two, c3_y three);
|
||||
void u3_po_to_prefix(u3_noun id, c3_y* a, c3_y* b, c3_y* c);
|
||||
void u3_po_to_suffix(u3_noun id, c3_y* a, c3_y* b, c3_y* c);
|
||||
|
||||
/** Tier 4.
|
||||
**/
|
||||
u3_noun u3qdb_bif(u3_noun, u3_noun);
|
||||
|
@ -116,6 +116,10 @@
|
||||
u3_noun u3we_rexp(u3_noun);
|
||||
u3_noun u3we_trip(u3_noun);
|
||||
|
||||
u3_noun u3we_scow(u3_noun);
|
||||
u3_noun u3we_scot(u3_noun);
|
||||
u3_noun u3we_slaw(u3_noun);
|
||||
|
||||
u3_noun u3we_pfix(u3_noun);
|
||||
u3_noun u3we_plug(u3_noun);
|
||||
u3_noun u3we_pose(u3_noun);
|
||||
|
@ -523,3 +523,8 @@
|
||||
void* ptr_v,
|
||||
void (*pat_f)(u3_atom, void*),
|
||||
c3_o (*cel_f)(u3_noun, void*));
|
||||
|
||||
/* u3a_string(): `a` as an on-loom c-string.
|
||||
*/
|
||||
c3_c*
|
||||
u3a_string(u3_atom a);
|
||||
|
@ -21,6 +21,8 @@
|
||||
# define u3x_sam_15 55
|
||||
# define u3x_sam_30 110
|
||||
# define u3x_sam_31 111
|
||||
# define u3x_sam_62 222
|
||||
# define u3x_sam_63 223
|
||||
# define u3x_con 7 // context
|
||||
# define u3x_con_2 14 // context
|
||||
# define u3x_con_3 15 // context
|
||||
|
@ -44,3 +44,13 @@
|
||||
return u3qa_div(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
u3_noun
|
||||
u3ka_div(u3_noun a,
|
||||
u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qa_div(a, b);
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
}
|
||||
|
@ -10,15 +10,10 @@
|
||||
u3qa_mod(u3_atom a,
|
||||
u3_atom b)
|
||||
{
|
||||
#if 0
|
||||
if ( b == 3 && a == 2684227708 ) {
|
||||
printf("dword at 0x27ff84ff8 is %" PRIu64 "\r\n", *(c3_d *)0x27ff84ff8);
|
||||
*(c3_d *)0x27ff84ff8 = 25;
|
||||
printf("see, we modified it\r\n");
|
||||
}
|
||||
#endif
|
||||
if ( 0 == b ) {
|
||||
return u3m_bail(c3__exit);
|
||||
} else if ( _(u3a_is_cat(a)) && _(u3a_is_cat(b)) ) {
|
||||
return a % b;
|
||||
} else {
|
||||
mpz_t a_mp, b_mp;
|
||||
|
||||
@ -46,3 +41,12 @@
|
||||
return u3qa_mod(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3ka_mod(u3_noun a,
|
||||
u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qa_mod(a, b);
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
}
|
||||
|
@ -49,3 +49,12 @@
|
||||
return u3qc_con(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3kc_con(u3_noun a,
|
||||
u3_noun b)
|
||||
{
|
||||
u3_noun c = u3qc_con(a, b);
|
||||
u3z(a); u3z(b);
|
||||
return c;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
389
pkg/urbit/jets/e/scow.c
Normal file
389
pkg/urbit/jets/e/scow.c
Normal file
@ -0,0 +1,389 @@
|
||||
/* j/3/scow.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
static
|
||||
c3_y to_digit(c3_y tig)
|
||||
{
|
||||
if (tig >= 10) {
|
||||
return 87 + tig;
|
||||
} else {
|
||||
return '0' + tig;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
c3_y to_w_digit(c3_y tig)
|
||||
{
|
||||
if (tig == 63) {
|
||||
return '~';
|
||||
} else if (tig == 62) {
|
||||
return '-';
|
||||
} else if (tig >= 36) {
|
||||
return 29 + tig;
|
||||
} else if (tig >= 10) {
|
||||
return 87 + tig;
|
||||
} else {
|
||||
return '0' + tig;
|
||||
}
|
||||
}
|
||||
|
||||
// gives the characters for a four 'digit' small hex atom.
|
||||
static
|
||||
void
|
||||
_x_co_four(c3_w src, c3_y* a, c3_y* b, c3_y* c, c3_y* d)
|
||||
{
|
||||
*d = to_digit(src & 0xF);
|
||||
src >>= 4;
|
||||
*c = to_digit(src & 0xF);
|
||||
src >>= 4;
|
||||
*b = to_digit(src & 0xF);
|
||||
src >>= 4;
|
||||
*a = to_digit(src & 0xF);
|
||||
}
|
||||
|
||||
// The parser always prints two digits on 0 in y-co.
|
||||
static
|
||||
void
|
||||
_y_co_two(c3_w src, c3_y* a, c3_y* b)
|
||||
{
|
||||
*b = to_digit(src % 10);
|
||||
*a = to_digit(src / 10);
|
||||
}
|
||||
|
||||
//
|
||||
static
|
||||
u3_noun
|
||||
_add_year(c3_w year, u3_noun out)
|
||||
{
|
||||
while (year > 0) {
|
||||
out = u3nc(to_digit(year % 10), out);
|
||||
year = year / 10;
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun
|
||||
_print_da(u3_noun cor, u3_atom raw_da)
|
||||
{
|
||||
u3_noun hok = u3j_cook("u3we_scow_print_da", u3k(cor), "yore");
|
||||
u3_noun yod = u3n_slam_on(hok, u3k(raw_da));
|
||||
|
||||
u3_noun out = 0;
|
||||
|
||||
u3_atom age, year, month, day, hour, min, sec, f;
|
||||
if (c3n == u3r_mean(yod, 4, &age,
|
||||
5, &year,
|
||||
6, &month,
|
||||
14, &day,
|
||||
30, &hour,
|
||||
62, &min,
|
||||
126, &sec,
|
||||
127, &f,
|
||||
0)) {
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
|
||||
if (f != 0) {
|
||||
u3_noun f_list = u3qb_flop(f);
|
||||
|
||||
for (u3_noun cur = f_list;
|
||||
_(u3a_is_cell(cur));
|
||||
cur = u3t(cur)) {
|
||||
if (_(u3a_is_cat(u3h(cur)))) {
|
||||
c3_y a, b, c, d;
|
||||
_x_co_four(u3h(cur), &a, &b, &c, &d);
|
||||
out = u3nq('.', a, b, u3nt(c, d, out));
|
||||
} else {
|
||||
// No way to deal with big atoms. fall back.
|
||||
u3z(yod);
|
||||
u3z(out);
|
||||
u3z(f_list);
|
||||
return u3_none;
|
||||
}
|
||||
}
|
||||
|
||||
u3z(f_list);
|
||||
out = u3nc('.', out);
|
||||
}
|
||||
|
||||
// if there isn't a hex list and the h/m/s are all 0, skip printing hours.
|
||||
if (f != 0 || hour != 0 || min != 0 || sec != 0) {
|
||||
if (!_(u3a_is_cat(hour)) ||
|
||||
!_(u3a_is_cat(min)) ||
|
||||
!_(u3a_is_cat(sec))) {
|
||||
// Input is weird, fallback to nock.
|
||||
u3z(yod);
|
||||
u3z(out);
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
c3_y sa, sb, ma, mb, ha, hb;
|
||||
_y_co_two(sec, &sa, &sb);
|
||||
out = u3nq('.', sa, sb, out);
|
||||
|
||||
_y_co_two(min, &ma, &mb);
|
||||
out = u3nq('.', ma, mb, out);
|
||||
|
||||
_y_co_two(hour, &ha, &hb);
|
||||
out = u3nq('.', ha, hb, out);
|
||||
|
||||
out = u3nc('.', out);
|
||||
}
|
||||
|
||||
// We always print the Y.M.D. Unlike others, these numbers are unconstrained
|
||||
// by length, but in practice, the month number and day number can only be up
|
||||
// to two digits because of +yore. We still need to remove 0 prefixes,
|
||||
// though.
|
||||
if (!_(u3a_is_cat(day)) || day > 99 ||
|
||||
!_(u3a_is_cat(month)) || month > 99 ||
|
||||
!_(u3a_is_cat(year))) {
|
||||
// Input is weird, fallback to nock.
|
||||
u3z(yod);
|
||||
u3z(out);
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
c3_y da, db;
|
||||
_y_co_two(day, &da, &db);
|
||||
out = u3nc(db, out);
|
||||
if (da != '0') {
|
||||
out = u3nc(da, out);
|
||||
}
|
||||
out = u3nc('.', out);
|
||||
|
||||
c3_y ma, mb;
|
||||
_y_co_two(month, &ma, &mb);
|
||||
out = u3nc(mb, out);
|
||||
if (ma != '0') {
|
||||
out = u3nc(ma, out);
|
||||
}
|
||||
out = u3nc('.', out);
|
||||
|
||||
// suffix the year with a '-' for BC dates
|
||||
if (age == c3n) {
|
||||
out = u3nc('-', out);
|
||||
}
|
||||
|
||||
// The year part is the only place where we have to explicitly loop over the
|
||||
// input because it can be arbitrarily large or small.
|
||||
out = _add_year(year, out);
|
||||
|
||||
out = u3nc('~', out);
|
||||
|
||||
u3z(yod);
|
||||
return out;
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun
|
||||
_print_p(u3_atom cor, u3_atom p)
|
||||
{
|
||||
// Scramble the raw number to the concealed version.
|
||||
u3_noun ob = u3j_cook("u3we_scow_ob_p", u3k(cor), "ob");
|
||||
u3_noun hok = u3j_cook("u3we_scow_fein_p", ob, "fein");
|
||||
u3_atom sxz = u3n_slam_on(hok, u3k(p));
|
||||
|
||||
// Simple galaxy case
|
||||
if (c3y == u3qa_lte(sxz, 256)) {
|
||||
c3_y a, b, c;
|
||||
u3_po_to_suffix(sxz, &a, &b, &c);
|
||||
u3z(sxz);
|
||||
return u3nq('~', a, b, u3nc(c, 0));
|
||||
}
|
||||
|
||||
u3_atom dyy = u3qc_met(4, sxz);
|
||||
if (!_(u3a_is_cat(dyy))) {
|
||||
u3z(sxz);
|
||||
u3z(dyy);
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
u3_noun list = 0;
|
||||
for (c3_w imp = 0; imp != dyy; ++imp) {
|
||||
c3_w log = u3qc_end(4, 1, sxz);
|
||||
c3_w prefix = u3qc_rsh(3, 1, log);
|
||||
c3_w suffix = u3qc_end(3, 1, log);
|
||||
|
||||
c3_y a, b, c, d, e, f;
|
||||
u3_po_to_prefix(prefix, &a, &b, &c);
|
||||
u3_po_to_suffix(suffix, &d, &e, &f);
|
||||
|
||||
if (imp % 4 == 0) {
|
||||
if (imp != 0) {
|
||||
list = u3nt('-', '-', list);
|
||||
}
|
||||
} else {
|
||||
list = u3nc('-', list);
|
||||
}
|
||||
|
||||
list = u3nq(a, b, c, u3nq(d, e, f, list));
|
||||
|
||||
sxz = u3qc_rsh(4, 1, sxz);
|
||||
}
|
||||
|
||||
u3z(sxz);
|
||||
return u3nc('~', list);
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun
|
||||
_print_ud(u3_atom ud)
|
||||
{
|
||||
// number of characters printed "between" periods.
|
||||
c3_i between = 0;
|
||||
u3_noun list = 0;
|
||||
|
||||
// increase input refcount to be consumed in u3ka_div(), which will free each
|
||||
// intermediary state.
|
||||
u3k(ud);
|
||||
|
||||
do {
|
||||
if (between == 3) {
|
||||
list = u3nc('.', list);
|
||||
between = 0;
|
||||
}
|
||||
|
||||
list = u3nc(u3ka_add(u3qa_mod(ud, 10), '0'), list);
|
||||
between++;
|
||||
ud = u3ka_div(ud, 10);
|
||||
} while (ud != 0);
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun
|
||||
_print_uv(u3_atom uv)
|
||||
{
|
||||
// number of characters printed "between" periods.
|
||||
c3_i between = 0;
|
||||
u3_noun list = 0;
|
||||
|
||||
// increase input refcount to be consumed in u3ka_div(), which will free each
|
||||
// intermediary state.
|
||||
u3k(uv);
|
||||
|
||||
do {
|
||||
if (between == 5) {
|
||||
list = u3nc('.', list);
|
||||
between = 0;
|
||||
}
|
||||
|
||||
c3_y tig = u3qa_mod(uv, 32);
|
||||
list = u3nc(to_digit(tig), list);
|
||||
between++;
|
||||
uv = u3ka_div(uv, 32);
|
||||
} while (uv != 0);
|
||||
|
||||
return u3nt('0', 'v', list);
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun
|
||||
_print_uw(u3_atom uw)
|
||||
{
|
||||
// number of characters printed "between" periods.
|
||||
c3_i between = 0;
|
||||
u3_noun list = 0;
|
||||
|
||||
// increase input refcount to be consumed in u3ka_div(), which will free each
|
||||
// intermediary state.
|
||||
u3k(uw);
|
||||
|
||||
do {
|
||||
if (between == 5) {
|
||||
list = u3nc('.', list);
|
||||
between = 0;
|
||||
}
|
||||
|
||||
c3_y tig = u3qa_mod(uw, 64);
|
||||
list = u3nc(to_w_digit(tig), list);
|
||||
between++;
|
||||
uw = u3ka_div(uw, 64);
|
||||
} while (uw != 0);
|
||||
|
||||
return u3nt('0', 'w', list);
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_scow(u3_noun cor)
|
||||
{
|
||||
u3_atom mod;
|
||||
u3_atom atom;
|
||||
|
||||
if (c3n == u3r_mean(cor, u3x_sam_2, &mod,
|
||||
u3x_sam_3, &atom, 0)) {
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
|
||||
switch (mod) {
|
||||
case c3__da:
|
||||
return _print_da(cor, atom);
|
||||
|
||||
case 'p':
|
||||
return _print_p(cor, atom);
|
||||
|
||||
case c3__ud:
|
||||
return _print_ud(atom);
|
||||
|
||||
case c3__uv:
|
||||
return _print_uv(atom);
|
||||
|
||||
case c3__uw:
|
||||
return _print_uw(atom);
|
||||
|
||||
default:
|
||||
return u3_none;
|
||||
}
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_scot(u3_noun cor)
|
||||
{
|
||||
u3_atom mod;
|
||||
u3_atom atom;
|
||||
|
||||
if (c3n == u3r_mean(cor, u3x_sam_2, &mod,
|
||||
u3x_sam_3, &atom, 0)) {
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
|
||||
u3_noun tape;
|
||||
switch (mod) {
|
||||
case c3__da:
|
||||
tape = _print_da(cor, atom);
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
tape = _print_p(cor, atom);
|
||||
break;
|
||||
|
||||
case c3__ud:
|
||||
tape = _print_ud(atom);
|
||||
break;
|
||||
|
||||
case c3__uv:
|
||||
tape = _print_uv(atom);
|
||||
break;
|
||||
|
||||
case c3__uw:
|
||||
tape = _print_uw(atom);
|
||||
break;
|
||||
|
||||
default:
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
if (tape == u3_none) {
|
||||
return tape;
|
||||
}
|
||||
u3_noun ret = u3qc_rap(3, tape);
|
||||
u3z(tape);
|
||||
return ret;
|
||||
}
|
510
pkg/urbit/jets/e/slaw.c
Normal file
510
pkg/urbit/jets/e/slaw.c
Normal file
@ -0,0 +1,510 @@
|
||||
/* j/3/slaw.c
|
||||
**
|
||||
*/
|
||||
#include "all.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
/* functions
|
||||
*/
|
||||
u3_noun
|
||||
_parse_ud(u3_noun txt) {
|
||||
c3_c* c = u3a_string(txt);
|
||||
|
||||
// First character must represent a digit
|
||||
c3_c* cur = c;
|
||||
if (cur[0] > '9' || cur[0] < '0') {
|
||||
u3a_free(c);
|
||||
return u3_none;
|
||||
}
|
||||
u3_atom total = cur[0] - '0';
|
||||
cur++;
|
||||
|
||||
int since_last_period = 0;
|
||||
while (cur[0] != 0) {
|
||||
since_last_period++;
|
||||
if (cur[0] == '.') {
|
||||
since_last_period = 0;
|
||||
cur++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cur[0] > '9' || cur[0] < '0') {
|
||||
u3a_free(c);
|
||||
u3z(total);
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
total = u3ka_mul(total, 10);
|
||||
total = u3ka_add(total, cur[0] - '0');
|
||||
cur++;
|
||||
|
||||
if (since_last_period > 3) {
|
||||
u3a_free(c);
|
||||
u3z(total);
|
||||
return u3_none;
|
||||
}
|
||||
}
|
||||
|
||||
u3a_free(c);
|
||||
return u3nc(0, total);
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun get_syllable(c3_c** cur_ptr, c3_c* one, c3_c* two, c3_c* three) {
|
||||
if (islower((*cur_ptr)[0]) && islower((*cur_ptr)[1]) &&
|
||||
islower((*cur_ptr)[2])) {
|
||||
*one = (*cur_ptr)[0];
|
||||
*two = (*cur_ptr)[1];
|
||||
*three = (*cur_ptr)[2];
|
||||
(*cur_ptr) += 3;
|
||||
return c3y;
|
||||
} else {
|
||||
return c3n;
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
u3_noun combine(u3_noun p, u3_noun q)
|
||||
{
|
||||
if (_(u3a_is_atom(p))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (_(u3a_is_atom(q))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u3_noun ret = u3nc(0, u3qa_add(u3t(p), u3qa_mul(256, u3t(q))));
|
||||
u3z(p);
|
||||
u3z(q);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#define ENSURE_NOT_END() do { \
|
||||
if (*cur == 0) { \
|
||||
u3a_free(c); \
|
||||
return u3_none; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define CONSUME(x) do { \
|
||||
if (*cur != x) { \
|
||||
u3a_free(c); \
|
||||
return u3_none; \
|
||||
} \
|
||||
cur++; \
|
||||
} while (0)
|
||||
|
||||
#define TRY_GET_SYLLABLE(prefix) \
|
||||
c3_c prefix##_one, prefix##_two, prefix##_three; \
|
||||
if (c3n == get_syllable(&cur, & prefix##_one, & prefix##_two, & prefix##_three)) { \
|
||||
u3a_free(c); \
|
||||
return u3_none; \
|
||||
}
|
||||
|
||||
u3_noun
|
||||
_parse_p(u3_noun cor, u3_noun txt) {
|
||||
c3_c* c = u3a_string(txt);
|
||||
|
||||
c3_c* cur = c;
|
||||
CONSUME('~');
|
||||
|
||||
// We at least have a sig prefix. We're now going to parse tuples of three
|
||||
// lowercase letters. Our naming pattern for the pieces we read is [a b c d
|
||||
// ...] as we read them.
|
||||
TRY_GET_SYLLABLE(a);
|
||||
|
||||
// There was only one syllable. If it's a valid suffix syllable, then
|
||||
// it's a galaxy. We don't even have to run this through the scrambler or
|
||||
// check for validity since its already a (unit @).
|
||||
if (*cur == 0) {
|
||||
u3a_free(c);
|
||||
return u3_po_find_suffix(a_one, a_two, a_three);
|
||||
}
|
||||
|
||||
TRY_GET_SYLLABLE(b);
|
||||
|
||||
// There were only two syllables. If they are a valid prefix and suffix, then
|
||||
// it's a star.
|
||||
if (*cur == 0) {
|
||||
u3_noun a_part = u3_po_find_prefix(a_one, a_two, a_three);
|
||||
u3_noun b_part = u3_po_find_suffix(b_one, b_two, b_three);
|
||||
u3_atom combined = combine(b_part, a_part);
|
||||
u3a_free(c);
|
||||
return combined;
|
||||
}
|
||||
|
||||
// There must now be a - or it is invalid
|
||||
CONSUME('-');
|
||||
|
||||
TRY_GET_SYLLABLE(c);
|
||||
|
||||
ENSURE_NOT_END();
|
||||
|
||||
TRY_GET_SYLLABLE(d);
|
||||
|
||||
if (*cur == 0) {
|
||||
u3_noun a_part = u3_po_find_prefix(a_one, a_two, a_three);
|
||||
u3_noun b_part = u3_po_find_suffix(b_one, b_two, b_three);
|
||||
u3_noun c_part = u3_po_find_prefix(c_one, c_two, c_three);
|
||||
u3_noun d_part = u3_po_find_suffix(d_one, d_two, d_three);
|
||||
|
||||
u3_noun m = combine(d_part, combine(c_part, combine(b_part, a_part)));
|
||||
u3a_free(c);
|
||||
|
||||
if (_(u3a_is_atom(m))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u3_atom raw = u3k(u3t(m));
|
||||
u3z(m);
|
||||
|
||||
u3_noun ob = u3j_cook("u3we_slaw_ob_p", u3k(cor), "ob");
|
||||
u3_noun hok = u3j_cook("u3we_slaw_fynd_p", ob, "fynd");
|
||||
return u3nc(0, u3n_slam_on(hok, raw));
|
||||
}
|
||||
|
||||
// There must now be a - or it is invalid.
|
||||
CONSUME('-');
|
||||
|
||||
// The next possible case is a "short" moon. (~ab-cd-ef)
|
||||
TRY_GET_SYLLABLE(e);
|
||||
|
||||
ENSURE_NOT_END();
|
||||
|
||||
TRY_GET_SYLLABLE(f);
|
||||
|
||||
if (*cur == 0) {
|
||||
u3_noun a_part = u3_po_find_prefix(a_one, a_two, a_three);
|
||||
u3_noun b_part = u3_po_find_suffix(b_one, b_two, b_three);
|
||||
u3_noun c_part = u3_po_find_prefix(c_one, c_two, c_three);
|
||||
u3_noun d_part = u3_po_find_suffix(d_one, d_two, d_three);
|
||||
u3_noun e_part = u3_po_find_prefix(e_one, e_two, e_three);
|
||||
u3_noun f_part = u3_po_find_suffix(f_one, f_two, f_three);
|
||||
|
||||
u3_noun m = combine(f_part, combine(e_part, combine(d_part,
|
||||
combine(c_part, combine(b_part, a_part)))));
|
||||
u3a_free(c);
|
||||
|
||||
if (_(u3a_is_atom(m))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u3_atom raw = u3k(u3t(m));
|
||||
u3z(m);
|
||||
u3_noun ob = u3j_cook("u3we_slaw_ob_p", u3k(cor), "ob");
|
||||
u3_noun hok = u3j_cook("u3we_slaw_fynd_p", ob, "fynd");
|
||||
return u3nc(0, u3n_slam_on(hok, raw));
|
||||
}
|
||||
|
||||
// There must now be a - or it is invalid.
|
||||
CONSUME('-');
|
||||
|
||||
// The next possible case is a "long" moon. (~ab-cd-ef-gh)
|
||||
TRY_GET_SYLLABLE(g);
|
||||
|
||||
ENSURE_NOT_END();
|
||||
|
||||
TRY_GET_SYLLABLE(h);
|
||||
|
||||
if (*cur == 0) {
|
||||
u3_noun a_part = u3_po_find_prefix(a_one, a_two, a_three);
|
||||
u3_noun b_part = u3_po_find_suffix(b_one, b_two, b_three);
|
||||
u3_noun c_part = u3_po_find_prefix(c_one, c_two, c_three);
|
||||
u3_noun d_part = u3_po_find_suffix(d_one, d_two, d_three);
|
||||
u3_noun e_part = u3_po_find_prefix(e_one, e_two, e_three);
|
||||
u3_noun f_part = u3_po_find_suffix(f_one, f_two, f_three);
|
||||
u3_noun g_part = u3_po_find_prefix(g_one, g_two, g_three);
|
||||
u3_noun h_part = u3_po_find_suffix(h_one, h_two, h_three);
|
||||
|
||||
u3_noun m = combine(h_part, combine(g_part, combine(f_part,
|
||||
combine(e_part, combine(d_part, combine(c_part,
|
||||
combine(b_part, a_part)))))));
|
||||
u3a_free(c);
|
||||
|
||||
if (_(u3a_is_atom(m))) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
u3_atom raw = u3k(u3t(m));
|
||||
u3z(m);
|
||||
u3_noun ob = u3j_cook("u3we_slaw_ob_p", u3k(cor), "ob");
|
||||
u3_noun hok = u3j_cook("u3we_slaw_fynd_p", ob, "fynd");
|
||||
return u3nc(0, u3n_slam_on(hok, raw));
|
||||
}
|
||||
|
||||
// At this point, the only thing it could be is a long comet, of the form
|
||||
// ~ab-cd-ef-gh--ij-kl-mn-op
|
||||
|
||||
CONSUME('-');
|
||||
CONSUME('-');
|
||||
|
||||
TRY_GET_SYLLABLE(i);
|
||||
ENSURE_NOT_END();
|
||||
TRY_GET_SYLLABLE(j);
|
||||
CONSUME('-');
|
||||
TRY_GET_SYLLABLE(k);
|
||||
ENSURE_NOT_END();
|
||||
TRY_GET_SYLLABLE(l);
|
||||
CONSUME('-');
|
||||
TRY_GET_SYLLABLE(m);
|
||||
ENSURE_NOT_END();
|
||||
TRY_GET_SYLLABLE(n);
|
||||
CONSUME('-');
|
||||
TRY_GET_SYLLABLE(o);
|
||||
ENSURE_NOT_END();
|
||||
TRY_GET_SYLLABLE(p);
|
||||
|
||||
if (*cur != 0) {
|
||||
// We've parsed all of a comet shape, and there's still more in the
|
||||
// string. Bail back to the interpreter.
|
||||
u3a_free(c);
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
// We have a long comet. Time to jam it all together. We rely on combine()
|
||||
// for the error checking and we don't have to scramble comet names.
|
||||
u3_noun a_part = u3_po_find_prefix(a_one, a_two, a_three);
|
||||
u3_noun b_part = u3_po_find_suffix(b_one, b_two, b_three);
|
||||
u3_noun c_part = u3_po_find_prefix(c_one, c_two, c_three);
|
||||
u3_noun d_part = u3_po_find_suffix(d_one, d_two, d_three);
|
||||
u3_noun e_part = u3_po_find_prefix(e_one, e_two, e_three);
|
||||
u3_noun f_part = u3_po_find_suffix(f_one, f_two, f_three);
|
||||
u3_noun g_part = u3_po_find_prefix(g_one, g_two, g_three);
|
||||
u3_noun h_part = u3_po_find_suffix(h_one, h_two, h_three);
|
||||
u3_noun i_part = u3_po_find_prefix(i_one, i_two, i_three);
|
||||
u3_noun j_part = u3_po_find_suffix(j_one, j_two, j_three);
|
||||
u3_noun k_part = u3_po_find_prefix(k_one, k_two, k_three);
|
||||
u3_noun l_part = u3_po_find_suffix(l_one, l_two, l_three);
|
||||
u3_noun m_part = u3_po_find_prefix(m_one, m_two, m_three);
|
||||
u3_noun n_part = u3_po_find_suffix(n_one, n_two, n_three);
|
||||
u3_noun o_part = u3_po_find_prefix(o_one, o_two, o_three);
|
||||
u3_noun p_part = u3_po_find_suffix(p_one, p_two, p_three);
|
||||
|
||||
u3a_free(c);
|
||||
|
||||
return combine(p_part, combine(o_part, combine(n_part, combine(m_part,
|
||||
combine(l_part, combine(k_part, combine(j_part, combine(i_part,
|
||||
combine(h_part, combine(g_part, combine(f_part, combine(e_part,
|
||||
combine(d_part, combine(c_part, combine(b_part, a_part)))))))))))))));
|
||||
}
|
||||
|
||||
#define PARSE_NONZERO_NUMBER(numname) \
|
||||
c3_w numname = 0; \
|
||||
do { \
|
||||
if (cur[0] > '9' || cur[0] < '1') { \
|
||||
u3a_free(c); \
|
||||
return u3_none; \
|
||||
} \
|
||||
numname = cur[0] - '0'; \
|
||||
cur++; \
|
||||
while (isdigit(cur[0])) { \
|
||||
numname = u3ka_mul(numname, 10); \
|
||||
numname = u3ka_add(numname, cur[0] - '0'); \
|
||||
cur++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PARSE_INCLUDING_ZERO_NUMBER(numname) \
|
||||
c3_w numname = 0; \
|
||||
do { \
|
||||
if (cur[0] > '9' || cur[0] < '0') { \
|
||||
u3a_free(c); \
|
||||
return u3_none; \
|
||||
} \
|
||||
numname = cur[0] - '0'; \
|
||||
cur++; \
|
||||
while (isdigit(cur[0])) { \
|
||||
numname = u3ka_mul(numname, 10); \
|
||||
numname = u3ka_add(numname, cur[0] - '0'); \
|
||||
cur++; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define PARSE_HEX_DIGIT(out) \
|
||||
do { \
|
||||
if (cur[0] >= '0' && cur[0] <= '9') { \
|
||||
out = cur[0] - '0'; \
|
||||
} else if (cur[0] >= 'a' && cur[0] <= 'f') { \
|
||||
out = 10 + cur[0] - 'a'; \
|
||||
} else { \
|
||||
u3a_free(c); \
|
||||
return u3_none; \
|
||||
} \
|
||||
cur++; \
|
||||
} while(0)
|
||||
|
||||
|
||||
u3_noun
|
||||
_parse_da(u3_noun cor, u3_noun txt) {
|
||||
c3_c* c = u3a_string(txt);
|
||||
|
||||
c3_c* cur = c;
|
||||
CONSUME('~');
|
||||
|
||||
// Parse out an arbitrary year number. Starts with a nonzero digit followed
|
||||
// by a series of any digits.
|
||||
PARSE_NONZERO_NUMBER(year);
|
||||
|
||||
// Parse the optional negative sign for BC dates.
|
||||
u3_noun bc = c3y;
|
||||
if (cur[0] == '-') {
|
||||
bc = c3n;
|
||||
cur++;
|
||||
}
|
||||
|
||||
CONSUME('.');
|
||||
|
||||
// Parse out a two digit month (mot:ag). Either a single digit 1-9 or 1[012].
|
||||
c3_y month;
|
||||
if (cur[0] == '1') {
|
||||
if (cur[1] <= '2' && cur[1] >= '0') {
|
||||
// This is a two number month.
|
||||
month = 10 + cur[1] - '0';
|
||||
cur += 2;
|
||||
} else {
|
||||
// This is January.
|
||||
month = 1;
|
||||
cur++;
|
||||
}
|
||||
} else if (cur[0] <= '9' && cur[0] >= '2') {
|
||||
month = cur[0] - '0';
|
||||
cur++;
|
||||
} else {
|
||||
u3a_free(c);
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
CONSUME('.');
|
||||
|
||||
// Parse out a two digit day (dip:ag). This number can be really big, so we
|
||||
// can track number of days since September 1993.
|
||||
PARSE_NONZERO_NUMBER(day);
|
||||
|
||||
if (cur[0] == 0) {
|
||||
u3a_free(c);
|
||||
u3_noun hok = u3j_cook("u3we_slaw_parse_da", u3k(cor), "year");
|
||||
u3_noun res = u3n_slam_on(hok,
|
||||
u3nt(u3nc(bc, year), month,
|
||||
u3nc(day, u3nq(0, 0, 0, 0))));
|
||||
return u3nc(0, res);
|
||||
}
|
||||
|
||||
CONSUME('.');
|
||||
CONSUME('.');
|
||||
|
||||
PARSE_INCLUDING_ZERO_NUMBER(hour);
|
||||
CONSUME('.');
|
||||
PARSE_INCLUDING_ZERO_NUMBER(minute);
|
||||
CONSUME('.');
|
||||
PARSE_INCLUDING_ZERO_NUMBER(second);
|
||||
|
||||
if (cur[0] == 0) {
|
||||
u3a_free(c);
|
||||
u3_noun hok = u3j_cook("u3we_slaw_parse_da", u3k(cor), "year");
|
||||
u3_noun res = u3n_slam_on(hok,
|
||||
u3nt(u3nc(bc, year), month,
|
||||
u3nc(day, u3nq(hour, minute, second, 0))));
|
||||
return u3nc(0, res);
|
||||
}
|
||||
|
||||
CONSUME('.');
|
||||
CONSUME('.');
|
||||
|
||||
// Now we have to parse a list of hexidecimal numbers 0-f of length 4 only
|
||||
// (zero padded otherwise) separated by dots.
|
||||
u3_noun list = 0;
|
||||
while (1) {
|
||||
// Parse 4 hex digits
|
||||
c3_y one, two, three, four;
|
||||
PARSE_HEX_DIGIT(one);
|
||||
PARSE_HEX_DIGIT(two);
|
||||
PARSE_HEX_DIGIT(three);
|
||||
PARSE_HEX_DIGIT(four);
|
||||
|
||||
c3_w current = (one << 12) + (two << 8) + (three << 4) + four;
|
||||
list = u3nc(u3i_words(1, ¤t), list);
|
||||
|
||||
if (cur[0] == 0) {
|
||||
u3a_free(c);
|
||||
|
||||
u3_noun flopped = u3qb_flop(list);
|
||||
u3z(list);
|
||||
|
||||
u3_noun hok = u3j_cook("u3we_slaw_parse_da", u3k(cor), "year");
|
||||
u3_noun res = u3n_slam_on(hok,
|
||||
u3nt(u3nc(bc, year), month,
|
||||
u3nc(day,
|
||||
u3nq(hour, minute, second, flopped))));
|
||||
return u3nc(0, res);
|
||||
}
|
||||
|
||||
CONSUME('.');
|
||||
}
|
||||
}
|
||||
|
||||
#undef ENSURE_NOT_END
|
||||
#undef CONSUME
|
||||
#undef TRY_GET_SYLLABLE
|
||||
#undef PARSE_NONZERO_NUMBER
|
||||
#undef PARSE_HEX_DIGIT
|
||||
|
||||
u3_noun
|
||||
_parse_tas(u3_noun txt) {
|
||||
// For any symbol which matches, txt will return itself as a
|
||||
// value. Therefore, this is mostly checking validity.
|
||||
c3_c* c = u3a_string(txt);
|
||||
|
||||
// First character must represent a lowercase letter
|
||||
c3_c* cur = c;
|
||||
if (!islower(cur[0])) {
|
||||
u3a_free(c);
|
||||
return 0;
|
||||
}
|
||||
cur++;
|
||||
|
||||
while (cur[0] != 0) {
|
||||
if (!(islower(cur[0]) || isdigit(cur[0]) || cur[0] == '-')) {
|
||||
u3a_free(c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cur++;
|
||||
}
|
||||
|
||||
u3a_free(c);
|
||||
return u3nc(0, u3k(txt));
|
||||
}
|
||||
|
||||
u3_noun
|
||||
u3we_slaw(u3_noun cor)
|
||||
{
|
||||
u3_noun mod;
|
||||
u3_noun txt;
|
||||
|
||||
if (c3n == u3r_mean(cor, u3x_sam_2, &mod,
|
||||
u3x_sam_3, &txt, 0)) {
|
||||
return u3m_bail(c3__exit);
|
||||
}
|
||||
|
||||
switch (mod) {
|
||||
case c3__da:
|
||||
return _parse_da(cor, txt);
|
||||
|
||||
case 'p':
|
||||
return _parse_p(cor, txt);
|
||||
|
||||
case c3__ud:
|
||||
return _parse_ud(txt);
|
||||
|
||||
// %ta is used once in link.hoon. don't bother.
|
||||
|
||||
case c3__tas:
|
||||
return _parse_tas(txt);
|
||||
|
||||
default:
|
||||
return u3_none;
|
||||
}
|
||||
}
|
@ -607,6 +607,19 @@ static c3_c* _141_qua_trip_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_harm _141_qua_slaw_a[] = {{".2", u3we_slaw}, {}};
|
||||
static c3_c* _141_qua_slaw_ha[] = {
|
||||
0
|
||||
};
|
||||
static u3j_harm _141_qua_scot_a[] = {{".2", u3we_scot}, {}};
|
||||
static c3_c* _141_qua_scot_ha[] = {
|
||||
0
|
||||
};
|
||||
static u3j_harm _141_qua_scow_a[] = {{".2", u3we_scow}, {}};
|
||||
static c3_c* _141_qua_scow_ha[] = {
|
||||
0
|
||||
};
|
||||
|
||||
static u3j_harm _141_qua__po_ind_a[] = {{".2", u3wcp_ind}, {}};
|
||||
static c3_c* _141_qua__po_ind_ha[] = {
|
||||
"95bbe9867dbbd1b9ce12671d64cf7b1dee8d987c6770955a83c73291c4537a61",
|
||||
@ -883,6 +896,10 @@ static u3j_core _141_qua_d[] =
|
||||
|
||||
{ "mink", 7, _141_qua_mink_a, 0, _141_qua_mink_ha },
|
||||
{ "mule", 7, _141_qua_mule_a, 0, _141_qua_mule_ha },
|
||||
|
||||
{ "scot", 7, _141_qua_scot_a, 0, _141_qua_scot_ha },
|
||||
{ "scow", 7, _141_qua_scow_a, 0, _141_qua_scow_ha },
|
||||
{ "slaw", 7, _141_qua_slaw_a, 0, _141_qua_slaw_ha },
|
||||
{}
|
||||
};
|
||||
static c3_c* _141_qua_ha[] = {
|
||||
|
@ -1002,6 +1002,7 @@ _me_gain_use(u3_noun dog)
|
||||
u3a_box* box_u = u3a_botox(dog_w);
|
||||
|
||||
if ( 0x7fffffff == box_u->use_w ) {
|
||||
u3l_log("fail in _me_gain_use");
|
||||
u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
@ -2320,3 +2321,16 @@ u3a_walk_fore_unsafe(u3_noun a,
|
||||
a = *top;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3a_string(): `a` as an on-loom c-string.
|
||||
*/
|
||||
c3_c*
|
||||
u3a_string(u3_atom a)
|
||||
{
|
||||
c3_w met_w = u3r_met(3, a);
|
||||
c3_c* str_c = u3a_malloc(met_w + 1);
|
||||
|
||||
u3r_bytes(0, met_w, (c3_y*)str_c, a);
|
||||
str_c[met_w] = 0;
|
||||
return str_c;
|
||||
}
|
||||
|
@ -950,11 +950,13 @@ _cj_hook_in(u3_noun cor,
|
||||
u3_noun roc, tem, got, pat, nam, huc;
|
||||
|
||||
if ( c3n == u3du(cor) ) {
|
||||
u3l_log("_cj_hook_in failure: c3n == u3du(cor)\r\n");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
loc = _cj_spot(cor, NULL);
|
||||
if ( u3_none == loc ) {
|
||||
u3l_log("_cj_hook_in failure: u3_none == loc\r\n");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
@ -1019,6 +1021,7 @@ _cj_hook_in(u3_noun cor,
|
||||
else {
|
||||
u3_noun sat = u3t(pat);
|
||||
if ( c3y == u3h(sat) ) {
|
||||
u3l_log("_cj_hook_in failure: c3y == u3h(sat)\r\n");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
@ -1158,11 +1161,13 @@ _cj_hank_fill(_cj_hank* han_u, u3_noun tam, u3_noun cor)
|
||||
u3j_site* sit_u = &(han_u->sit_u);
|
||||
|
||||
if ( c3n == u3du(cor) ) {
|
||||
u3l_log("fail in _cj_hank_fill (c3n == u3du(cor))");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
sit_u->bas = u3_none;
|
||||
if ( u3_none == (col = loc = _cj_spot(cor, NULL)) ) {
|
||||
u3l_log("fail in _cj_hank_fill (_cj_spot(cor, NULL))");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
@ -1205,6 +1210,7 @@ _cj_hank_fill(_cj_hank* han_u, u3_noun tam, u3_noun cor)
|
||||
else {
|
||||
u3_noun sat = u3t(pat);
|
||||
if ( c3y == u3h(sat) ) {
|
||||
u3l_log("fail in _cj_hank_fill (c3y == u3h(sat))");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
|
@ -90,6 +90,7 @@ u3_walk_load(c3_c* pas_c)
|
||||
|
||||
if ( fln_w != red_w ) {
|
||||
c3_free(pad_y);
|
||||
u3l_log("u3_walk_load failed");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
else {
|
||||
|
Loading…
Reference in New Issue
Block a user