mirror of
https://github.com/urbit/shrub.git
synced 2025-01-05 19:46:50 +03:00
Merge pull request #1741 from urbit/reunity
u3: unifies unifying-equality unification
This commit is contained in:
commit
2f739c0edd
@ -387,6 +387,11 @@
|
||||
c3_w
|
||||
u3a_use(u3_noun som);
|
||||
|
||||
/* u3a_wed(): unify noun references.
|
||||
*/
|
||||
void
|
||||
u3a_wed(u3_noun* a, u3_noun* b);
|
||||
|
||||
/* u3a_luse(): check refcount sanity.
|
||||
*/
|
||||
void
|
||||
|
@ -124,13 +124,6 @@
|
||||
u3_weak
|
||||
u3h_git(u3p(u3h_root) har_p, u3_noun key);
|
||||
|
||||
/* u3h_gut(): read from hashtable, unifying key nouns.
|
||||
**
|
||||
** `key` is RETAINED.
|
||||
*/
|
||||
u3_weak
|
||||
u3h_gut(u3p(u3h_root) har_p, u3_noun key);
|
||||
|
||||
/* u3h_trim_to(): trim to n key-value pairs
|
||||
*/
|
||||
void
|
||||
|
@ -134,29 +134,14 @@
|
||||
u3_noun s,
|
||||
u3_noun b);
|
||||
|
||||
/* u3r_sing():
|
||||
/* u3r_sing(): noun value equality.
|
||||
**
|
||||
** Yes iff (a) and (b) are the same noun.
|
||||
** Unifies noun pointers on inner roads.
|
||||
*/
|
||||
c3_o
|
||||
u3r_sing(u3_noun a, u3_noun b);
|
||||
|
||||
/* u3rz_sing(): transferring u3r_sing
|
||||
*/
|
||||
c3_o
|
||||
u3rz_sing(u3_noun a, u3_noun b);
|
||||
|
||||
/* u3r_sung(): yes iff (a) and (b) are the same noun, unifying equals.
|
||||
**
|
||||
** Make sure you have no live, uncounted pointers to any noun
|
||||
** within (a) or (b)!
|
||||
*/
|
||||
c3_o
|
||||
u3r_sung(u3_noun a, u3_noun b);
|
||||
|
||||
/* u3r_sing_c):
|
||||
**
|
||||
** Yes iff (b) is the same noun as the C string [a].
|
||||
/* u3r_sing_c(): cord/C-string value equivalence.
|
||||
*/
|
||||
c3_o
|
||||
u3r_sing_c(const c3_c* a_c,
|
||||
|
@ -1492,6 +1492,103 @@ u3a_use(u3_noun som)
|
||||
}
|
||||
}
|
||||
|
||||
/* _ca_wed_who(): unify [a] and [b] on [rod_u], keeping the senior
|
||||
**
|
||||
** NB: this leaks a reference when it unifies in a senior road
|
||||
*/
|
||||
static c3_o
|
||||
_ca_wed_who(u3a_road* rod_u, u3_noun* a, u3_noun* b)
|
||||
{
|
||||
c3_t asr_t = ( c3y == u3a_is_senior(rod_u, *a) );
|
||||
c3_t bsr_t = ( c3y == u3a_is_senior(rod_u, *b) );
|
||||
c3_t nor_t = ( c3y == u3a_is_north(rod_u) );
|
||||
c3_t own_t = ( rod_u == u3R );
|
||||
|
||||
// both are on [rod_u]; gain a reference to whichever we keep
|
||||
//
|
||||
if ( !asr_t && !bsr_t ) {
|
||||
// keep [a]; it's deeper in the heap
|
||||
//
|
||||
// (N && >) || (S && <)
|
||||
//
|
||||
if ( (*a > *b) == nor_t ) {
|
||||
_me_gain_use(*a);
|
||||
if ( own_t ) { u3z(*b); }
|
||||
*b = *a;
|
||||
}
|
||||
// keep [b]; it's deeper in the heap
|
||||
//
|
||||
else {
|
||||
_me_gain_use(*b);
|
||||
if ( own_t ) { u3z(*a); }
|
||||
*a = *b;
|
||||
}
|
||||
|
||||
return c3y;
|
||||
}
|
||||
// keep [a]; it's senior
|
||||
//
|
||||
else if ( asr_t && !bsr_t ) {
|
||||
if ( own_t ) { u3z(*b); }
|
||||
*b = *a;
|
||||
return c3y;
|
||||
}
|
||||
// keep [b]; it's senior
|
||||
//
|
||||
else if ( !asr_t && bsr_t ) {
|
||||
if ( own_t ) { u3z(*a); }
|
||||
*a = *b;
|
||||
return c3y;
|
||||
}
|
||||
|
||||
// both [a] and [b] are senior; we can't unify on [rod_u]
|
||||
//
|
||||
return c3n;
|
||||
}
|
||||
|
||||
/* u3a_wed(): unify noun references.
|
||||
*/
|
||||
void
|
||||
u3a_wed(u3_noun* a, u3_noun* b)
|
||||
{
|
||||
if ( *a != *b ) {
|
||||
u3_road* rod_u = u3R;
|
||||
|
||||
// while not at home, attempt to unify
|
||||
//
|
||||
// we try to unify on our road, and retry on senior roads
|
||||
// until we succeed or reach the home road.
|
||||
//
|
||||
// we can't perform this kind of butchery on the home road,
|
||||
// where asynchronous things can allocate.
|
||||
// (XX anything besides u3t_samp?)
|
||||
//
|
||||
// when unifying on a higher road, we can't free nouns,
|
||||
// because we can't track junior nouns that point into
|
||||
// that road.
|
||||
//
|
||||
// this is just an implementation issue -- we could set use
|
||||
// counts to 0 without actually freeing. but the allocator
|
||||
// would have to be actually designed for this.
|
||||
// (alternately, we could keep a deferred free-list)
|
||||
//
|
||||
// not freeing may generate spurious leaks, so we disable
|
||||
// senior unification when debugging memory. this will
|
||||
// cause a very slow boot process as the compiler compiles
|
||||
// itself, constantly running into duplicates.
|
||||
//
|
||||
while ( (rod_u != &u3H->rod_u) &&
|
||||
(c3n == _ca_wed_who(rod_u, a, b)) )
|
||||
{
|
||||
#ifdef U3_MEMORY_DEBUG
|
||||
break;
|
||||
#else
|
||||
rod_u = u3to(u3_road, rod_u->par_p);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u3a_luse(): check refcount sanity.
|
||||
*/
|
||||
void
|
||||
|
@ -626,102 +626,6 @@ u3h_get(u3p(u3h_root) har_p, u3_noun key)
|
||||
return pro;
|
||||
}
|
||||
|
||||
/* _ch_buck_gut(): read in bucket, unifying key nouns.
|
||||
*/
|
||||
static u3_weak
|
||||
_ch_buck_gut(u3h_buck* hab_u, u3_noun key)
|
||||
{
|
||||
c3_w i_w;
|
||||
|
||||
for ( i_w = 0; i_w < hab_u->len_w; i_w++ ) {
|
||||
u3_noun kev = u3h_slot_to_noun(hab_u->sot_w[i_w]);
|
||||
if ( _(u3r_sung(key, u3h(kev))) ) {
|
||||
return u3t(kev);
|
||||
}
|
||||
}
|
||||
return u3_none;
|
||||
}
|
||||
|
||||
/* _ch_node_gut(): read in node, unifying key nouns.
|
||||
*/
|
||||
static u3_weak
|
||||
_ch_node_gut(u3h_node* han_u, c3_w lef_w, c3_w rem_w, u3_noun key)
|
||||
{
|
||||
c3_w bit_w, map_w;
|
||||
|
||||
lef_w -= 5;
|
||||
bit_w = (rem_w >> lef_w);
|
||||
rem_w = CUT_END(rem_w, lef_w);
|
||||
map_w = han_u->map_w;
|
||||
|
||||
if ( !BIT_SET(map_w, bit_w) ) {
|
||||
return u3_none;
|
||||
}
|
||||
else {
|
||||
c3_w inx_w = _ch_popcount(CUT_END(map_w, bit_w));
|
||||
c3_w sot_w = han_u->sot_w[inx_w];
|
||||
|
||||
if ( _(u3h_slot_is_noun(sot_w)) ) {
|
||||
u3_noun kev = u3h_slot_to_noun(sot_w);
|
||||
|
||||
if ( _(u3r_sung(key, u3h(kev))) ) {
|
||||
return u3t(kev);
|
||||
}
|
||||
else {
|
||||
return u3_none;
|
||||
}
|
||||
}
|
||||
else {
|
||||
void* hav_v = u3h_slot_to_node(sot_w);
|
||||
|
||||
if ( 0 == lef_w ) {
|
||||
return _ch_buck_gut(hav_v, key);
|
||||
}
|
||||
else return _ch_node_gut(hav_v, lef_w, rem_w, key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* u3h_gut(): read from hashtable, unifying key nouns.
|
||||
**
|
||||
** `key` is RETAINED.
|
||||
*/
|
||||
u3_weak
|
||||
u3h_gut(u3p(u3h_root) har_p, u3_noun key)
|
||||
{
|
||||
u3h_root* har_u = u3to(u3h_root, har_p);
|
||||
c3_w mug_w = u3r_mug(key);
|
||||
c3_w inx_w = (mug_w >> 25);
|
||||
c3_w rem_w = CUT_END(mug_w, 25);
|
||||
c3_w sot_w = har_u->sot_w[inx_w];
|
||||
|
||||
if ( _(u3h_slot_is_null(sot_w)) ) {
|
||||
return u3_none;
|
||||
}
|
||||
else if ( _(u3h_slot_is_noun(sot_w)) ) {
|
||||
u3_noun kev = u3h_slot_to_noun(sot_w);
|
||||
|
||||
if ( _(u3r_sung(key, u3h(kev))) ) {
|
||||
har_u->sot_w[inx_w] = u3h_noun_be_warm(sot_w);
|
||||
return u3k(u3t(kev));
|
||||
}
|
||||
else {
|
||||
return u3_none;
|
||||
}
|
||||
}
|
||||
else {
|
||||
u3h_node* han_u = u3h_slot_to_node(sot_w);
|
||||
u3_weak pro = _ch_node_gut(han_u, 25, rem_w, key);
|
||||
|
||||
if ( u3_none == pro ) {
|
||||
return u3_none;
|
||||
}
|
||||
else {
|
||||
return u3k(pro);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* _ch_free_buck(): free bucket
|
||||
*/
|
||||
static void
|
||||
|
@ -486,7 +486,7 @@ _cj_find_cold(u3_noun bat)
|
||||
u3a_road* rod_u = u3R;
|
||||
|
||||
while ( 1 ) {
|
||||
u3_weak bar = u3h_gut(rod_u->jed.cod_p, bat);
|
||||
u3_weak bar = u3h_get(rod_u->jed.cod_p, bat);
|
||||
|
||||
if ( u3_none != bar ) {
|
||||
return bar;
|
||||
@ -508,7 +508,7 @@ _cj_find_warm(u3_noun loc)
|
||||
u3a_road* rod_u = u3R;
|
||||
|
||||
while ( 1 ) {
|
||||
u3_weak ank = u3h_gut(rod_u->jed.war_p, loc);
|
||||
u3_weak ank = u3h_get(rod_u->jed.war_p, loc);
|
||||
|
||||
if ( u3_none != ank ) {
|
||||
return ank;
|
||||
|
@ -744,9 +744,9 @@ u3m_leap(c3_w pad_w)
|
||||
|
||||
rod_u = _pave_south(u3a_into(bot_p), c3_wiseof(u3a_road), len_w);
|
||||
#if 0
|
||||
u3l_log("leap: from north %p (cap %x), to south %p\r\n",
|
||||
fprintf(stderr, "leap: from north %p (cap 0x%x), to south %p\r\n",
|
||||
u3R,
|
||||
u3R->cap_p + len_p,
|
||||
u3R->cap_p + len_w,
|
||||
rod_u);
|
||||
#endif
|
||||
}
|
||||
@ -756,9 +756,9 @@ u3m_leap(c3_w pad_w)
|
||||
|
||||
rod_u = _pave_north(u3a_into(bot_p), c3_wiseof(u3a_road), len_w);
|
||||
#if 0
|
||||
u3l_log("leap: from north %p (cap %p), to south %p\r\n",
|
||||
fprintf(stderr, "leap: from south %p (cap 0x%x), to north %p\r\n",
|
||||
u3R,
|
||||
u3R->cap_p - len_p,
|
||||
u3R->cap_p - len_w,
|
||||
rod_u);
|
||||
#endif
|
||||
}
|
||||
@ -791,13 +791,13 @@ u3m_fall()
|
||||
c3_assert(0 != u3R->par_p);
|
||||
|
||||
#if 0
|
||||
u3l_log("fall: from %s %p, to %s %p (cap %p, was %p)\r\n",
|
||||
fprintf(stderr, "fall: from %s %p, to %s %p (cap 0x%x, was 0x%x)\r\n",
|
||||
_(u3a_is_north(u3R)) ? "north" : "south",
|
||||
u3R,
|
||||
_(u3a_is_north(u3R)) ? "north" : "south",
|
||||
_(u3a_is_north(u3to(u3_road, u3R->par_p))) ? "north" : "south",
|
||||
u3to(u3_road, u3R->par_p),
|
||||
u3R->hat_w,
|
||||
u3R->rut_w);
|
||||
u3R->hat_p,
|
||||
u3R->rut_p);
|
||||
#endif
|
||||
|
||||
u3to(u3_road, u3R->par_p)->pro.nox_d += u3R->pro.nox_d;
|
||||
|
@ -220,59 +220,6 @@ u3r_mean(u3_noun som, ...)
|
||||
return ret_o;
|
||||
}
|
||||
|
||||
/* _sang_one(): unify but leak old.
|
||||
*/
|
||||
static void
|
||||
_sang_one(u3_noun* a, u3_noun* b)
|
||||
{
|
||||
if ( *a == *b ) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
c3_o asr_o = u3a_is_senior(u3R, *a);
|
||||
c3_o bsr_o = u3a_is_senior(u3R, *b);
|
||||
|
||||
if ( _(asr_o) && _(bsr_o) ) {
|
||||
// You shouldn't have let this happen. We don't want to
|
||||
// descend down to a lower road and free there, because
|
||||
// synchronization - though this could be revisited under
|
||||
// certain circumstances.
|
||||
//
|
||||
return;
|
||||
}
|
||||
if ( _(asr_o) && !_(bsr_o) ){
|
||||
// u3z(*b);
|
||||
*b = *a;
|
||||
}
|
||||
if ( _(bsr_o) && !_(asr_o) ) {
|
||||
// u3z(*a);
|
||||
*a = *b;
|
||||
}
|
||||
if ( u3a_is_north(u3R) ) {
|
||||
if ( *a <= *b ) {
|
||||
u3k(*a);
|
||||
// u3z(*b);
|
||||
*b = *a;
|
||||
} else {
|
||||
u3k(*b);
|
||||
// u3z(*a);
|
||||
*a = *b;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( *a >= *b ) {
|
||||
u3k(*a);
|
||||
// u3z(*b);
|
||||
*b = *a;
|
||||
} else {
|
||||
u3k(*b);
|
||||
// u3z(*a);
|
||||
*a = *b;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define SONG_NONE 0
|
||||
#define SONG_HEAD 1
|
||||
#define SONG_TAIL 2
|
||||
@ -301,115 +248,26 @@ _eq_pop(c3_ys mov, c3_ys off)
|
||||
return u3to(eqframe, u3R->cap_p + off);
|
||||
}
|
||||
|
||||
/* _sing_one(): do not pick a unified pointer for identical (a) and (b).
|
||||
/* _song_atom(): check if atom [a] is indirect and equal to noun [b]
|
||||
*/
|
||||
static void
|
||||
_sing_one(u3_noun* a, u3_noun* b)
|
||||
{
|
||||
// this space left intentionally blank
|
||||
}
|
||||
|
||||
/* _sung_one(): pick a unified pointer for identical (a) and (b).
|
||||
**
|
||||
** Assumes exclusive access to noun memory.
|
||||
*/
|
||||
static void
|
||||
_sung_one(u3_noun* a, u3_noun* b)
|
||||
{
|
||||
|
||||
if ( *a == *b ) {
|
||||
return;
|
||||
} else {
|
||||
u3_road* rod_u = u3R;
|
||||
while ( 1 ) {
|
||||
//
|
||||
// we can't perform this kind of butchery on the home road,
|
||||
// where asynchronous things can allocate.
|
||||
//
|
||||
if ( u3R == &u3H->rod_u ) {
|
||||
break;
|
||||
}
|
||||
else {
|
||||
c3_o asr_o = u3a_is_senior(u3R, *a);
|
||||
c3_o bsr_o = u3a_is_senior(u3R, *b);
|
||||
|
||||
if ( _(asr_o) && _(bsr_o) ) {
|
||||
//
|
||||
// when unifying on a higher road, we can't free nouns,
|
||||
// because we can't track junior nouns that point into
|
||||
// that road.
|
||||
//
|
||||
// this is just an implementation issue -- we could set use
|
||||
// counts to 0 without actually freeing. but the allocator
|
||||
// would have to be actually designed for this.
|
||||
//
|
||||
// not freeing may generate spurious leaks, so we disable
|
||||
// senior unification when debugging memory. this will
|
||||
// cause a very slow boot process as the compiler compiles
|
||||
// itself, constantly running into duplicates.
|
||||
//
|
||||
#ifdef U3_MEMORY_DEBUG
|
||||
return;
|
||||
#else
|
||||
u3R = u3to(u3_road, u3R->par_p);
|
||||
continue;
|
||||
#endif
|
||||
}
|
||||
|
||||
if ( _(asr_o) && !_(bsr_o) ){
|
||||
if ( u3R == rod_u ) { u3z(*b); }
|
||||
*b = *a;
|
||||
}
|
||||
if ( _(bsr_o) && !_(asr_o) ) {
|
||||
if ( u3R == rod_u ) { u3z(*a); }
|
||||
*a = *b;
|
||||
}
|
||||
if ( u3a_is_north(u3R) ) {
|
||||
if ( *a <= *b ) {
|
||||
u3k(*a);
|
||||
if ( u3R == rod_u ) { u3z(*b); }
|
||||
*b = *a;
|
||||
} else {
|
||||
u3k(*b);
|
||||
if ( u3R == rod_u ) { u3z(*a); }
|
||||
*a = *b;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ( *a >= *b ) {
|
||||
u3k(*a);
|
||||
if ( u3R == rod_u ) { u3z(*b); }
|
||||
*b = *a;
|
||||
} else {
|
||||
u3k(*b);
|
||||
if ( u3R == rod_u ) { u3z(*a); }
|
||||
*a = *b;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
u3R = rod_u;
|
||||
}
|
||||
}
|
||||
|
||||
static inline c3_o
|
||||
_song_atom(u3_atom a, u3_atom b)
|
||||
_song_atom(u3_atom a, u3_noun b)
|
||||
{
|
||||
u3a_atom* a_u = u3a_to_ptr(a);
|
||||
|
||||
if ( !_(u3a_is_atom(b)) ||
|
||||
_(u3a_is_cat(a)) ||
|
||||
_(u3a_is_cat(b)) )
|
||||
// [a] is an atom, not pointer-equal to noun [b].
|
||||
// if they're not both indirect atoms, they can't be equal.
|
||||
//
|
||||
if ( (c3n == u3a_is_pug(a)) ||
|
||||
(c3n == u3a_is_pug(b)) )
|
||||
{
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
u3a_atom* a_u = u3a_to_ptr(a);
|
||||
u3a_atom* b_u = u3a_to_ptr(b);
|
||||
|
||||
if ( a_u->mug_w &&
|
||||
b_u->mug_w &&
|
||||
(a_u->mug_w != b_u->mug_w) )
|
||||
if ( (0 != a_u->mug_w) &&
|
||||
(0 != b_u->mug_w) &&
|
||||
(a_u->mug_w != b_u->mug_w) )
|
||||
{
|
||||
return c3n;
|
||||
}
|
||||
@ -431,6 +289,7 @@ _song_atom(u3_atom a, u3_atom b)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return c3y;
|
||||
}
|
||||
|
||||
@ -440,8 +299,7 @@ _song_atom(u3_atom a, u3_atom b)
|
||||
static c3_o
|
||||
_song_x_cape(c3_ys mov, c3_ys off,
|
||||
eqframe* fam, eqframe* don,
|
||||
u3p(u3h_root) har_p,
|
||||
void (*uni)(u3_noun*, u3_noun*))
|
||||
u3p(u3h_root) har_p)
|
||||
{
|
||||
u3_noun a, b, key;
|
||||
u3_weak got;
|
||||
@ -468,12 +326,13 @@ _song_x_cape(c3_ys mov, c3_ys off,
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
u3a_cell* a_u = u3a_to_ptr(a);
|
||||
u3a_cell* b_u = u3a_to_ptr(b);
|
||||
a_u = u3a_to_ptr(a);
|
||||
b_u = u3a_to_ptr(b);
|
||||
|
||||
if ( a_u->mug_w &&
|
||||
b_u->mug_w &&
|
||||
(a_u->mug_w != b_u->mug_w) ) {
|
||||
if ( (0 != a_u->mug_w) &&
|
||||
(0 != b_u->mug_w) &&
|
||||
(a_u->mug_w != b_u->mug_w) )
|
||||
{
|
||||
return c3n;
|
||||
}
|
||||
else {
|
||||
@ -495,7 +354,7 @@ _song_x_cape(c3_ys mov, c3_ys off,
|
||||
case SONG_HEAD:
|
||||
a_u = u3a_to_ptr(a);
|
||||
b_u = u3a_to_ptr(b);
|
||||
uni(&(a_u->hed), &(b_u->hed));
|
||||
u3a_wed(&(a_u->hed), &(b_u->hed));
|
||||
fam->sat_y = SONG_TAIL;
|
||||
fam = _eq_push(mov, off, a_u->tel, b_u->tel);
|
||||
continue;
|
||||
@ -503,7 +362,7 @@ _song_x_cape(c3_ys mov, c3_ys off,
|
||||
case SONG_TAIL:
|
||||
a_u = u3a_to_ptr(a);
|
||||
b_u = u3a_to_ptr(b);
|
||||
uni(&(a_u->tel), &(b_u->tel));
|
||||
u3a_wed(&(a_u->tel), &(b_u->tel));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -511,6 +370,10 @@ _song_x_cape(c3_ys mov, c3_ys off,
|
||||
break;
|
||||
}
|
||||
|
||||
// [har_p] is effectively a set of equal pairs.
|
||||
// we cons [a] and [b] as posts so that we don't
|
||||
// touch their reference counts.
|
||||
//
|
||||
key = u3nc(u3a_to_off(a), u3a_to_off(b));
|
||||
u3t_off(euq_o);
|
||||
u3h_put(har_p, key, c3y);
|
||||
@ -525,7 +388,7 @@ _song_x_cape(c3_ys mov, c3_ys off,
|
||||
/* _song_x(): yes if a and b are the same noun, use uni to unify
|
||||
*/
|
||||
static c3_o
|
||||
_song_x(u3_noun a, u3_noun b, void (*uni)(u3_noun*, u3_noun*))
|
||||
_song_x(u3_noun a, u3_noun b)
|
||||
{
|
||||
u3p(eqframe) empty = u3R->cap_p;
|
||||
|
||||
@ -565,9 +428,10 @@ _song_x(u3_noun a, u3_noun b, void (*uni)(u3_noun*, u3_noun*))
|
||||
a_u = u3a_to_ptr(a);
|
||||
b_u = u3a_to_ptr(b);
|
||||
|
||||
if ( a_u->mug_w &&
|
||||
b_u->mug_w &&
|
||||
(a_u->mug_w != b_u->mug_w) ) {
|
||||
if ( (0 != a_u->mug_w) &&
|
||||
(0 != b_u->mug_w) &&
|
||||
(a_u->mug_w != b_u->mug_w) )
|
||||
{
|
||||
u3R->cap_p = empty;
|
||||
return c3n;
|
||||
}
|
||||
@ -581,7 +445,7 @@ _song_x(u3_noun a, u3_noun b, void (*uni)(u3_noun*, u3_noun*))
|
||||
case SONG_HEAD:
|
||||
a_u = u3a_to_ptr(a);
|
||||
b_u = u3a_to_ptr(b);
|
||||
uni(&(a_u->hed), &(b_u->hed));
|
||||
u3a_wed(&(a_u->hed), &(b_u->hed));
|
||||
fam->sat_y = SONG_TAIL;
|
||||
fam = _eq_push(mov, off, a_u->tel, b_u->tel);
|
||||
continue;
|
||||
@ -589,7 +453,7 @@ _song_x(u3_noun a, u3_noun b, void (*uni)(u3_noun*, u3_noun*))
|
||||
case SONG_TAIL:
|
||||
a_u = u3a_to_ptr(a);
|
||||
b_u = u3a_to_ptr(b);
|
||||
uni(&(a_u->tel), &(b_u->tel));
|
||||
u3a_wed(&(a_u->tel), &(b_u->tel));
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -597,9 +461,12 @@ _song_x(u3_noun a, u3_noun b, void (*uni)(u3_noun*, u3_noun*))
|
||||
break;
|
||||
}
|
||||
|
||||
// [ovr_s] counts iterations. when it overflows, we know we've hit a
|
||||
// pathological case and MUST start de-duplicating comparisons.
|
||||
//
|
||||
if ( 0 == ++ovr_s ) {
|
||||
u3p(u3h_root) har_p = u3h_new();
|
||||
c3_o ret_o = _song_x_cape(mov, off, fam, don, har_p, uni);
|
||||
c3_o ret_o = _song_x_cape(mov, off, fam, don, har_p);
|
||||
u3h_free(har_p);
|
||||
u3R->cap_p = empty;
|
||||
return ret_o;
|
||||
@ -610,59 +477,14 @@ _song_x(u3_noun a, u3_noun b, void (*uni)(u3_noun*, u3_noun*))
|
||||
return c3y;
|
||||
}
|
||||
|
||||
/* u3r_sang(): yes iff (a) and (b) are the same noun, unifying equals.
|
||||
*/
|
||||
c3_o
|
||||
u3r_sang(u3_noun a, u3_noun b)
|
||||
{
|
||||
c3_o ret_o;
|
||||
u3t_on(euq_o);
|
||||
ret_o = _song_x(a, b, &_sang_one);
|
||||
u3t_off(euq_o);
|
||||
return ret_o;
|
||||
}
|
||||
|
||||
/* u3r_sing():
|
||||
**
|
||||
** Yes iff (a) and (b) are the same noun.
|
||||
/* u3r_sing(): Yes iff [a] and [b] are the same noun.
|
||||
*/
|
||||
c3_o
|
||||
u3r_sing(u3_noun a, u3_noun b)
|
||||
{
|
||||
#ifndef U3_MEMORY_DEBUG
|
||||
if ( u3R->par_p ) {
|
||||
return u3r_sang(a, b);
|
||||
}
|
||||
#endif
|
||||
{
|
||||
c3_o ret_o;
|
||||
|
||||
u3t_on(euq_o);
|
||||
ret_o = _song_x(a, b, &_sing_one);
|
||||
u3t_off(euq_o);
|
||||
|
||||
return ret_o;
|
||||
}
|
||||
}
|
||||
|
||||
/* u3rz_sing(): transferring u3r_sing
|
||||
*/
|
||||
c3_o
|
||||
u3rz_sing(u3_noun a, u3_noun b)
|
||||
{
|
||||
c3_o ret_o = u3r_sing(a, b);
|
||||
u3z(a); u3z(b);
|
||||
return ret_o;
|
||||
}
|
||||
|
||||
/* u3r_sung(): yes iff (a) and (b) are the same noun, unifying equals.
|
||||
*/
|
||||
c3_o
|
||||
u3r_sung(u3_noun a, u3_noun b)
|
||||
{
|
||||
c3_o ret_o;
|
||||
u3t_on(euq_o);
|
||||
ret_o = _song_x(a, b, &_sung_one);
|
||||
ret_o = _song_x(a, b);
|
||||
u3t_off(euq_o);
|
||||
return ret_o;
|
||||
}
|
||||
@ -841,13 +663,11 @@ u3r_nord(u3_noun a,
|
||||
}
|
||||
}
|
||||
|
||||
/* u3r_sing_c():
|
||||
**
|
||||
** Yes iff (b) is the same noun as the C string a_c.
|
||||
/* u3r_sing_c(): cord/C-string value equivalence.
|
||||
*/
|
||||
c3_o
|
||||
u3r_sing_c(const c3_c* a_c,
|
||||
u3_noun b)
|
||||
u3_noun b)
|
||||
{
|
||||
c3_assert(u3_none != b);
|
||||
|
||||
|
@ -970,7 +970,7 @@ u3_cttp_ef_http_client(u3_noun fav)
|
||||
{
|
||||
u3_creq* ceq_u;
|
||||
|
||||
if ( c3y == u3rz_sing(u3i_string("request"), u3k(u3h(fav))) ) {
|
||||
if ( c3y == u3r_sing_c("request", u3h(fav)) ) {
|
||||
u3_noun p_fav, q_fav;
|
||||
u3x_cell(u3t(fav), &p_fav, &q_fav);
|
||||
|
||||
@ -983,7 +983,7 @@ u3_cttp_ef_http_client(u3_noun fav)
|
||||
u3l_log("cttp: strange request (unparsable url)\n");
|
||||
}
|
||||
}
|
||||
else if ( c3y == u3rz_sing(u3i_string("cancel-request"), u3k(u3h(fav))) ) {
|
||||
else if ( c3y == u3r_sing_c("cancel-request", u3h(fav)) ) {
|
||||
ceq_u =_cttp_creq_find(u3r_word(0, u3t(fav)));
|
||||
|
||||
if ( ceq_u ) {
|
||||
|
@ -1505,16 +1505,16 @@ u3_http_ef_http_server(c3_l sev_l,
|
||||
|
||||
// sets server configuration
|
||||
//
|
||||
if ( c3y == u3rz_sing(u3i_string("set-config"), u3k(tag)) ) {
|
||||
if ( c3y == u3r_sing_c("set-config", tag) ) {
|
||||
u3_http_ef_form(u3k(dat));
|
||||
}
|
||||
// responds to an open request
|
||||
//
|
||||
else if ( 0 != (req_u = _http_search_req(sev_l, coq_l, seq_l)) ) {
|
||||
if ( c3y == u3rz_sing(u3i_string("response"), u3k(tag)) ) {
|
||||
if ( c3y == u3r_sing_c("response", tag) ) {
|
||||
u3_noun response = dat;
|
||||
|
||||
if ( c3y == u3rz_sing(u3i_string("start"), u3k(u3h(response))) ) {
|
||||
if ( c3y == u3r_sing_c("start", u3h(response)) ) {
|
||||
// Separate the %start message into its components.
|
||||
//
|
||||
u3_noun response_header, data, complete;
|
||||
@ -1525,7 +1525,7 @@ u3_http_ef_http_server(c3_l sev_l,
|
||||
_http_start_respond(req_u, u3k(status), u3k(headers), u3k(data),
|
||||
u3k(complete));
|
||||
}
|
||||
else if ( c3y == u3rz_sing(u3i_string("continue"), u3k(u3h(response))) ) {
|
||||
else if ( c3y == u3r_sing_c("continue", u3h(response)) ) {
|
||||
// Separate the %continue message into its components.
|
||||
//
|
||||
u3_noun data, complete;
|
||||
@ -1533,7 +1533,7 @@ u3_http_ef_http_server(c3_l sev_l,
|
||||
|
||||
_http_continue_respond(req_u, u3k(data), u3k(complete));
|
||||
}
|
||||
else if (c3y == u3rz_sing(u3i_string("cancel"), u3k(u3h(response)))) {
|
||||
else if (c3y == u3r_sing_c("cancel", u3h(response))) {
|
||||
u3l_log("http: %%cancel not handled yet\n");
|
||||
}
|
||||
else {
|
||||
|
@ -280,7 +280,7 @@ _reck_kick_spec(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
if ( (c3n == u3r_cell(t_pox, &it_pox, &tt_pox)) ) {
|
||||
u3z(pox); u3z(fav); return c3n;
|
||||
}
|
||||
else if ( c3y == u3rz_sing(u3i_string("http-server"), u3k(it_pox)) ) {
|
||||
else if ( c3y == u3r_sing_c("http-server", it_pox) ) {
|
||||
u3_noun pud = tt_pox;
|
||||
u3_noun p_pud, t_pud, tt_pud, q_pud, r_pud, s_pud;
|
||||
c3_l sev_l, coq_l, seq_l;
|
||||
@ -317,7 +317,7 @@ _reck_kick_spec(u3_pier* pir_u, u3_noun pox, u3_noun fav)
|
||||
u3z(pox); u3z(fav);
|
||||
return c3y;
|
||||
}
|
||||
else if ( c3y == u3rz_sing(u3i_string("http-client"), u3k(it_pox)) ) {
|
||||
else if ( c3y == u3r_sing_c("http-client", it_pox) ) {
|
||||
u3_cttp_ef_http_client(u3k(fav));
|
||||
|
||||
u3z(pox); u3z(fav);
|
||||
|
Loading…
Reference in New Issue
Block a user