// tape and area are included with Tape Machine to facilitate abstract interfaces.
typedef struct{
- struct {
- Core路Status (*topo) ( TM *tm ,TM路Tape路Topo *result );
- 螢(extent_t ,CVT) (*extent)( TM *tm );
- } tape;
-
- struct {
- // Initialize tm
- Core路Status (*mount_pe)(TM *tm ,CVT position[] ,螢(extent_t ,CVT) extent);
- Core路Status (*mount_pp)(TM *tm ,CVT *position_left ,CVT *position_right);
- } area;
+ Core路Status (*topo) (TM *tm ,TM路Tape路Topo *result);
// tape machine functions
Core路Status (*mount) (TM *tm);
void (*step_right)(TM *tm); // Synonym for step
void (*rewind) (TM *tm);
- void (*copy_datum)( TM *tm_read ,TM *tm_write );
- void (*apply)( TM *tm_read , TM路FN);
-
} TM路FG;
-
#endif // #ifndef CVT
#ifdef CVT
+ typedef 螢(extent_t ,CVT) size_t;
+ // instance struct with vtable pointer as first entry
typedef struct{
-
- void (*read) ( TM *tm ,CVT *remote_pt );
- void (*write) ( TM *tm ,CVT *remote_pt );
-
+ 螢(extent_t ,CVT) (*extent)(TM *tm);
+ CVT (*read) (TM *tm);
+ void (*write)(TM *tm ,CVT *remote_pt);
} 螢(TM ,CVT);
- // default table for TM implemented by an Array
- #ifdef Array
- 螢(TM ,CVT)路FG 螢(TM路Array ,CVT)路fg;
- #endif
+ // Array Initializers
+ typedef struct{
+ TM *(*mount_pe)( 螢(TM路Array ,CVT) *tm ,CVT position[] ,螢(extent_t ,CVT) extent );
+ TM *(*mount_pp)( 螢(TM路Array ,CVT) *tm ,CVT *position_left ,CVT *position_right );
+ } 螢(TM路Array ,CVT)路FG;
+
+ 螢(TM ,CVT)路FG 螢(TM路Array ,CVT)路fg;
#endif // #ifdef CVT
//-----------------------------------
// common error messages
- const char *TM路Array路Msg路tm="given NULL tm";
- const char *TM路Array路Msg路flag="given NULL flag pointer";
- const char *TM路Array路Msg路result="given NULL result pointer";
- const char *TM路Array路Msg路position=
+ const char *TM路Msg路tm="given NULL tm";
+ const char *TM路Msg路position=
"Null position.This is only possible when the tape machine has not been initialized.";
+ const char *TM路Msg路flag="given NULL flag pointer";
+ const char *TM路Msg路result="given NULL result pointer";
- #endif // #ifndef CVT
-
- #ifdef CVT
+ //-----------------------------------
+ // generic instance type, with vtable pointer at top
struct{
- 螢(TM ,CVT)路FG *fg
- }螢(TM ,CVT);
+ TM路FG *fg;
+ } TM;
//-----------------------------------
- // TM路Array.tape implementation
+ // generic call wrappers
- /*
- For an Array Tape Machine ,a bound tape will be singleton or segment.
- An initialized Array Tape Machine always has a bound tape.
- */
- Core路Status 螢(TM ,CVT)路topo(螢(TM路Array ,CVT) *tm ,TM路Tape路Topo *result){
+ Core路Status TM路topo(TM *tm ,TM路Tape路Topo *result){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
- Core路Guard路fg.check(&chk ,1 ,result ,TM路Array路Msg路result);
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
+ Core路Guard路fg.check(&chk ,1 ,result ,TM路Msg路result);
Core路Guard路if_return(chk);
#endif
- if(tm->extent == 0){
- *result = TM路Tape路Topo路singleton;
- }else{
- *result = TM路Tape路Topo路segment;
- }
- return Core路Status路on_track;
+ return tm->fg.topo(tm ,result);
}
- // check the topo to make sure tape has extent before calling this
- // `extent路CVT` returns the index to the rightmost cell in the array.
- Local 螢(extent_t ,CVT) 螢(TM路Array ,CVT)路extent(螢(TM路Array ,CVT) *tm){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- Core路Tape路Topo topo = Core路Tape路Topo路mu;
- Core路Status status = 螢(TM路Array ,CVT)路topo(tm ,&topo);
- bool good_topo =
- (status == Core路Status路on_track) && (topo & Core路Tape路Topo路finite_nz)
- ;
- Core路Guard路fg.check(&chk ,1 ,good_topo ,"Tape does not have an extent.");
- Core路Guard路assert(chk);
- #endif
-
- *result = tm->extent;
- return Core路Status路on_track;
+ // mount dismount
+ #define Core路Status_tm(name) \
+ Local Core路Status TM##name##(TM *tm) { \
+ #ifdef TM路DEBUG \
+ Core路Guard路init_count(chk); \
+ Core路Guard路fg.check(&chk, 1, tm, TM路Msg路tm); \
+ Core路Guard路if_return(chk); \
+ #endif \
+ return tm->fg.##name##(tm); \
}
- //-----------------------------------
- // TM路Array.area implementation
-
- Local Core路Status 螢(TM路Array ,CVT)路mount_pe(
- 螢(TM路Array ,CVT) *tm ,CVT *position ,螢(extent_t ,CVT) extent
- ){
+ Core路Status_tm(mount);
+ Core路Status_tm(dismount);
+
+ Local TM路Head路Status TM路status(TM *tm ,TM路Head路Status *result){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
- Core路Guard路fg.check(&chk ,1 ,position ,"Given NULL position.");
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
+ Core路Guard路fg.check(&chk ,1 ,result ,TM路Msg路result);
Core路Guard路if_return(chk);
#endif
- tm->position = position;
- tm->extent = extent;
- tm->hd = position; // mount the head on the origin cell
- return Core路Status路on_track;
+ return tm->fg.status(tm ,result);
}
- // If size of CVT is not a power of two this can perform a divide
- Local Core路Status 螢(TM路Array ,CVT)路mount_pp(
- 螢(TM路Array ,CVT) *tm ,CVT *pos_leftmost ,CVT *pos_rightmost
- ){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,pos_leftmost ,"Null pos_leftmost.");
- Core路Guard路fg.check(&chk ,1 ,pos_rightmost ,"Null pos_rightmost.");
- if(pos_leftmost && pos_rightmost){
- Core路Guard路fg.check(&chk ,1 ,pos_rightmost >= pos_leftmost
- ,"pos_rightmost < pos_leftmost"
- );
- }
- Core路Guard路if_return(chk);
- #endif
-
- 螢(extent_t ,CVT) extent = pos_rightmost - pos_leftmost);
- return 螢(TM路Array ,CVT)路mount_pe(tm ,pos_leftmost ,extent);
- }
-
- //-----------------------------------
- // base Tape Machine operations
-
- Local Core路Status 螢(TM路Array ,CVT)路mount(螢(TM路Array ,CVT) *tm){
+ // Stronger than `can_read`. Used mostly for debugging.
+ // as it checks for a legal head position.
+ Local Core路Status TM路head_on_format(TM *tm ,bool *flag){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
- if(tm) Core路Guard路fg.check(&chk ,1 ,tm->position ,TM路Array路Msg路position);
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
+ Core路Guard路fg.check(&chk ,1 ,flag ,TM路Msg路flag);
Core路Guard路if_return(chk);
#endif
-
- // mounting an already mounted head does nothing ,perhaps you meant `rewind`?
- if(!tm->hd) tm->hd = tm->position;
- return Core路Status路on_track;
+ return tm->fg.head_on_format(tm ,flag);
}
- Local Core路Status 螢(TM路Array ,CVT)路dismount(螢(TM路Array ,CVT) *tm){
+ bool bool_fn_tm(TM *tm){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
Core路Guard路if_return(chk);
#endif
-
- tm->hd = NULL;
- return Core路Status路on_track;
+ return tm->fg.read(tm);
}
- Local TM路Head路Status 螢(TM路Array ,CVT)路status(
- 螢(TM路Array ,CVT) *tm ,TM路Head路Status *status
- ){
+ bool TM路on_leftmost(TM *tm){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
- Core路Guard路fg.check(&chk ,1 ,status ,"given NULL status pointer");
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
Core路Guard路if_return(chk);
#endif
-
- if(tm->hd == NULL){
- *status = TM路Head路Status路not_on_tape;
- }else if(tm->hd == tm->position){
- *status = TM路Head路Status路origin;
- }else if(tm->hd == tm->position + tm->extent){
- *status = TM路Head路Status路rightmost;
- }else{
- *status = TM路Head路Status路interim;
- }
-
- return Core路Status路on_track;
+ return tm->fg.on_leftmost(tm);
}
- // Stronger than `can_read`. Used mostly for debugging.
- // as it checks for a legal head position.
- Local Core路Status 螢(TM路Array ,CVT)路head_on_format(
- 螢(TM路Array ,CVT) *tm ,bool *flag
- ){
+ bool TM路on_rigthmost(TM *tm){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
- Core路Guard路fg.check(&chk ,1 ,tm ,TM路Array路Msg路tm);
- if(tm) Core路Guard路fg.check(&chk ,1 ,tm->position ,TM路Array路Msg路position);
- Core路Guard路fg.check(&chk ,1 ,flag ,TM路Array路Msg路flag);
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
Core路Guard路if_return(chk);
#endif
-
- *flag =
- tm->hd
- && tm->hd >= tm->position
- && tm->hd - tm->position <= tm->extent
- && ( (AU *)tm->hd - (AU *)tm->position ) % sizeof(CVT) == 0 // '%' expensive
- ;
- return Core路Status路on_track;
- }
-
- bool 螢(TM路Array ,CVT)路can_read(螢(TM路Array ,CVT) *tm){
- return tm && tm->position && tm->hd;
- }
-
- // can_read was true
- bool 螢(TM路Array ,CVT)路on_origin(螢(TM路Array ,CVT) *tm){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
- Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
- Core路Guard路assert(chk);
- #endif
- return tm->hd == tm->position;
+ return tm->fg.on_rigthmost(tm);
}
- // can_read was true
- bool 螢(TM路Array ,CVT)路on_rightmost(螢(TM路Array ,CVT) *tm){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
- Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
- Core路Guard路assert(chk);
- #endif
- return tm->hd == tm->position;
- }
- void 螢(TM路Array ,CVT)路step(螢(TM路Array ,CVT) *tm){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
- Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
- Core路Guard路assert(chk);
- #endif
- tm->hd++;
- }
- void 螢(TM路Array ,CVT)路step_left(螢(TM路Array ,CVT) *tm){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
- Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
- Core路Guard路assert(chk);
- #endif
- tm->hd--;
- }
-
- void 螢(TM路Array ,CVT)路rewind(螢(TM路Array ,CVT) *tm){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
- Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
- Core路Guard路assert(chk);
- #endif
- tm->hd = tm->position;
- }
+ Local bool TM路Given1(can_read);
+ Local bool TM路Given1(on_leftmost);
+ Local bool TM路Given1(on_rightmost);
+ Local bool TM路Given1(step);
+ Local bool TM路Given1(step_left);
+ Local bool TM路Given1(rewind);
// tm_can_read must be true for both machines.
- void 螢(TM路Array ,CVT)路copy_datum(螢(TM路Array ,CVT) *tm_read ,螢(TM路Array ,CVT) *tm_write){
+ void TM路copy_datum(TM *tm_read ,TM *tm_write){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm_read ,flag) == Control路Status路on_track;
+ s = TM路head_on_format(tm_read ,flag) == Control路Status路on_track;
Core路Guard路fg.check(&chk ,1 ,s && flag ,"tm_read head off track");
- s = 螢(TM路Array ,CVT)路head_on_format(tm_write ,flag) == Control路Status路on_track;
+ s = TM路head_on_format(tm_write ,flag) == Control路Status路on_track;
Core路Guard路fg.check(&chk ,1 ,s && flag ,"tm_write head off track");
Core路Guard路assert(chk);
#endif
return Core路Status路on_track;
}
- void 螢(TM路Array ,CVT)路read(螢(TM路Array ,CVT) *tm ,CVT *read_pt){
+ void TM路read(TM *tm ,CVT *read_pt){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+ s = TM路head_on_format(tm ,flag) == Core路Status路on_track;
Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
Core路Guard路assert(chk);
#endif
*read_pt = *(tm->hd);
}
- void 螢(TM路Array ,CVT)路write(螢(TM路Array ,CVT) *tm ,CVT *write_pt){
+ void TM路write(TM *tm ,CVT *write_pt){
#ifdef TM路DEBUG
Core路Guard路init_count(chk);
bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+ s = TM路head_on_format(tm ,flag) == Core路Status路on_track;
Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
Core路Guard路assert(chk);
#endif
// step_right is a synonym for step
+ // check the topo to make sure tape has extent before calling this
+ // `extent路CVT` returns the index to the rightmost cell in the array.
+ Local 螢(extent_t ,CVT) TM路extent(TM *tm){
+ #ifdef TM路DEBUG
+ Core路Guard路init_count(chk);
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
+ Core路Guard路assert(chk);
+ #endif
+ return tm->fg.extent(tm);
+ }
+
+
//----------------------------------------
- // Initialization for 螢(TM路Array ,CVT)路fg
+ // Initialization for TM路fg
- Local 螢(TM路Array ,CVT)路FG 螢(TM路Array ,CVT)路fg = {
+ Local TM路FG TM路fg = {
.tape = {
- .topo = 螢(TM路Array ,CVT)路topo
- .extent = 螢(TM路Array ,CVT)路extent
+ .topo = TM路topo
+ .extent = TM路extent
}
,.area = {
- .mount_pe = 螢(TM路Array ,CVT)路mount_pe
- ,.mount_pp = 螢(TM路Array ,CVT)路mount_pp
+ .mount_pe = TM路mount_pe
+ ,.mount_pp = TM路mount_pp
}
- ,.mount = 螢(TM路Array ,CVT)路mount
- ,.dismount = 螢(TM路Array ,CVT)路dismount
+ ,.mount = TM路mount
+ ,.dismount = TM路dismount
- ,.status = 螢(TM路Array ,CVT)路status
- ,.head_on_format = 螢(TM路Array ,CVT)路head_on_format
+ ,.status = TM路status
+ ,.head_on_format = TM路head_on_format
- ,.can_read = 螢(TM路Array ,CVT)路can_read
- ,.on_origin = 螢(TM路Array ,CVT)路on_origin
- ,.on_rightmost = 螢(TM路Array ,CVT)路on_rightmost
+ ,.can_read = TM路can_read
+ ,.on_origin = TM路on_origin
+ ,.on_rightmost = TM路on_rightmost
- ,.step = 螢(TM路Array ,CVT)路step
- ,.step_left = 螢(TM路Array ,CVT)路step_left
- ,.step_right = 螢(TM路Array ,CVT)路step_right // Synonym for step
- ,.rewind = 螢(TM路Array ,CVT)路rewind
-
- ,.copy_datum = 螢(TM路Array ,CVT)路copy_datum
- ,.read = 螢(TM路Array ,CVT)路read
- ,.write = 螢(TM路Array ,CVT)路write
+ ,.step = TM路step
+ ,.step_left = TM路step_left
+ ,.step_right = TM路step_right // Synonym for step
+ ,.rewind = TM路rewind
+ ,.read = TM路read
+ ,.write = TM路write
};
#endif // ifdef CVT
*read_pt = *(tm->hd);
}
- void 螢(TM路Array ,CVT)路write(螢(TM路Array ,CVT) *tm ,CVT *write_pt){
- #ifdef TM路DEBUG
- Core路Guard路init_count(chk);
- bool flag = true ,s;
- s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
- Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
- Core路Guard路assert(chk);
- #endif
-
- *(tm->hd) = *write_pt;
- }
// step_right is a synonym for step
#endif // LOCAL
#endif // IMPLEMENTATION
+
+
+void 螢(TM路Array ,CVT)路write(螢(TM路Array ,CVT) *tm ,CVT *write_pt){
+ #ifdef TM路DEBUG
+ Core路Guard路init_count(chk);
+ bool flag = true ,s;
+ s = 螢(TM路Array ,CVT)路head_on_format(tm ,flag) == Core路Status路on_track;
+ Core路Guard路fg.check(&chk ,1 ,s && flag ,"head off format");
+ Core路Guard路assert(chk);
+ #endif
+
+ *(tm->hd) = *write_pt;
+}
+
+ //-----------------------------------
+ // TM struct initializers
+
+ Local Core路Status TM路mount_pe(
+ TM *tm ,CVT *position ,螢(extent_t ,CVT) extent
+ ){
+ #ifdef TM路DEBUG
+ Core路Guard路init_count(chk);
+ Core路Guard路fg.check(&chk ,1 ,tm ,TM路Msg路tm);
+ Core路Guard路fg.check(&chk ,1 ,position ,"Given NULL position.");
+ Core路Guard路if_return(chk);
+ #endif
+ tm->position = position;
+ tm->extent = extent;
+ tm->hd = position; // mount the head on the origin cell
+ return Core路Status路on_track;
+ }
+
+ // If size of CVT is not a power of two this can perform a divide
+ Local Core路Status TM路mount_pp(
+ TM *tm ,CVT *pos_leftmost ,CVT *pos_rightmost
+ ){
+ #ifdef TM路DEBUG
+ Core路Guard路init_count(chk);
+ Core路Guard路fg.check(&chk ,1 ,pos_leftmost ,"Null pos_leftmost.");
+ Core路Guard路fg.check(&chk ,1 ,pos_rightmost ,"Null pos_rightmost.");
+ if(pos_leftmost && pos_rightmost){
+ Core路Guard路fg.check(&chk ,1 ,pos_rightmost >= pos_leftmost
+ ,"pos_rightmost < pos_leftmost"
+ );
+ }
+ Core路Guard路if_return(chk);
+ #endif
+
+ 螢(extent_t ,CVT) extent = pos_rightmost - pos_leftmost);
+ return TM路mount_pe(tm ,pos_leftmost ,extent);
+ }
+