Merge pull request #2853 from urbit/scot-jets

+scot and +slaw jets
This commit is contained in:
Elliot Glaysher 2020-05-14 15:07:50 -07:00 committed by GitHub
commit 03f4bd35bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 2419 additions and 104 deletions

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:9d131da321b891c126f62cc587c5e27c257695ff9ae15e502356159fba7f9bf3
size 1234415
oid sha256:df9ab46632f1a6727837eb03ddf5d37c8f415d89b3205fbc2005891fd3e8921e
size 1234585

View File

@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:ecfe53c9e00d8cba244c85eb0ec0ed3b4e8ac07737bb0c6a7aa57d6c52f52c85
size 15993675
oid sha256:50a06217c5354abe42baec10072ddba8e0129c20806fc8173529989724397836
size 12874302

View File

@ -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].
::

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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
View 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
View 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, &current), 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;
}
}

View File

@ -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[] = {

View File

@ -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;
}

View File

@ -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 {

View File

@ -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 {