jets: implement partial %da parser.

This parses dates of the form '~2020.4.29', but not ones with time.
This uses a hook to call back to +year, since jetting that would be
a bit much.
This commit is contained in:
Elliot Glaysher 2020-04-29 16:28:36 -07:00
parent 1ef953c9ac
commit b947b569bb
2 changed files with 142 additions and 52 deletions

View File

@ -2133,7 +2133,10 @@
:: 3f: scrambling :: :: 3f: scrambling ::
:: 3g: molds and mold builders :: :: 3g: molds and mold builders ::
:: :: :: ::
~% %tri + ~ ~% %tri +
==
%year year
==
|% |%
:: ::
:::: 3a: signed and modular ints :: :::: 3a: signed and modular ints ::

View File

@ -98,8 +98,8 @@ u3_noun combine(u3_noun p, u3_noun q)
} \ } \
} while (0) } while (0)
#define CONSUME_HEP() do { \ #define CONSUME(x) do { \
if (*cur != '-') { \ if (*cur != x) { \
c3_free(c); \ c3_free(c); \
return 0; \ return 0; \
} \ } \
@ -150,7 +150,7 @@ _parse_p(u3_noun txt) {
} }
// There must now be a - or it is invalid // There must now be a - or it is invalid
CONSUME_HEP(); CONSUME('-');
TRY_GET_SYLLABLE(c); TRY_GET_SYLLABLE(c);
@ -177,7 +177,7 @@ _parse_p(u3_noun txt) {
} }
// There must now be a - or it is invalid. // There must now be a - or it is invalid.
CONSUME_HEP(); CONSUME('-');
// The next possible case is a "short" moon. (~ab-cd-ef) // The next possible case is a "short" moon. (~ab-cd-ef)
TRY_GET_SYLLABLE(e); TRY_GET_SYLLABLE(e);
@ -208,7 +208,7 @@ _parse_p(u3_noun txt) {
} }
// There must now be a - or it is invalid. // There must now be a - or it is invalid.
CONSUME_HEP(); CONSUME('-');
// The next possible case is a "long" moon. (~ab-cd-ef-gh) // The next possible case is a "long" moon. (~ab-cd-ef-gh)
TRY_GET_SYLLABLE(g); TRY_GET_SYLLABLE(g);
@ -244,21 +244,21 @@ _parse_p(u3_noun txt) {
// At this point, the only thing it could be is a long comet, of the form // At this point, the only thing it could be is a long comet, of the form
// ~ab-cd-ef-gh--ij-kl-mn-op // ~ab-cd-ef-gh--ij-kl-mn-op
CONSUME_HEP(); CONSUME('-');
CONSUME_HEP(); CONSUME('-');
TRY_GET_SYLLABLE(i); TRY_GET_SYLLABLE(i);
ENSURE_NOT_END(); ENSURE_NOT_END();
TRY_GET_SYLLABLE(j); TRY_GET_SYLLABLE(j);
CONSUME_HEP(); CONSUME('-');
TRY_GET_SYLLABLE(k); TRY_GET_SYLLABLE(k);
ENSURE_NOT_END(); ENSURE_NOT_END();
TRY_GET_SYLLABLE(l); TRY_GET_SYLLABLE(l);
CONSUME_HEP(); CONSUME('-');
TRY_GET_SYLLABLE(m); TRY_GET_SYLLABLE(m);
ENSURE_NOT_END(); ENSURE_NOT_END();
TRY_GET_SYLLABLE(n); TRY_GET_SYLLABLE(n);
CONSUME_HEP(); CONSUME('-');
TRY_GET_SYLLABLE(o); TRY_GET_SYLLABLE(o);
ENSURE_NOT_END(); ENSURE_NOT_END();
TRY_GET_SYLLABLE(p); TRY_GET_SYLLABLE(p);
@ -297,12 +297,96 @@ _parse_p(u3_noun txt) {
combine(d_part, combine(c_part, combine(b_part, a_part))))))))))))))); combine(d_part, combine(c_part, combine(b_part, a_part)))))))))))))));
} }
#undef ENSURE_NOT_END #define PARSE_NONZERO_NUMBER(numname) \
#undef CONSUME_HEP c3_w numname = 0; \
#undef TRY_GET_SYLLABLE do { \
if (cur[0] > '9' || cur[0] < '1') { \
c3_free(c); \
return 0; \
} \
numname = cur[0] - '0'; \
cur++; \
while (isdigit(cur[0])) { \
numname = u3qa_mul(numname, 10); \
numname = u3qa_add(numname, cur[0] - '0'); \
cur++; \
} \
} while (0)
u3_noun u3_noun
_parse_tas(u3_noun txt) { _parse_da(u3_noun cor, u3_noun txt) {
c3_c* c = u3r_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);
fprintf(stderr, "Year: %d\r\n", year);
// Parse the optional negative sign for BC dates.
u3_noun bc = c3n;
if (cur[0] == '-') {
bc = c3y;
cur++;
}
CONSUME('.');
// Parse out a two digit month (mot:ag). Either a single digit 1-9 or 1[012].
c3_w 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 {
c3_free(c);
return 0;
}
fprintf(stderr, "Month: %d\r\n", month);
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);
fprintf(stderr, "Day: %d\r\n", day);
if (cur[0] == 0) {
fprintf(stderr, "Going fast path...\r\n");
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('.'); */
// TODO: Cool. We've parsed a bunch of atoms. But the actual thing we return
// is the above run through the +year function which produces a @da.
return u3_none;
}
#undef ENSURE_NOT_END
#undef CONSUME
#undef TRY_GET_SYLLABLE
#undef PARSE_NONZERO_NUMBER
u3_noun
_parse_tas(u3_noun txt) {
// For any symbol which matches, txt will return itself as a // For any symbol which matches, txt will return itself as a
// value. Therefore, this is mostly checking validity. // value. Therefore, this is mostly checking validity.
c3_c* c = u3r_string(txt); c3_c* c = u3r_string(txt);
@ -326,11 +410,11 @@ _parse_p(u3_noun txt) {
c3_free(c); c3_free(c);
return u3nc(0, u3k(txt)); return u3nc(0, u3k(txt));
} }
u3_noun u3_noun
u3we_slaw(u3_noun cor) u3we_slaw(u3_noun cor)
{ {
u3_noun mod; u3_noun mod;
u3_noun txt; u3_noun txt;
@ -341,6 +425,9 @@ _parse_p(u3_noun txt) {
} }
switch (mod) { switch (mod) {
case c3__da:
return _parse_da(cor, txt);
case 'p': case 'p':
return _parse_p(txt); return _parse_p(txt);
@ -355,4 +442,4 @@ _parse_p(u3_noun txt) {
default: default:
return u3_none; return u3_none;
} }
} }