mirror of
https://github.com/urbit/shrub.git
synced 2024-12-23 19:05:48 +03:00
959 lines
24 KiB
C
959 lines
24 KiB
C
/* include/loom.h
|
|
**
|
|
** This file is in the public domain.
|
|
*/
|
|
/** Global variables and definitions.
|
|
**/
|
|
# define Loom ((c3_w *)U2_OS_LoomBase)
|
|
# define LoomBits U2_OS_LoomBits
|
|
# define LoomSize (1 << LoomBits)
|
|
# define HalfBits (U2_OS_LoomBits - 1)
|
|
# define HalfSize (1 << HalfBits)
|
|
# define HalfEnd (HalfSize - 1)
|
|
# define LoomPageWords 12 // 16K pages
|
|
# define LoomAllPages (1 << 16) // 65536 pages
|
|
# define LoomHalfPages (1 << 15) // 32768 pages
|
|
# define LoomVersion 0xdeafbee
|
|
|
|
/** Data structures.
|
|
**/
|
|
/* u2_life: page state.
|
|
*/
|
|
typedef enum {
|
|
u2_page_none = 0, // page is not mapped
|
|
u2_page_slow = 1, // page not yet loaded (not used)
|
|
u2_page_neat = 2, // page is unmodified
|
|
u2_page_tref = 3 // page is dirty
|
|
} u2_page_life;
|
|
|
|
typedef struct {
|
|
u2_page_life lif_e: 2; // page state
|
|
c3_w mug_e: 30; // 30-bit mug
|
|
} u2_chit;
|
|
|
|
/* u2_chef: memory control, per whole, on disk.
|
|
*/
|
|
typedef struct _u2_chef { // control image
|
|
c3_d ent_d; // event number
|
|
c3_w ven_w; // version
|
|
c3_w bot_w; // offset in loom
|
|
c3_w pgs_w; // pages saved
|
|
} u2_chef;
|
|
|
|
/* u2_cheg: mapped segment. always grows upward for now.
|
|
*/
|
|
typedef struct _u2_cheg {
|
|
c3_c* nam_c; // name as a file
|
|
struct _u2_cheg* nex_u; // linked in list
|
|
c3_w bot_w; // beginning page
|
|
c3_w len_w; // length in pages
|
|
c3_w pgs_w; // pages in used prefix
|
|
c3_i ctl_i; // control file
|
|
c3_i dat_i; // data file
|
|
} u2_cheg;
|
|
|
|
# ifdef U2_GLOBAL
|
|
/* Memory control structures.
|
|
*/
|
|
volatile u2_chit LoomChem[LoomAllPages]; // memory
|
|
|
|
/* Direct segment pointers.
|
|
*/
|
|
u2_cheg LoomSegmentD = { "d" };
|
|
u2_cheg LoomSegmentC = { "c", &LoomSegmentD };
|
|
u2_cheg LoomSegmentB = { "b", &LoomSegmentC };
|
|
u2_cheg LoomSegmentA = { "a", &LoomSegmentB };
|
|
|
|
/* Critical-section bit, for signal handlers.
|
|
*/
|
|
volatile uint32_t u2_Critical;
|
|
|
|
# else
|
|
extern uint32_t LoomFrame;
|
|
extern volatile sig_atomic_t LoomStop;
|
|
extern volatile sig_atomic_t LoomIntr;
|
|
extern volatile uint32_t u2_Critical;
|
|
|
|
extern volatile u2_chit LoomChem[LoomAllPages];
|
|
extern u2_cheg LoomSegmentA, LoomSegmentB, LoomSegmentC, LoomSegmentD;
|
|
# endif
|
|
|
|
# define LoomFrameMax 8192
|
|
# define LoomSink \
|
|
(LoomFrame == LoomFrameMax ? (LoomStop = 1) : LoomFrame++)
|
|
# define LoomRise \
|
|
(LoomFrame--)
|
|
|
|
// # define LoomFold
|
|
|
|
/** Data types.
|
|
**/
|
|
/** Bitfields. Assumes HalfBits == 28 (the maximum).
|
|
***
|
|
*** u2_nit - word offset in loom
|
|
*** &&&&:28a
|
|
*** a: offset from loom
|
|
***
|
|
*** u2_ray - word offset on beam
|
|
*** &&&:1a:28b
|
|
*** a: beam (& = low = west, | = high = east)
|
|
*** b: offset on beam
|
|
***
|
|
*** u2_noun - noun
|
|
*** ?(u2_cat, u2_dog)
|
|
*** 1a:31b
|
|
*** a: cat if 0, dog if 1
|
|
***
|
|
*** u2_weak - noun
|
|
*** ?(noun, u2_none)
|
|
***
|
|
*** u2_dog - indirect atom or cell
|
|
*** ?(u2_pom, u2_pug)
|
|
*** |:29a:1b:1c
|
|
*** a: ray to data
|
|
*** b: boxed bit
|
|
***
|
|
*** u2_cat - direct atom
|
|
*** &:31a
|
|
*** a: unsigned integer
|
|
***
|
|
*** u2_pom - indirect cell
|
|
*** |:29a:1b:&
|
|
*** a: ray to struct u2_cell
|
|
*** b: allocated bit (0 == fixed, 1 == allocated)
|
|
***
|
|
*** u2_pug - indirect atom
|
|
*** |:29a:1b:|
|
|
*** a: ray to struct u2_atom
|
|
*** b: allocated bit (0 == fixed, 1 == allocated)
|
|
**/
|
|
typedef c3_w u2_nit;
|
|
typedef c3_w u2_ray;
|
|
typedef c3_w u2_fly;
|
|
typedef c3_w u2_dog;
|
|
typedef c3_w u2_cat;
|
|
typedef c3_w u2_pug;
|
|
|
|
/** Structures.
|
|
***
|
|
**/
|
|
/* u2_atom, u2_cell: logical atom and cell structures.
|
|
**
|
|
** Not referenced as such, since in ray space.
|
|
*/
|
|
typedef struct _u2_loom_atom {
|
|
c3_w mug_w;
|
|
c3_w len_w;
|
|
c3_w buf_w[0];
|
|
} u2_loom_atom;
|
|
|
|
typedef struct _u2_loom_cell {
|
|
c3_w mug_w;
|
|
u2_ray hed_r;
|
|
u2_ray tel_r;
|
|
} u2_loom_cell;
|
|
|
|
/** Basic macros.
|
|
**/
|
|
/** Bitfield unpacking. See above.
|
|
**/
|
|
# define u2_ray_a(ray) ( (ray) >> HalfBits )
|
|
# define u2_ray_b(ray) ( (ray) & ((1 << HalfBits) - 1) )
|
|
|
|
# define u2_fly_a(fly) ( (fly) >> 31 )
|
|
|
|
# define u2_dog_a(dog) ( ((dog) &~ (1 << 31)) >> 2 )
|
|
# define u2_dog_b(dog) ( 1 & ((dog) >> 1) )
|
|
# define u2_dog_c(dog) ( 1 & (dog) )
|
|
|
|
# define u2_pom_a(pom) u2_dog_a(pom)
|
|
# define u2_pom_b(pom) u2_dog_b(pom)
|
|
# define u2_pug_a(pug) u2_dog_a(pug)
|
|
# define u2_pug_b(pug) u2_dog_b(pug)
|
|
|
|
# define u2_fly_is_cat(fly) ( !u2_fly_a(fly) )
|
|
# define u2_fly_is_dog(fly) ( u2_fly_a(fly) )
|
|
|
|
# define u2_dog_is_pom(dog) ( !u2_dog_c(dog) )
|
|
# define u2_dog_is_pug(dog) ( u2_dog_c(dog) )
|
|
|
|
# define u2_dog_is_all(dog) ( u2_dog_b(dog) )
|
|
|
|
# define u2_fly_is_atom(a) \
|
|
(u2_fly_is_cat(a) || u2_dog_is_pug(a))
|
|
|
|
|
|
/** Bitfield packing. See above.
|
|
**/
|
|
# define u2_ray_of(a, b) ( ((a) << HalfBits) | (b) )
|
|
|
|
# define u2_dog_of(a, b, c) \
|
|
( (1 << 31) | ((a) << 2) | ((b) << 1) | (c) )
|
|
|
|
# define u2_pom_of(a, b) u2_dog_of(a, b, 0)
|
|
# define u2_pug_of(a, b) u2_dog_of(a, b, 1)
|
|
|
|
|
|
/** Cage reference and geometry.
|
|
***
|
|
*** Formally, we are always folded.
|
|
**/
|
|
# define u2_ray_fnit(ray) \
|
|
( u2_ray_a(ray) ? (HalfEnd - u2_ray_b(ray)) : (ray) )
|
|
# ifdef LoomFold
|
|
# define u2_ray_nit(ray) u2_ray_fnit(ray)
|
|
# else
|
|
# define u2_ray_nit(ray) (ray)
|
|
# endif
|
|
|
|
# define u2_ray_open(tid, tat, das) \
|
|
( (0 == u2_ray_a(tid)) \
|
|
? ( (u2_ray_fnit(tid) + (das)) < u2_ray_fnit(tat) ) \
|
|
: ( (u2_ray_fnit(tat) + (das)) < u2_ray_fnit(tid) ) )
|
|
|
|
# define u2_ray_gap(tid, tat) \
|
|
( (HalfSize - (u2_ray_b(tid) + u2_ray_b(tat))) )
|
|
|
|
/* last word of opposite is first word of other. so, in a 4-word loom:
|
|
**
|
|
** 0 1 2 3
|
|
** | | | |
|
|
** ## ## ## ##
|
|
** | | | |
|
|
** 3 2 1 0
|
|
*/
|
|
|
|
# define u2_ray_over(ray, siz_w) \
|
|
u2_ray_of(!u2_ray_a(ray), (HalfSize - (u2_ray_b(ray) + (siz_w))))
|
|
|
|
# define u2_at_nit(nit) (Loom + nit)
|
|
# define u2_at_ray(ray) u2_at_nit(u2_ray_nit(ray))
|
|
# define u2_nit_at(ptr_v) (((c3_w *)(ptr_v)) - Loom)
|
|
|
|
# ifdef LoomFold
|
|
# define u2_at_cord(ray, siz) \
|
|
(u2_ray_a(ray) ? (u2_at_ray(ray) - ((siz) - 1)) : u2_at_ray(ray))
|
|
# else
|
|
# define u2_at_cord(ray, siz) u2_at_ray(ray)
|
|
# endif
|
|
|
|
# define u2_aftr(ray, type, field) \
|
|
((ray) + \
|
|
( ((c3_w *)&((type *)0)->field) - \
|
|
((c3_w *)0) ) \
|
|
)
|
|
# define u2_fore(ray, type, field) \
|
|
((ray - 1) - \
|
|
( ((c3_w *)&((type *)0)->field) - \
|
|
((c3_w *)0) ) \
|
|
)
|
|
|
|
# define u2_at(ray, type, field) \
|
|
u2_at_ray(u2_aftr(ray, type, field))
|
|
# define u2_by(ray, type, field) \
|
|
u2_at_ray(u2_fore(ray, type, field))
|
|
|
|
# define u2_be(ray, type, item, field) \
|
|
( (item *)(void *)u2_at_ray(u2_aftr(ray, type, field)) )
|
|
|
|
# define u2_ray_beam(ray) u2_ray_a(ray)
|
|
# define u2_ray_point(ray) u2_ray_b(ray)
|
|
|
|
# define u2_dog_ray(dog) u2_dog_a(dog)
|
|
|
|
# define u2_dog_beam(dog) u2_ray_beam(u2_dog_ray(dog))
|
|
|
|
|
|
/*** Noun structure access.
|
|
***/
|
|
# define u2_at_dog_mug(a) u2_at_ray(u2_dog_a(a))
|
|
|
|
# define u2_at_pom_hed(a) u2_at_ray((1 + u2_pom_a(a)))
|
|
# define u2_at_pom_tel(a) u2_at_ray((2 + u2_pom_a(a)))
|
|
|
|
# define u2_at_pug_len(a) u2_at_ray((1 + u2_pug_a(a)))
|
|
# define u2_at_pug_buf(a, b) \
|
|
u2_at_ray((2 + (b) + u2_pug_a(a)))
|
|
|
|
# define u2_atom_word(a, b) \
|
|
( u2_fly_is_cat(a) ? (b ? 0 : (a)) : *u2_at_pug_buf(a, b) )
|
|
|
|
/*** Word axis macros.
|
|
****
|
|
**** Use these on axes known to be in 31-bit range.
|
|
***/
|
|
/* u2_ax_dep(): number of axis bits.
|
|
*/
|
|
# define u2_ax_dep(a_w) (c3_bits_word(a_w) - 1)
|
|
|
|
/* u2_ax_cap(): root axis, 2 or 3.
|
|
*/
|
|
# define u2_ax_cap(a_w) (0x2 | (a_w >> (u2_ax_dep(a_w) - 1)))
|
|
|
|
/* u2_ax_mas(): remainder after cap.
|
|
*/
|
|
# define u2_ax_mas(a_w) \
|
|
( (a_w & ~(1 << u2_ax_dep(a_w))) | (1 << (u2_ax_dep(a_w) - 1)) )
|
|
|
|
/* u2_ax_peg(): connect two axes.
|
|
*/
|
|
# define u2_ax_peg(a_w, b_w) \
|
|
( (a_w << u2_ax_dep(b_w)) | (b_w &~ (1 << u2_ax_dep(b_w))) )
|
|
|
|
/** Constants and macros.
|
|
**/
|
|
/* u2_none:
|
|
**
|
|
** An exceptional value, comparable to NaN for floats.
|
|
*/
|
|
# define u2_none u2_dog_of(u2_ray_of(0, 0), 0, 0)
|
|
|
|
/* Small atoms.
|
|
*/
|
|
# define _0 0
|
|
# define _1 1
|
|
# define _2 2
|
|
# define _3 3
|
|
# define _4 4
|
|
# define _5 5
|
|
# define _6 6
|
|
# define _7 7
|
|
# define _8 8
|
|
# define _9 9
|
|
# define _10 10
|
|
# define _11 11
|
|
# define _12 12
|
|
# define _13 13
|
|
# define _14 14
|
|
# define _15 15
|
|
|
|
/* Nock operators.
|
|
*/
|
|
# define u2_nock_frag 0
|
|
# define u2_nock_bone 1
|
|
# define u2_nock_sail 2
|
|
# define u2_nock_dust 3
|
|
# define u2_nock_vint 4
|
|
# define u2_nock_sing 5
|
|
# define u2_nock_trol 6
|
|
# define u2_nock_flac 7
|
|
# define u2_nock_gant 8
|
|
# define u2_nock_kick 9
|
|
# define u2_nock_hint 10
|
|
|
|
# define u2_nock_0 0
|
|
# define u2_nock_1 1
|
|
# define u2_nock_2 2
|
|
# define u2_nock_3 3
|
|
# define u2_nock_4 4
|
|
# define u2_nock_5 5
|
|
# define u2_nock_6 6
|
|
# define u2_nock_7 7
|
|
# define u2_nock_8 8
|
|
# define u2_nock_9 9
|
|
# define u2_nock_10 10
|
|
|
|
|
|
/* New (Nock 5) conventional axes for gate call.
|
|
*/
|
|
#if 1
|
|
# define u2_cv_pay 3 // payload
|
|
# define u2_cv_sam 6 // sample
|
|
# define u2_cv_sam_1 6
|
|
# define u2_cv_sam_2 12
|
|
# define u2_cv_sam_3 13
|
|
# define u2_cv_sam_4 24
|
|
# define u2_cv_sam_5 25
|
|
# define u2_cv_sam_6 26
|
|
# define u2_cv_sam_12 52
|
|
# define u2_cv_sam_13 53
|
|
# define u2_cv_sam_7 27
|
|
# define u2_cv_con 7 // context
|
|
# define u2_cv_con_2 14 // context
|
|
# define u2_cv_con_3 15 // context
|
|
# define u2_cv_con_sam 30 // sample in gate context
|
|
# define u2_cv_noc 2 // deprecated
|
|
# define u2_cv_bat 2 // battery
|
|
#endif
|
|
|
|
/* u2_yes, u2_no, u2_nul;
|
|
**
|
|
** Our Martian booleans and list terminator; empty string.
|
|
*/
|
|
# define u2_yes 0
|
|
# define u2_no 1
|
|
# define u2_nul 0
|
|
# define u2_blip 0
|
|
|
|
/* Tools for Martian booleans.
|
|
*/
|
|
# define u2_na(x) (u2_no == (x))
|
|
# define u2_so(x) (u2_yes == (x))
|
|
# define u2_say(x) ( (x) ? u2_yes : u2_no )
|
|
# define u2_not(x) ( (x == u2_yes) ? u2_no : u2_yes )
|
|
# define u2_and(x, y) ( (u2_so(x) && u2_so(y)) ? u2_yes : u2_no )
|
|
# define u2_or(x, y) ( (u2_so(x) || u2_so(y)) ? u2_yes : u2_no )
|
|
|
|
/** Typedefs.
|
|
***
|
|
*** Noun typedefs may reflect usage, structure, or both. Any noun
|
|
*** typedef is a noun - that is, it may not be (u2_none).
|
|
**/
|
|
/* u2_noun:
|
|
**
|
|
** A fly which is not u2_none.
|
|
*/
|
|
typedef u2_fly u2_noun;
|
|
|
|
/* u2_weak:
|
|
**
|
|
** A fly which may be (and must be tested for) u2_none.
|
|
*/
|
|
typedef u2_fly u2_weak;
|
|
|
|
/* u2_atom:
|
|
**
|
|
** A noun which is an atom.
|
|
*/
|
|
typedef u2_noun u2_atom;
|
|
|
|
/* u2_cell:
|
|
**
|
|
** A noun which is a cell.
|
|
*/
|
|
typedef u2_noun u2_cell;
|
|
|
|
/* u2_bean:
|
|
**
|
|
** A Martian boolean (0 = yes, 1 = no).
|
|
*/
|
|
typedef u2_noun u2_bean;
|
|
|
|
/* u2_axis:
|
|
**
|
|
** An atomic tree address.
|
|
*/
|
|
typedef u2_noun u2_axis;
|
|
|
|
/* u2_mote:
|
|
**
|
|
** An atom < (1 << 31).
|
|
*/
|
|
typedef u2_atom u2_mote;
|
|
|
|
/* u2_term:
|
|
**
|
|
** A Watt symbol.
|
|
*/
|
|
typedef u2_noun u2_term;
|
|
|
|
/* u2_list:
|
|
**
|
|
** A zero-terminated, tailward list.
|
|
*/
|
|
typedef u2_noun u2_list;
|
|
|
|
/* u2_tool:
|
|
**
|
|
** A valid or presumptive Nock formula.
|
|
*/
|
|
typedef u2_noun u2_tool;
|
|
|
|
/* u2_pool:
|
|
**
|
|
** A set, stored as binary treap by mug.
|
|
*/
|
|
typedef u2_noun u2_pool;
|
|
|
|
/* u2_book:
|
|
**
|
|
** An associative array, stored as binary treap by mug.
|
|
*/
|
|
typedef u2_noun u2_book;
|
|
|
|
/* u2_unit:
|
|
**
|
|
** A conditional (maybe), `[0 n]` or `0`.
|
|
*/
|
|
typedef u2_noun u2_unit;
|
|
|
|
/** Functions.
|
|
**/
|
|
/** Lifecycle.
|
|
**/
|
|
/* u2_loom_boot():
|
|
**
|
|
** Instantiate the loom as a new image.
|
|
*/
|
|
void
|
|
u2_loom_boot(void);
|
|
|
|
/* u2_loom_clip():
|
|
**
|
|
** Clip top and bottom.
|
|
*/
|
|
void
|
|
u2_loom_clip(c3_w bot_w, c3_w top_w);
|
|
|
|
/* u2_loom_load():
|
|
**
|
|
** Load the loom from a file.
|
|
*/
|
|
u2_bean
|
|
u2_loom_load(void);
|
|
|
|
/* u2_loom_exit():
|
|
**
|
|
** Quit out of the loom.
|
|
*/
|
|
void
|
|
u2_loom_exit(void);
|
|
|
|
/* u2_loom_save():
|
|
**
|
|
** Save the current loom at the current event number.
|
|
*/
|
|
u2_bean
|
|
u2_loom_save(c3_d ent_d);
|
|
|
|
/** General.
|
|
**/
|
|
|
|
/* u2_dust():
|
|
**
|
|
** Yes iff (a) is a cell.
|
|
*/
|
|
#if 0
|
|
u2_bean
|
|
u2_dust(u2_noun a)
|
|
#else
|
|
# define u2_dust(a) \
|
|
(u2_fly_is_atom(a) ? u2_no : u2_yes)
|
|
#endif
|
|
|
|
/* u2_frag():
|
|
**
|
|
** Return fragment (a) of (b), or u2_none if not applicable.
|
|
*/
|
|
u2_weak
|
|
u2_frag(u2_atom a,
|
|
u2_noun b);
|
|
|
|
/* u2_mean():
|
|
**
|
|
** Attempt to deconstruct `a` by axis, noun pairs; 0 terminates.
|
|
** Axes must be sorted in tree order.
|
|
*/
|
|
u2_bean
|
|
u2_mean(u2_noun a,
|
|
...);
|
|
|
|
/* u2_mug():
|
|
**
|
|
** Compute and/or recall the mug (31-bit hash) of (a).
|
|
*/
|
|
c3_w
|
|
u2_mug(u2_noun a);
|
|
|
|
/* u2_mug_string():
|
|
**
|
|
** Compute the mug of `a`, LSB first.
|
|
*/
|
|
c3_w
|
|
u2_mug_string(const c3_c *a_c);
|
|
|
|
/* u2_mug_words():
|
|
**
|
|
** Compute the mug of `buf`, `len`, LSW first.
|
|
*/
|
|
c3_w
|
|
u2_mug_words(const c3_w *buf_w,
|
|
c3_w len_w);
|
|
|
|
/* u2_mug_cell():
|
|
**
|
|
** Compute the mug of `[a b]`.
|
|
*/
|
|
c3_w
|
|
u2_mug_cell(u2_noun a,
|
|
u2_noun b);
|
|
|
|
/* u2_mug_trel():
|
|
**
|
|
** Compute the mug of `[a b c]`.
|
|
*/
|
|
c3_w
|
|
u2_mug_trel(u2_noun a,
|
|
u2_noun b,
|
|
u2_noun c);
|
|
|
|
/* u2_mug_qual():
|
|
**
|
|
** Compute the mug of `[a b c d]`.
|
|
*/
|
|
c3_w
|
|
u2_mug_qual(u2_noun a,
|
|
u2_noun b,
|
|
u2_noun c,
|
|
u2_noun d);
|
|
|
|
/* u2_mug_both():
|
|
**
|
|
** Join two mugs.
|
|
*/
|
|
c3_w
|
|
u2_mug_both(c3_w a_w,
|
|
c3_w b_w);
|
|
|
|
/* u2_fing():
|
|
**
|
|
** Yes iff (a) and (b) are the same copy of the same noun.
|
|
** (Ie, by pointer equality - u2_sing with false negatives.)
|
|
*/
|
|
u2_bean
|
|
u2_fing(u2_noun a,
|
|
u2_noun b);
|
|
|
|
/* u2_fing_c():
|
|
**
|
|
** Yes iff (b) is the same copy of the same noun as the C string [a].
|
|
*/
|
|
u2_bean
|
|
u2_fing_c(const c3_c* a_c,
|
|
u2_noun b);
|
|
|
|
/* u2_fing_cell():
|
|
**
|
|
** Yes iff `[p q]` and `b` are the same copy of the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_fing_cell(u2_noun p,
|
|
u2_noun q,
|
|
u2_noun b);
|
|
|
|
/* u2_fing_mixt():
|
|
**
|
|
** Yes iff `[p q]` and `b` are the same copy of the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_fing_mixt(const c3_c* p_c,
|
|
u2_noun q,
|
|
u2_noun b);
|
|
|
|
/* u2_fing_trel():
|
|
**
|
|
** Yes iff `[p q r]` and `b` are the same copy of the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_fing_trel(u2_noun p,
|
|
u2_noun q,
|
|
u2_noun r,
|
|
u2_noun b);
|
|
|
|
/* u2_fing_qual():
|
|
**
|
|
** Yes iff `[p q r s]` and `b` are the same copy of the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_fing_qual(u2_noun p,
|
|
u2_noun q,
|
|
u2_noun r,
|
|
u2_noun s,
|
|
u2_noun b);
|
|
|
|
/* u2_sing():
|
|
**
|
|
** Yes iff (a) and (b) are the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_sing(u2_noun a,
|
|
u2_noun b);
|
|
|
|
/* u2_sing_c():
|
|
**
|
|
** Yes iff (b) is the same noun as the C string [a].
|
|
*/
|
|
u2_bean
|
|
u2_sing_c(const c3_c* a_c,
|
|
u2_noun b);
|
|
|
|
/* u2_sing_cell():
|
|
**
|
|
** Yes iff `[p q]` and `b` are the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_sing_cell(u2_noun p,
|
|
u2_noun q,
|
|
u2_noun b);
|
|
|
|
/* u2_sing_mixt():
|
|
**
|
|
** Yes iff `[p q]` and `b` are the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_sing_mixt(const c3_c* p_c,
|
|
u2_noun q,
|
|
u2_noun b);
|
|
|
|
/* u2_sing_trel():
|
|
**
|
|
** Yes iff `[p q r]` and `b` are the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_sing_trel(u2_noun p,
|
|
u2_noun q,
|
|
u2_noun r,
|
|
u2_noun b);
|
|
|
|
/* u2_sing_qual():
|
|
**
|
|
** Yes iff `[p q r s]` and `b` are the same noun.
|
|
*/
|
|
u2_bean
|
|
u2_sing_qual(u2_noun p,
|
|
u2_noun q,
|
|
u2_noun r,
|
|
u2_noun s,
|
|
u2_noun b);
|
|
|
|
/* u2_nord():
|
|
**
|
|
** Return 0, 1 or 2 if `a` is below, equal to, or above `b`.
|
|
*/
|
|
u2_atom
|
|
u2_nord(u2_noun a,
|
|
u2_noun b);
|
|
|
|
/* u2_stud():
|
|
**
|
|
** Yes iff (a) is an atom.
|
|
*/
|
|
#if 0
|
|
u2_bean
|
|
u2_stud(u2_noun a)
|
|
#else
|
|
# define u2_stud(a) \
|
|
(u2_fly_is_atom(a) ? u2_yes : u2_no)
|
|
#endif
|
|
|
|
/** Cell access.
|
|
**/
|
|
/* u2_as_bush():
|
|
**
|
|
** Factor [a] as a bush [b.[p q] c].
|
|
*/
|
|
u2_bean
|
|
u2_as_bush(u2_noun a,
|
|
u2_noun* b,
|
|
u2_noun* c);
|
|
|
|
/* u2_as_cell():
|
|
**
|
|
** Factor (a) as a cell (b c).
|
|
*/
|
|
u2_bean
|
|
u2_as_cell(u2_noun a,
|
|
u2_noun* b,
|
|
u2_noun* c);
|
|
|
|
/* u2_as_hext():
|
|
**
|
|
** Factor (a) as a hext (b c d e f g)
|
|
*/
|
|
u2_bean
|
|
u2_as_hext(u2_noun a,
|
|
u2_noun* b,
|
|
u2_noun* c,
|
|
u2_noun* d,
|
|
u2_noun* e,
|
|
u2_noun* f,
|
|
u2_noun* g);
|
|
|
|
/* u2_as_p():
|
|
**
|
|
** & [0] if [a] is of the form [b *c].
|
|
*/
|
|
u2_bean
|
|
u2_as_p(u2_noun a,
|
|
u2_noun b,
|
|
u2_noun* c);
|
|
|
|
/* u2_as_pq():
|
|
**
|
|
** & [0] if [a] is of the form [b *c d].
|
|
*/
|
|
u2_bean
|
|
u2_as_pq(u2_noun a,
|
|
u2_noun b,
|
|
u2_noun* c,
|
|
u2_noun* d);
|
|
|
|
/* u2_as_pqr():
|
|
**
|
|
** & [0] if [a] is of the form [b *c *d *e].
|
|
*/
|
|
u2_bean
|
|
u2_as_pqr(u2_noun a,
|
|
u2_noun b,
|
|
u2_noun* c,
|
|
u2_noun* d,
|
|
u2_noun* e);
|
|
|
|
/* u2_as_pqrs():
|
|
**
|
|
** & [0] if [a] is of the form [b *c *d *e *f].
|
|
*/
|
|
u2_bean
|
|
u2_as_pqrs(u2_noun a,
|
|
u2_noun b,
|
|
u2_noun* c,
|
|
u2_noun* d,
|
|
u2_noun* e,
|
|
u2_noun* f);
|
|
|
|
/* u2_as_qual():
|
|
**
|
|
** Factor (a) as a qual (b c d e).
|
|
*/
|
|
u2_bean
|
|
u2_as_qual(u2_noun a,
|
|
u2_noun* b,
|
|
u2_noun* c,
|
|
u2_noun* d,
|
|
u2_noun* e);
|
|
|
|
/* u2_as_quil():
|
|
**
|
|
** Factor (a) as a quil (b c d e f).
|
|
*/
|
|
u2_bean
|
|
u2_as_quil(u2_noun a,
|
|
u2_noun* b,
|
|
u2_noun* c,
|
|
u2_noun* d,
|
|
u2_noun* e,
|
|
u2_noun* f);
|
|
|
|
/* u2_as_trel():
|
|
**
|
|
** Factor (a) as a trel (b c d).
|
|
*/
|
|
u2_bean
|
|
u2_as_trel(u2_noun a,
|
|
u2_noun *b,
|
|
u2_noun *c,
|
|
u2_noun *d);
|
|
|
|
/* u2_h(), u2_sh():
|
|
**
|
|
** Return the head of `a`, unsafely or safely.
|
|
*/
|
|
#if 0
|
|
u2_noun
|
|
u2_h(u2_noun a);
|
|
#else
|
|
# define u2_h(a) (*u2_at_pom_hed(a))
|
|
#endif
|
|
u2_noun
|
|
u2_sh(u2_noun a);
|
|
|
|
/* u2_t(), u2_st():
|
|
**
|
|
** Return the tail of `a`, unsafely or safely.
|
|
*/
|
|
#if 0
|
|
u2_noun
|
|
u2_t(u2_noun a);
|
|
#else
|
|
# define u2_t(a) (*u2_at_pom_tel(a))
|
|
#endif
|
|
u2_noun
|
|
u2_st(u2_noun a);
|
|
|
|
/** Atom access.
|
|
**/
|
|
/* u2_met():
|
|
**
|
|
** Return the size of (b) in bits, rounded up to
|
|
** (1 << a_y).
|
|
**
|
|
** For example, (a_y == 3) returns the size in bytes.
|
|
*/
|
|
c3_w
|
|
u2_met(c3_y a_y,
|
|
u2_atom b);
|
|
|
|
/* u2_bit():
|
|
**
|
|
** Return bit (a_w) of (b).
|
|
*/
|
|
c3_b
|
|
u2_bit(c3_w a_w,
|
|
u2_atom b);
|
|
|
|
/* u2_byte():
|
|
**
|
|
** Return byte (a_w) of (b).
|
|
*/
|
|
c3_y
|
|
u2_byte(c3_w a_w,
|
|
u2_atom b);
|
|
|
|
/* u2_bytes():
|
|
**
|
|
** Copy bytes (a_w) through (a_w + b_w - 1) from (d) to (c).
|
|
*/
|
|
void
|
|
u2_bytes(c3_w a_w,
|
|
c3_w b_w,
|
|
c3_y* c_y,
|
|
u2_atom d);
|
|
|
|
/* u2_chop():
|
|
**
|
|
** Into the bloq space of `met`, from position `fum` for a
|
|
** span of `wid`, to position `tou`, XOR from atom `src`
|
|
** into ray `dst`.
|
|
*/
|
|
void
|
|
u2_chop(c3_g met_g,
|
|
c3_w fum_w,
|
|
c3_w wid_w,
|
|
c3_w tou_w,
|
|
u2_ray dst_r,
|
|
u2_atom src);
|
|
|
|
/* u2_mp():
|
|
**
|
|
** Copy (b) into (a_mp).
|
|
*/
|
|
void
|
|
u2_mp(mpz_t a_mp,
|
|
u2_atom b);
|
|
|
|
/* u2_word():
|
|
**
|
|
** Return word (a_w) of (b).
|
|
*/
|
|
c3_w
|
|
u2_word(c3_w a_w,
|
|
u2_atom b);
|
|
|
|
/* u2_chub():
|
|
**
|
|
** Return double-word (a_w) of (b).
|
|
*/
|
|
c3_d
|
|
u2_chub(c3_w a_w,
|
|
u2_atom b);
|
|
|
|
/* u2_words():
|
|
**
|
|
** Copy words (a_w) through (a_w + b_w - 1) from (d) to (c).
|
|
*/
|
|
void
|
|
u2_words(c3_w a_w,
|
|
c3_w b_w,
|
|
c3_w* c_w,
|
|
u2_atom d);
|