shrub/f/chad.c
2013-09-28 13:21:18 -07:00

373 lines
9.0 KiB
C

/* f/chad.c
**
** This file is in the public domain.
*/
#include "all.h"
/* u2_ch_init():
**
** Initialize empty chad.
*/
void
u2_ch_init(u2_ray cad_r)
{
c3_w i_w;
for ( i_w = 0; i_w < 16; i_w++ ) {
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * i_w));
*u2_at(per_r, u2_loom_pear, nam) = u2_none;
*u2_at(per_r, u2_loom_pear, val) = 0;
}
}
/* u2_ch_find():
**
** Find value for `nam` in `cad`, or return `u2_none`.
*/
u2_weak
u2_ch_find(u2_ray cad_r,
u2_noun nam)
{
c3_w mug_w = u2_mug(nam);
c3_w off_w = 0;
while ( 1 ) {
if ( off_w == 32 ) {
/* Linear search in a list of 16 total collisions.
** Overflow probability: (n/(2^31))^15 ~= 0.
*/
c3_w i_w;
for ( i_w = 0; i_w < 16; i_w++ ) {
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * i_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( (u2_none != nom) && (u2_yes == u2_sing(nam, nom)) ) {
return *u2_at(per_r, u2_loom_pear, val);
}
}
return u2_none;
}
else {
c3_w fat_w = (mug_w >> off_w) & 15;
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * fat_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none == nom ) {
cad_r = *u2_at(per_r, u2_loom_pear, val);
if ( 0 == cad_r ) {
return u2_none;
} else {
off_w += 4;
continue;
}
}
else if ( u2_yes == u2_sing(nam, nom) ) {
return *u2_at(per_r, u2_loom_pear, val);
}
else return u2_none;
}
}
}
void
u2_b_print(const c3_c* cap_c, u2_noun som);
/* u2_ch_find_cell():
**
** Find value for `[hed tal]` in `cad`, or return `u2_none`.
*/
u2_weak
u2_ch_find_cell(u2_ray cad_r,
u2_noun hed,
u2_noun tal)
{
c3_w mug_w = u2_mug_cell(hed, tal);
c3_w off_w = 0;
while ( 1 ) {
if ( off_w == 32 ) {
/* Linear search in a list of 16 total collisions.
** Overflow probability: (n/(2^31))^15 ~= 0.
*/
c3_w i_w;
for ( i_w = 0; i_w < 16; i_w++ ) {
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * i_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none != nom ) {
if ( (u2_yes == u2_dust(nom)) &&
(u2_yes == u2_sing(hed, u2_h(nom))) &&
(u2_yes == u2_sing(tal, u2_t(nom))) )
{
return *u2_at(per_r, u2_loom_pear, val);
}
}
}
return u2_none;
}
else {
c3_w fat_w = (mug_w >> off_w) & 15;
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear )* fat_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none == nom ) {
cad_r = *u2_at(per_r, u2_loom_pear, val);
if ( 0 == cad_r ) {
return u2_none;
} else {
off_w += 4;
continue;
}
}
else if ( u2_yes == u2_dust(nom) &&
(u2_yes == u2_sing(hed, u2_h(nom))) &&
(u2_yes == u2_sing(tal, u2_t(nom))) )
{
return *u2_at(per_r, u2_loom_pear, val);
}
else {
return u2_none;
}
}
}
}
/* u2_ch_find_mixt():
**
** Find value for `[hed tal]` in `cad`, or return `u2_none`.
*/
u2_weak
u2_ch_find_mixt(u2_ray cad_r,
const c3_c* hed_c,
u2_noun tal)
{
c3_w mug_w = u2_mug_both(u2_mug_string(hed_c), u2_mug(tal));
c3_w off_w = 0;
while ( 1 ) {
if ( off_w == 32 ) {
/* Linear search in a list of 16 total collisions.
** Overflow probability: (n/(2^31))^15 ~= 0.
*/
c3_w i_w;
for ( i_w = 0; i_w < 16; i_w++ ) {
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * i_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none != nom ) {
if ( (u2_yes == u2_dust(nom)) &&
(u2_yes == u2_sing_c(hed_c, u2_h(nom))) &&
(u2_yes == u2_sing(tal, u2_t(nom))) )
{
return *u2_at(per_r, u2_loom_pear, val);
}
}
}
return u2_none;
}
else {
c3_w fat_w = (mug_w >> off_w) & 15;
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear )* fat_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none == nom ) {
cad_r = *u2_at(per_r, u2_loom_pear, val);
if ( 0 == cad_r ) {
return u2_none;
} else {
off_w += 4;
continue;
}
}
else if ( u2_yes == u2_dust(nom) &&
(u2_yes == u2_sing_c(hed_c, u2_h(nom))) &&
(u2_yes == u2_sing(tal, u2_t(nom))) )
{
return *u2_at(per_r, u2_loom_pear, val);
}
else {
return u2_none;
}
}
}
}
/* _ch_save(): as u2_ch_save(), with mug and offset, and iced nouns.
*/
static u2_bean
_ch_save(u2_ray ral_r,
u2_ray cad_r,
u2_noun nim,
u2_noun vil,
c3_w mug_w,
c3_w off_w)
{
while ( 1 ) {
if ( off_w == 32 ) {
/* Linear search in a list of 16 total collisions.
** Overflow probability: (n/(2^31))^15 ~= 0.
*/
c3_w i_w;
// printf("conflict: %x\n", mug_w);
for ( i_w = 0; i_w < 16; i_w++ ) {
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * i_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none != nom ) {
c3_assert(u2_no == u2_sing(nim, nom));
}
else {
*u2_at(per_r, u2_loom_pear, nam) = nim;
*u2_at(per_r, u2_loom_pear, val) = vil;
return u2_yes;
}
}
return u2_no;
}
else {
c3_w fat_w = (mug_w >> off_w) & 15;
u2_ray per_r = (cad_r + (c3_wiseof(u2_loom_pear) * fat_w));
u2_noun nom = *u2_at(per_r, u2_loom_pear, nam);
if ( u2_none == nom ) {
cad_r = *u2_at(per_r, u2_loom_pear, val);
if ( 0 == cad_r ) {
*u2_at(per_r, u2_loom_pear, nam) = nim;
*u2_at(per_r, u2_loom_pear, val) = vil;
return u2_yes;
}
else {
off_w += 4;
continue;
}
}
else {
u2_noun vol = *u2_at(per_r, u2_loom_pear, val);
u2_ray osh_r;
if ( 0 == (osh_r = u2_rl_ralloc(ral_r, c3_wiseof(u2_loom_chad))) ) {
return u2_no;
}
u2_ch_init(osh_r);
if ( u2_no == _ch_save(ral_r, osh_r, nom, vol, u2_mug(nom), 4+off_w) ) {
u2_rl_rfree(ral_r, osh_r);
return u2_no;
}
if ( u2_no == _ch_save(ral_r, osh_r, nim, vil, mug_w, 4+off_w) ) {
u2_rl_rfree(ral_r, osh_r);
return u2_no;
}
*u2_at(per_r, u2_loom_pear, nam) = u2_none;
*u2_at(per_r, u2_loom_pear, val) = osh_r;
return u2_yes;
}
}
}
}
/* u2_ch_save():
**
** Save `val` under `nam` in `cad`, allocating in `ral`.
** Return `u2_none` iff allocation fails. Asserts on duplicate.
**
** Caller retains arguments; callee retains result.
*/
u2_weak
u2_ch_save(u2_ray ral_r,
u2_ray cad_r,
u2_noun nam,
u2_noun val)
{
u2_weak nim, vil;
if ( u2_none == (nim = u2_rl_ice(ral_r, nam)) ) {
return u2_none;
}
if ( u2_none == (vil = u2_rl_ice(ral_r, val)) ) {
u2_rl_lose(ral_r, nim);
return u2_none;
}
if ( u2_no == _ch_save(ral_r, cad_r, nim, vil, u2_mug(nim), 0) ) {
u2_rl_lose(ral_r, nim);
u2_rl_lose(ral_r, vil);
return u2_none;
}
return vil;
}
/* u2_ch_save_cell():
**
** Save `val` under `[hed tal]` in `cad`, allocating in `ral`.
** Return `u2_none` iff allocation fails. Asserts on duplicate.
**
** Caller retains arguments; callee retains result.
*/
u2_weak
u2_ch_save_cell(u2_ray ral_r,
u2_ray cad_r,
u2_noun hed,
u2_noun tal,
u2_noun val)
{
u2_weak nim, vil;
if ( u2_none == (nim = u2_rl_cell(ral_r, u2_rl_ice(ral_r, hed),
u2_rl_ice(ral_r, tal))) )
{
return u2_none;
}
if ( u2_none == (vil = u2_rl_ice(ral_r, val)) ) {
u2_rl_lose(ral_r, nim);
return u2_none;
}
if ( u2_no == _ch_save(ral_r, cad_r, nim, vil, u2_mug(nim), 0) ) {
u2_rl_lose(ral_r, nim);
u2_rl_lose(ral_r, vil);
return u2_none;
}
return vil;
}
/* u2_ch_save_mixt():
**
** Save `val` under `[hed tal]` in `cad`, allocating in `ral`.
** Return `u2_none` iff allocation fails. Asserts on duplicate.
**
** Caller retains ownership of arguments; callee retains result.
*/
u2_weak
u2_ch_save_mixt(u2_ray ral_r,
u2_ray cad_r,
const c3_c* hed_c,
u2_noun tal,
u2_noun val)
{
u2_weak nim, vil;
if ( u2_none == (nim = u2_rl_cell(ral_r, u2_rl_string(ral_r, hed_c),
u2_rl_ice(ral_r, tal))) )
{
return u2_none;
}
if ( u2_none == (vil = u2_rl_ice(ral_r, val)) ) {
u2_rl_lose(ral_r, nim);
return u2_none;
}
if ( u2_no == _ch_save(ral_r, cad_r, nim, vil, u2_mug(nim), 0) ) {
u2_rl_lose(ral_r, nim);
u2_rl_lose(ral_r, vil);
return u2_none;
}
return vil;
}