mirror of
https://github.com/urbit/shrub.git
synced 2024-12-21 18:01:32 +03:00
jets: first pass as (scow %da ...)
When trying to hook this up to +scot, I can reliably crash vere, so there's still a bug here around memory.
This commit is contained in:
parent
d61a54d52a
commit
e097bdda58
@ -5,6 +5,167 @@
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
static
|
||||
c3_y to_digit(u3_atom tig)
|
||||
{
|
||||
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(u3_atom 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(u3_atom src, c3_y* a, c3_y* b)
|
||||
{
|
||||
*b = to_digit(src % 10);
|
||||
*a = to_digit(src / 10);
|
||||
}
|
||||
|
||||
//
|
||||
static
|
||||
u3_noun
|
||||
_add_year(u3_atom 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_atom 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;
|
||||
u3m_p("yod", yod);
|
||||
|
||||
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 (c3n == u3r_sing(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 (c3n == u3r_sing(f, 0) ||
|
||||
c3n == u3r_sing(hour, 0) ||
|
||||
c3n == u3r_sing(min, 0) ||
|
||||
c3n == u3r_sing(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 p)
|
||||
@ -83,12 +244,13 @@ u3we_scow(u3_noun cor)
|
||||
if (c3n == u3r_mean(cor, u3x_sam_2, &mod,
|
||||
u3x_sam_3, &atom, 0) ||
|
||||
!_(u3a_is_cat(mod))) {
|
||||
u3l_log("u3we_scow fail\r\n");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
switch (mod) {
|
||||
/* case c3__da: */
|
||||
/* return _parse_da(cor, txt); */
|
||||
case c3__da:
|
||||
return _print_da(cor, atom);
|
||||
|
||||
case 'p':
|
||||
return _print_p(atom);
|
||||
@ -115,10 +277,21 @@ u3we_scot(u3_noun cor)
|
||||
if (c3n == u3r_mean(cor, u3x_sam_2, &mod,
|
||||
u3x_sam_3, &atom, 0) ||
|
||||
!_(u3a_is_cat(mod))) {
|
||||
u3l_log("u3we_scot fail\r\n");
|
||||
return u3m_bail(c3__fail);
|
||||
}
|
||||
|
||||
switch (mod) {
|
||||
// TODO: This causes a bail fail. why?
|
||||
/* case c3__da: { */
|
||||
/* u3_noun x = _print_da(cor, atom); */
|
||||
/* if (x == u3_none) { */
|
||||
/* return x; */
|
||||
/* } */
|
||||
|
||||
/* return u3qc_rap(3, x); */
|
||||
/* } */
|
||||
|
||||
case 'p':
|
||||
return u3qc_rap(3, _print_p(atom));
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user