From 5276bd7ffd81ad5d9d8909a6d7ee53d4cd020fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Wed, 24 May 2023 17:30:46 +0800 Subject: [PATCH 01/16] u3: adds %ux parsing --- pkg/noun/jets/e/slaw.c | 15 +++ pkg/noun/jets_tests.c | 136 ++++++++++++++++++++++++ pkg/noun/serial.c | 231 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/serial.h | 10 ++ 4 files changed, 392 insertions(+) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index 906b0d7ad0..db7ca96af1 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -20,6 +20,18 @@ _parse_ud(u3_noun a) return u3nc(u3_nul, pro); } +static inline u3_noun +_parse_ux(u3_noun a) +{ + u3_weak pro; + + if ( u3_none == (pro = u3s_sift_ux(u3x_atom(a))) ) { + return u3_nul; + } + + return u3nc(u3_nul, pro); +} + 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]) && @@ -466,6 +478,9 @@ u3we_slaw(u3_noun cor) case c3__ud: return _parse_ud(txt); + case c3__ux: + return _parse_ux(txt); + // %ta is used once in link.hoon. don't bother. case c3__tas: diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index 257ec81e3b..466ae44540 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -474,6 +474,137 @@ _test_sift_ud(void) return ret_i; } +static inline c3_i +_ux_good(c3_d num_d, const c3_c* num_c) +{ + u3_weak out; + + out = u3s_sift_ux_bytes(strlen(num_c), (c3_y*)num_c); + + if ( c3y == u3a_is_cat(out) ) { + if ( num_d != out ) { + fprintf(stderr, "sift_ux: %s wrong; expected 0x%llx: actual 0x%x\r\n", num_c, num_d, out); + return 0; + } + + return 1; + } + else { + + if ( u3_none == out ) { + fprintf(stderr, "sift_ux: %s fail; expected 0x%llx\r\n", num_c, num_d); + return 0; + } + + c3_d out_d = u3r_chub(0, out); + + if ( num_d != out_d ) { + fprintf(stderr, "sift_ux: %s wrong; expected 0x%llx: actual 0x%llx\r\n", num_c, num_d, out_d); + + u3z(out); + return 0; + } + + u3z(out); + return 1; + } + +} + +static inline c3_i +_ux_fail(const c3_c* num_c) +{ + u3_weak out; + if ( u3_none != (out = u3s_sift_ux_bytes(strlen(num_c), (c3_y*)num_c)) ) { + u3m_p("out", out); + fprintf(stderr, "sift_ux: %s expected fail\r\n", num_c); + return 0; + } + + return 1; +} + +static c3_i +_test_sift_ux(void) +{ + c3_i ret_i = 1; + + ret_i &= _ux_good(0x0, "0x0"); + ret_i &= _ux_good(0x1, "0x1"); + ret_i &= _ux_good(0x12, "0x12"); + ret_i &= _ux_good(0x1a3, "0x1a3"); + ret_i &= _ux_good(0x123b, "0x123b"); + ret_i &= _ux_good(0x1234c, "0x1.234c"); + ret_i &= _ux_good(0x12e3e56, "0x12e.3e56"); + ret_i &= _ux_good(0x1234e67, "0x123.4e67"); + ret_i &= _ux_good(0x1234567f, "0x1234.567f"); + ret_i &= _ux_good(0x123456789, "0x1.2345.6789"); + ret_i &= _ux_good(0x100000000, "0x1.0000.0000"); + ret_i &= _ux_good(0x101101101, "0x1.0110.1101"); + ret_i &= _ux_good(0x201201201, "0x2.0120.1201"); + ret_i &= _ux_good(0x302201100, "0x3.0220.1100"); + + ret_i &= _ux_fail("0x"); + ret_i &= _ux_fail("x0"); + ret_i &= _ux_fail("0x01"); + ret_i &= _ux_fail("0x12.345"); + ret_i &= _ux_fail("0x12.3456.789"); + ret_i &= _ux_fail("0x1.2.3456.789"); + + { + c3_c* num_c = "0x1.0000.0000"; + u3_weak out = u3s_sift_ux_bytes(strlen(num_c), (c3_y*)num_c); + u3_atom pro = u3qc_bex(32); + + if ( u3_none == out ) { + fprintf(stderr, "sift_ux: (bex 32) fail\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(pro, out) ) { + u3m_p("out", out); + fprintf(stderr, "sift_ux: (bex 32) wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); u3z(pro); + } + + { + c3_c* num_c = "0x1.1234.5678.9abc.def0.1234.5678.9abc.def0"; + c3_c* bnum_c = "0x1234.5678.9abc.def0"; + + u3_weak out = u3s_sift_ux_bytes(strlen(num_c), (c3_y*)num_c); + u3_atom bout = u3s_sift_ux_bytes(strlen(bnum_c), (c3_y*)bnum_c); + + u3_atom pro = u3qc_bex(128); + u3_atom bpro = u3qa_add(pro, bout); + u3_atom cpro = u3qc_lsh(6,1, bout); + u3_atom dpro = u3qa_add(bpro, cpro); + + if ( u3_none == out ) { + fprintf(stderr, "sift_ux: big hex fail\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(dpro, out) ) { + u3m_p("out", out); + fprintf(stderr, "sift_ux: big hex wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); u3z(bout); + u3z(pro); u3z(bpro); + u3z(cpro); u3z(dpro); + } + + return ret_i; +} + static c3_i _test_en_base16(void) { @@ -890,6 +1021,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_sift_ux() ) { + fprintf(stderr, "test jets: sift_ux: failed\r\n"); + ret_i = 0; + } + if ( !_test_base16() ) { fprintf(stderr, "test jets: base16: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 698a959d66..943dbd0f0a 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -1293,6 +1293,20 @@ u3s_etch_uw_c(u3_atom a, c3_c** out_c) #undef _divc_nz +/* +dot + */ +static inline c3_o _cs_dot(c3_w* len_w, c3_y** byt_yp) +{ + if ( *len_w > 0 && **byt_yp == '.' ) { + (*byt_yp)++; + (*len_w)--; + return c3y; + } + else { + return c3n; + } +} + #define DIGIT(a) ( ((a) >= '0') && ((a) <= '9') ) #define BLOCK(a) ( ('.' == (a)[0]) \ && DIGIT(a[1]) \ @@ -1417,3 +1431,220 @@ u3s_sift_ud(u3_atom a) return u3s_sift_ud_bytes(len_w, byt_y); } + +#define PFIXD(a,b) { \ + if ( len_w < 3) { \ + return u3_none; \ + } \ + if ( !(*byt_y == a && *(byt_y+1) == b) ) { \ + return u3_none; \ + } \ + len_w -= 2; \ + byt_y += 2; \ +} + +/* _cs_hex_val: char to hexadecimal digit. + */ +static inline c3_s _cs_hex_val(c3_y hex) { + + if ( hex > '9' ) { + if ( hex < 'a' ) { + return -1; + } + // hex >= 'a' + else { + return (hex - 'a') + 10; + } + } + // hex <= '9' + else { + return hex - '0'; + } +} + +/* u3s_sift_ux_bytes: parse @ux impl. + */ +u3_weak +u3s_sift_ux_bytes(c3_w len_w, c3_y* byt_y) +{ + + if ( ! len_w ) { + return u3_none; + } + + // Parse the 0x prefix + // + PFIXD('0', 'x'); + + if ( ! len_w ) { + return u3_none; + } + + // Parse 0x0 + // + if ( *byt_y == '0' ) { + if ( len_w > 1 ) { + return u3_none; + } + else { + return (u3_noun)0; + } + } + + // Parse a small 64-bit hex number + // + c3_d val_d = 0; + c3_s dit_s = 0; + + // Parse the head + // + for ( size_t i = 0; i < 4; i++ ) { + + if ( ! len_w ) { + break; + } + + dit_s = _cs_hex_val(*byt_y); + + if ( dit_s < 16 ) { + val_d <<= 4; + val_d += dit_s; + } + else { + break; + } + + byt_y++; + len_w--; + } + + // Parse a list of dog followed by + // a quadruple of hex digits + // + size_t cuk = 0; + + while ( len_w && cuk < 3) { + + if ( ! _(_cs_dot(&len_w, &byt_y)) ) { + return u3_none; + } + + for ( size_t i = 0; i < 4; i++ ) { + + if ( ! len_w ) { + return u3_none; + } + + dit_s = _cs_hex_val(*byt_y); + + if ( dit_s < 16 ) { + val_d <<= 4; + val_d += dit_s; + } + else { + return u3_none; + } + + byt_y++; + len_w--; + } + cuk++; + } + + if ( !len_w ) { + return u3i_chub(val_d); + } + + // Parse a big hex + // + else { + mpz_t a_mp; + mpz_init2(a_mp, 128); + mpz_set_ui(a_mp, val_d); + + val_d = 0; + + // Parse a list of dog followed by + // a quadruple of hex digits + // + cuk = 0; + + while ( len_w ) { + + if ( ! _(_cs_dot(&len_w, &byt_y)) ) { + goto sift_ux_fail; + } + + for ( size_t i = 0; i < 4; i++ ) { + + if ( ! len_w ) { + goto sift_ux_fail; + } + + dit_s = _cs_hex_val(*byt_y); + + if ( dit_s < 16 ) { + val_d <<= 4; + val_d += dit_s; + } + else { + goto sift_ux_fail; + } + + byt_y++; + len_w--; + } + + cuk++; + + // Read 4 chunks + // + if ( cuk == 4 ) { + mpz_mul_2exp(a_mp, a_mp, cuk*16); + mpz_add_ui(a_mp, a_mp, val_d); + + val_d = 0; + cuk = 0; + } + } + + if ( cuk ) { + mpz_mul_2exp(a_mp, a_mp, cuk*16); + mpz_add_ui(a_mp, a_mp, val_d); + } + + if ( len_w ) { +sift_ux_fail: + mpz_clear(a_mp); + return u3_none; + } + + return u3i_mp(a_mp); + } + +} + +/* u3s_sift_ux: parse @ux. + */ +u3_weak +u3s_sift_ux(u3_noun a) +{ + + c3_w len_w = u3r_met(3, a); + c3_y* byt_y; + + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + + else{ + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + return u3s_sift_ux_bytes(len_w, byt_y); +} + +#undef PFIXD diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index 608d702de7..a37dfc8862 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -134,4 +134,14 @@ u3_weak u3s_sift_ud(u3_atom a); + /* u3s_sift_ux_bytes: parse @ux. + */ + u3_weak + u3s_sift_ux_bytes(c3_w len_w, c3_y* byt_y); + + /* u3s_sift_ux: parse @ux. + */ + u3_weak + u3s_sift_ux(u3_atom a); + #endif /* ifndef U3_SERIAL_H */ From 3d50a11fea8eb154223c40ec840ce3bebd7aa514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Wed, 24 May 2023 17:34:47 +0800 Subject: [PATCH 02/16] u3: little refactoring of %ud printer --- pkg/noun/serial.c | 21 +++++++++------------ pkg/noun/serial.h | 3 ++- 2 files changed, 11 insertions(+), 13 deletions(-) diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 943dbd0f0a..6a49e4c63a 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -883,7 +883,6 @@ _cs_etch_ud_bytes(mpz_t a_mp, size_t len_i, c3_y* hun_y) else { while ( 1 ) { b_w = mpz_tdiv_qr_ui(a_mp, b_mp, a_mp, 1000); - u3_assert( mpz_get_ui(b_mp) == b_w ); // XX if ( !mpz_size(a_mp) ) { while ( b_w ) { @@ -904,8 +903,6 @@ _cs_etch_ud_bytes(mpz_t a_mp, size_t len_i, c3_y* hun_y) buf_y++; - u3_assert( buf_y >= hun_y ); // XX - // mpz_sizeinbase may overestimate by 1 // { @@ -919,7 +916,6 @@ _cs_etch_ud_bytes(mpz_t a_mp, size_t len_i, c3_y* hun_y) } mpz_clear(b_mp); - return len_i; } @@ -928,14 +924,15 @@ _cs_etch_ud_bytes(mpz_t a_mp, size_t len_i, c3_y* hun_y) ** =(26 (met 3 (scot %ud (dec (bex 64))))) */ c3_y* -u3s_etch_ud_smol(c3_d a_d, c3_y hun_y[26]) +u3s_etch_ud_smol(c3_d a_d, c3_y hun_y[SMOL_UD]) { - c3_y* buf_y = hun_y + 25; + c3_y* buf_y = hun_y + SMOL_UD - 1; c3_w b_w; if ( !a_d ) { *buf_y-- = '0'; } + else { while ( 1 ) { b_w = a_d % 1000; @@ -969,10 +966,10 @@ u3s_etch_ud(u3_atom a) c3_d a_d; if ( c3y == u3r_safe_chub(a, &a_d) ) { - c3_y hun_y[26]; + c3_y hun_y[SMOL_UD]; c3_y* buf_y = u3s_etch_ud_smol(a_d, hun_y); c3_w dif_w = (c3_p)buf_y - (c3_p)hun_y; - return u3i_bytes(26 - dif_w, buf_y); + return u3i_bytes(SMOL_UD - dif_w, buf_y); } u3i_slab sab_u; @@ -1000,10 +997,10 @@ u3s_etch_ud_c(u3_atom a, c3_c** out_c) c3_y* buf_y; if ( c3y == u3r_safe_chub(a, &a_d) ) { - c3_y hun_y[26]; + c3_y hun_y[SMOL_UD]; buf_y = u3s_etch_ud_smol(a_d, hun_y); - len_i = 26 - ((c3_p)buf_y - (c3_p)hun_y); + len_i = SMOL_UD - ((c3_p)buf_y - (c3_p)hun_y); *out_c = c3_malloc(len_i + 1); (*out_c)[len_i] = 0; @@ -1021,9 +1018,9 @@ u3s_etch_ud_c(u3_atom a, c3_c** out_c) len_i = _cs_etch_ud_bytes(a_mp, len_i, buf_y); - mpz_clear(a_mp); - *out_c = (c3_c*)buf_y; + + mpz_clear(a_mp); return len_i; } diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index a37dfc8862..b2a3ee844d 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -81,8 +81,9 @@ ** ** =(26 (met 3 (scot %ud (dec (bex 64))))) */ +#define SMOL_UD 26 c3_y* - u3s_etch_ud_smol(c3_d a_d, c3_y hun_y[26]); + u3s_etch_ud_smol(c3_d a_d, c3_y hun_y[SMOL_UD]); /* u3s_etch_ud(): atom to @ud. */ From 7ef3c6bb75420e857f64974f85ab292a29efc3a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Wed, 24 May 2023 17:37:31 +0800 Subject: [PATCH 03/16] tests: improve the %ud, %ux, %uv, %uw printers testing --- pkg/noun/jets_tests.c | 70 +++++++++++++++++++++++++++++-------------- 1 file changed, 48 insertions(+), 22 deletions(-) diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index 466ae44540..c77853fb8b 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -11,6 +11,8 @@ _setup(void) u3m_pave(c3y); } +#define _neq_etch_out(sa, sb, len) ((strlen((sa)) != strlen((sb))) || (0 != strncmp((sa), (sb), (len)))) + static inline c3_i _ud_etch(c3_d num_d, const c3_c* num_c) { @@ -19,7 +21,7 @@ _ud_etch(c3_d num_d, const c3_c* num_c) size_t len_i = u3s_etch_ud_c(num, &out_c); c3_i ret_i = 1; - if ( 0 != strcmp(num_c, out_c) ) { + if ( _neq_etch_out(num_c, out_c, len_i) ) { fprintf(stderr, "etch_ud: %" PRIu64 " fail; expected %s, got '%s'\r\n", num_d, num_c, out_c); ret_i = 0; @@ -74,7 +76,7 @@ _test_etch_ud(void) c3_c* out_c; size_t len_i = u3s_etch_ud_c(num, &out_c); - if ( 0 != strncmp(num_c, out_c, len_i) ) { + if ( _neq_etch_out(num_c, out_c, len_i) ) { fprintf(stderr, "etch_ud: (bex 128) fail; expected %s, got '%s'\r\n", num_c, out_c); ret_i = 0; @@ -108,7 +110,7 @@ _ux_etch(c3_d num_d, const c3_c* num_c) size_t len_i = u3s_etch_ux_c(num, &out_c); c3_i ret_i = 1; - if ( 0 != strcmp(num_c, out_c) ) { + if ( _neq_etch_out(num_c, out_c, len_i) ) { fprintf(stderr, "etch_ux: 0x%" PRIx64 " fail; expected %s, got '%s'\r\n", num_d, num_c, out_c); ret_i = 0; @@ -164,7 +166,7 @@ _test_etch_ux(void) c3_c* out_c; size_t len_i = u3s_etch_ux_c(num, &out_c); - if ( 0 != strncmp(num_c, out_c, len_i) ) { + if ( _neq_etch_out(num_c, out_c, len_i) ) { fprintf(stderr, "etch_ux: (bex 128) fail; expected %s, got '%s'\r\n", num_c, out_c); ret_i = 0; @@ -198,7 +200,7 @@ _uv_etch(c3_d num_d, const c3_c* num_c) size_t len_i = u3s_etch_uv_c(num, &out_c); c3_i ret_i = 1; - if ( 0 != strcmp(num_c, out_c) ) { + if ( _neq_etch_out(num_c, out_c, len_i) ) { fprintf(stderr, "etch_uv: 0x%" PRIx64 " fail; expected %s, got '%s'\r\n", num_d, num_c, out_c); ret_i = 0; @@ -250,22 +252,32 @@ _test_etch_uv(void) ret_i &= _uv_etch(0x6744073709551615ULL, "0v6eh.076s4.la5gl"); { - c3_c* num_c = "0v8.00000.00000.00000.00000.00000"; - u3_atom num = u3qc_bex(128); + c3_c* hex_c = "0x1.1234.5678.9abc.def0.1234.5678.9abc.def0"; + c3_c* num_c = "0v8.i6hb7.h6lsr.ro14d.2mf2d.bpnng"; + + u3_noun hot = u3i_bytes(strlen(hex_c), (c3_y*)hex_c); + u3_weak hou = u3s_sift_ux(hot); + + if ( u3_none == hou ) { + fprintf(stderr, "etch_uv: big hex fail\r\n"); + ret_i = 0; + } + c3_c* out_c; - size_t len_i = u3s_etch_uv_c(num, &out_c); + size_t len_i = u3s_etch_uv_c(hou, &out_c); - if ( 0 != strncmp(num_c, out_c, len_i) ) { - fprintf(stderr, "etch_uv: (bex 128) fail; expected %s, got '%s'\r\n", + if ( _neq_etch_out(num_c, out_c, len_i) ) { + fprintf(stderr, "etch_uv: big viz fail; expected %s, got '%s'\r\n", num_c, out_c); ret_i = 0; } + else { - u3_noun out = u3s_etch_uv(num); + u3_noun out = u3s_etch_uv(hou); u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); if ( c3n == u3r_sing(tou, out) ) { - // fprintf(stderr, "etch_uv: (bex 128) mismatch; expected %s\r\n", num_c); + fprintf(stderr, "etch_uv: big viz mismatch; expected %s\r\n", num_c); u3m_p("out", out); ret_i = 0; } @@ -275,7 +287,8 @@ _test_etch_uv(void) } c3_free(out_c); - u3z(num); + u3z(hot); + u3z(hou); } return ret_i; @@ -289,7 +302,7 @@ _uw_etch(c3_d num_d, const c3_c* num_c) size_t len_i = u3s_etch_uw_c(num, &out_c); c3_i ret_i = 1; - if ( 0 != strcmp(num_c, out_c) ) { + if ( _neq_etch_out(num_c, out_c, len_i) ) { fprintf(stderr, "etch_uw: 0x%" PRIx64 " fail; expected %s, got '%s'\r\n", num_d, num_c, out_c); ret_i = 0; @@ -341,22 +354,32 @@ _test_etch_uw(void) ret_i &= _uw_etch(0x6744073709551615ULL, "0w6.t41Ps.9lhol"); { - c3_c* num_c = "0w40.00000.00000.00000.00000"; - u3_atom num = u3qc_bex(128); + c3_c* num_hex_c = "0x1.1234.5678.9abc.def0.1234.5678.9abc.def0"; + c3_c* num_c = "0w4i.d5pUC.HPuY1.8QlDy.qLdXM"; + + u3_noun hot = u3i_bytes(strlen(num_hex_c), (c3_y*)num_hex_c); + u3_weak hou = u3s_sift_ux(hot); + + if ( u3_none == hou ) { + fprintf(stderr, "etch_uw: big hex fail\r\n"); + ret_i = 0; + } + c3_c* out_c; - size_t len_i = u3s_etch_uw_c(num, &out_c); + size_t len_i = u3s_etch_uw_c(hou, &out_c); - if ( 0 != strncmp(num_c, out_c, len_i) ) { - fprintf(stderr, "etch_uw: (bex 128) fail; expected %s, got '%s'\r\n", + if ( _neq_etch_out(num_c, out_c, len_i) ) { + fprintf(stderr, "etch_uw: big wiz fail; expected %s, got '%s'\r\n", num_c, out_c); ret_i = 0; } + else { - u3_noun out = u3s_etch_uw(num); + u3_noun out = u3s_etch_uw(hou); u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); if ( c3n == u3r_sing(tou, out) ) { - fprintf(stderr, "etch_uw: (bex 128) mismatch; expected %s\r\n", num_c); + fprintf(stderr, "etch_uw: big wiz mismatch; expected %s\r\n", num_c); u3m_p("out", out); ret_i = 0; } @@ -366,12 +389,15 @@ _test_etch_uw(void) } c3_free(out_c); - u3z(num); + u3z(hot); + u3z(hou); } return ret_i; } +#undef _neq_etch_out + static inline c3_i _ud_good(c3_w num_w, const c3_c* num_c) { From 2a0d19c6fc3a69d747fd75b8b1bd4fe793a7a35d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 09:59:42 +0800 Subject: [PATCH 04/16] jets: enables the +scot jet --- pkg/noun/jets/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/noun/jets/tree.c b/pkg/noun/jets/tree.c index f6233cd74d..cf1ed62c03 100644 --- a/pkg/noun/jets/tree.c +++ b/pkg/noun/jets/tree.c @@ -2215,7 +2215,7 @@ static u3j_core _139_qua_d[] = // XX disabled, implicated in memory corruption // write tests and re-enable // - // { "scot", 7, _140_qua_scot_a, 0, no_hashes }, + { "scot", 7, _140_qua_scot_a, 0, no_hashes }, // { "scow", 7, _140_qua_scow_a, 0, no_hashes }, { "slaw", 7, _140_qua_slaw_a, 0, no_hashes }, {} From f48decb05dbaf05d25a134ed18d7d2a381f1e1dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 10:04:28 +0800 Subject: [PATCH 05/16] u3: adds %da printing --- pkg/noun/jets/e/scot.c | 3 + pkg/noun/jets_tests.c | 153 +++++++++++ pkg/noun/serial.c | 591 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/serial.h | 8 + 4 files changed, 755 insertions(+) diff --git a/pkg/noun/jets/e/scot.c b/pkg/noun/jets/e/scot.c index f39c46b052..fcf0b878b9 100644 --- a/pkg/noun/jets/e/scot.c +++ b/pkg/noun/jets/e/scot.c @@ -13,6 +13,9 @@ u3qe_scot(u3_atom a, u3_atom b) { switch (a) { case c3__tas: return u3k(b); + + case c3__da: return u3s_etch_da(b); + case c3__ud: return u3s_etch_ud(b); case c3__ux: return u3s_etch_ux(b); case c3__uv: return u3s_etch_uv(b); diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index c77853fb8b..dab832000a 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -13,6 +13,154 @@ _setup(void) #define _neq_etch_out(sa, sb, len) ((strlen((sa)) != strlen((sb))) || (0 != strncmp((sa), (sb), (len)))) +static inline c3_i +_da_etch(mpz_t a_mp, const c3_c* dat_c) +{ + u3_atom dat = u3i_mp(a_mp); + c3_c* out_c; + c3_i ret_i = 1; + size_t len_i; + + len_i = u3s_etch_da_c(dat, &out_c); + + if ( _neq_etch_out(dat_c, out_c, len_i) ) { + fprintf(stderr, "etch_da: 0x"); + mpz_out_str(stderr, 16, a_mp); + fprintf(stderr, " fail; expected %s, got '%s'\r\n", + dat_c, out_c); + ret_i = 0; + } + + else { + u3_noun out = u3s_etch_da(dat); + u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); + + if ( c3n == u3r_sing(tou, out) ) { + fprintf(stderr, "etch_da: 0x"); + mpz_out_str(stderr, 16, a_mp); + fprintf(stderr, " mismatch; expected %s\r\n", dat_c); + u3m_p("out", out); + ret_i = 0; + } + + u3z(out); + u3z(tou); + } + + c3_free(out_c); + u3z(dat); + + return ret_i; +} + +#define _init_date_atom(mp, hi, lo) \ + { \ + mpz_init(mp); \ + mpz_set_ui(dat_mp, hi); \ + mpz_mul_2exp(dat_mp, dat_mp, 64); \ + mpz_add_ui(dat_mp, dat_mp, lo); \ + } \ + +#define _init_date_atom_big(mp, ex, hi, lo) \ + { \ + mpz_init(mp); \ + mpz_set_ui(dat_mp, ex); \ + mpz_mul_2exp(dat_mp, dat_mp, 64); \ + mpz_add_ui(dat_mp, dat_mp, hi); \ + mpz_mul_2exp(dat_mp, dat_mp, 64); \ + mpz_add_ui(dat_mp, dat_mp, lo); \ + } \ + +static c3_i +_test_etch_da(void) +{ + mpz_t dat_mp; + c3_i ret_i = 1; + + // In the beginning was the Word + _init_date_atom(dat_mp, 0x0, 0x0); + ret_i &= _da_etch(dat_mp, "~292277024401-.1.1"); + + // the Word was with God + _init_date_atom(dat_mp, + 0x7ffffffe58e40f80, + 0xbabe000000000000); + ret_i &= _da_etch(dat_mp, "~1.12.25..00.00.00..babe"); + + // and the Word was God - John 1:1 + _init_date_atom(dat_mp, + 0x7ffffffe93b72f70, + 0x3300000000000000) + ret_i &= _da_etch(dat_mp, "~33.4.3..15.00.00..3300"); + + // Test fractional seconds + // + _init_date_atom(dat_mp, + 0x8000000d32bb462f, + 0xcafe000000000000); + ret_i &= _da_etch(dat_mp, "~2023.3.24..05.44.15..cafe"); + + _init_date_atom(dat_mp, + 0x8000000d32bb462f, + 0x0000cafe00000000); + ret_i &= _da_etch(dat_mp, "~2023.3.24..05.44.15..0000.cafe"); + + _init_date_atom(dat_mp, + 0x8000000d32bb462f, + 0x00000000cafe0000); + ret_i &= _da_etch(dat_mp, "~2023.3.24..05.44.15..0000.0000.cafe"); + + _init_date_atom(dat_mp, + 0x8000000d32bb462f, + 0x000000000000cafe); + ret_i &= _da_etch(dat_mp, "~2023.3.24..05.44.15..0000.0000.0000.cafe"); + + // General tests + // + _init_date_atom(dat_mp, + 0x8000000d329d6f76, + 0xadef000000000000); + ret_i &= _da_etch(dat_mp, "~2023.3.1..14.32.22..adef"); + + _init_date_atom(dat_mp, + 0x8000000d32c33b88, + 0x2d00000000000000); + ret_i &= _da_etch(dat_mp, "~2023.3.30..06.36.56..2d00"); + + _init_date_atom(dat_mp, + 0x8000000d32c51c00, + 0x2d00000000000000); + ret_i &= _da_etch(dat_mp, "~2023.3.31..16.46.56..2d00"); + + _init_date_atom(dat_mp, + 0x8000000d3a19f0c0, + 0x2d00000000000000); + ret_i &= _da_etch(dat_mp, "~2027.2.22..07.26.56..2d00"); + + _init_date_atom(dat_mp, + 0x80000029dd78fec0, + 0x2d00000000000000); + ret_i &= _da_etch(dat_mp, "~5924.11.10..10.06.56..2d00"); + + _init_date_atom(dat_mp, + 0x8000700808c7aec0, + 0x2d00000000000000); + ret_i &= _da_etch(dat_mp, "~3903639.9.11..12.46.56..2d00"); + + _init_date_atom_big(dat_mp, + 0xcafeabcd, + 0x8000000d330a6fca, + 0xd022000000000000); + ret_i &= _da_etch(dat_mp, "~1990808568848630424650.2.5..23.52.42..d022"); + + _init_date_atom_big(dat_mp, + 0xcafeabcd, + 0x8000000d330a6fca, + 0xd0220000cafe0000); + ret_i &= _da_etch(dat_mp, "~1990808568848630424650.2.5..23.52.42..d022.0000.cafe"); + + return ret_i; +} static inline c3_i _ud_etch(c3_d num_d, const c3_c* num_c) { @@ -1022,6 +1170,11 @@ _test_jets(void) { c3_i ret_i = 1; + if ( !_test_etch_da() ) { + fprintf(stderr, "test jets: etch_da: failed\r\n"); + ret_i = 0; + } + if ( !_test_etch_ud() ) { fprintf(stderr, "test jets: etch_ud: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 6a49e4c63a..c849987169 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -3,6 +3,7 @@ #include "serial.h" #include +#include #include #include "allocate.h" @@ -856,6 +857,596 @@ u3s_cue_atom(u3_atom a) return u3s_cue_bytes((c3_d)len_w, byt_y); } +/* +yo time constants + */ +#define CET_YO 36524 +#define DAY_YO 86400 +#define ERA_YO 146097 +#define HOR_YO 3600 +#define MIT_YO 60 +#define JES_YO 292277024400 + +static c3_s _cs_moh_yo[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; +static c3_s _cs_moy_yo[12] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; + +/* +tarp - parsed time + */ +struct _tarp { + + // days + union { + mpz_t day_mp; // big + c3_d day_d; // smol + }; + c3_o dag_o; // is day big? + + c3_w hor_w; // hours + c3_w mit_w; // minutes + c3_w sec_w; // seconds + + c3_d fan_d; // fractional seconds + size_t cuk_i; // number 4-bit chunks in fan_d + +}; + +/* [year month day] + */ +struct _cald { + + // year + union { + mpz_t yer_mp; + c3_d yer_d; + }; + + // year AD? + c3_y yad_o; + + c3_s mot_s; // month + c3_s day_s; // day +}; + +static size_t _cs_etch_da_size(struct _tarp* rip, struct _cald* ger) +{ + size_t len_i = 0; + + // Space for fractional part + // + if ( rip->fan_d > 0 ) { + + len_i += 4*rip->cuk_i + rip->cuk_i; // cuk_i 2-byte chunks + cuk_i . + + len_i += 1; // . + + len_i += 8+2; // hh.mm.ss + .. + } + + // No fractional part + // + else { + + // Time hh.mm.ss + if ( !( rip->hor_w == 0 && rip->mit_w == 0 && rip->sec_w == 0) ) { + len_i += 8 + 2; // + .. + } + } + + // year.month.day + // + if ( ger->day_s < 10 ) { + len_i += 1; + } + else { + len_i += 2; + } + + len_i += 1; // . + + if( ger->mot_s < 10 ) { + len_i += 1; + } + else { + len_i += 2; + } + + len_i += 1; // . + + if ( _(rip->dag_o) ) { + len_i += mpz_sizeinbase(ger->yer_mp, 10); + } + else { + len_i += ceil(log10(ger->yer_d)) + 1; + } + + if ( !_(ger->yad_o) ) { + len_i += 1; // - + } + + len_i += 1; // ~ + + return len_i; +} + +/* +yell: atom to +tarp + */ +static struct _tarp _cs_yell(u3_atom a) { + + u3_atom sec_a; + mpz_t sec_mp; + + struct _tarp rip; + + rip.fan_d = u3r_chub(0,a); + rip.cuk_i = 4; + + // Shift right until first non-zero chunk + // + if (rip.fan_d > 0) { + while ( (rip.fan_d & 0xffff) == 0) { + rip.fan_d >>= 16; + rip.cuk_i--; + } + } + else { + rip.cuk_i = 0; + } + + c3_d sec_d; + sec_a = u3qc_rsh(6, 1, a); + + if ( c3y == u3r_safe_chub(sec_a, &sec_d) ) { + rip.day_d = sec_d / DAY_YO; + rip.sec_w = sec_d % DAY_YO; + + rip.dag_o = c3n; + } + + else { + u3r_mp(sec_mp, sec_a); + mpz_init2(rip.day_mp, 64+32); + + mpz_tdiv_qr_ui(rip.day_mp, sec_mp, sec_mp, DAY_YO); + rip.sec_w = mpz_get_ui(sec_mp); + + if ( mpz_fits_ulong_p(rip.day_mp) ) { + // XX make sure this C is solid + rip.day_d = mpz_get_ui(rip.day_mp); + + mpz_clear(rip.day_mp); + + rip.dag_o = c3n; + } + else { + rip.dag_o = c3y; + } + + mpz_clear(sec_mp); + } + + rip.hor_w = rip.sec_w / HOR_YO; + rip.sec_w %= HOR_YO; + + rip.mit_w = rip.sec_w / MIT_YO; + rip.sec_w %= MIT_YO; + + + u3z(sec_a); + return rip; +} + +/* +yall: small day / day of year + */ +static struct _cald _cs_yall_smol(c3_d day_d) { + + c3_d era_d; + c3_d cet_d; + c3_y lep_o; + + struct _cald ger; + + era_d = 0; + ger.yer_d = 0; + + era_d = day_d / ERA_YO; + day_d %= ERA_YO; + + // We are within the first century, + // and the first year is a leap year, despite + // it being a centurial year -- it is divisible by 400 + // + if ( day_d <= CET_YO ) { + lep_o = c3y; + cet_d = 0; + } + + // We are past the first century + // + else { + lep_o = c3n; + cet_d = 1; + day_d -= (CET_YO + 1); + + cet_d += day_d / CET_YO; + day_d = day_d % CET_YO; + + // yer <- yer + cet*100 + ger.yer_d += cet_d*100; + + } + + // yer <- yer + era*400 + ger.yer_d += era_d*400; + + c3_d dis_d; + c3_d ner_d = 0; + + if ( _(lep_o) ) { + dis_d = 366; + } + else { + dis_d = 365; + } + + // Exceeded a year + // + while ( day_d >= dis_d ) { + ner_d += 1; + day_d -= dis_d; + + // leap year + // + if ( !(ner_d % 4) ) { + lep_o = c3y; + dis_d = 366; + } + else { + lep_o = c3n; + dis_d = 365; + } + } + + ger.yer_d += ner_d; + + c3_s* cah; + ger.mot_s = 0; + + if ( _(lep_o) ) { + cah = _cs_moy_yo; + } + else { + cah = _cs_moh_yo; + } + + // At this point day_d < 366 + ger.day_s = day_d; + + // Count towards the month + // + while ( ger.day_s >= cah[ger.mot_s] ) { + ger.day_s -= cah[ger.mot_s]; + ger.mot_s++; + } + + ger.day_s++; + ger.mot_s++; + + // Year before Christ + // + if ( ger.yer_d <= JES_YO ) { + ger.yer_d = 1 + JES_YO - ger.yer_d; // 0 AD is 1 BC + ger.yad_o = c3n; + } + + // Year after Christ + // + else { + ger.yer_d -= JES_YO; + ger.yad_o = c3y; + } + + return ger; +} +/* +yall: day / day of year + */ +static struct _cald _cs_yall(mpz_t day_mp) { + + mpz_t era_mp; + c3_d cet_d; + c3_d day_d; + c3_y lep_o; + + struct _cald ger; + + mpz_init(era_mp); + mpz_init(ger.yer_mp); + + mpz_tdiv_qr_ui(era_mp, day_mp, day_mp, ERA_YO); + + day_d = mpz_get_ui(day_mp); + + // We are within the first century, + // and the first year is a leap year, despite + // it being a centurial year -- it is divisible by 400 + // + if ( day_d <= CET_YO ) { + lep_o = c3y; + cet_d = 0; + } + + // We are past the first century + // + else { + lep_o = c3n; + cet_d = 1; + day_d -= (CET_YO + 1); + + cet_d += day_d / CET_YO; + day_d = day_d % CET_YO; + + // yer <- yer + cet*100 + mpz_add_ui(ger.yer_mp, ger.yer_mp, cet_d*100); + + } + + // yer <- yer + era*400 + mpz_addmul_ui(ger.yer_mp, era_mp, 400); + + c3_d dis_d; + c3_d ner_d = 0; + + if ( _(lep_o) ) { + dis_d = 366; + } + else { + dis_d = 365; + } + + // Exceeded a year + // + while ( day_d >= dis_d ) { + ner_d += 1; + day_d -= dis_d; + + // leap year + // + if ( !(ner_d % 4) ) { + lep_o = c3y; + dis_d = 366; + } + else { + lep_o = c3n; + dis_d = 365; + } + } + + mpz_add_ui(ger.yer_mp, ger.yer_mp, ner_d); + + c3_s* cah; + ger.mot_s = 0; + + if ( _(lep_o) ) { + cah = _cs_moy_yo; + } + else { + cah = _cs_moh_yo; + } + + // At this point day_d < 366 + ger.day_s = day_d; + + // Count towards the month + // + while ( ger.day_s >= cah[ger.mot_s] ) { + ger.day_s -= cah[ger.mot_s]; + ger.mot_s++; + } + + ger.day_s++; + ger.mot_s++; + + // Year before Christ + // + if ( mpz_cmp_ui(ger.yer_mp, JES_YO) <= 0 ) { + + mpz_ui_sub(ger.yer_mp, 1 + JES_YO, ger.yer_mp); + ger.yad_o = c3n; + } + + // Year after Christ + // + else { + mpz_sub_ui(ger.yer_mp, ger.yer_mp, JES_YO); + ger.yad_o = c3y; + } + + mpz_clear(era_mp); + return ger; +} +/* _cs_etch_da_bytes(): atom to @da impl. + */ +size_t _cs_etch_da_bytes(struct _tarp* rip, struct _cald* ger, size_t len_i, c3_y* hun_y) +{ + + c3_y* buf_y = hun_y + (len_i - 1); + + c3_s paf_s = 0x0; + + // Print out up to four 16-bit chunks + // + if ( rip->fan_d > 0) { + + while ( rip->cuk_i > 0) { + + paf_s = rip->fan_d & 0xffff; + rip->fan_d >>= 16; + + // Print the 16-bit chunk in hexadecimal + *buf_y-- = u3s_dit_y[ (paf_s >> 0) & 0xf ]; + *buf_y-- = u3s_dit_y[ (paf_s >> 4) & 0xf ]; + *buf_y-- = u3s_dit_y[ (paf_s >> 8) & 0xf ]; + *buf_y-- = u3s_dit_y[ (paf_s >> 12) & 0xf ]; + *buf_y-- = '.'; + + rip->cuk_i--; + } + + *buf_y-- = '.'; + } + + // Print the time if the time is non-zero, or + // if we have printed fractional seconds + // + if ( buf_y < (hun_y + len_i - 1) || ! ( rip->fan_d == 0 && rip->hor_w == 0 && rip->mit_w == 0 && rip->sec_w == 0 ) ) { + + *buf_y-- = '0' + ( rip->sec_w % 10 ); + *buf_y-- = '0' + ( rip->sec_w / 10 ); + *buf_y-- = '.'; + + *buf_y-- = '0' + ( rip->mit_w % 10 ); + *buf_y-- = '0' + ( rip->mit_w / 10 ); + *buf_y-- = '.'; + + *buf_y-- = '0' + ( rip->hor_w % 10 ); + *buf_y-- = '0' + ( rip->hor_w / 10 ); + *buf_y-- = '.'; + *buf_y-- = '.'; + } + + // print out the day of the year + // + *buf_y-- = '0' + ( ger->day_s % 10); + ger->day_s /= 10; + if ( ger->day_s > 0 ) { + *buf_y-- = '0' + ger->day_s; + } + *buf_y-- = '.'; + + *buf_y-- = '0' + ( ger->mot_s % 10); + ger->mot_s /= 10; + if ( ger->mot_s > 0 ) { + *buf_y-- = '0' + ger->mot_s; + } + *buf_y-- = '.'; + + // Print out the year + // + + // BC year + if( ger->yad_o == c3n ) { + *buf_y-- = '-'; + } + + + // Smol year + // + if ( !_(rip->dag_o) ) { + while ( ger->yer_d > 0 ) { + *buf_y-- = '0' + ger->yer_d % 10; + ger->yer_d /= 10; + } + } + + else { + + mpz_t r_mp; + mpz_init(r_mp); + c3_d dit_d; + + // XX speed up by reading whole words ? + // + while ( mpz_size(ger->yer_mp) > 0 ) { + + dit_d = mpz_tdiv_qr_ui(ger->yer_mp, r_mp, ger->yer_mp, 10); + *buf_y-- = '0' + dit_d; + } + + mpz_clear(r_mp); + } + + *buf_y = '~'; + + size_t dif_i = buf_y - hun_y; + + if ( dif_i > 0 ) { + len_i -= dif_i; + memmove(hun_y, buf_y, len_i); + memset(hun_y + len_i, 0, dif_i); + } + + return len_i; +} + +/* _u3s_etch_da: atom to @da. + */ +u3_atom +u3s_etch_da(u3_atom a) +{ + + struct _tarp rip; + struct _cald ger; + size_t len_i; + + rip = _cs_yell(a); + + if ( !_(rip.dag_o) ) { + ger = _cs_yall_smol(rip.day_d); + } + else { + ger = _cs_yall(rip.day_mp); + } + + len_i = _cs_etch_da_size(&rip, &ger); + + u3i_slab sab_u; + c3_y* buf_y; + + u3i_slab_bare(&sab_u, 3, len_i); + sab_u.buf_w[sab_u.len_w - 1] = 0; + + _cs_etch_da_bytes(&rip, &ger, len_i, sab_u.buf_y); + + if ( _(rip.dag_o) ) { + mpz_clear(rip.day_mp); + mpz_clear(ger.yer_mp); + } + return u3i_slab_mint_bytes(&sab_u); +} + +/* u3s_etch_da_c: atom to @da, as a malloc'd c string. + */ +size_t +u3s_etch_da_c(u3_atom a, c3_c** out_c) +{ + c3_y* buf_y; + size_t len_i; + struct _tarp rip; + struct _cald ger; + + rip = _cs_yell(a); + + if ( !_(rip.dag_o) ) { + ger = _cs_yall_smol(rip.day_d); + } + else { + ger = _cs_yall(rip.day_mp); + } + + len_i = _cs_etch_da_size(&rip, &ger); + + buf_y = c3_malloc(len_i + 1); + buf_y[len_i] = 0; + + len_i = _cs_etch_da_bytes(&rip, &ger, len_i, buf_y); + + *out_c = (c3_c*)buf_y; + + if ( _(rip.dag_o) ) { + mpz_clear(rip.day_mp); + mpz_clear(ger.yer_mp); + } + return len_i; +} + /* _cs_etch_ud_size(): output length in @ud for given mpz_t. */ static inline size_t diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index b2a3ee844d..c67f494e89 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -77,6 +77,14 @@ u3_noun u3s_cue_atom(u3_atom a); + /* u3s_etch_da(): atom to @da. + */ + u3_atom u3s_etch_da(u3_atom a); + + /* u3s_etch_da_c(): atom to @da, as a malloc'd c string. + */ + size_t u3s_etch_da_c(u3_atom a, c3_c** out_c); + /* u3s_etch_ud_smol(): c3_d to @ud ** ** =(26 (met 3 (scot %ud (dec (bex 64))))) From 202505102a549bd77be581a56aafcc875cca9013 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 10:30:33 +0800 Subject: [PATCH 06/16] u3: implements new %da parser --- pkg/noun/jets/e/slaw.c | 171 ++------------ pkg/noun/jets_tests.c | 121 ++++++++++ pkg/noun/serial.c | 511 +++++++++++++++++++++++++++++++++++++++-- pkg/noun/serial.h | 10 + 4 files changed, 637 insertions(+), 176 deletions(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index db7ca96af1..e90c036be9 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -1,4 +1,4 @@ -/// @file +/// @fil #include "jets/k.h" #include "jets/q.h" @@ -8,6 +8,18 @@ #include +static inline u3_noun +_parse_da(u3_noun a) +{ + u3_weak pro; + + if ( u3_none == (pro = u3s_sift_da(u3x_atom(a))) ) { + return u3_nul; + } + + return u3nc(u3_nul, pro); +} + static inline u3_noun _parse_ud(u3_noun a) { @@ -270,165 +282,10 @@ _parse_p(u3_noun cor, u3_noun txt) { 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) { @@ -470,7 +327,7 @@ u3we_slaw(u3_noun cor) switch (mod) { case c3__da: - return _parse_da(cor, txt); + return _parse_da(txt); case 'p': return _parse_p(cor, txt); diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index dab832000a..3fd439885e 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -546,6 +546,122 @@ _test_etch_uw(void) #undef _neq_etch_out +static inline c3_i +_da_good(c3_d hi, c3_d lo, const c3_c* dat_c) +{ + u3_weak out; + + out = u3s_sift_da_bytes(strlen(dat_c), (c3_y*)dat_c); + + if ( u3_none == out) { + fprintf(stderr, "sift_da: %s fail; expected hi: 0x%llx, lo: 0x%llx\r\n", + dat_c, hi, lo); + + return 0; + } + + c3_d out_lo = u3r_chub(0, out); + + // Careful, works only on 128-bit dates + // + c3_d out_hi = u3r_chub(1, out); + + if ( out_hi != hi || out_lo != lo ) { + fprintf(stderr, "sift_da: %s fail; expected 0x%llx,0x%llx: actual 0x%llx,0x%llx\r\n",dat_c, hi, lo, out_hi, out_lo); + + u3z(out); + + return 0; + } + + u3z(out); + + return 1; +} + +static inline c3_i +_da_fail(const c3_c* dat_c) +{ + u3_weak out; + + if ( u3_none != (out = u3s_sift_da_bytes(strlen(dat_c), (c3_y*)dat_c)) ) { + u3m_p("out", out); + fprintf(stderr, "sift_da: %s expected fail\r\n", dat_c); + + u3z(out); + + return 0; + } + + u3z(out); + + return 1; +} + +static c3_i +_test_sift_da(void) +{ + c3_i ret_i = 1; + + ret_i &= _da_good(0x0, 0x0, "~292277024401-.1.1"); + ret_i &= _da_good(0x7ffffffe58e40f80, + 0xbabe000000000000, + "~1.12.25..00.00.00..babe"); + ret_i &= _da_good(0x7ffffffe93b72f70, + 0x3300000000000000, + "~33.4.3..15.00.00..3300"); + ret_i &= _da_good(0x7ffffffe93b72f70, + 0x3300000000000000, + "~33.4.3..15.00.00..3300"); + ret_i &= _da_good(0x8000000d32bb462f, + 0xcafe000000000000, + "~2023.3.24..05.44.15..cafe"); + ret_i &= _da_good(0x8000000d32bb462f, + 0xcafe00000000, + "~2023.3.24..05.44.15..0000.cafe"); + ret_i &= _da_good(0x8000000d32bb462f, + 0xcafe0000, + "~2023.3.24..05.44.15..0000.0000.cafe"); + ret_i &= _da_good(0x8000000d32bb462f, + 0xcafe, + "~2023.3.24..05.44.15..0000.0000.0000.cafe"); + ret_i &= _da_good(0x8000000d329d6f76, + 0xadef000000000000, + "~2023.3.1..14.32.22..adef"); + ret_i &= _da_good(0x8000000d32c33b88, + 0x2d00000000000000, + "~2023.3.30..06.36.56..2d00"); + ret_i &= _da_good(0x8000000d32c51c00, + 0x2d00000000000000, + "~2023.3.31..16.46.56..2d00"); + ret_i &= _da_good(0x8000000d3a19f0c0, + 0x2d00000000000000, + "~2027.2.22..07.26.56..2d00"); + ret_i &= _da_good(0x80000029dd78fec0, + 0x2d00000000000000, + "~5924.11.10..10.06.56..2d00"); + ret_i &= _da_good(0x8000700808c7aec0, + 0x2d00000000000000, + "~3903639.9.11..12.46.56..2d00"); + + ret_i &= _da_fail("~2023--.1.1"); + ret_i &= _da_fail("~2.023.1.1"); + ret_i &= _da_fail("~2023.01.1"); + ret_i &= _da_fail("~2023.1.01"); + ret_i &= _da_fail("~2023.13.1"); + ret_i &= _da_fail("~2023.12.32"); + ret_i &= _da_fail("~2023.2.31"); + ret_i &= _da_fail("~2023.2.29"); + + ret_i &= _da_fail("~2023.3.3..24.00.00"); + ret_i &= _da_fail("~2023.3.3..24.00.00..ca"); + ret_i &= _da_fail("~2023.3.3..24.00.00..cAFE"); + ret_i &= _da_fail("~2023.3.3..24.00.00..cAFE"); + ret_i &= _da_fail("~2023.3.3..24.00.00..cafe.cafe."); + + return ret_i; +} + static inline c3_i _ud_good(c3_w num_w, const c3_c* num_c) { @@ -1195,6 +1311,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_sift_da() ) { + fprintf(stderr, "test jets: sift_da: failed\r\n"); + ret_i = 0; + } + if ( !_test_sift_ud() ) { fprintf(stderr, "test jets: sift_ud: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index c849987169..9c85477774 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -1896,6 +1896,498 @@ static inline c3_o _cs_dot(c3_w* len_w, c3_y** byt_yp) } #define DIGIT(a) ( ((a) >= '0') && ((a) <= '9') ) + +/* +two: parse a maximum 2 digit decimal number, greater than 0. + */ +static inline c3_o _cs_two(c3_s* num, c3_w* len_w, c3_y** byt_yp) +{ + + if ( !(*len_w) || !DIGIT(**byt_yp) || **byt_yp == '0' ) { + return c3n; + } + + *num = **byt_yp - '0'; + + (*byt_yp)++; + (*len_w)--; + + if ( *len_w && DIGIT(**byt_yp)) { + *num *= 10; + *num += **byt_yp - '0'; + + (*byt_yp)++; + (*len_w)--; + } + + return c3y; +} + +/* +duo: parse a maximum 2 digit decimal number, + * allowing for leading 0. + */ +static inline c3_o _cs_duo(c3_s* num, c3_w* len_w, c3_y** byt_yp) +{ + + if ( !(*len_w) || !DIGIT(**byt_yp) ) { + return c3n; + } + + *num = **byt_yp - '0'; + (*byt_yp)++; + (*len_w)--; + + if ( *len_w && DIGIT(**byt_yp)) { + *num *= 10; + *num += **byt_yp - '0'; + (*byt_yp)++; + (*len_w)--; + } + + return c3y; +} + +/* _cs_hex_val: char to hexadecimal digit. + */ +static inline c3_s _cs_hex_val(c3_y hex) { + + if ( hex > '9' ) { + if ( hex < 'a' ) { + return -1; + } + // hex >= 'a' + else { + return (hex - 'a') + 10; + } + } + // hex <= '9' + else { + return hex - '0'; + } +} + +/* +yelp + */ +static inline c3_o _cs_yelp_mp(mpz_t yer_mp) +{ + + c3_o res_o; + + if ( mpz_divisible_ui_p(yer_mp, 4) ) { + + if ( mpz_divisible_ui_p(yer_mp, 100) ) { + + if ( mpz_divisible_ui_p(yer_mp, 400) ) { + res_o = c3y; + } + else { + res_o = c3n; + } + } + + else { + res_o = c3y; + } + } + else { + res_o = c3n; + } + + return res_o; +} + +/* ++yelq:when:so + */ +static inline c3_o _cs_yelq_mp(c3_o ad_o, mpz_t yer_mp) { + + if ( _(ad_o) ) { + return _cs_yelp_mp(yer_mp); + } + else { + c3_o res_o; + + mpz_t ber_mp; + mpz_init(ber_mp); + + mpz_sub_ui(ber_mp, yer_mp, 1); + + res_o = _cs_yelp_mp(ber_mp); + + mpz_clear(ber_mp); + return res_o; + } +} +/* +yawn: days since the beginning. + */ +static inline void _cs_yawn(mpz_t days_mp, struct _cald* cal) +{ + c3_s* cah; + + mpz_init2(days_mp, 128); + + if ( _(_cs_yelp_mp(cal->yer_mp)) ) { + cah = _cs_moy_yo; + } + else { + cah = _cs_moh_yo; + } + + cal->day_s--; + cal->mot_s--; + + // Elapsed days + // + mpz_add_ui(days_mp, days_mp, cal->day_s); + + // Elapsed days in months + // + for ( size_t mot = 0; mot < cal->mot_s; mot++ ) { + mpz_add_ui(days_mp, days_mp, cah[mot]); + } + + // Elapsed days in years + // + while ( mpz_cmp_ui(cal->yer_mp, 0) > 0) { + + // Not divisible by 4 + // + if ( ! mpz_divisible_ui_p(cal->yer_mp, 4) ) { + + mpz_sub_ui(cal->yer_mp, cal->yer_mp, 1); + + if ( _(_cs_yelp_mp(cal->yer_mp)) ) { + mpz_add_ui(days_mp, days_mp, 366); + } + else { + mpz_add_ui(days_mp, days_mp, 365); + } + } + + // Divisible by 4 + // + else { + + // Not divisible by 100 + // + if ( ! mpz_divisible_ui_p(cal->yer_mp, 100) ) { + + mpz_sub_ui(cal->yer_mp, cal->yer_mp, 4); + + if ( _(_cs_yelp_mp(cal->yer_mp)) ) { + mpz_add_ui(days_mp, days_mp, 1 + 365*4); + } + else { + mpz_add_ui(days_mp, days_mp, 365*4); + } + } + + // Divisible by 4 & 100 + // + else { + + // Not divisible by 400 + // + if ( ! mpz_divisible_ui_p(cal->yer_mp, 400) ) { + mpz_sub_ui(cal->yer_mp, cal->yer_mp, 100); + + if ( _(_cs_yelp_mp(cal->yer_mp)) ) { + mpz_add_ui(days_mp, days_mp, 1 + 365*100 + 24); + } + else { + mpz_add_ui(days_mp, days_mp, 365*100 + 24); + } + } + // Divisible by 4 & 100 & 400, + // finish the calculation + // + else { + mpz_tdiv_q_ui(cal->yer_mp, cal->yer_mp, 400); + mpz_addmul_ui(days_mp, cal->yer_mp, 1 + (365*100+24)*4); + break; + } + } + } + } +} + +#define HEXDIGIT(a) ( ((a) >= '0' && (a) <= '9') || ((a) >= 'a' && (a) <= 'f') ) + +/* u3s_sift_da_bytes: parse @da impl. + */ +u3_weak +u3s_sift_da_bytes(c3_w len_w, c3_y* byt_y) +{ + struct _cald cal; + + if ( !len_w ) return u3_none; + + // ++ slaw %da + // + + // The shortest date is ~1.1.1, 6 bytes + if ( *byt_y != '~' || len_w < 6) return u3_none; + + byt_y++; + len_w--; + + // Parse the year + // + if ( DIGIT(*byt_y) && *byt_y != '0' ) { + + mpz_init(cal.yer_mp); + + mpz_add_ui(cal.yer_mp, cal.yer_mp, *byt_y - '0'); + + len_w--; + byt_y++; + + while ( DIGIT(*byt_y) && len_w > 0) { + + mpz_mul_ui(cal.yer_mp, cal.yer_mp, 10); + mpz_add_ui(cal.yer_mp, cal.yer_mp, *byt_y - '0'); + + len_w--; + byt_y++; + } + + } + + else { + return u3_none; + } + + if ( !len_w ) { + goto sift_da_fail; + } + + // Optional following hep to indicate a BC year + // + if ( *byt_y == '-' ) { + + cal.yad_o = c3n; + + len_w--; + byt_y++; + } + else { + cal.yad_o = c3y; + } + + // +veal: check whether the year is in proper range + // For AD years: from 1 AD to the future + // For BC years: from 1 BC until JES_YO+1 BC + // + if ( mpz_cmp_ui(cal.yer_mp, 0) == 0 || + (!_(cal.yad_o) && mpz_cmp_ui(cal.yer_mp, JES_YO+1) > 0 ) ) { + goto sift_da_fail; + } + + // We need at least .m.d + // + if ( len_w < 4 ) { + goto sift_da_fail; + } + + // Parse .month + // + cal.mot_s = 0; + + if ( !_(_cs_dot(&len_w, &byt_y)) || + !_(_cs_two(&cal.mot_s, &len_w, &byt_y)) ) { + goto sift_da_fail; + } + + if ( cal.mot_s > 12 ) { + goto sift_da_fail; + } + + // Parse .day + // + cal.day_s = 0; + + if ( !_(_cs_dot(&len_w, &byt_y)) || + !_(_cs_two(&cal.day_s, &len_w, &byt_y)) ){ + goto sift_da_fail; + } + + + // Validate the day + // + c3_s mob; + + // Leap year + // + if ( _(_cs_yelq_mp(cal.yad_o, cal.yer_mp)) ) { + mob = _cs_moy_yo[cal.mot_s-1]; + } + else { + mob = _cs_moh_yo[cal.mot_s-1]; + } + + if ( cal.day_s > mob ) { + goto sift_da_fail; + } + + + /* hor.mit.sec..fan + */ + c3_s hor_s = 0; + c3_s mit_s = 0; + c3_s sec_s = 0; + c3_d fan_d = 0; + + // Parse the time ..hh.mm.ss + // This requires minimum of 10 bytes + // + if ( len_w >= 10 ) { + + if ( *byt_y != '.' || *(byt_y+1) != '.') { + goto sift_da_fail; + } + + len_w -= 2; + byt_y += 2; + + // Parse hour + // + if ( !_(_cs_duo(&hor_s, &len_w, &byt_y)) ) { + goto sift_da_fail; + } + + if ( hor_s > 23 ) { + goto sift_da_fail; + } + + // Parse .minutes + // + if ( !_(_cs_dot(&len_w, &byt_y)) || + !_(_cs_duo(&mit_s, &len_w, &byt_y)) ) { + goto sift_da_fail; + } + + if ( mit_s > 59 ) { + goto sift_da_fail; + } + + // Parse .seconds + // + if ( !_(_cs_dot(&len_w, &byt_y)) || + !_(_cs_duo(&sec_s, &len_w, &byt_y)) ) { + goto sift_da_fail; + } + + if ( sec_s > 59 ) { + goto sift_da_fail; + } + + // Parse ..fractional, at least ..cafe + // + if ( len_w >= 6 ) { + + if ( *byt_y != '.' ) { + goto sift_da_fail; + } + + byt_y++; + len_w--; + + size_t muc = 4; + + while ( len_w >= 5 && muc > 0 ) { + + if ( *byt_y != '.' ) { + goto sift_da_fail; + } + + if ( !( HEXDIGIT(*(byt_y+1)) && + HEXDIGIT(*(byt_y+2)) && + HEXDIGIT(*(byt_y+3)) && + HEXDIGIT(*(byt_y+4)) ) ) { + goto sift_da_fail; + } + + fan_d += (c3_d)((_cs_hex_val(*(byt_y+1)) << 12) + + (_cs_hex_val(*(byt_y+2)) << 8) + + (_cs_hex_val(*(byt_y+3)) << 4) + + (_cs_hex_val(*(byt_y+4))) ) << ((muc-1)*16); + muc--; + len_w -= 5; + byt_y += 5; + + } + + } + } + + if ( len_w != 0 ) { +sift_da_fail: + mpz_clear(cal.yer_mp); + return u3_none; + } + + // + // ++ year, date to @da + // + + // year to absolute year + // + if ( _(cal.yad_o) ) { + mpz_add_ui(cal.yer_mp, cal.yer_mp, JES_YO); + } + + else { + mpz_ui_sub(cal.yer_mp, JES_YO+1, cal.yer_mp); + } + + mpz_t days_mp; + + _cs_yawn(days_mp, &cal); + + // day_mp is now expressed in seconds + // + mpz_mul_ui(days_mp, days_mp, DAY_YO); + + if ( hor_s ) { + mpz_add_ui(days_mp, days_mp, hor_s*HOR_YO); + } + + if ( mit_s ) { + mpz_add_ui(days_mp, days_mp, mit_s*MIT_YO); + } + + if ( sec_s ) { + mpz_add_ui(days_mp, days_mp, sec_s); + } + + mpz_mul_2exp(days_mp, days_mp, 64); + mpz_add_ui(days_mp, days_mp, fan_d); + + mpz_clear(cal.yer_mp); + return u3i_mp(days_mp); +} + +#undef HEXDIGIT + +/* u3s_sift_da: parse @da. +*/ +u3_weak +u3s_sift_da(u3_atom a) +{ + c3_w len_w = u3r_met(3, a); + c3_y* byt_y; + + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + else { + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + return u3s_sift_da_bytes(len_w, byt_y); +} + #define BLOCK(a) ( ('.' == (a)[0]) \ && DIGIT(a[1]) \ && DIGIT(a[2]) \ @@ -2031,25 +2523,6 @@ u3s_sift_ud(u3_atom a) byt_y += 2; \ } -/* _cs_hex_val: char to hexadecimal digit. - */ -static inline c3_s _cs_hex_val(c3_y hex) { - - if ( hex > '9' ) { - if ( hex < 'a' ) { - return -1; - } - // hex >= 'a' - else { - return (hex - 'a') + 10; - } - } - // hex <= '9' - else { - return hex - '0'; - } -} - /* u3s_sift_ux_bytes: parse @ux impl. */ u3_weak diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index c67f494e89..0699982568 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -133,6 +133,16 @@ size_t u3s_etch_uw_c(u3_atom a, c3_c** out_c); + /* u3s_sift_da_bytes: parse @da. + */ + u3_weak + u3s_sift_da_bytes(c3_w len_w, c3_y* byt_y); + + /* u3s_sift_da: parse @da. + */ + u3_weak + u3s_sift_da(u3_atom a); + /* u3s_sift_ud_bytes: parse @ud. */ u3_weak From add5dc4c2fe88d686bd07127e2544f2f61020362 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 10:55:02 +0800 Subject: [PATCH 07/16] u3: adds %p printing --- pkg/noun/jets/e/scot.c | 3 + pkg/noun/jets_tests.c | 144 +++++++++++++++++++++++++ pkg/noun/serial.c | 235 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/serial.h | 18 ++++ 4 files changed, 400 insertions(+) diff --git a/pkg/noun/jets/e/scot.c b/pkg/noun/jets/e/scot.c index fcf0b878b9..0d143e6175 100644 --- a/pkg/noun/jets/e/scot.c +++ b/pkg/noun/jets/e/scot.c @@ -16,10 +16,13 @@ u3qe_scot(u3_atom a, u3_atom b) case c3__da: return u3s_etch_da(b); + case 'p': return u3s_etch_p(b); + case c3__ud: return u3s_etch_ud(b); case c3__ux: return u3s_etch_ux(b); case c3__uv: return u3s_etch_uv(b); case c3__uw: return u3s_etch_uw(b); + default: return u3_none; } } diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index 3fd439885e..89c3e07cdb 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -161,6 +161,145 @@ _test_etch_da(void) return ret_i; } + +static inline c3_i +_p_etch(c3_d pun_d, const c3_c* pun_c) +{ + u3_atom pun = u3i_chub(pun_d); + c3_c* out_c; + size_t len_i = u3s_etch_p_c(pun, &out_c); + c3_i ret_i = 1; + + if ( _neq_etch_out(out_c, pun_c, len_i) ) { + fprintf(stderr, "etch_p: %" PRIu64 " fail; expected %s, got '%s'\r\n", + pun_d, pun_c, out_c); + ret_i = 0; + } + else { + u3_noun out = u3s_etch_p(pun); + u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); + + if ( c3n == u3r_sing(tou, out) ) { + fprintf(stderr, "etch_p: %" PRIu64 " mismatch; expected %s\r\n", pun_d, pun_c); + u3m_p("out", out); + ret_i = 0; + } + + u3z(out); + u3z(tou); + } + + c3_free(out_c); + u3z(pun); + + return ret_i; +} +static c3_i +_big_p_etch(c3_c* big_str, c3_c* pun_c) +{ + size_t ret_i = 1; + + u3_atom big; + mpz_t big_mp; + + mpz_init(big_mp); + mpz_set_str(big_mp, big_str, 16); + + big = u3i_mp(big_mp); + + c3_c* out_c; + size_t len_i = u3s_etch_p_c(big, &out_c); + + if ( _neq_etch_out(pun_c, out_c, len_i) ) { + fprintf(stderr, "etch_p_big: %s fail; expected %s, got '%s'\r\n", + big_str, pun_c, out_c); + ret_i = 0; + } + else { + u3_noun out = u3s_etch_p(big); + u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); + + if ( c3n == u3r_sing(tou, out) ) { + fprintf(stderr, "etch_ud: %s mismatch; expected %s\r\n", big_str, pun_c); + u3m_p("out", out); + ret_i = 0; + } + + u3z(out); + u3z(tou); + } + + c3_free(out_c); + u3z(big); + + return ret_i; +} + +static c3_i +_test_etch_p(void) +{ + c3_i ret_i = 1; + + ret_i &= _p_etch(0x0, "~zod"); + + ret_i &= _p_etch(0x3, "~wes"); + ret_i &= _p_etch(0x17, "~dep"); + ret_i &= _p_etch(0x29, "~led"); + ret_i &= _p_etch(0xbf, "~myl"); + ret_i &= _p_etch(0xcf, "~wel"); + + ret_i &= _p_etch(0xff, "~fes"); + + ret_i &= _p_etch(0x1cc, "~marryd"); + ret_i &= _p_etch(0x2513, "~dalnup"); + ret_i &= _p_etch(0x753b, "~dacwyc"); + ret_i &= _p_etch(0xb365, "~dibwet"); + ret_i &= _p_etch(0xdcaa, "~rislep"); + + ret_i &= _p_etch(0xffff, "~fipfes"); + + ret_i &= _p_etch(0x6d2030, "~hocmeb-dapsen"); + ret_i &= _p_etch(0x108deca3, "~divbud-ladbyn"); + ret_i &= _p_etch(0x64f4eace, "~mopten-hilfex"); + ret_i &= _p_etch(0xa1ae3130, "~tinbyn-fammun"); + ret_i &= _p_etch(0xb91f853a, "~dinnex-sonnum"); + + ret_i &= _p_etch(0xffffffff, "~dostec-risfen"); + + ret_i &= _p_etch(0x6bfc3f1881b, "~sigmyl-bintus-sovpet"); + ret_i &= _p_etch(0x46f6e0458bc7, "~novweg-bilnet-radfep"); + ret_i &= _p_etch(0xab36928a695b, "~boswyd-lagdut-tobhes"); + ret_i &= _p_etch(0xe1a670e9eebd, "~larpub-bacfus-nisbex"); + ret_i &= _p_etch(0xf6b014781344, "~tonbyl-dasryg-bitlen"); + + ret_i &= _p_etch(0xffffffffffff, "~fipfes-dostec-risfen"); + + ret_i &= _p_etch(0x94fede64d31f2a0, "~lisnet-rivnys-natdem-donful"); + ret_i &= _p_etch(0xb39638ae3f909214, "~dibryg-bichut-witsev-fanpub"); + ret_i &= _p_etch(0xd226683f5a2fa433, "~nilsul-picpur-nocsem-tasrys"); + ret_i &= _p_etch(0xd5bc5e03458e7790, "~fopbyt-worwes-rolput-nodruc"); + ret_i &= _p_etch(0xe203169849fc1124, "~fitwes-hopfep-bitwyd-doswer"); + + ret_i &= _p_etch(0xffffffffffffffff, "~fipfes-fipfes-dostec-risfen"); + + ret_i &= _big_p_etch("b46c9c7817150a23781c15d2c20c2f3", + "~dirrul-radner-dister-ritnus--taddus-digmus-torlun-filnyt"); + ret_i &= _big_p_etch("9fd9c878ceb2bdd0db35376f6b8b495f", + "~patdun-hinfel-fadpem-tocnyd--nactyl-tadpel-balrev-tipsym"); + ret_i &= _big_p_etch("c9ee5fffc61ce2d923149c405dd2ab6c", + "~radbec-sipfes-harryt-fitdun--rovheb-haprys-morrel-bostux"); + ret_i &= _big_p_etch("5172f9231ededdfaa56cddc363bd703d", + "~podmeb-sovsep-silryl-fotrep--pintux-fotfex-wictyp-sivder"); + ret_i &= _big_p_etch("54c36542cc9f897c1b8587e4dc95fff1", + "~tolfex-watden-ragmer-navren--folseg-lonryc-rispyx-fiptes"); + + ret_i &= _big_p_etch("4524acf6cfe1ed7c974843bb918e0cae4c01", "~locpes--batweg-toplys-rivren-ripreg--moldyt-hadted-wachut-witnec"); + + ret_i &= _big_p_etch("5711709a8c188c2ca4439727e342dc3f20e8b66769e1", "~napsyx-sivtus-nibdys--nibwen-sonnut-ripped-walden--rispur-hollyn-bitmyn-davlys"); + + return ret_i; +} + static inline c3_i _ud_etch(c3_d num_d, const c3_c* num_c) { @@ -1291,6 +1430,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_etch_p() ) { + fprintf(stderr, "test jets: etch_p: failed\r\n"); + ret_i = 0; + } + if ( !_test_etch_ud() ) { fprintf(stderr, "test jets: etch_ud: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 9c85477774..637866a618 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -857,6 +857,241 @@ u3s_cue_atom(u3_atom a) return u3s_cue_bytes((c3_d)len_w, byt_y); } +/* Compute the length of the address + */ +size_t _cs_etch_p_size(mpz_t a_mp) { + + size_t syb_i = mpz_sizeinbase(a_mp, 256); + + // 3 characters per syllabe, - every 2 syllabes, and -- every 8 syllabes, + // and ~ + size_t len_i = syb_i * 3 + (syb_i / 2) + (syb_i / 8) + 1; + + // Discount hep at the boundary of 2 syllabes + if ( 0 == (syb_i % 2) ) { + len_i -= 1; + } + + // Discount hep at the boundary of 8 syllabes + if ( 0 == (syb_i % 8) ) { + len_i -= 1; + } + + return len_i; +} + +/* _cs_etch_p_bytes: atom to @p impl. + */ +c3_y* +_cs_etch_p_bytes(mpz_t sxz_mp, c3_w len_w, c3_y* hun_y) +{ + c3_y* byt_y = hun_y + len_w - 1; + + // Comets and below + // + c3_d sxz; + c3_s huk, hi, lo; + + // Process in chunks of 64 bits + // + while ( mpz_size(sxz_mp) ) { + + sxz = (c3_d) mpz_get_ui(sxz_mp); + mpz_tdiv_q_2exp(sxz_mp, sxz_mp, 64); + + while ( sxz ) { + + huk = sxz & 0xffff; + + hi = huk >> 8; + lo = huk & 0xff; + + u3_po_to_suffix(lo, byt_y - 2, byt_y - 1, byt_y); + u3_po_to_prefix(hi, byt_y - 5, byt_y - 4, byt_y - 3); + + sxz >>= 16; + byt_y -= 6; + len_w -= 6; + + // Print - every two syllabes + if ( sxz ) { + *byt_y = '-'; + byt_y--; + len_w--; + } + } + + // Print -- every four syllabes + if ( mpz_size(sxz_mp) ) { + *byt_y = '-'; + *(byt_y - 1) = '-'; + + byt_y -= 2; + len_w -= 2; + } + } + + *byt_y = '~'; + + return byt_y; +} + + +/* u3s_etch_p_smol(): c3_d to @p +** +** =(28 (met 3 (scot %p (dec (bex 64))))) +*/ +c3_y* +u3s_etch_p_smol(c3_d sxz, c3_y hun_y[SMOL_P]) +{ + c3_y* byt_y = hun_y + SMOL_P - 1; + + // Galaxy + // + if ( sxz <= 0xff) { + + u3_po_to_suffix(sxz & 0xff, byt_y - 2, byt_y - 1, byt_y); + byt_y -= 3; + + *byt_y = '~'; + + return byt_y; + } + + // Stars, planets and moons + // + c3_s huk, hi, lo; + + while ( sxz ) { + + huk = sxz & 0xffff; + + hi = huk >> 8; + lo = huk & 0xff; + + u3_po_to_suffix(lo, byt_y - 2, byt_y - 1, byt_y); + u3_po_to_prefix(hi, byt_y - 5, byt_y - 4, byt_y - 3); + + sxz >>= 16; + byt_y -= 6; + + // Print a separator every two syllabes + if ( sxz ) { + *byt_y = '-'; + byt_y--; + } + } + + *byt_y = '~'; + + return byt_y; +} + +/* u3s_etch_p_c(): atom to @p, as a malloc'd c string. + */ +size_t +u3s_etch_p_c(u3_atom a, c3_c** out_c) +{ + + c3_d a_d; + size_t len_i; + c3_y* buf_y; + + u3_atom sxz = a; + c3_o fen_o = c3n; + + // We only need to unscramble planets and below + // + if ( c3n == u3a_is_cat(a) || + (c3y == u3a_is_cat(a) && a >= 0x10000) ) { + + sxz = u3qe_fein_ob(a); + fen_o = c3y; + } + + if ( c3y == u3r_safe_chub(sxz, &a_d) ) { + c3_y hun_y[SMOL_P]; + + buf_y = u3s_etch_p_smol(a_d, hun_y); + len_i = SMOL_P - ((c3_p)buf_y - (c3_p)hun_y); + + *out_c = c3_malloc(len_i + 1); + (*out_c)[len_i] = 0; + memcpy(*out_c, buf_y, len_i); + + if ( _(fen_o) ) { + u3z(sxz); + } + + return len_i; + } + + mpz_t sxz_mp; + u3r_mp(sxz_mp, sxz); + + len_i = _cs_etch_p_size(sxz_mp); + buf_y = malloc(len_i+1); + buf_y[len_i] = 0; + + _cs_etch_p_bytes(sxz_mp, len_i, buf_y); + + *out_c = (c3_c*)buf_y; + + if ( _(fen_o) ) { + u3z(sxz); + } + mpz_clear(sxz_mp); + return len_i; +} + +/* u3s_etch_p(): atom to @p. + */ +u3_atom +u3s_etch_p(u3_atom a) +{ + c3_d a_d; + + u3_atom sxz = a; + c3_o fen_o = c3n; + + // We only need to unscramble planets and below + // + if ( c3n == u3a_is_cat(a) || + (c3y == u3a_is_cat(a) && a >= 0x10000) ) { + + sxz = u3qe_fein_ob(a); + fen_o = c3y; + } + + if ( c3y == u3r_safe_chub(sxz, &a_d) ) { + c3_y hun_y[SMOL_P]; + c3_y* buf_y = u3s_etch_p_smol(a_d, hun_y); + c3_w dif_w = (c3_p)buf_y - (c3_p)hun_y; + + if ( _(fen_o) ) { + u3z(sxz); + } + return u3i_bytes(SMOL_P - dif_w, buf_y); + } + + u3i_slab sab_u; + size_t len_i; + mpz_t sxz_mp; + u3r_mp(sxz_mp, sxz); + + len_i = _cs_etch_p_size(sxz_mp); + u3i_slab_bare(&sab_u, 3, len_i); + sab_u.buf_w[sab_u.len_w - 1] = 0; + + _cs_etch_p_bytes(sxz_mp, len_i, sab_u.buf_y); + + if ( _(fen_o) ) { + u3z(sxz); + } + mpz_clear(sxz_mp); + return u3i_slab_mint_bytes(&sab_u); +} + /* +yo time constants */ #define CET_YO 36524 diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index 0699982568..e66c78cf58 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -85,6 +85,24 @@ */ size_t u3s_etch_da_c(u3_atom a, c3_c** out_c); + /* u3s_etch_p_smol(): c3_d to @p + ** + ** =(28 (met 3 (scot %p (dec (bex 64))))) + */ +#define SMOL_P 28 + c3_y* + u3s_etch_p_smol(c3_d sxz_d, c3_y hun_y[SMOL_P]); + + /* u3s_etch_p(): atom to @p. + */ + u3_atom + u3s_etch_p(u3_atom a); + + /* u3s_etch_p_c(): atom to @p, as a malloc'd c string. + */ + size_t + u3s_etch_p_c(u3_atom a, c3_c** out_c); + /* u3s_etch_ud_smol(): c3_d to @ud ** ** =(26 (met 3 (scot %ud (dec (bex 64))))) From bd0dd9e758ede59df1a72f5bd1ff9bc414c27ae8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 10:55:39 +0800 Subject: [PATCH 08/16] u3: implements a new %p parser --- pkg/noun/jets/c/po.c | 1280 ++++++++++++++++++++-------------------- pkg/noun/jets/e/slaw.c | 253 +------- pkg/noun/jets/q.h | 4 +- pkg/noun/jets_tests.c | 215 +++++++ pkg/noun/serial.c | 276 +++++++++ pkg/noun/serial.h | 10 + 6 files changed, 1162 insertions(+), 876 deletions(-) diff --git a/pkg/noun/jets/c/po.c b/pkg/noun/jets/c/po.c index 2fe88584db..1b88dfbf12 100644 --- a/pkg/noun/jets/c/po.c +++ b/pkg/noun/jets/c/po.c @@ -5,410 +5,410 @@ #include "noun.h" -u3_noun +c3_s u3_po_find_prefix(c3_y one, c3_y two, c3_y three) { switch (one) { case 'b': switch (two) { case 'a': switch (three) { - case 'c': return u3nc(0, 238); - case 'l': return u3nc(0, 107); - case 'n': return u3nc(0, 92); - case 'r': return u3nc(0, 183); - case 't': return u3nc(0, 172); - default: return 0; + case 'c': return 238; + case 'l': return 107; + case 'n': return 92; + case 'r': return 183; + case 't': return 172; + default: return -1; } case 'i': switch (three) { - case 'c': return u3nc(0, 56); - case 'd': return u3nc(0, 106); - case 'l': return u3nc(0, 144); - case 'n': return u3nc(0, 2); - case 's': return u3nc(0, 60); - case 't': return u3nc(0, 182); - default: return 0; + case 'c': return 56; + case 'd': return 106; + case 'l': return 144; + case 'n': return 2; + case 's': return 60; + case 't': return 182; + default: return -1; } case 'o': switch (three) { - case 'l': return u3nc(0, 45); - case 'n': return u3nc(0, 244); - case 'r': return u3nc(0, 188); - case 's': return u3nc(0, 171); - case 't': return u3nc(0, 98); - default: return 0; - } - default: return 0; + case 'l': return 45; + case 'n': return 244; + case 'r': return 188; + case 's': return 171; + case 't': return 98; + default: return -1; + } + default: return -1; } case 'd': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 181); - case 'c': return u3nc(0, 117); - case 'l': return u3nc(0, 37); - case 'n': return u3nc(0, 234); - case 'p': return u3nc(0, 66); - case 'r': return u3nc(0, 23); - case 's': return u3nc(0, 61); - case 't': return u3nc(0, 215); - case 'v': return u3nc(0, 105); - default: return 0; + case 'b': return 181; + case 'c': return 117; + case 'l': return 37; + case 'n': return 234; + case 'p': return 66; + case 'r': return 23; + case 's': return 61; + case 't': return 215; + case 'v': return 105; + default: return -1; } case 'i': switch (three) { - case 'b': return u3nc(0, 179); - case 'f': return u3nc(0, 57); - case 'g': return u3nc(0, 193); - case 'l': return u3nc(0, 49); - case 'n': return u3nc(0, 217); - case 'r': return u3nc(0, 11); - case 's': return u3nc(0, 129); - case 'v': return u3nc(0, 116); - default: return 0; + case 'b': return 179; + case 'f': return 57; + case 'g': return 193; + case 'l': return 49; + case 'n': return 217; + case 'r': return 11; + case 's': return 129; + case 'v': return 116; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 146); - case 'l': return u3nc(0, 102); - case 'n': return u3nc(0, 233); - case 'p': return u3nc(0, 18); - case 'r': return u3nc(0, 24); - case 's': return u3nc(0, 187); - case 't': return u3nc(0, 47); - case 'v': return u3nc(0, 236); - case 'z': return u3nc(0, 0); - default: return 0; - } - default: return 0; + case 'c': return 146; + case 'l': return 102; + case 'n': return 233; + case 'p': return 18; + case 'r': return 24; + case 's': return 187; + case 't': return 47; + case 'v': return 236; + case 'z': return 0; + default: return -1; + } + default: return -1; } case 'f': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 120); - case 'd': return u3nc(0, 206); - case 'l': return u3nc(0, 152); - case 'm': return u3nc(0, 214); - case 'n': return u3nc(0, 158); - case 's': return u3nc(0, 195); - default: return 0; + case 'b': return 120; + case 'd': return 206; + case 'l': return 152; + case 'm': return 214; + case 'n': return 158; + case 's': return 195; + default: return -1; } case 'i': switch (three) { - case 'd': return u3nc(0, 8); - case 'g': return u3nc(0, 138); - case 'l': return u3nc(0, 194); - case 'n': return u3nc(0, 90); - case 'p': return u3nc(0, 255); - case 'r': return u3nc(0, 169); - case 't': return u3nc(0, 226); - default: return 0; + case 'd': return 8; + case 'g': return 138; + case 'l': return 194; + case 'n': return 90; + case 'p': return 255; + case 'r': return 169; + case 't': return 226; + default: return -1; } case 'o': switch (three) { - case 'd': return u3nc(0, 247); - case 'g': return u3nc(0, 20); - case 'l': return u3nc(0, 27); - case 'n': return u3nc(0, 91); - case 'p': return u3nc(0, 213); - case 'r': return u3nc(0, 50); - case 's': return u3nc(0, 46); - case 't': return u3nc(0, 221); - default: return 0; - } - default: return 0; + case 'd': return 247; + case 'g': return 20; + case 'l': return 27; + case 'n': return 91; + case 'p': return 213; + case 'r': return 50; + case 's': return 46; + case 't': return 221; + default: return -1; + } + default: return -1; } case 'h': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 209); - case 'c': return u3nc(0, 174); - case 'd': return u3nc(0, 145); - case 'l': return u3nc(0, 203); - case 'n': return u3nc(0, 41); - case 'p': return u3nc(0, 156); - case 'r': return u3nc(0, 198); - case 's': return u3nc(0, 170); - case 't': return u3nc(0, 218); - case 'v': return u3nc(0, 176); - default: return 0; + case 'b': return 209; + case 'c': return 174; + case 'd': return 145; + case 'l': return 203; + case 'n': return 41; + case 'p': return 156; + case 'r': return 198; + case 's': return 170; + case 't': return 218; + case 'v': return 176; + default: return -1; } case 'i': switch (three) { - case 'd': return u3nc(0, 7); - case 'l': return u3nc(0, 190); - case 'n': return u3nc(0, 200); - default: return 0; + case 'd': return 7; + case 'l': return 190; + case 'n': return 200; + default: return -1; } case 'o': switch (three) { - case 'b': return u3nc(0, 197); - case 'c': return u3nc(0, 223); - case 'd': return u3nc(0, 26); - case 'l': return u3nc(0, 32); - case 'p': return u3nc(0, 22); - case 's': return u3nc(0, 180); - default: return 0; - } - default: return 0; + case 'b': return 197; + case 'c': return 223; + case 'd': return 26; + case 'l': return 32; + case 'p': return 22; + case 's': return 180; + default: return -1; + } + default: return -1; } case 'l': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 161); - case 'c': return u3nc(0, 34); - case 'd': return u3nc(0, 235); - case 'g': return u3nc(0, 205); - case 'n': return u3nc(0, 232); - case 'p': return u3nc(0, 240); - case 'r': return u3nc(0, 225); - case 's': return u3nc(0, 128); - case 't': return u3nc(0, 134); - case 'v': return u3nc(0, 252); - default: return 0; + case 'b': return 161; + case 'c': return 34; + case 'd': return 235; + case 'g': return 205; + case 'n': return 232; + case 'p': return 240; + case 'r': return 225; + case 's': return 128; + case 't': return 134; + case 'v': return 252; + default: return -1; } case 'i': switch (three) { - case 'b': return u3nc(0, 39); - case 'd': return u3nc(0, 21); - case 'g': return u3nc(0, 111); - case 'n': return u3nc(0, 178); - case 's': return u3nc(0, 9); - case 't': return u3nc(0, 5); - case 'v': return u3nc(0, 36); - default: return 0; + case 'b': return 39; + case 'd': return 21; + case 'g': return 111; + case 'n': return 178; + case 's': return 9; + case 't': return 5; + case 'v': return 36; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 69); - case 'd': return u3nc(0, 186); - case 'm': return u3nc(0, 166); - case 'n': return u3nc(0, 135); - case 'p': return u3nc(0, 63); - case 'r': return u3nc(0, 25); - case 's': return u3nc(0, 48); - default: return 0; - } - default: return 0; + case 'c': return 69; + case 'd': return 186; + case 'm': return 166; + case 'n': return 135; + case 'p': return 63; + case 'r': return 25; + case 's': return 48; + default: return -1; + } + default: return -1; } case 'm': switch (two) { case 'a': switch (three) { - case 'c': return u3nc(0, 191); - case 'g': return u3nc(0, 103); - case 'l': return u3nc(0, 110); - case 'p': return u3nc(0, 130); - case 'r': return u3nc(0, 1); - case 's': return u3nc(0, 202); - case 't': return u3nc(0, 253); - default: return 0; + case 'c': return 191; + case 'g': return 103; + case 'l': return 110; + case 'p': return 130; + case 'r': return 1; + case 's': return 202; + case 't': return 253; + default: return -1; } case 'i': switch (three) { - case 'c': return u3nc(0, 157); - case 'd': return u3nc(0, 62); - case 'g': return u3nc(0, 199); - case 'l': return u3nc(0, 212); - case 'n': return u3nc(0, 79); - case 'p': return u3nc(0, 254); - case 'r': return u3nc(0, 31); - case 's': return u3nc(0, 126); - case 't': return u3nc(0, 196); - default: return 0; + case 'c': return 157; + case 'd': return 62; + case 'g': return 199; + case 'l': return 212; + case 'n': return 79; + case 'p': return 254; + case 'r': return 31; + case 's': return 126; + case 't': return 196; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 148); - case 'd': return u3nc(0, 19); - case 'g': return u3nc(0, 162); - case 'l': return u3nc(0, 67); - case 'n': return u3nc(0, 122); - case 'p': return u3nc(0, 208); - case 'r': return u3nc(0, 93); - case 's': return u3nc(0, 231); - case 't': return u3nc(0, 82); - default: return 0; - } - default: return 0; + case 'c': return 148; + case 'd': return 19; + case 'g': return 162; + case 'l': return 67; + case 'n': return 122; + case 'p': return 208; + case 'r': return 93; + case 's': return 231; + case 't': return 82; + default: return -1; + } + default: return -1; } case 'n': switch (two) { case 'a': switch (three) { - case 'c': return u3nc(0, 219); - case 'l': return u3nc(0, 230); - case 'm': return u3nc(0, 243); - case 'p': return u3nc(0, 87); - case 'r': return u3nc(0, 65); - case 't': return u3nc(0, 77); - case 'v': return u3nc(0, 137); - default: return 0; + case 'c': return 219; + case 'l': return 230; + case 'm': return 243; + case 'p': return 87; + case 'r': return 65; + case 't': return 77; + case 'v': return 137; + default: return -1; } case 'i': switch (three) { - case 'b': return u3nc(0, 140); - case 'd': return u3nc(0, 72); - case 'l': return u3nc(0, 210); - case 'm': return u3nc(0, 224); - case 's': return u3nc(0, 124); - default: return 0; + case 'b': return 140; + case 'd': return 72; + case 'l': return 210; + case 'm': return 224; + case 's': return 124; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 250); - case 'd': return u3nc(0, 136); - case 'l': return u3nc(0, 216); - case 'm': return u3nc(0, 139); - case 'p': return u3nc(0, 88); - case 'r': return u3nc(0, 97); - case 's': return u3nc(0, 211); - case 'v': return u3nc(0, 70); - default: return 0; - } - default: return 0; + case 'c': return 250; + case 'd': return 136; + case 'l': return 216; + case 'm': return 139; + case 'p': return 88; + case 'r': return 97; + case 's': return 211; + case 'v': return 70; + default: return -1; + } + default: return -1; } case 'p': switch (two) { case 'a': switch (three) { - case 'c': return u3nc(0, 149); - case 'd': return u3nc(0, 114); - case 'g': return u3nc(0, 141); - case 'l': return u3nc(0, 127); - case 'n': return u3nc(0, 78); - case 'r': return u3nc(0, 185); - case 's': return u3nc(0, 33); - case 't': return u3nc(0, 159); - default: return 0; + case 'c': return 149; + case 'd': return 114; + case 'g': return 141; + case 'l': return 127; + case 'n': return 78; + case 'r': return 185; + case 's': return 33; + case 't': return 159; + default: return -1; } case 'i': switch (three) { - case 'c': return u3nc(0, 104); - case 'd': return u3nc(0, 43); - case 'l': return u3nc(0, 51); - case 'n': return u3nc(0, 165); - case 't': return u3nc(0, 242); - default: return 0; + case 'c': return 104; + case 'd': return 43; + case 'l': return 51; + case 'n': return 165; + case 't': return 242; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 173); - case 'd': return u3nc(0, 81); - case 'l': return u3nc(0, 239); - case 'n': return u3nc(0, 248); - case 's': return u3nc(0, 86); - default: return 0; - } - default: return 0; + case 'c': return 173; + case 'd': return 81; + case 'l': return 239; + case 'n': return 248; + case 's': return 86; + default: return -1; + } + default: return -1; } case 'r': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 131); - case 'c': return u3nc(0, 184); - case 'd': return u3nc(0, 201); - case 'g': return u3nc(0, 204); - case 'l': return u3nc(0, 143); - case 'm': return u3nc(0, 52); - case 'n': return u3nc(0, 123); - case 'p': return u3nc(0, 228); - case 'v': return u3nc(0, 150); - default: return 0; + case 'b': return 131; + case 'c': return 184; + case 'd': return 201; + case 'g': return 204; + case 'l': return 143; + case 'm': return 52; + case 'n': return 123; + case 'p': return 228; + case 'v': return 150; + default: return -1; } case 'i': switch (three) { - case 'b': return u3nc(0, 222); - case 'c': return u3nc(0, 167); - case 'd': return u3nc(0, 147); - case 'g': return u3nc(0, 16); - case 'l': return u3nc(0, 64); - case 'n': return u3nc(0, 28); - case 'p': return u3nc(0, 151); - case 's': return u3nc(0, 220); - case 't': return u3nc(0, 80); - case 'v': return u3nc(0, 237); - default: return 0; + case 'b': return 222; + case 'c': return 167; + case 'd': return 147; + case 'g': return 16; + case 'l': return 64; + case 'n': return 28; + case 'p': return 151; + case 's': return 220; + case 't': return 80; + case 'v': return 237; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 58); - case 'l': return u3nc(0, 133); - case 'n': return u3nc(0, 96); - case 'p': return u3nc(0, 75); - case 's': return u3nc(0, 245); - case 'v': return u3nc(0, 35); - default: return 0; - } - default: return 0; + case 'c': return 58; + case 'l': return 133; + case 'n': return 96; + case 'p': return 75; + case 's': return 245; + case 'v': return 35; + default: return -1; + } + default: return -1; } case 's': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 13); - case 'l': return u3nc(0, 115); - case 'm': return u3nc(0, 4); - case 'n': return u3nc(0, 68); - case 'p': return u3nc(0, 177); - case 'r': return u3nc(0, 229); - case 't': return u3nc(0, 38); - case 'v': return u3nc(0, 85); - default: return 0; + case 'b': return 13; + case 'l': return 115; + case 'm': return 4; + case 'n': return 68; + case 'p': return 177; + case 'r': return 229; + case 't': return 38; + case 'v': return 85; + default: return -1; } case 'i': switch (three) { - case 'b': return u3nc(0, 15); - case 'c': return u3nc(0, 74); - case 'd': return u3nc(0, 119); - case 'g': return u3nc(0, 6); - case 'l': return u3nc(0, 30); - case 'm': return u3nc(0, 163); - case 'p': return u3nc(0, 95); - case 't': return u3nc(0, 71); - case 'v': return u3nc(0, 112); - default: return 0; + case 'b': return 15; + case 'c': return 74; + case 'd': return 119; + case 'g': return 6; + case 'l': return 30; + case 'm': return 163; + case 'p': return 95; + case 't': return 71; + case 'v': return 112; + default: return -1; } case 'o': switch (three) { - case 'c': return u3nc(0, 100); - case 'g': return u3nc(0, 10); - case 'l': return u3nc(0, 17); - case 'm': return u3nc(0, 89); - case 'n': return u3nc(0, 164); - case 'p': return u3nc(0, 142); - case 'r': return u3nc(0, 251); - case 'v': return u3nc(0, 249); - default: return 0; - } - default: return 0; + case 'c': return 100; + case 'g': return 10; + case 'l': return 17; + case 'm': return 89; + case 'n': return 164; + case 'p': return 142; + case 'r': return 251; + case 'v': return 249; + default: return -1; + } + default: return -1; } case 't': switch (two) { case 'a': switch (three) { - case 'b': return u3nc(0, 40); - case 'c': return u3nc(0, 160); - case 'd': return u3nc(0, 55); - case 'g': return u3nc(0, 113); - case 'l': return u3nc(0, 241); - case 'm': return u3nc(0, 83); - case 'n': return u3nc(0, 118); - case 'p': return u3nc(0, 168); - case 'r': return u3nc(0, 121); - case 's': return u3nc(0, 109); - default: return 0; + case 'b': return 40; + case 'c': return 160; + case 'd': return 55; + case 'g': return 113; + case 'l': return 241; + case 'm': return 83; + case 'n': return 118; + case 'p': return 168; + case 'r': return 121; + case 's': return 109; + default: return -1; } case 'i': switch (three) { - case 'c': return u3nc(0, 42); - case 'd': return u3nc(0, 175); - case 'l': return u3nc(0, 154); - case 'm': return u3nc(0, 108); - case 'n': return u3nc(0, 155); - case 'p': return u3nc(0, 73); - case 'r': return u3nc(0, 53); - default: return 0; + case 'c': return 42; + case 'd': return 175; + case 'l': return 154; + case 'm': return 108; + case 'n': return 155; + case 'p': return 73; + case 'r': return 53; + default: return -1; } case 'o': switch (three) { - case 'b': return u3nc(0, 132); - case 'c': return u3nc(0, 189); - case 'd': return u3nc(0, 153); - case 'g': return u3nc(0, 29); - case 'l': return u3nc(0, 84); - case 'm': return u3nc(0, 192); - case 'n': return u3nc(0, 246); - case 'p': return u3nc(0, 207); - case 'r': return u3nc(0, 44); - default: return 0; - } - default: return 0; + case 'b': return 132; + case 'c': return 189; + case 'd': return 153; + case 'g': return 29; + case 'l': return 84; + case 'm': return 192; + case 'n': return 246; + case 'p': return 207; + case 'r': return 44; + default: return -1; + } + default: return -1; } case 'w': switch (two) { case 'a': switch (three) { - case 'c': return u3nc(0, 12); - case 'l': return u3nc(0, 227); - case 'n': return u3nc(0, 3); - case 't': return u3nc(0, 101); - default: return 0; + case 'c': return 12; + case 'l': return 227; + case 'n': return 3; + case 't': return 101; + default: return -1; } case 'i': switch (three) { - case 'c': return u3nc(0, 99); - case 'd': return u3nc(0, 59); - case 'n': return u3nc(0, 54); - case 's': return u3nc(0, 14); - case 't': return u3nc(0, 76); - default: return 0; + case 'c': return 99; + case 'd': return 59; + case 'n': return 54; + case 's': return 14; + case 't': return 76; + default: return -1; } case 'o': switch (three) { - case 'l': return u3nc(0, 125); - case 'r': return u3nc(0, 94); - default: return 0; + case 'l': return 125; + case 'r': return 94; + default: return -1; } - default: return 0; + default: return -1; } - default: return 0; + default: return -1; } } @@ -676,410 +676,410 @@ u3_po_to_prefix(u3_noun id, c3_y* a, c3_y* b, c3_y* c) } } -u3_noun +c3_s u3_po_find_suffix(c3_y one, c3_y two, c3_y three) { switch (one) { case 'b': switch (two) { case 'e': switch (three) { - case 'c': return u3nc(0, 238); - case 'l': return u3nc(0, 107); - case 'n': return u3nc(0, 92); - case 'p': return u3nc(0, 183); - case 'r': return u3nc(0, 172); - case 's': return u3nc(0, 56); - case 't': return u3nc(0, 106); - case 'x': return u3nc(0, 144); - default: return 0; + case 'c': return 238; + case 'l': return 107; + case 'n': return 92; + case 'p': return 183; + case 'r': return 172; + case 's': return 56; + case 't': return 106; + case 'x': return 144; + default: return -1; } case 'u': switch (three) { - case 'd': return u3nc(0, 2); - case 'r': return u3nc(0, 60); - case 's': return u3nc(0, 182); - default: return 0; + case 'd': return 2; + case 'r': return 60; + case 's': return 182; + default: return -1; } case 'y': switch (three) { - case 'l': return u3nc(0, 176); - case 'n': return u3nc(0, 45); - case 'r': return u3nc(0, 244); - case 't': return u3nc(0, 188); - default: return 0; + case 'l': return 176; + case 'n': return 45; + case 'r': return 244; + case 't': return 188; + default: return -1; } - default: return 0; + default: return -1; } case 'd': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 171); - case 'c': return u3nc(0, 98); - case 'f': return u3nc(0, 181); - case 'g': return u3nc(0, 117); - case 'l': return u3nc(0, 37); - case 'm': return u3nc(0, 234); - case 'n': return u3nc(0, 66); - case 'p': return u3nc(0, 23); - case 'r': return u3nc(0, 61); - case 's': return u3nc(0, 215); - case 't': return u3nc(0, 105); - case 'v': return u3nc(0, 179); - case 'x': return u3nc(0, 57); - default: return 0; + case 'b': return 171; + case 'c': return 98; + case 'f': return 181; + case 'g': return 117; + case 'l': return 37; + case 'm': return 234; + case 'n': return 66; + case 'p': return 23; + case 'r': return 61; + case 's': return 215; + case 't': return 105; + case 'v': return 179; + case 'x': return 57; + default: return -1; } case 'u': switch (three) { - case 'c': return u3nc(0, 193); - case 'l': return u3nc(0, 49); - case 'n': return u3nc(0, 217); - case 'r': return u3nc(0, 11); - case 's': return u3nc(0, 129); - case 't': return u3nc(0, 116); - case 'x': return u3nc(0, 146); - default: return 0; + case 'c': return 193; + case 'l': return 49; + case 'n': return 217; + case 'r': return 11; + case 's': return 129; + case 't': return 116; + case 'x': return 146; + default: return -1; } case 'y': switch (three) { - case 'l': return u3nc(0, 102); - case 'n': return u3nc(0, 233); - case 'r': return u3nc(0, 18); - case 's': return u3nc(0, 24); - case 't': return u3nc(0, 187); - default: return 0; - } - default: return 0; + case 'l': return 102; + case 'n': return 233; + case 'r': return 18; + case 's': return 24; + case 't': return 187; + default: return -1; + } + default: return -1; } case 'f': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 47); - case 'd': return u3nc(0, 236); - case 'l': return u3nc(0, 120); - case 'n': return u3nc(0, 206); - case 'p': return u3nc(0, 152); - case 'r': return u3nc(0, 158); - case 's': return u3nc(0, 255); - case 't': return u3nc(0, 214); - case 'x': return u3nc(0, 195); - default: return 0; + case 'b': return 47; + case 'd': return 236; + case 'l': return 120; + case 'n': return 206; + case 'p': return 152; + case 'r': return 158; + case 's': return 255; + case 't': return 214; + case 'x': return 195; + default: return -1; } case 'u': switch (three) { - case 'l': return u3nc(0, 8); - case 'n': return u3nc(0, 138); - case 'r': return u3nc(0, 194); - case 's': return u3nc(0, 90); - default: return 0; + case 'l': return 8; + case 'n': return 138; + case 'r': return 194; + case 's': return 90; + default: return -1; } case 'y': switch (three) { - case 'l': return u3nc(0, 169); - case 'n': return u3nc(0, 226); - case 'r': return u3nc(0, 247); - default: return 0; + case 'l': return 169; + case 'n': return 226; + case 'r': return 247; + default: return -1; } - default: return 0; + default: return -1; } case 'h': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 20); - case 'c': return u3nc(0, 27); - case 'p': return u3nc(0, 91); - case 's': return u3nc(0, 213); - case 't': return u3nc(0, 50); - case 'x': return u3nc(0, 46); - default: return 0; + case 'b': return 20; + case 'c': return 27; + case 'p': return 91; + case 's': return 213; + case 't': return 50; + case 'x': return 46; + default: return -1; } case 'u': switch (three) { - case 'l': return u3nc(0, 221); - case 's': return u3nc(0, 209); - case 't': return u3nc(0, 174); - default: return 0; + case 'l': return 221; + case 's': return 209; + case 't': return 174; + default: return -1; } - default: return 0; + default: return -1; } case 'l': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 145); - case 'c': return u3nc(0, 203); - case 'd': return u3nc(0, 41); - case 'g': return u3nc(0, 156); - case 'n': return u3nc(0, 198); - case 'p': return u3nc(0, 170); - case 'r': return u3nc(0, 218); - case 't': return u3nc(0, 7); - case 'v': return u3nc(0, 190); - case 'x': return u3nc(0, 200); - default: return 0; + case 'b': return 145; + case 'c': return 203; + case 'd': return 41; + case 'g': return 156; + case 'n': return 198; + case 'p': return 170; + case 'r': return 218; + case 't': return 7; + case 'v': return 190; + case 'x': return 200; + default: return -1; } case 'u': switch (three) { - case 'c': return u3nc(0, 197); - case 'd': return u3nc(0, 223); - case 'g': return u3nc(0, 26); - case 'n': return u3nc(0, 32); - case 'p': return u3nc(0, 22); - case 'r': return u3nc(0, 180); - case 's': return u3nc(0, 161); - case 't': return u3nc(0, 34); - case 'x': return u3nc(0, 235); - default: return 0; + case 'c': return 197; + case 'd': return 223; + case 'g': return 26; + case 'n': return 32; + case 'p': return 22; + case 'r': return 180; + case 's': return 161; + case 't': return 34; + case 'x': return 235; + default: return -1; } case 'y': switch (three) { - case 'd': return u3nc(0, 205); - case 'n': return u3nc(0, 232); - case 'r': return u3nc(0, 240); - case 's': return u3nc(0, 225); - case 't': return u3nc(0, 128); - case 'x': return u3nc(0, 134); - default: return 0; - } - default: return 0; + case 'd': return 205; + case 'n': return 232; + case 'r': return 240; + case 's': return 225; + case 't': return 128; + case 'x': return 134; + default: return -1; + } + default: return -1; } case 'm': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 114); - case 'c': return u3nc(0, 141); - case 'd': return u3nc(0, 127); - case 'g': return u3nc(0, 78); - case 'l': return u3nc(0, 185); - case 'p': return u3nc(0, 33); - case 'r': return u3nc(0, 159); - case 's': return u3nc(0, 104); - case 't': return u3nc(0, 43); - case 'v': return u3nc(0, 51); - case 'x': return u3nc(0, 165); - default: return 0; + case 'b': return 114; + case 'c': return 141; + case 'd': return 127; + case 'g': return 78; + case 'l': return 185; + case 'p': return 33; + case 'r': return 159; + case 's': return 104; + case 't': return 43; + case 'v': return 51; + case 'x': return 165; + default: return -1; } case 'u': switch (three) { - case 'd': return u3nc(0, 242); - case 'g': return u3nc(0, 173); - case 'l': return u3nc(0, 81); - case 'n': return u3nc(0, 239); - case 'r': return u3nc(0, 248); - case 's': return u3nc(0, 93); - case 't': return u3nc(0, 86); - default: return 0; + case 'd': return 242; + case 'g': return 173; + case 'l': return 81; + case 'n': return 239; + case 'r': return 248; + case 's': return 93; + case 't': return 86; + default: return -1; } case 'y': switch (three) { - case 'l': return u3nc(0, 191); - case 'n': return u3nc(0, 103); - case 'r': return u3nc(0, 110); - default: return 0; + case 'l': return 191; + case 'n': return 103; + case 'r': return 110; + default: return -1; } - default: return 0; + default: return -1; } case 'n': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 130); - case 'c': return u3nc(0, 1); - case 'd': return u3nc(0, 202); - case 'l': return u3nc(0, 253); - case 'm': return u3nc(0, 157); - case 'p': return u3nc(0, 62); - case 'r': return u3nc(0, 199); - case 's': return u3nc(0, 212); - case 't': return u3nc(0, 79); - case 'v': return u3nc(0, 254); - case 'x': return u3nc(0, 31); - default: return 0; + case 'b': return 130; + case 'c': return 1; + case 'd': return 202; + case 'l': return 253; + case 'm': return 157; + case 'p': return 62; + case 'r': return 199; + case 's': return 212; + case 't': return 79; + case 'v': return 254; + case 'x': return 31; + default: return -1; } case 'u': switch (three) { - case 'b': return u3nc(0, 126); - case 'l': return u3nc(0, 196); - case 'm': return u3nc(0, 148); - case 'p': return u3nc(0, 19); - case 's': return u3nc(0, 162); - case 't': return u3nc(0, 67); - case 'x': return u3nc(0, 122); - default: return 0; + case 'b': return 126; + case 'l': return 196; + case 'm': return 148; + case 'p': return 19; + case 's': return 162; + case 't': return 67; + case 'x': return 122; + default: return -1; } case 'y': switch (three) { - case 'd': return u3nc(0, 208); - case 'l': return u3nc(0, 231); - case 'm': return u3nc(0, 82); - case 'r': return u3nc(0, 219); - case 's': return u3nc(0, 230); - case 't': return u3nc(0, 243); - case 'x': return u3nc(0, 87); - default: return 0; - } - default: return 0; + case 'd': return 208; + case 'l': return 231; + case 'm': return 82; + case 'r': return 219; + case 's': return 230; + case 't': return 243; + case 'x': return 87; + default: return -1; + } + default: return -1; } case 'p': switch (two) { case 'e': switch (three) { - case 'c': return u3nc(0, 252); - case 'd': return u3nc(0, 39); - case 'g': return u3nc(0, 21); - case 'l': return u3nc(0, 111); - case 'm': return u3nc(0, 178); - case 'n': return u3nc(0, 9); - case 'r': return u3nc(0, 5); - case 's': return u3nc(0, 36); - case 't': return u3nc(0, 69); - case 'x': return u3nc(0, 186); - default: return 0; + case 'c': return 252; + case 'd': return 39; + case 'g': return 21; + case 'l': return 111; + case 'm': return 178; + case 'n': return 9; + case 'r': return 5; + case 's': return 36; + case 't': return 69; + case 'x': return 186; + default: return -1; } case 'u': switch (three) { - case 'b': return u3nc(0, 166); - case 'n': return u3nc(0, 135); - case 'r': return u3nc(0, 63); - case 't': return u3nc(0, 25); - default: return 0; + case 'b': return 166; + case 'n': return 135; + case 'r': return 63; + case 't': return 25; + default: return -1; } case 'y': switch (three) { - case 'l': return u3nc(0, 48); - case 'x': return u3nc(0, 149); - default: return 0; + case 'l': return 48; + case 'x': return 149; + default: return -1; } - default: return 0; + default: return -1; } case 'r': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 65); - case 'c': return u3nc(0, 77); - case 'd': return u3nc(0, 137); - case 'f': return u3nc(0, 140); - case 'g': return u3nc(0, 72); - case 'l': return u3nc(0, 210); - case 'm': return u3nc(0, 224); - case 'n': return u3nc(0, 124); - case 'p': return u3nc(0, 250); - case 's': return u3nc(0, 136); - case 't': return u3nc(0, 216); - case 'v': return u3nc(0, 139); - case 'x': return u3nc(0, 88); - default: return 0; + case 'b': return 65; + case 'c': return 77; + case 'd': return 137; + case 'f': return 140; + case 'g': return 72; + case 'l': return 210; + case 'm': return 224; + case 'n': return 124; + case 'p': return 250; + case 's': return 136; + case 't': return 216; + case 'v': return 139; + case 'x': return 88; + default: return -1; } case 'u': switch (three) { - case 'c': return u3nc(0, 97); - case 'd': return u3nc(0, 211); - case 'l': return u3nc(0, 70); - case 'm': return u3nc(0, 131); - case 'n': return u3nc(0, 184); - case 'p': return u3nc(0, 201); - case 's': return u3nc(0, 143); - case 't': return u3nc(0, 52); - case 'x': return u3nc(0, 123); - default: return 0; + case 'c': return 97; + case 'd': return 211; + case 'l': return 70; + case 'm': return 131; + case 'n': return 184; + case 'p': return 201; + case 's': return 143; + case 't': return 52; + case 'x': return 123; + default: return -1; } case 'y': switch (three) { - case 'c': return u3nc(0, 228); - case 'd': return u3nc(0, 204); - case 'g': return u3nc(0, 150); - case 'l': return u3nc(0, 222); - case 'm': return u3nc(0, 167); - case 'n': return u3nc(0, 147); - case 'p': return u3nc(0, 16); - case 's': return u3nc(0, 64); - case 't': return u3nc(0, 28); - case 'x': return u3nc(0, 151); - default: return 0; - } - default: return 0; + case 'c': return 228; + case 'd': return 204; + case 'g': return 150; + case 'l': return 222; + case 'm': return 167; + case 'n': return 147; + case 'p': return 16; + case 's': return 64; + case 't': return 28; + case 'x': return 151; + default: return -1; + } + default: return -1; } case 's': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 220); - case 'c': return u3nc(0, 80); - case 'd': return u3nc(0, 237); - case 'f': return u3nc(0, 58); - case 'g': return u3nc(0, 133); - case 'l': return u3nc(0, 96); - case 'm': return u3nc(0, 75); - case 'n': return u3nc(0, 245); - case 'p': return u3nc(0, 35); - case 'r': return u3nc(0, 13); - case 't': return u3nc(0, 115); - case 'v': return u3nc(0, 4); - default: return 0; + case 'b': return 220; + case 'c': return 80; + case 'd': return 237; + case 'f': return 58; + case 'g': return 133; + case 'l': return 96; + case 'm': return 75; + case 'n': return 245; + case 'p': return 35; + case 'r': return 13; + case 't': return 115; + case 'v': return 4; + default: return -1; } case 'u': switch (three) { - case 'b': return u3nc(0, 68); - case 'd': return u3nc(0, 177); - case 'g': return u3nc(0, 229); - case 'l': return u3nc(0, 38); - case 'm': return u3nc(0, 85); - case 'n': return u3nc(0, 15); - case 'p': return u3nc(0, 74); - case 'r': return u3nc(0, 119); - case 't': return u3nc(0, 6); - default: return 0; + case 'b': return 68; + case 'd': return 177; + case 'g': return 229; + case 'l': return 38; + case 'm': return 85; + case 'n': return 15; + case 'p': return 74; + case 'r': return 119; + case 't': return 6; + default: return -1; } case 'y': switch (three) { - case 'd': return u3nc(0, 30); - case 'l': return u3nc(0, 163); - case 'm': return u3nc(0, 95); - case 'n': return u3nc(0, 71); - case 'p': return u3nc(0, 112); - case 'r': return u3nc(0, 100); - case 't': return u3nc(0, 10); - case 'x': return u3nc(0, 17); - default: return 0; - } - default: return 0; + case 'd': return 30; + case 'l': return 163; + case 'm': return 95; + case 'n': return 71; + case 'p': return 112; + case 'r': return 100; + case 't': return 10; + case 'x': return 17; + default: return -1; + } + default: return -1; } case 't': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 89); - case 'c': return u3nc(0, 164); - case 'd': return u3nc(0, 142); - case 'g': return u3nc(0, 251); - case 'l': return u3nc(0, 249); - case 'm': return u3nc(0, 40); - case 'n': return u3nc(0, 160); - case 'p': return u3nc(0, 55); - case 'r': return u3nc(0, 113); - case 's': return u3nc(0, 241); - case 'v': return u3nc(0, 83); - case 'x': return u3nc(0, 118); - default: return 0; + case 'b': return 89; + case 'c': return 164; + case 'd': return 142; + case 'g': return 251; + case 'l': return 249; + case 'm': return 40; + case 'n': return 160; + case 'p': return 55; + case 'r': return 113; + case 's': return 241; + case 'v': return 83; + case 'x': return 118; + default: return -1; } case 'u': switch (three) { - case 'c': return u3nc(0, 168); - case 'd': return u3nc(0, 121); - case 'g': return u3nc(0, 109); - case 'l': return u3nc(0, 42); - case 'n': return u3nc(0, 175); - case 's': return u3nc(0, 154); - case 'x': return u3nc(0, 108); - default: return 0; + case 'c': return 168; + case 'd': return 121; + case 'g': return 109; + case 'l': return 42; + case 'n': return 175; + case 's': return 154; + case 'x': return 108; + default: return -1; } case 'y': switch (three) { - case 'c': return u3nc(0, 155); - case 'd': return u3nc(0, 73); - case 'l': return u3nc(0, 53); - case 'n': return u3nc(0, 132); - case 'p': return u3nc(0, 189); - case 'r': return u3nc(0, 153); - case 'v': return u3nc(0, 29); - default: return 0; - } - default: return 0; + case 'c': return 155; + case 'd': return 73; + case 'l': return 53; + case 'n': return 132; + case 'p': return 189; + case 'r': return 153; + case 'v': return 29; + default: return -1; + } + default: return -1; } case 'w': switch (two) { case 'e': switch (three) { - case 'b': return u3nc(0, 84); - case 'd': return u3nc(0, 192); - case 'g': return u3nc(0, 246); - case 'l': return u3nc(0, 207); - case 'n': return u3nc(0, 44); - case 'p': return u3nc(0, 12); - case 'r': return u3nc(0, 227); - case 's': return u3nc(0, 3); - case 't': return u3nc(0, 101); - case 'x': return u3nc(0, 99); - default: return 0; + case 'b': return 84; + case 'd': return 192; + case 'g': return 246; + case 'l': return 207; + case 'n': return 44; + case 'p': return 12; + case 'r': return 227; + case 's': return 3; + case 't': return 101; + case 'x': return 99; + default: return -1; } case 'y': switch (three) { - case 'c': return u3nc(0, 59); - case 'd': return u3nc(0, 54); - case 'l': return u3nc(0, 14); - case 'n': return u3nc(0, 76); - case 't': return u3nc(0, 125); - case 'x': return u3nc(0, 94); - default: return 0; - } - default: return 0; + case 'c': return 59; + case 'd': return 54; + case 'l': return 14; + case 'n': return 76; + case 't': return 125; + case 'x': return 94; + default: return -1; + } + default: return -1; } case 'z': switch (two) { case 'o': switch (three) { - case 'd': return u3nc(0, 0); - default: return 0; + case 'd': return 0; + default: return -1; } - default: return 0; + default: return -1; } - default: return 0; + default: return -1; } } @@ -1353,7 +1353,15 @@ u3qc_po_ins(u3_noun a) c3_y byt_y[3]; u3r_bytes(0, 3, byt_y, a); - return u3_po_find_prefix(byt_y[0], byt_y[1], byt_y[2]); + c3_s puf_s; + + puf_s = u3_po_find_prefix(byt_y[0], byt_y[1], byt_y[2]); + + if ( puf_s <= 0xff ) { + return u3nc(u3_nul, u3i_word(puf_s)); + } + + return u3_nul; } u3_noun @@ -1375,7 +1383,15 @@ u3qc_po_ind(u3_noun a) c3_y byt_y[3]; u3r_bytes(0, 3, byt_y, a); - return u3_po_find_suffix(byt_y[0], byt_y[1], byt_y[2]); + c3_s suf_s; + + suf_s = u3_po_find_suffix(byt_y[0], byt_y[1], byt_y[2]); + + if ( suf_s <= 0xff ) { + return u3nc(u3_nul, suf_s); + } + + return u3_nul; } u3_noun diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index e90c036be9..e22712b73b 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -21,11 +21,11 @@ _parse_da(u3_noun a) } static inline u3_noun -_parse_ud(u3_noun a) +_parse_p(u3_noun a) { u3_weak pro; - if ( u3_none == (pro = u3s_sift_ud(u3x_atom(a))) ) { + if ( u3_none == (pro = u3s_sift_p(u3x_atom(a))) ) { return u3_nul; } @@ -33,260 +33,29 @@ _parse_ud(u3_noun a) } static inline u3_noun -_parse_ux(u3_noun a) +_parse_ud(u3_noun a) { u3_weak pro; - if ( u3_none == (pro = u3s_sift_ux(u3x_atom(a))) ) { + if ( u3_none == (pro = u3s_sift_ud(u3x_atom(a))) ) { return u3_nul; } return u3nc(u3_nul, pro); } -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) +static inline u3_noun +_parse_ux(u3_noun a) { - if ( (c3y == u3a_is_atom(p)) || (c3y == u3a_is_atom(q)) ) { - return 0; - } - - u3_noun lef = u3qa_mul(256, u3t(q)); - u3_noun ret = u3nc(0, u3qa_add(u3t(p), lef)); - u3z(lef); - 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); + u3_weak pro; - 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; + if ( u3_none == (pro = u3s_sift_ux(u3x_atom(a))) ) { + return u3_nul; } - // 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))))))))))))))); + return u3nc(u3_nul, pro); } - -#undef ENSURE_NOT_END -#undef CONSUME -#undef TRY_GET_SYLLABLE - u3_noun _parse_tas(u3_noun txt) { // For any symbol which matches, txt will return itself as a @@ -330,7 +99,7 @@ u3we_slaw(u3_noun cor) return _parse_da(txt); case 'p': - return _parse_p(cor, txt); + return _parse_p(txt); case c3__ud: return _parse_ud(txt); diff --git a/pkg/noun/jets/q.h b/pkg/noun/jets/q.h index e9c8bfd9b3..3afa4714fd 100644 --- a/pkg/noun/jets/q.h +++ b/pkg/noun/jets/q.h @@ -73,8 +73,8 @@ 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); + c3_s u3_po_find_prefix(c3_y one, c3_y two, c3_y three); + c3_s 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); diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index 89c3e07cdb..5f9f0d3a09 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -801,6 +801,216 @@ _test_sift_da(void) return ret_i; } +static inline u3_noun +_p_good(c3_d num_d, const c3_c* num_c) +{ + u3_weak out; + + out = u3s_sift_p_bytes(strlen(num_c), (c3_y*)num_c); + + if ( c3y == u3a_is_cat(out) ) { + if ( num_d != out) { + fprintf(stderr, "sift_p: %s wrong; expected 0x%llx: actual 0x%x\r\n", num_c, num_d, out); + return 0; + } + + return 1; + } + else { + + if ( u3_none == out ) { + fprintf(stderr, "sift_p: %s fail; expected 0x%llx\r\n", num_c, num_d); + return 0; + } + + c3_d out_d = u3r_chub(0, out); + + if ( num_d != out_d ) { + fprintf(stderr, "sift_p: %s wrong; expected 0x%llx: actual 0x%llx\r\n", num_c, num_d, out_d); + + u3z(out); + return 0; + } + + u3z(out); + return 1; + } + +} + +static inline c3_i +_p_fail(const c3_c* num_c) +{ + u3_weak out; + if ( u3_none != (out = u3s_sift_p_bytes(strlen(num_c), (c3_y*)num_c)) ) { + u3m_p("out", out); + fprintf(stderr, "sift_p: %s expected fail\r\n", num_c); + return 0; + } + + return 1; +} + +static c3_i +_test_sift_p(void) +{ + c3_i ret_i = 1; + + ret_i &= _p_good(0x0, "~zod"); + ret_i &= _p_good(0x3, "~wes"); + ret_i &= _p_good(0x10, "~ryp"); + ret_i &= _p_good(0x17, "~dep"); + ret_i &= _p_good(0x1b, "~hec"); + ret_i &= _p_good(0x26, "~sul"); + ret_i &= _p_good(0x29, "~led"); + ret_i &= _p_good(0x2e, "~hex"); + ret_i &= _p_good(0x31, "~dul"); + ret_i &= _p_good(0x3e, "~nep"); + ret_i &= _p_good(0x56, "~mut"); + ret_i &= _p_good(0x66, "~dyl"); + ret_i &= _p_good(0x7c, "~ren"); + ret_i &= _p_good(0x8a, "~fun"); + ret_i &= _p_good(0x92, "~dux"); + ret_i &= _p_good(0xac, "~ber"); + ret_i &= _p_good(0xbf, "~myl"); + ret_i &= _p_good(0xcf, "~wel"); + ret_i &= _p_good(0xd2, "~rel"); + ret_i &= _p_good(0xd4, "~nes"); + ret_i &= _p_good(0xf9, "~tel"); + ret_i &= _p_good(0xff, "~fes"); + + ret_i &= _p_good(0x1cc, "~marryd"); + ret_i &= _p_good(0xf18, "~sibdys"); + ret_i &= _p_good(0x134b, "~modsem"); + ret_i &= _p_good(0x18c7, "~dorner"); + ret_i &= _p_good(0x2513, "~dalnup"); + ret_i &= _p_good(0x2570, "~dalsyp"); + ret_i &= _p_good(0x39f6, "~difweg"); + ret_i &= _p_good(0x4a94, "~sicnum"); + ret_i &= _p_good(0x5cfa, "~banrep"); + ret_i &= _p_good(0x63c6, "~wiclen"); + ret_i &= _p_good(0x753b, "~dacwyc"); + ret_i &= _p_good(0x8b45, "~nompet"); + ret_i &= _p_good(0xa03c, "~tacbur"); + ret_i &= _p_good(0xa2b4, "~moglur"); + ret_i &= _p_good(0xad0a, "~pocsyt"); + ret_i &= _p_good(0xb365, "~dibwet"); + ret_i &= _p_good(0xba42, "~lodden"); + ret_i &= _p_good(0xdcaa, "~rislep"); + ret_i &= _p_good(0xeec2, "~bacfur"); + ret_i &= _p_good(0xf674, "~tondut"); + ret_i &= _p_good(0xffff, "~fipfes"); + + ret_i &= _p_good(0x6d2030, "~hocmeb-dapsen"); + ret_i &= _p_good(0x19e3826, "~ladlen-nidrev"); + ret_i &= _p_good(0x60e5726, "~ropsyn-magtyl"); + ret_i &= _p_good(0x108deca3, "~divbud-ladbyn"); + ret_i &= _p_good(0x1cb220fb, "~dathut-miplep"); + ret_i &= _p_good(0x2a84b998, "~haplun-savruc"); + ret_i &= _p_good(0x2e380f98, "~darben-firlyx"); + ret_i &= _p_good(0x3e2f64cc, "~hodbep-lavmep"); + ret_i &= _p_good(0x64f4eace, "~mopten-hilfex"); + ret_i &= _p_good(0x7c0fdcda, "~sipsyt-simweg"); + ret_i &= _p_good(0x7d0a9aa1, "~tocseg-fitneb"); + ret_i &= _p_good(0x82622083, "~wicwyt-marsur"); + ret_i &= _p_good(0x9266739d, "~widfen-tadmut"); + ret_i &= _p_good(0x95f01ec8, "~foddus-sabden"); + ret_i &= _p_good(0xa1ae3130, "~tinbyn-fammun"); + ret_i &= _p_good(0xaf7c1801, "~molryn-nisnux"); + ret_i &= _p_good(0xb91f853a, "~dinnex-sonnum"); + ret_i &= _p_good(0xc14c7ccf, "~morwes-pasbyn"); + ret_i &= _p_good(0xca76d018, "~borred-dozrus"); + ret_i &= _p_good(0xf2ea4743, "~bansec-tabnus"); + ret_i &= _p_good(0xffffffff, "~dostec-risfen"); + + ret_i &= _p_good(0x6bfc3f1881b, "~sigmyl-bintus-sovpet"); + ret_i &= _p_good(0x37e37b1a3551, "~tadwer-ropfed-binleg"); + ret_i &= _p_good(0x410347ee002e, "~narwes-tidlud-fasmyn"); + ret_i &= _p_good(0x46f6e0458bc7, "~novweg-bilnet-radfep"); + ret_i &= _p_good(0x47c87321d50b, "~sitlex-tocrul-lodsep"); + ret_i &= _p_good(0x51353dce0067, "~podtyl-sicnes-samfet"); + ret_i &= _p_good(0x518ce06c70e1, "~podref-worlex-doclep"); + ret_i &= _p_good(0x5c68ea866ab7, "~banmes-bisryt-ralrul"); + ret_i &= _p_good(0x611273cbe100, "~nordyr-dacpel-libsud"); + ret_i &= _p_good(0x71191aad547c, "~tagput-batteg-dirdyn"); + ret_i &= _p_good(0x73f1ea2b6764, "~saltes-faddyn-norpur"); + ret_i &= _p_good(0x8a44e8857186, "~figsub-fabwed-lasnys"); + ret_i &= _p_good(0x93da8f14e8eb, "~ridler-tastel-roctul"); + ret_i &= _p_good(0xab36928a695b, "~boswyd-lagdut-tobhes"); + ret_i &= _p_good(0xae9859f74a22, "~hacfep-dibled-moddet"); + ret_i &= _p_good(0xb04e0a68a36d, "~havmeg-dirsev-padtem"); + ret_i &= _p_good(0xd2a8b958c1ec, "~niltuc-rolfur-ricref"); + ret_i &= _p_good(0xd682b6a7a9c1, "~famneb-tarnut-rilnes"); + ret_i &= _p_good(0xe1a670e9eebd, "~larpub-bacfus-nisbex"); + ret_i &= _p_good(0xf6b014781344, "~tonbyl-dasryg-bitlen"); + ret_i &= _p_good(0xffffffffffff, "~fipfes-dostec-risfen"); + + ret_i &= _p_good(0x94fede64d31f2a0, "~lisnet-rivnys-natdem-donful"); + ret_i &= _p_good(0xf4baddc87e49501, "~sibsem-pocseb-balduc-davbus"); + ret_i &= _p_good(0x354e583df2681571, "~tirmeg-nopder-hinwes-micdur"); + ret_i &= _p_good(0x3d0b51f8a79c9cbb, "~dasdur-podmur-doswed-motlys"); + ret_i &= _p_good(0x3e2dc8e804dda5f7, "~midbyn-hinlyn-dossub-faslyt"); + ret_i &= _p_good(0x4974294fa5c476be, "~tipdut-hannet-talpec-dasted"); + ret_i &= _p_good(0x51caf3d176a3e85c, "~podned-namhus-dirtes-moglud"); + ret_i &= _p_good(0x5f1a0462f14c6a4e, "~siplug-samdec-pinsev-rigwes"); + ret_i &= _p_good(0x648393ba45a204bc, "~socrum-ridpex-hanlyx-nidfyn"); + ret_i &= _p_good(0x681e0b656bf4a5ba, "~picsyd-dirwet-rabdyt-davtul"); + ret_i &= _p_good(0x767340cdb232bbdd, "~tanset-rillyd-rovdet-sondeg"); + ret_i &= _p_good(0xa3a6f3dffaa1b143, "~simpub-namlud-dovnux-fampun"); + ret_i &= _p_good(0xa9ec7fcb9023e486, "~firfed-pallec-tonzod-monbep"); + ret_i &= _p_good(0xb39638ae3f909214, "~dibryg-bichut-witsev-fanpub"); + ret_i &= _p_good(0xc356a0bec7c9f106, "~fasmut-taclev-hocmun-pidnel"); + ret_i &= _p_good(0xd226683f5a2fa433, "~nilsul-picpur-nocsem-tasrys"); + ret_i &= _p_good(0xd5bc5e03458e7790, "~fopbyt-worwes-rolput-nodruc"); + ret_i &= _p_good(0xe203169849fc1124, "~fitwes-hopfep-bitwyd-doswer"); + ret_i &= _p_good(0xfb0b09b610c92278, "~sordur-lisbus-ritsyd-wanpet"); + ret_i &= _p_good(0xfe96342d19d7cf69, "~mipryg-rambyn-livdyr-paglun"); + ret_i &= _p_good(0xffffffffffffffff, "~fipfes-fipfes-dostec-risfen"); + + ret_i &= _p_fail("~"); + ret_i &= _p_fail("~doz"); + ret_i &= _p_fail("~dozzod"); + ret_i &= _p_fail("~bin-zod"); + ret_i &= _p_fail("~zod-mipryg-rambyn"); + ret_i &= _p_fail("~doz-mipryg-rambyn"); + ret_i &= _p_fail("dozzod-fipfes-dostec-risfen"); + ret_i &= _p_fail("fipfes-fipfes-dostec-risfen--"); + ret_i &= _p_fail("fipfes-fipfes--dostec-risfen"); + + { + c3_c* hex_c = "0x1.1234.5678.9abc.def0.1234.5678.9abc.def0"; + c3_c* pun_c = "~doznec--doprut-posfel-tilbyt-riblyr--doprut-posfel-tilbyt-riblyr"; + + u3_weak out = u3s_sift_p_bytes(strlen(pun_c), (c3_y*)pun_c); + u3_weak hot = u3s_sift_ux_bytes(strlen(hex_c), (c3_y*)hex_c); + + + if ( u3_none == out ) { + fprintf(stderr, "sift_p: big p fail\r\n"); + ret_i = 0; + } + + if ( u3_none == hot ) { + fprintf(stderr, "sift_p: big hex fail during big p test\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(hot, out) ) { + u3m_p("hot", hot); + u3m_p("out", out); + fprintf(stderr, "sift_p: big p wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); + u3z(hot); + } + + return ret_i; +} + static inline c3_i _ud_good(c3_w num_w, const c3_c* num_c) { @@ -1460,6 +1670,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_sift_p() ) { + fprintf(stderr, "test jets: sift_ud: failed\r\n"); + ret_i = 0; + } + if ( !_test_sift_ud() ) { fprintf(stderr, "test jets: sift_ud: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 637866a618..335773e3fb 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -2130,6 +2130,282 @@ static inline c3_o _cs_dot(c3_w* len_w, c3_y** byt_yp) } } +#define arelower(a,b,c) (islower(a) && islower(b) && islower(c)) + +static inline c3_s _cs_parse_prefix(c3_w* len_w, c3_y** byt_yp) { + + c3_y a,b,c; + c3_y* byt_y = *byt_yp; + + if ( *len_w < 3 ) { + return -1; + } + + a = *byt_y; + b = *(byt_y + 1); + c = *(byt_y + 2); + + if ( ! arelower(a,b,c) ) { + return -1; + } + + *byt_yp += 3; + *len_w -= 3; + + return u3_po_find_prefix(a,b,c); +} + +static inline c3_s _cs_parse_suffix(c3_w* len_w, c3_y** byt_yp) { + + c3_y a,b,c; + c3_y* byt_y = *byt_yp; + + if ( *len_w < 3 ) { + return -1; + } + + a = *byt_y; + b = *(byt_y + 1); + c = *(byt_y + 2); + + if ( ! arelower(a,b,c) ) { + return -1; + } + + *byt_yp += 3; + *len_w -= 3; + + return u3_po_find_suffix(a,b,c); +} + +#undef arelower + +/* u3s_sift_p_bytes: parse @p impl. + */ +u3_weak +u3s_sift_p_bytes(c3_w len_w, c3_y* byt_y) +{ + c3_d pun_d; + + c3_s suf_s; + c3_s puf_s; + + if ( !len_w || *byt_y != '~') { + return u3_none; + } + + len_w--; + byt_y++; + + suf_s = _cs_parse_suffix(&len_w, &byt_y); + + // A galaxy + // + if ( !len_w && suf_s <= 0xff) { + return (u3_atom) suf_s; + } + + if ( !len_w ) { + return u3_none; + } + + // Rewind to match a star + // + len_w += 3; + byt_y -= 3; + + puf_s = _cs_parse_prefix(&len_w, &byt_y); + + if ( puf_s > 0xff) { + return u3_none; + } + + suf_s = _cs_parse_suffix(&len_w, &byt_y); + + if ( suf_s > 0xff ) { + return u3_none; + } + + pun_d = (puf_s << 8 ) + suf_s; + + // A star, disallow ~doz for prefix + // + if ( !len_w && puf_s > 0 ) { + return (u3_atom) pun_d; + } + + // +hef + if ( !pun_d ) { + return u3_none; + } + + // At least a planet + // + if ( len_w < 7 ) { + return u3_none; + } + + size_t hak = 1; + + // Parse up to 3 head words (64-bit) + // + while ( len_w && hak < 4) { + + if ( *byt_y != '-') { + return u3_none; + } + + byt_y++; + len_w--; + + puf_s = _cs_parse_prefix(&len_w, &byt_y); + + if ( puf_s > 0xff ) { + + // --, end of head + // + if ( *byt_y == '-' ) { + break; + } + + else { + return u3_none; + } + } + + suf_s = _cs_parse_suffix(&len_w, &byt_y); + + if ( suf_s > 0xff ) { + return u3_none; + } + + pun_d <<= 16; + pun_d += (puf_s << 8) + suf_s; + + hak++; + } + + if ( !len_w ) { + + if ( c3y == u3a_is_cat(pun_d) ) { + return (u3_atom) u3qe_fynd_ob(pun_d); + } + else { + u3_atom pun = u3i_chub(pun_d); + u3_atom sun = u3qe_fynd_ob(pun); + + u3z(pun); + return sun; + } + } + + // Parse a big address in quadruples + // + mpz_t pun_mp; + mpz_init2(pun_mp, 128); + + mpz_set_ui(pun_mp, pun_d); + pun_d = 0; + + hak = 0; + + // Rewind to separating -- + // + byt_y -= 1; + len_w += 1; + + // Parse in 64-bit chunks + // + while ( len_w ) { + + if ( *byt_y != '-') { + goto sift_p_fail; + } + + byt_y++; + len_w--; + + if ( 0 == (hak % 4) ) { + + // Separated by -- + // + if ( *byt_y != '-' || len_w < 7) { + goto sift_p_fail; + } + + byt_y++; + len_w--; + } + + puf_s = _cs_parse_prefix(&len_w, &byt_y); + + if ( puf_s > 0xff ) { + goto sift_p_fail; + } + + suf_s = _cs_parse_suffix(&len_w, &byt_y); + + if ( suf_s > 0xff ) { + goto sift_p_fail; + } + + pun_d <<= 16; + pun_d += (puf_s << 8) + suf_s; + + hak++; + + if ( hak == 4 ) { + mpz_mul_2exp(pun_mp, pun_mp, 64); + mpz_add_ui(pun_mp, pun_mp, pun_d); + + pun_d = 0; + hak = 0; + } + } + + // Number of words in the tail + // must be a multiple of four + // + if ( hak ) { + goto sift_p_fail; + } + + if ( len_w ) { +sift_p_fail: + + mpz_clear(pun_mp); + return u3_none; + } + + u3_atom pun = u3i_mp(pun_mp); + u3_atom sun = u3qe_fynd_ob(pun); + + u3z(pun); + return sun; +} + +/* u3s_sift_p: parse @p. +*/ +u3_weak +u3s_sift_p(u3_atom a) +{ + c3_w len_w = u3r_met(3, a); + c3_y* byt_y; + + // + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + else { + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + return u3s_sift_p_bytes(len_w, byt_y); +} + #define DIGIT(a) ( ((a) >= '0') && ((a) <= '9') ) /* +two: parse a maximum 2 digit decimal number, greater than 0. diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index e66c78cf58..81defea835 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -161,6 +161,16 @@ u3_weak u3s_sift_da(u3_atom a); + /* u3s_sift_p_bytes: parse @p. + */ + u3_weak + u3s_sift_p_bytes(c3_w len_w, c3_y* byt_y); + + /* u3s_sift_p: parse @p. + */ + u3_weak + u3s_sift_p(u3_atom a); + /* u3s_sift_ud_bytes: parse @ud. */ u3_weak From a0d660359bc73d5571711b05cc5a31d9aa5be346 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 11:06:44 +0800 Subject: [PATCH 09/16] u3: adds %ui printing --- pkg/c3/motes.h | 1 + pkg/noun/jets/e/scot.c | 1 + pkg/noun/jets_tests.c | 94 +++++++++++++++++++++++++++ pkg/noun/serial.c | 143 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/serial.h | 18 ++++++ 5 files changed, 257 insertions(+) diff --git a/pkg/c3/motes.h b/pkg/c3/motes.h index 40740522ee..d5eb8acf13 100644 --- a/pkg/c3/motes.h +++ b/pkg/c3/motes.h @@ -1224,6 +1224,7 @@ # define c3__ubin c3_s4('u','b','i','n') # define c3__ubit c3_s4('u','b','i','t') # define c3__ud c3_s2('u','d') +# define c3__ui c3_s2('u','i') # define c3__ulib c3_s4('u','l','i','b') # define c3__un c3_s2('u','n') # define c3__uniq c3_s4('u','n','i','q') diff --git a/pkg/noun/jets/e/scot.c b/pkg/noun/jets/e/scot.c index 0d143e6175..dc12cd9add 100644 --- a/pkg/noun/jets/e/scot.c +++ b/pkg/noun/jets/e/scot.c @@ -19,6 +19,7 @@ u3qe_scot(u3_atom a, u3_atom b) case 'p': return u3s_etch_p(b); case c3__ud: return u3s_etch_ud(b); + case c3__ui: return u3s_etch_ui(b); case c3__ux: return u3s_etch_ux(b); case c3__uv: return u3s_etch_uv(b); case c3__uw: return u3s_etch_uw(b); diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index 5f9f0d3a09..a6d4844db7 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -389,6 +389,95 @@ _test_etch_ud(void) return ret_i; } +static inline c3_i +_ui_etch(c3_d num_d, const c3_c* num_c) +{ + u3_atom num = u3i_chub(num_d); + c3_c* out_c; + size_t len_i = u3s_etch_ui_c(num, &out_c); + c3_i ret_i = 1; + + if ( _neq_etch_out(num_c, out_c, len_i) ) { + fprintf(stderr, "etch_ui: %" PRIu64 " fail; expected %s, got '%s'\r\n", + num_d, num_c, out_c); + ret_i = 0; + } + else { + u3_noun out = u3s_etch_ui(num); + u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); + + if ( c3n == u3r_sing(tou, out) ) { + fprintf(stderr, "etch_ui: %" PRIu64 " mismatch; expected %s\r\n", num_d, num_c); + u3m_p("out", out); + ret_i = 0; + } + + u3z(out); + u3z(tou); + } + + c3_free(out_c); + u3z(num); + + return ret_i; +} + +static c3_i +_test_etch_ui(void) +{ + c3_i ret_i = 1; + + ret_i &= _ui_etch(0, "0i0"); + ret_i &= _ui_etch(1, "0i1"); + ret_i &= _ui_etch(12, "0i12"); + ret_i &= _ui_etch(123, "0i123"); + ret_i &= _ui_etch(1234, "0i1234"); + ret_i &= _ui_etch(12345, "0i12345"); + ret_i &= _ui_etch(123456, "0i123456"); + ret_i &= _ui_etch(1234567, "0i1234567"); + ret_i &= _ui_etch(12345678, "0i12345678"); + ret_i &= _ui_etch(123456789, "0i123456789"); + ret_i &= _ui_etch(100000000, "0i100000000"); + ret_i &= _ui_etch(101101101, "0i101101101"); + ret_i &= _ui_etch(201201201, "0i201201201"); + ret_i &= _ui_etch(302201100, "0i302201100"); + + ret_i &= _ui_etch(8589934592ULL, "0i8589934592"); + ret_i &= _ui_etch(2305843009213693952ULL, "0i2305843009213693952"); + ret_i &= _ui_etch(18446744073709551615ULL, "0i18446744073709551615"); + + { + c3_c* num_c = "0i340282366920938463463374607431768211456"; + u3_atom num = u3qc_bex(128); + c3_c* out_c; + size_t len_i = u3s_etch_ui_c(num, &out_c); + + if ( _neq_etch_out(num_c, out_c, len_i) ) { + fprintf(stderr, "etch_ui: (bex 128) fail; expected %s, got '%s'\r\n", + num_c, out_c); + ret_i = 0; + } + else { + u3_noun out = u3s_etch_ui(num); + u3_noun tou = u3i_bytes(len_i, (c3_y*)out_c); + + if ( c3n == u3r_sing(tou, out) ) { + fprintf(stderr, "etch_ui: (bex 128) mismatch; expected %s\r\n", num_c); + u3m_p("out", out); + ret_i = 0; + } + + u3z(out); + u3z(tou); + } + + c3_free(out_c); + u3z(num); + } + + return ret_i; +} + static inline c3_i _ux_etch(c3_d num_d, const c3_c* num_c) { @@ -1650,6 +1739,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_etch_ui() ) { + fprintf(stderr, "test jets: etch_ui: failed\r\n"); + ret_i = 0; + } + if ( !_test_etch_ux() ) { fprintf(stderr, "test jets: etch_ux: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 335773e3fb..16ed1a3d22 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -1850,6 +1850,149 @@ u3s_etch_ud_c(u3_atom a, c3_c** out_c) return len_i; } +/* _cs_etch_ui_size(): output length in @ui for given mpz_t + */ +static inline size_t +_cs_etch_ui_size(mpz_t a_mp) +{ + size_t len_i = mpz_sizeinbase(a_mp, 10); + return len_i + 2; // + 0i +} + +/* _cs_etch_ui_bytes(): atom to @ui impl. + */ +static size_t +_cs_etch_ui_bytes(mpz_t a_mp, size_t len_i, c3_y* hun_y) +{ + c3_y* buf_y = hun_y + (len_i - 1); + c3_w b_w; + size_t dif_i; + + if ( !mpz_size(a_mp) ) { + *buf_y-- = '0'; + } + else { + while ( mpz_size(a_mp) ) { + + // 9 digits fit into a word + b_w = mpz_tdiv_q_ui(a_mp, a_mp, 1000000000); + + while ( b_w ) { + *buf_y-- = '0' + (b_w % 10); + b_w /= 10; + } + } + } + + *buf_y-- = 'i'; + *buf_y = '0'; + + // XX mpz_sizeinbase may overestimate by 1 + { + size_t dif_i = buf_y - hun_y; + + if ( dif_i ) { + len_i -= dif_i; + memmove(hun_y, buf_y, len_i); + memset(hun_y + len_i, 0, dif_i); + } + } + + return len_i; +} + +/* u3s_etch_ui_smol(): c3_d to @ui + ** + ** =(22 (met 3 (scot %ud (dec (bex 64))))) + */ +c3_y* +u3s_etch_ui_smol(c3_d a_d, c3_y hun_y[SMOL_UI]) +{ + c3_y* buf_y = hun_y + SMOL_UI - 1; + c3_w b_w; + + if ( !a_d ) { + *buf_y-- = '0'; + } + else{ + while ( a_d > 0 ) { + b_w = a_d % 10; + a_d /= 10; + + *buf_y-- = '0' + b_w; + } + } + + *buf_y-- = 'i'; + *buf_y-- = '0'; + + return buf_y + 1; +} + +/* u3s_etch_ui(): atom to @ui. + */ +u3_atom +u3s_etch_ui(u3_atom a) +{ + c3_d a_d; + + if ( c3y == u3r_safe_chub(a, &a_d) ) { + c3_y hun_y[SMOL_UI]; + c3_y* buf_y = u3s_etch_ui_smol(a_d, hun_y); + c3_w dif_w = (c3_p)buf_y - (c3_p)hun_y; + return u3i_bytes(SMOL_UI - dif_w, buf_y); + } + + u3i_slab sab_u; + size_t len_i; + mpz_t a_mp; + u3r_mp(a_mp, a); + + len_i = _cs_etch_ui_size(a_mp); + u3i_slab_bare(&sab_u, 3, len_i); + sab_u.buf_w[sab_u.len_w - 1] = 0; + + _cs_etch_ui_bytes(a_mp, len_i, sab_u.buf_y); + + mpz_clear(a_mp); + return u3i_slab_mint_bytes(&sab_u); +} + +/* u3s_etch_ui_c(): atom to @ui, as a malloc'd c string. + */ +size_t +u3s_etch_ui_c(u3_atom a, c3_c** out_c) +{ + c3_d a_d; + size_t len_i; + c3_y* buf_y; + + if ( c3y == u3r_safe_chub(a, &a_d) ) { + c3_y hun_y[SMOL_UI]; + buf_y = u3s_etch_ui_smol(a_d, hun_y); + len_i = SMOL_UI - ((c3_p)buf_y - (c3_p)hun_y); + *out_c = c3_malloc(len_i + 1); + (*out_c)[len_i] = 0; + memcpy(*out_c, buf_y, len_i); + + return len_i; + } + + mpz_t a_mp; + u3r_mp(a_mp, a); + + len_i = _cs_etch_ui_size(a_mp); + buf_y = c3_malloc(len_i + 1); + buf_y[len_i] = 0; + + len_i = _cs_etch_ui_bytes(a_mp, len_i, buf_y); + + *out_c = (c3_c*)buf_y; + + mpz_clear(a_mp); + return len_i; +} + /* _cs_etch_ux_bytes(): atom to @ux impl. */ static void diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index 81defea835..99f459ab9f 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -121,6 +121,24 @@ size_t u3s_etch_ud_c(u3_atom a, c3_c** out_c); + /* u3s_etch_ui_smol(): c3_d to @ui + ** + ** =(22 (met 3 (scot %ui (dec (bex 64))))) + */ +#define SMOL_UI 22 + c3_y* + u3s_etch_ui_smol(c3_d a_d, c3_y hun_y[SMOL_UI]); + + /* u3s_etch_ui(): atom to @ui. + */ + u3_atom + u3s_etch_ui(u3_atom a); + + /* u3s_etch_ui_c(): atom to @ui, as a malloc'd c string. + */ + size_t + u3s_etch_ui_c(u3_atom a, c3_c** out_c); + /* u3s_etch_ux(): atom to @ux. */ u3_atom From 1e0313616206315ba550346ab25b85d4d72de6f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 11:15:43 +0800 Subject: [PATCH 10/16] u3: adds %ui parsing --- pkg/noun/jets/e/slaw.c | 18 +++++- pkg/noun/jets_tests.c | 108 +++++++++++++++++++++++++++++++- pkg/noun/serial.c | 137 ++++++++++++++++++++++++++++++++++++++++- pkg/noun/serial.h | 10 +++ 4 files changed, 270 insertions(+), 3 deletions(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index e22712b73b..111e9dd22f 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -1,4 +1,4 @@ -/// @fil +/// @file #include "jets/k.h" #include "jets/q.h" @@ -44,6 +44,19 @@ _parse_ud(u3_noun a) return u3nc(u3_nul, pro); } +static inline u3_noun +_parse_ui(u3_noun a) +{ + u3_weak pro; + + if ( u3_none == (pro = u3s_sift_ui(u3x_atom(a))) ) { + return u3_nul; + } + + return u3nc(u3_nul, pro); +} + + static inline u3_noun _parse_ux(u3_noun a) { @@ -104,6 +117,9 @@ u3we_slaw(u3_noun cor) case c3__ud: return _parse_ud(txt); + case c3__ui: + return _parse_ui(txt); + case c3__ux: return _parse_ux(txt); diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index a6d4844db7..b1e843b838 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -1202,6 +1202,107 @@ _test_sift_ud(void) return ret_i; } +static inline c3_i +_ui_good(c3_w num_w, const c3_c* num_c) +{ + u3_weak out; + if ( num_w != (out = u3s_sift_ui_bytes(strlen(num_c), (c3_y*)num_c)) ) { + if ( u3_none == out ) { + fprintf(stderr, "sift_ui: %s fail; expected %u\r\n", num_c, num_w); + } + else { + fprintf(stderr, "sift_ui: %s wrong; expected %u: actual %u\r\n", num_c, num_w, out); + } + return 0; + } + + return 1; +} + +static inline c3_i +_ui_fail(const c3_c* num_c) +{ + u3_weak out; + if ( u3_none != (out = u3s_sift_ui_bytes(strlen(num_c), (c3_y*)num_c)) ) { + u3m_p("out", out); + fprintf(stderr, "sift_ui: %s expected fail\r\n", num_c); + return 0; + } + + return 1; +} + +extern c3_d _cs_bit_dec(c3_d l); + +static c3_i +_test_sift_ui(void) +{ + c3_i ret_i = 1; + + ret_i &= _ui_good(0, "0i0"); + ret_i &= _ui_good(1, "0i1"); + ret_i &= _ui_good(12, "0i12"); + ret_i &= _ui_good(123, "0i123"); + ret_i &= _ui_good(1234, "0i1234"); + ret_i &= _ui_good(12345, "0i12345"); + ret_i &= _ui_good(123456, "0i123456"); + ret_i &= _ui_good(1234567, "0i1234567"); + ret_i &= _ui_good(12345678, "0i12345678"); + ret_i &= _ui_good(123456789, "0i123456789"); + ret_i &= _ui_good(100000000, "0i100000000"); + ret_i &= _ui_good(101101101, "0i101101101"); + ret_i &= _ui_good(201201201, "0i201201201"); + ret_i &= _ui_good(302201100, "0i302201100"); + + ret_i &= _ui_fail("0i"); + ret_i &= _ui_fail("i0"); + ret_i &= _ui_fail("0i01"); + + { + c3_c* num_c = "0i4294967296"; + u3_weak out = u3s_sift_ui_bytes(strlen(num_c), (c3_y*)num_c); + u3_atom pro = u3qc_bex(32); + + if ( u3_none == out ) { + fprintf(stderr, "sift_ui: (bex 32) fail\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(pro, out) ) { + u3m_p("out", out); + fprintf(stderr, "sift_ui: (bex 32) wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); u3z(pro); + } + + { + c3_c* num_c = "0i340282366920938463463374607431768211456"; + u3_weak out = u3s_sift_ui_bytes(strlen(num_c), (c3_y*)num_c); + u3_atom pro = u3qc_bex(128); + + if ( u3_none == out ) { + fprintf(stderr, "sift_ui: (bex 128) fail\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(pro, out) ) { + u3m_p("out", out); + fprintf(stderr, "sift_ui: (bex 128) wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); u3z(pro); + } + + return ret_i; +} + static inline c3_i _ux_good(c3_d num_d, const c3_c* num_c) { @@ -1765,7 +1866,7 @@ _test_jets(void) } if ( !_test_sift_p() ) { - fprintf(stderr, "test jets: sift_ud: failed\r\n"); + fprintf(stderr, "test jets: sift_p: failed\r\n"); ret_i = 0; } @@ -1774,6 +1875,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_sift_ui() ) { + fprintf(stderr, "test jets: sift_ui: failed\r\n"); + ret_i = 0; + } + if ( !_test_sift_ux() ) { fprintf(stderr, "test jets: sift_ux: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 16ed1a3d22..9876d72004 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -2600,6 +2600,18 @@ static inline c3_o _cs_duo(c3_s* num, c3_w* len_w, c3_y** byt_yp) return c3y; } +/* _cs_dex_val: char to decimal digit. + */ +static inline c3_s _cs_dex_val(c3_y dex) { + + if ( dex > '9' ) { + return -1; + } + else { + return dex - '0'; + } +} + /* _cs_hex_val: char to hexadecimal digit. */ static inline c3_s _cs_hex_val(c3_y hex) { @@ -3143,7 +3155,6 @@ u3s_sift_ud_bytes(c3_w len_w, c3_y* byt_y) } #undef BLOCK -#undef DIGIT /* u3s_sift_ud: parse @ud. */ @@ -3177,6 +3188,130 @@ u3s_sift_ud(u3_atom a) byt_y += 2; \ } +/* u3s_sift_ui_bytes: parse @ui. + */ +u3_weak +u3s_sift_ui_bytes(c3_w len_w, c3_y* byt_y) +{ + + PFIXD('0', 'i'); + + // Parse 0i0 + // + if ( *byt_y == '0' ) { + if ( len_w > 1 ) { + return u3_none; + } + else { + return (u3_noun)0; + } + } + + c3_d val_d = 0; + + // Avoid gmp allocation if possible + // - 19 decimal digits fit in 64 bits + // + if ( len_w <= 19 ) { + + c3_s dit_s; + + while ( len_w > 0 ) { + + dit_s = _cs_dex_val(*byt_y); + + if ( dit_s > 9 ) { + return u3_none; + } + + val_d *= 10; + val_d += dit_s; + + byt_y++; + len_w--; + } + + return u3i_chub(val_d); + } + + else { + mpz_t a_mp; + mpz_t bas_mp; + + // avoid gmp realloc if possible + // + { + c3_d bit_d = len_w/3 * 10; + mpz_init2(a_mp, (c3_w)c3_min(bit_d, UINT32_MAX)); + + mpz_init(bas_mp); + mpz_ui_pow_ui(bas_mp, 10, 19); + } + + val_d = 0; + c3_s hak_s = 0; + + while ( len_w ) { + + if ( ! DIGIT(*byt_y) ) { + + mpz_clear(bas_mp); + mpz_clear(a_mp); + return u3_none; + } + + val_d *= 10; + val_d += *byt_y++ - '0'; + + len_w--; + hak_s++; + + if ( hak_s == 19) { + mpz_mul(a_mp, a_mp, bas_mp); + mpz_add_ui(a_mp, a_mp, val_d); + + val_d = 0; + hak_s = 0; + } + + } + + if ( hak_s ) { + mpz_ui_pow_ui(bas_mp, 10, hak_s); + mpz_mul(a_mp, a_mp, bas_mp); + mpz_add_ui(a_mp, a_mp, val_d); + } + + mpz_clear(bas_mp); + return u3i_mp(a_mp); + } +} + +#undef DIGIT + +/* u3s_sift_ui: parse @ui. + */ +u3_weak +u3s_sift_ui(u3_noun a) +{ + + c3_w len_w = u3r_met(3, a); + c3_y* byt_y; + + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + else{ + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + return u3s_sift_ui_bytes(len_w, byt_y); +} + + /* u3s_sift_ux_bytes: parse @ux impl. */ u3_weak diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index 99f459ab9f..a7b3112052 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -199,6 +199,16 @@ u3_weak u3s_sift_ud(u3_atom a); + /* u3s_sift_ui_bytes: parse @ui. + */ + u3_weak + u3s_sift_ui_bytes(c3_w len_w, c3_y* byt_y); + + /* u3s_sift_ui: parse @ui. + */ + u3_weak + u3s_sift_ui(u3_atom a); + /* u3s_sift_ux_bytes: parse @ux. */ u3_weak From abb00207307388a83035d51d0b881340073edc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 11:22:34 +0800 Subject: [PATCH 11/16] u3: adds %uv parsing --- pkg/noun/jets/e/slaw.c | 16 +++- pkg/noun/jets_tests.c | 142 ++++++++++++++++++++++++++++++++++++ pkg/noun/serial.c | 162 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/serial.h | 10 +++ 4 files changed, 329 insertions(+), 1 deletion(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index 111e9dd22f..180a09e70f 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -56,7 +56,6 @@ _parse_ui(u3_noun a) return u3nc(u3_nul, pro); } - static inline u3_noun _parse_ux(u3_noun a) { @@ -69,6 +68,18 @@ _parse_ux(u3_noun a) return u3nc(u3_nul, pro); } +static inline u3_noun +_parse_uv(u3_noun a) +{ + u3_weak pro; + + if ( u3_none == (pro = u3s_sift_uv(u3x_atom(a))) ) { + return u3_nul; + } + + return u3nc(u3_nul, pro); +} + u3_noun _parse_tas(u3_noun txt) { // For any symbol which matches, txt will return itself as a @@ -123,6 +134,9 @@ u3we_slaw(u3_noun cor) case c3__ux: return _parse_ux(txt); + case c3__uv: + return _parse_uv(txt); + // %ta is used once in link.hoon. don't bother. case c3__tas: diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index b1e843b838..d2bbd12453 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -1434,6 +1434,143 @@ _test_sift_ux(void) return ret_i; } +static inline c3_i +_uv_good(c3_d num_d, const c3_c* num_c) +{ + u3_weak out; + + out = u3s_sift_uv_bytes(strlen(num_c), (c3_y*)num_c); + + if ( c3y == u3a_is_cat(out) ) { + if ( num_d != out ) { + fprintf(stderr, "sift_uv: %s wrong; expected 0x%llx: actual 0x%x\r\n", num_c, num_d, out); + return 0; + } + return 1; + } + + else { + if ( u3_none == out ) { + fprintf(stderr, "sift_uv: %s fail; expected 0x%llx\r\n", num_c, num_d); + return 1; + } + + c3_d out_d = u3r_chub(0, out); + + if ( num_d != out_d ) { + fprintf(stderr, "sift_uv: %s wrong; expected 0x%llx: actual 0x%llx\r\n", num_c, num_d, out_d); + + u3z(out); + return 0; + } + u3z(out); + + return 1; + } + +} + +static inline c3_i +_uv_fail(const c3_c* num_c) +{ + u3_weak out; + if ( u3_none != (out = u3s_sift_uv_bytes(strlen(num_c), (c3_y*)num_c)) ) { + u3m_p("out", out); + fprintf(stderr, "sift_uv: %s expected fail\r\n", num_c); + u3z(out); + + return 0; + } + + + return 1; +} + +static c3_i +_test_sift_uv(void) +{ + c3_i ret_i = 1; + + + ret_i &= _uv_good(0x0, "0v0"); + ret_i &= _uv_good(0x1, "0v1"); + ret_i &= _uv_good(0x110c85, "0v12345"); + ret_i &= _uv_good(0x63a12a, "0v6789a"); + ret_i &= _uv_good(0xb635cf, "0vbcdef"); + ret_i &= _uv_good(0x108ca74, "0vghijk"); + ret_i &= _uv_good(0x15b5f19, "0vlmnop"); + ret_i &= _uv_good(0x1adf3be, "0vqrstu"); + ret_i &= _uv_good(0xa5b1bf, "0vabcdv"); + ret_i &= _uv_good(0x886110c85, "0v123.12345"); + ret_i &= _uv_good(0x88663a12a, "0v123.6789a"); + ret_i &= _uv_good(0x886b635cf, "0v123.bcdef"); + ret_i &= _uv_good(0x88708ca74, "0v123.ghijk"); + ret_i &= _uv_good(0x8875b5f19, "0v123.lmnop"); + ret_i &= _uv_good(0x887adf3be, "0v123.qrstu"); + ret_i &= _uv_good(0x887f0887f, "0v123.v123v"); + ret_i &= _uv_good(0xfffffffffffffff, "0vvv.vvvvv.vvvvv"); + + ret_i &= _uv_fail("0v"); + ret_i &= _uv_fail("v0"); + ret_i &= _uv_fail("0v01"); + ret_i &= _uv_fail("0v12.345"); + ret_i &= _uv_fail("0v12.f3456.v789"); + ret_i &= _uv_fail("0v1.3456v.v789vv"); + + { + c3_c* num_c = "0v40.00000"; + u3_weak out = u3s_sift_uv_bytes(strlen(num_c), (c3_y*)num_c); + u3_atom pro = u3qc_bex(32); + + if ( u3_none == out ) { + fprintf(stderr, "sift_uv: (bex 32) fail\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(pro, out) ) { + u3m_p("out", out); + fprintf(stderr, "sift_uv: (bex 32) wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); u3z(pro); + } + + { + c3_c* hex_c = "0x1.1234.5678.9abc.def0.1234.5678.9abc.def0"; + c3_c* num_c = "0v8.i6hb7.h6lsr.ro14d.2mf2d.bpnng"; + + u3_weak out = u3s_sift_uv_bytes(strlen(num_c), (c3_y*)num_c); + u3_weak hot = u3s_sift_ux_bytes(strlen(hex_c), (c3_y*)hex_c); + + if ( u3_none == out) { + fprintf(stderr, "sift_uv: big viz fail\r\n"); + ret_i = 0; + } + + if ( u3_none == hot ) { + fprintf(stderr, "sift_uv: big hex fail during big viz test\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(out, hot) ) { + u3m_p("hot", hot); + u3m_p("out", out); + fprintf(stderr, "sift_uv: big viz wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); + u3z(hot); + } + + return ret_i; +} + static c3_i _test_en_base16(void) { @@ -1885,6 +2022,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_sift_uv() ) { + fprintf(stderr, "test jets: sift_uv: failed\r\n"); + ret_i = 0; + } + if ( !_test_base16() ) { fprintf(stderr, "test jets: base16: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 9876d72004..930595ed8c 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -2631,6 +2631,27 @@ static inline c3_s _cs_hex_val(c3_y hex) { } } +/* _cs_viz_val: char to base-32 digit. + */ +static inline c3_s _cs_viz_val(c3_y viz) { + + if ( viz > '9' ) { + if ( viz < 'a' ) { + return -1; + } + // viz >= 'a' + else { + return (viz - 'a') + 10; + } + } + + // viz <= '9' + else { + return viz - '0'; + } + +} + /* +yelp */ static inline c3_o _cs_yelp_mp(mpz_t yer_mp) @@ -3497,4 +3518,145 @@ u3s_sift_ux(u3_noun a) return u3s_sift_ux_bytes(len_w, byt_y); } +/* u3s_sift_uv_bytes: parse @uv impl. + */ +u3_weak +u3s_sift_uv_bytes(c3_w len_w, c3_y* byt_y) +{ + + PFIXD('0', 'v'); + + // Parse 0v0 + // + if ( *byt_y == '0' ) { + if ( len_w > 1 ) { + return u3_none; + } + else { + return (u3_noun)0; + } + } + + // Parse a 64-bit viz number + // + c3_d val_d = 0; + c3_s dit_s = 0; + + // Parse the head + // + for ( size_t i = 0; i < 5; i++ ) { + + if ( ! len_w ) { + break; + } + + dit_s = _cs_viz_val(*byt_y); + + if ( dit_s < 32) { + val_d <<= 5; + val_d += dit_s; + } + else { + break; + } + + byt_y++; + len_w--; + } + + if ( !len_w ) { + return u3i_chub(val_d); + } + + // Parse a big viz + // + else { + mpz_t a_mp; + mpz_init2(a_mp, 128); + mpz_set_ui(a_mp, val_d); + + val_d = 0; + + // Parse a list of dog followed by + // a quintuple of viz digits + // + size_t dit = 0; + + while ( len_w ) { + + if ( ! _(_cs_dot(&len_w, &byt_y)) ) { + goto sift_uv_fail; + } + + for ( size_t i = 0; i < 5; i++ ) { + + if ( ! len_w ) { + goto sift_uv_fail; + } + + dit_s = _cs_viz_val(*byt_y); + + if ( dit_s < 32) { + val_d <<= 5; + val_d += dit_s; + } + else { + goto sift_uv_fail; + } + + byt_y++; + len_w--; + dit++; + + // Read 12 digits + // + if ( dit == 12 ) { + mpz_mul_2exp(a_mp, a_mp, dit*5); + mpz_add_ui(a_mp, a_mp, val_d); + + val_d = 0; + dit = 0; + } + } + + } + + if ( dit ) { + mpz_mul_2exp(a_mp, a_mp, dit*5); + mpz_add_ui(a_mp, a_mp, val_d); + } + + if ( len_w ) { +sift_uv_fail: + mpz_clear(a_mp); + return u3_none; + } + + return u3i_mp(a_mp); + } + +} + +/* u3s_sift_uv: parse @uv. + */ +u3_weak +u3s_sift_uv(u3_noun a) +{ + + c3_w len_w = u3r_met(3, a); + c3_y* byt_y; + + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + else{ + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + return u3s_sift_uv_bytes(len_w, byt_y); +} + #undef PFIXD diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index a7b3112052..6de472e180 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -209,6 +209,16 @@ u3_weak u3s_sift_ui(u3_atom a); + /* u3s_sift_uv_bytes: parse @uv. + */ + u3_weak + u3s_sift_uv_bytes(c3_w len_w, c3_y* byt_y); + + /* u3s_sift_uv: parse @uv. + */ + u3_weak + u3s_sift_uv(u3_atom a); + /* u3s_sift_ux_bytes: parse @ux. */ u3_weak From 739cf224cd09ffa6568fd21fd13d634378d86931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 11:27:18 +0800 Subject: [PATCH 12/16] u3: adds %uw parsing --- pkg/noun/jets/e/slaw.c | 15 +++ pkg/noun/jets_tests.c | 153 +++++++++++++++++++++++++++++++ pkg/noun/serial.c | 204 +++++++++++++++++++++++++++++++++++++++++ pkg/noun/serial.h | 19 +++- 4 files changed, 387 insertions(+), 4 deletions(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index 180a09e70f..7e27ccdc2f 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -80,6 +80,18 @@ _parse_uv(u3_noun a) return u3nc(u3_nul, pro); } +static inline u3_noun +_parse_uw(u3_noun a) +{ + u3_weak pro; + + if ( u3_none == (pro = u3s_sift_uw(u3x_atom(a))) ) { + return u3_nul; + } + + return u3nc(u3_nul, pro); +} + u3_noun _parse_tas(u3_noun txt) { // For any symbol which matches, txt will return itself as a @@ -137,6 +149,9 @@ u3we_slaw(u3_noun cor) case c3__uv: return _parse_uv(txt); + case c3__uw: + return _parse_uw(txt); + // %ta is used once in link.hoon. don't bother. case c3__tas: diff --git a/pkg/noun/jets_tests.c b/pkg/noun/jets_tests.c index d2bbd12453..9401bf18a0 100644 --- a/pkg/noun/jets_tests.c +++ b/pkg/noun/jets_tests.c @@ -1571,6 +1571,154 @@ _test_sift_uv(void) return ret_i; } +static inline c3_i +_uw_good(c3_d num_d, const c3_c* num_c) +{ + u3_weak out; + + out = u3s_sift_uw_bytes(strlen(num_c), (c3_y*)num_c); + + if ( c3y == u3a_is_cat(out) ) { + if ( num_d != out ) { + fprintf(stderr, "sift_uw: %s wrong; expected 0x%llx: actual 0x%x\r\n", num_c, num_d, out); + return 0; + } + + return 1; + } + + else { + + if ( u3_none == out ) { + fprintf(stderr, "sift_uw: %s fail; expected 0x%llx\r\n", num_c, num_d); + return 0; + } + + c3_d out_d = u3r_chub(0, out); + + if ( num_d != out_d ) { + fprintf(stderr, "sift_uw: %s wrong; expected 0x%llx: actual 0x%llx\r\n", num_c, num_d, out_d); + + u3z(out); + return 0; + } + + u3z(out); + return 1; + } +} + +static inline c3_i +_uw_fail(const c3_c* num_c) +{ + u3_weak out; + if ( u3_none != (out = u3s_sift_uw_bytes(strlen(num_c), (c3_y*)num_c)) ) { + u3m_p("out", out); + fprintf(stderr, "sift_uw: %s expected fail\r\n", num_c); + u3z(out); + + return 0; + } + + + return 1; +} + +static c3_i +_test_sift_uw(void) +{ + c3_i ret_i = 1; + + + ret_i &= _uw_good(0x0, "0w0"); + ret_i &= _uw_good(0x1, "0w1"); + ret_i &= _uw_good(0x1083105, "0w12345"); + ret_i &= _uw_good(0x61c824a, "0w6789a"); + ret_i &= _uw_good(0xb30d38f, "0wbcdef"); + ret_i &= _uw_good(0x104524d4, "0wghijk"); + ret_i &= _uw_good(0x15597619, "0wlmnop"); + ret_i &= _uw_good(0x1a6dc75e, "0wqrstu"); + ret_i &= _uw_good(0x1f8218a3, "0wvwxyz"); + ret_i &= _uw_good(0x249669e8, "0wABCDE"); + ret_i &= _uw_good(0x29aabb2d, "0wFGHIJ"); + ret_i &= _uw_good(0x2ebf0c72, "0wKLMNO"); + ret_i &= _uw_good(0x33d35db7, "0wPQRST"); + ret_i &= _uw_good(0x38e7aefc, "0wUVWXY"); + ret_i &= _uw_good(0x3dffe24a, "0wZ~-9a"); + ret_i &= _uw_good(0x3efbefbe, "0w-----"); + ret_i &= _uw_good(0x3fffffff, "0w~~~~~"); + ret_i &= _uw_good(0x3effeffe, "0w-~-~-"); + ret_i &= _uw_good(0x108310a2cc34e,"0w1234.abcde"); + ret_i &= _uw_good(0x3d04524d45565d8, "0wfghij.klmno"); + ret_i &= _uw_good(0x65a6dc75e7e0862, "0wpqrst.uvwxy"); + ret_i &= _uw_good(0x8e49669e8a6aaec, "0wzABCD.EFGHI"); + ret_i &= _uw_good(0xb6ebf0c72cf4d76, "0wJKLMN.OPQRS"); + ret_i &= _uw_good(0xdf8e7aefcf41083, "0wTUVWX.YZ123"); + ret_i &= _uw_good(0x105187209fbffbe, "0w45678.9-~--"); + ret_i &= _uw_good(0xffffffffffffffff, "0wf.~~~~~.~~~~~"); + + ret_i &= _uw_fail("w0"); + ret_i &= _uw_fail("0w01"); + ret_i &= _uw_fail("0w12.345"); + ret_i &= _uw_fail("0w1~.f3456.-789"); + ret_i &= _uw_fail("0w1.3456-.-789~-"); + ret_i &= _uw_fail("0wwwwww.wwwwww"); + + { + c3_c* num_c = "0w4.00000"; + u3_weak out = u3s_sift_uw_bytes(strlen(num_c), (c3_y*)num_c); + u3_atom pro = u3qc_bex(32); + + if ( u3_none == out ) { + fprintf(stderr, "sift_uw: (bex 32) fail\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(pro, out) ) { + u3m_p("out", out); + fprintf(stderr, "sift_uw: (bex 32) wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); u3z(pro); + } + + { + + c3_c* num_c = "0w9.37a8e.elucg.lcgpl.~--38.alllz.-----.~~~~~"; + c3_c* hex_c = "0x24.31ca.20e3.9578.c415.3106.55ff.ef83.20a5.5556.3fbe.fbef.bfff.ffff"; + + u3_weak hot = u3s_sift_ux_bytes(strlen(hex_c), (c3_y*)hex_c); + u3_atom out = u3s_sift_uw_bytes(strlen(num_c), (c3_y*)num_c); + + if ( u3_none == out) { + fprintf(stderr, "sift_uw: big wiz fail\r\n"); + ret_i = 0; + } + + if ( u3_none == hot ) { + fprintf(stderr, "sift_uw: big hex fail during big wiz test\r\n"); + ret_i = 0; + } + + else { + if ( c3n == u3r_sing(hot, out) ) { + u3m_p("out", out); + u3m_p("hot", hot); + fprintf(stderr, "sift_uw: big wiz wrong\r\n"); + ret_i = 0; + } + } + + u3z(out); + u3z(hot); + } + + return ret_i; +} + static c3_i _test_en_base16(void) { @@ -2027,6 +2175,11 @@ _test_jets(void) ret_i = 0; } + if ( !_test_sift_uw() ) { + fprintf(stderr, "test jets: sift_uw: failed\r\n"); + ret_i = 0; + } + if ( !_test_base16() ) { fprintf(stderr, "test jets: base16: failed\r\n"); ret_i = 0; diff --git a/pkg/noun/serial.c b/pkg/noun/serial.c index 930595ed8c..f6789372a3 100644 --- a/pkg/noun/serial.c +++ b/pkg/noun/serial.c @@ -2652,6 +2652,65 @@ static inline c3_s _cs_viz_val(c3_y viz) { } +/* _cs_wiz_val: char to base-64 digit. + */ +static inline c3_s _cs_wiz_val(c3_y wiz) { + + if ( wiz > '9' ) { + + if ( wiz < 'A' ) { + return -1; + } + + // wiz >= 'A' + else { + + if ( wiz > 'Z' ) { + + if ( wiz < 'a' ) { + return -1; + } + + // wiz >= 'a' + else { + + if ( wiz > 'z' ) { + + if ( wiz == '~' ) { + return 63; + } + + else { + return -1; + } + } + // 'a' <= wiz <= 'z' + else { + return wiz - 'a' + 10; + } + + } + } + + // 'A' <= wiz <= 'Z' + else { + return wiz - 'A' + 36; + } + } + + } + // wiz <= '9' + else { + if ( wiz == '-' ) { + return 62; + } + else { + return wiz - '0'; + } + } +} + + /* +yelp */ static inline c3_o _cs_yelp_mp(mpz_t yer_mp) @@ -3659,4 +3718,149 @@ u3s_sift_uv(u3_noun a) return u3s_sift_uv_bytes(len_w, byt_y); } +/* u3s_sift_uw_bytes: parse @uw impl. + */ +u3_weak +u3s_sift_uw_bytes(c3_w len_w, c3_y* byt_y) +{ + + if ( ! len_w ) { + return u3_none; + } + + // Parse the 0w prefix + // + PFIXD('0', 'w'); + + if ( ! len_w ) { + return u3_none; + } + + // Parse 0w0 + // + if ( *byt_y == '0' ) { + if ( len_w > 1 ) { + return u3_none; + } + else { + return (u3_noun)0; + } + } + + c3_d val_d = 0; + c3_s dit_s = 0; + + // Parse the head + // + for ( size_t i = 0; i < 5; i++ ) { + + if ( ! len_w ) { + break; + } + + dit_s = _cs_wiz_val(*byt_y); + + if ( dit_s < 64) { + val_d <<= 6; + val_d += dit_s; + } + else { + break; + } + + byt_y++; + len_w--; + } + + if ( !len_w ) { + return u3i_chub(val_d); + } + + // Parse the tail + // + else { + mpz_t a_mp; + mpz_init2(a_mp, 128); + mpz_set_ui(a_mp, val_d); + + val_d = 0; + + size_t dit = 0; + + while ( len_w ) { + + if ( ! _(_cs_dot(&len_w, &byt_y)) ) { + goto sift_uw_fail; + } + + for ( size_t i = 0; i < 5; i++ ) { + + if ( ! len_w ) { + goto sift_uw_fail; + } + + + dit_s = _cs_wiz_val(*byt_y); + + if ( dit_s < 64) { + val_d <<= 6; + val_d += dit_s; + } + else { + goto sift_uw_fail; + } + + byt_y++; + len_w--; + dit++; + + if ( dit == 10) { + mpz_mul_2exp(a_mp, a_mp, dit*6); + mpz_add_ui(a_mp, a_mp, val_d); + + val_d = 0; + dit = 0; + } + } + + } + + if ( dit ) { + mpz_mul_2exp(a_mp, a_mp, dit*6); + mpz_add_ui(a_mp, a_mp, val_d); + } + + if ( len_w ) { +sift_uw_fail: + mpz_clear(a_mp); + return u3_none; + } + + return u3i_mp(a_mp); + } + +} + +/* u3s_sift_uw: parse @uw. + */ +u3_weak +u3s_sift_uw(u3_noun a) +{ + + c3_w len_w = u3r_met(3, a); + c3_y* byt_y; + + // XX assumes little-endian + // + if ( c3y == u3a_is_cat(a) ) { + byt_y = (c3_y*)&a; + } + else{ + u3a_atom* vat_u = u3a_to_ptr(a); + byt_y = (c3_y*)vat_u->buf_w; + } + + return u3s_sift_uw_bytes(len_w, byt_y); +} + #undef PFIXD diff --git a/pkg/noun/serial.h b/pkg/noun/serial.h index 6de472e180..b38938c4bb 100644 --- a/pkg/noun/serial.h +++ b/pkg/noun/serial.h @@ -209,6 +209,16 @@ u3_weak u3s_sift_ui(u3_atom a); + /* u3s_sift_ux_bytes: parse @ux. + */ + u3_weak + u3s_sift_ux_bytes(c3_w len_w, c3_y* byt_y); + + /* u3s_sift_ux: parse @ux. + */ + u3_weak + u3s_sift_ux(u3_atom a); + /* u3s_sift_uv_bytes: parse @uv. */ u3_weak @@ -219,14 +229,15 @@ u3_weak u3s_sift_uv(u3_atom a); - /* u3s_sift_ux_bytes: parse @ux. + /* u3s_sift_uw_bytes: parse @uw. */ u3_weak - u3s_sift_ux_bytes(c3_w len_w, c3_y* byt_y); + u3s_sift_uw_bytes(c3_w len_w, c3_y* byt_y); - /* u3s_sift_ux: parse @ux. + /* u3s_sift_uw: parse @uw. */ u3_weak - u3s_sift_ux(u3_atom a); + u3s_sift_uw(u3_atom a); + #endif /* ifndef U3_SERIAL_H */ From aa79a639faa5721328cb79a93ade27d8762d35ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Thu, 25 May 2023 11:28:43 +0800 Subject: [PATCH 13/16] jets: refactors the +slaw jet --- pkg/noun/jets/e/slaw.c | 158 ++++++++++++----------------------------- 1 file changed, 44 insertions(+), 114 deletions(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index 7e27ccdc2f..13de3b37e7 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -8,90 +8,6 @@ #include -static inline u3_noun -_parse_da(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_da(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - -static inline u3_noun -_parse_p(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_p(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - -static inline u3_noun -_parse_ud(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_ud(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - -static inline u3_noun -_parse_ui(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_ui(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - -static inline u3_noun -_parse_ux(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_ux(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - -static inline u3_noun -_parse_uv(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_uv(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - -static inline u3_noun -_parse_uw(u3_noun a) -{ - u3_weak pro; - - if ( u3_none == (pro = u3s_sift_uw(u3x_atom(a))) ) { - return u3_nul; - } - - return u3nc(u3_nul, pro); -} - u3_noun _parse_tas(u3_noun txt) { // For any symbol which matches, txt will return itself as a @@ -102,62 +18,76 @@ _parse_tas(u3_noun txt) { c3_c* cur = c; if (!islower(cur[0])) { u3a_free(c); - return 0; + return u3_none; } cur++; while (cur[0] != 0) { if (!(islower(cur[0]) || isdigit(cur[0]) || cur[0] == '-')) { u3a_free(c); - return 0; + return u3_none; } cur++; } u3a_free(c); - return u3nc(0, u3k(txt)); + return u3k(txt); } u3_noun -u3we_slaw(u3_noun cor) +u3qe_slaw(u3_atom a, u3_atom b) { - u3_noun mod; - u3_noun txt; + u3_noun res; - if (c3n == u3r_mean(cor, u3x_sam_2, &mod, - u3x_sam_3, &txt, 0)) { - return u3m_bail(c3__exit); - } + switch(a) { - switch (mod) { - case c3__da: - return _parse_da(txt); + case c3__da: res = u3s_sift_da(b); break; - case 'p': - return _parse_p(txt); + case 'p': res = u3s_sift_p(b); break; - case c3__ud: - return _parse_ud(txt); + case c3__ud: res = u3s_sift_ud(b); break; + case c3__ui: res = u3s_sift_ui(b); break; + case c3__uv: res = u3s_sift_uv(b); break; + case c3__uw: res = u3s_sift_uw(b); break; + case c3__ux: res = u3s_sift_ux(b); break; - case c3__ui: - return _parse_ui(txt); + // %ta is used once in link.hoon. don't bother. - case c3__ux: - return _parse_ux(txt); + case c3__tas: { + res = _parse_tas(b); + if ( res == u3_none ) { + return u3_nul; + } + } - case c3__uv: - return _parse_uv(txt); - case c3__uw: - return _parse_uw(txt); + default: return u3_none; + } - // %ta is used once in link.hoon. don't bother. + // The u3s_sift functions + // signal parsing failure by returning u3_none. + // This does not mean the input was wrong - the jet + // could simply choose not to handle certain cases. + // + if ( res == u3_none ) { + return u3_none; + } - case c3__tas: - return _parse_tas(txt); + return u3nc(u3_nul, res); - default: - return u3_none; +} + +u3_noun +u3we_slaw(u3_noun cor) +{ + u3_noun a; + u3_noun b; + + if (c3n == u3r_mean(cor, u3x_sam_2, &a, + u3x_sam_3, &b, 0)) { + return u3m_bail(c3__exit); } + + return u3qe_slaw(u3x_atom(a), u3x_atom(b)); } From 75919304de2e43d42ae14d5cd58c8efddea79074 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Fri, 26 May 2023 10:12:09 +0800 Subject: [PATCH 14/16] u3: refactors the slaw %tas jet to be allocation-free --- pkg/noun/jets/e/slaw.c | 52 +++++++++++++++++++++++++----------------- 1 file changed, 31 insertions(+), 21 deletions(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index 13de3b37e7..e9bcfb6ae2 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -9,30 +9,41 @@ #include 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 u3_none; - } - cur++; +_parse_tas(u3_noun txt) +{ + c3_w len_w = u3r_met(3, txt); - while (cur[0] != 0) { - if (!(islower(cur[0]) || isdigit(cur[0]) || cur[0] == '-')) { - u3a_free(c); - return u3_none; + if ( !len_w ) { + return u3_none; } - cur++; - } + // For any symbol which matches, txt will return itself as a + // value. Therefore, this is mostly checking validity. + // + + c3_w i_w; + c3_c c; + + // First character must represent a lowercase letter + // + c = u3r_byte(0, txt); + + if (!islower(c)) { + return u3_none; + } + + for ( i_w = 1; i_w < len_w; i_w++ ) { + + // XX Is this future-proof? + // + c = (c3_y) u3r_byte(i_w, txt); - u3a_free(c); - return u3k(txt); + if (!(islower(c) || isdigit(c) || c == '-')) { + return u3_none; + } + } + + return u3k(txt); } u3_noun @@ -75,7 +86,6 @@ u3qe_slaw(u3_atom a, u3_atom b) } return u3nc(u3_nul, res); - } u3_noun From 201f5d716987eff595fe18536d973ffccf4547b9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Fri, 26 May 2023 10:12:46 +0800 Subject: [PATCH 15/16] u3: refactors the +scow jet to the +scot implementation; enables the +scow jet --- pkg/noun/jets/e/scow.c | 234 ++--------------------------------------- pkg/noun/jets/e/slaw.c | 2 - pkg/noun/jets/tree.c | 7 +- 3 files changed, 9 insertions(+), 234 deletions(-) diff --git a/pkg/noun/jets/e/scow.c b/pkg/noun/jets/e/scow.c index 986dc412fe..eaecc5bdf5 100644 --- a/pkg/noun/jets/e/scow.c +++ b/pkg/noun/jets/e/scow.c @@ -8,238 +8,18 @@ #include -static -c3_y to_digit(c3_y 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(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_lth(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); -} - u3_atom u3qe_scow(u3_atom a, u3_atom b) { - switch (a) { - // XX disabled due to memory corruption - // rewrite for +scot jet and test there - // - // case c3__da: return _print_da(cor, atom); - // case 'p': return _print_p(cor, atom); + u3_weak dat = u3qe_scot(a, b); + u3_weak pro = u3_none; - default: { - u3_weak dat = u3qe_scot(a, b); - u3_weak pro = u3_none; - - if ( u3_none != dat ) { - pro = u3qc_rip(3, 1, dat); - u3z(dat); - } - - return pro; - } + if ( u3_none != dat ) { + pro = u3qc_rip(3, 1, dat); + u3z(dat); } + + return pro; } u3_noun diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index e9bcfb6ae2..6e45937cc1 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -34,8 +34,6 @@ _parse_tas(u3_noun txt) for ( i_w = 1; i_w < len_w; i_w++ ) { - // XX Is this future-proof? - // c = (c3_y) u3r_byte(i_w, txt); if (!(islower(c) || isdigit(c) || c == '-')) { diff --git a/pkg/noun/jets/tree.c b/pkg/noun/jets/tree.c index cf1ed62c03..34c9960909 100644 --- a/pkg/noun/jets/tree.c +++ b/pkg/noun/jets/tree.c @@ -2212,12 +2212,9 @@ static u3j_core _139_qua_d[] = { "mole", 7, _140_qua_mole_a, 0, no_hashes }, { "mule", 7, _140_qua_mule_a, 0, no_hashes }, - // XX disabled, implicated in memory corruption - // write tests and re-enable - // { "scot", 7, _140_qua_scot_a, 0, no_hashes }, - // { "scow", 7, _140_qua_scow_a, 0, no_hashes }, - { "slaw", 7, _140_qua_slaw_a, 0, no_hashes }, + { "scow", 7, _140_qua_scow_a, 0, no_hashes }, + { "slaw", 7, _140_qua_slaw_a, 0, no_hashes }, {} }; From cc77c5c321fb4b4860e89cc58e0b3109f0904497 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miko=C5=82aj=20Paraniak?= Date: Fri, 26 May 2023 10:53:06 +0800 Subject: [PATCH 16/16] u3: orders the %u auras in +slaw according to basis size --- pkg/noun/jets/e/slaw.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/noun/jets/e/slaw.c b/pkg/noun/jets/e/slaw.c index 6e45937cc1..c2c1d63411 100644 --- a/pkg/noun/jets/e/slaw.c +++ b/pkg/noun/jets/e/slaw.c @@ -57,9 +57,9 @@ u3qe_slaw(u3_atom a, u3_atom b) case c3__ud: res = u3s_sift_ud(b); break; case c3__ui: res = u3s_sift_ui(b); break; + case c3__ux: res = u3s_sift_ux(b); break; case c3__uv: res = u3s_sift_uv(b); break; case c3__uw: res = u3s_sift_uw(b); break; - case c3__ux: res = u3s_sift_ux(b); break; // %ta is used once in link.hoon. don't bother.