#include #include #include "getcmd.h" #include "help.h" #include "quint.h" #include "tape.h" #include "step.h" #include "macro.h" #include "watch.h" #include "setsho.h" #include "fileio.h" #include "tm.h" /********************/ #ifdef VMS char *help_file="tm_hlp:tm.hlp"; #else char *help_file="tm.hlp"; #endif char tm_state = '0'; /* the turing machine state */ int tm_num_exe = 0; /* total number of quintuple executions */ int trace=0; /* flag for showing tape at each machine step */ int debug=1; /* flag for setting debug on or off */ int max_step=10000; /* maximum number of steps to take with 'go' */ char filename[PATHSIZE]; /* name of the file that was just read */ char ans[ANS_LENGTH]; /* buffer for tokens that are input by user*/ struct quint *lastquint; /* last quintuple that was executed */ struct quint *nextquint; /* next quintuple to be executed */ /************ 'WATCH' variables *******/ char watch_state[WATCH_LIM + 1]; /* buffer for watch points*/ int nwatchstate = -1; /* pointer to watch point buffer*/ char watch_symbol[WATCH_LIM + 1]; int nwatchsymbol = -1; /*******************************/ void dele(struct qlist *ql) { int status; while(1) { getcmd("delete what? ",ans); if ( iscmd(ans,"?") || iscmd(ans,"h*elp") ) get_help("tm delete"); else if ( iscmd(ans,"e*xit") || iscmd(ans,"quit" ) || iscmd(ans,".") ) break; else if ( iscmd(ans,"quin*tuple") ) { while(1) { getcmd("enter a two character string: ",ans); if ( iscmd(ans,"exit") || iscmd(ans,".") ) break; del_quint(ql,ans[0],ans[1],&status); if (status == OK) break; else { message(ans,status); if (status != NO_SUCH_Q) /* don't ask again--there is no list*/ break; } } break; } else if ( iscmd(ans,"a*ll") ) { del_all_quint(ql,&status); if (status != OK ) message("",status); break; } else if ( iscmd(ans,"l*ist") ) { del_list_quint(ql,&status); if (status != EMPTY_QLIST) message("",status); break; } else if (iscmd(ans,"#") ) flushcmd("","",0); else flushcmd("invalid or ambiguous delete command -> ",ans,1); } } /* prompts the user for a quintuple list. */ /**/ void enter(struct qlist *ql) { #ifdef DEAD char cmmt[COMMENT_LENGTH]; inbuf[COMMENT_LENGTH + 8]; #else char *cmmt; char inbuf[ANS_LENGTH]; #endif char quint[6]; char ch; int i,status; printf("Input quintuples with (optional) comments, one per line.\n"); printf("Start each quintuple with '('. End with '.' in column 1. \n"); quint[5] = '\0'; while (1) { /* get a line from standard input. */ /* WTF? What's wrong with gets? */ i = 0; while ( (ch=getchar())!=EOF && ch!= '\n' ) inbuf[i++] = ch; inbuf[i] = '\0'; /* quit if requested. */ if ( inbuf[0] == '.' || (inbuf[0] == '\0' && ch == EOF) ) break; /* check the line, and store it as a quintuple if valid. */ if ( inbuf[0] != '(' && inbuf[0] != '.' ) printf("column one must have ( for quintuple or . to quit\n"); else if ( strlen(inbuf) < 6 ) printf("quintuples must have 5 characters\n"); else { strncpy(quint,inbuf+1,5); #ifdef DEAD if ( inbuf[6] != '\0' ) strcpy(cmmt,inbuf+6); else cmmt[0] = '\0'; #else if ( inbuf[6] != '\0' ) cmmt = inbuf+6; else cmmt = NULL; #endif /* add the quintuple, signal on error */ if ( new_quint(ql, quint,cmmt,&status) == NULL ) message(quint,status); if ( ch == EOF ) break; } } } main (int argc, char* argv[]) { struct tape tp; /* the turing machine tape */ struct maclist mlist; /* a macro buffer */ struct qlist *lptr = NULL; struct tape *tptr = &tp; struct maclist *mptr = &mlist; int status; /* returned by some routines to signal success or failure. See TM.H for possible status values.*/ char buff[80]; /******** Executable code: ******************************/ lptr = new_qlist(&status); tptr->head = tptr->root = NULL; /* pointer to tape and the tape head */ tptr->leftend = NULL; /* pointer to left end of the tape */ tptr->tape_len = 0; /* length of the tape */ mptr->root = NULL; /* pointer to macrolist */ mptr->list_name = NULL; /* filename of the macro file */ mptr->num_macword = 0; /* number of words in the macro */ lastquint = NULL; /* for displaying last executed quint*/ nextquint = NULL; /* for displaying next quint to use */ printf (" TM -- Turing machine program. V1.32\n"); printf (" Enter 'help' for help.\n"); strcpy(filename,"(none selected yet)"); if (argc == 2) { read_tm_file(argv[1],lptr,&status); if ( status != OK ) message(argv[1],status); else strcpy(filename,argv[1]); } init_help(help_file); /* read the help file */ /* main program loop */ while(1) { getcmd("tm> ",ans); if ( ans[0] == 0 ); /* flush invalid input */ else if ( iscmd (ans,"exit") || iscmd (ans,"quit") ) break; else if (iscmd (ans,"en*ter")) enter(lptr); /*primitive quintuple editor*/ else if (iscmd (ans,"se*t")) set(lptr,tptr,mptr); else if (iscmd (ans,"ad*d")) add(lptr); /*add a quintuple*/ else if (iscmd(ans,"ca*ncel")) cancel(lptr); /*cancel a break point*/ else if (iscmd (ans,"sh*ow")) show(lptr,tptr,mptr); else if (iscmd (ans,"li*st")) { list_quints(lptr, &status); /*show the quintuples*/ if ( status != OK ) message("",status); } else if (iscmd (ans,"st*ep")) { step(lptr,tptr,&status); /*perform some machine executions*/ if ( status != OK ) message("",status); } else if (iscmd (ans,"go")) { go(lptr,tptr,&status); /*execute till halt*/ if ( status == HALTED_FINAL || status == HALTED ) { buff[0]=tm_state; buff[1]='\0'; message(buff,status); } else if ( status == SHOW_TAPE ) show_tape(tptr,&status); /*if display of tape was requested*/ else if ( status != OK ) message("",status); } else if ( iscmd (ans,"run") ) /*run the stored macro*/ { run_mac(mptr, &status); /* pushes the macro onto command stack*/ if ( status != OK ) message("",status); } else if ( iscmd (ans,"del*ete") ) dele(lptr); /* delete one or all quintuples*/ else if (iscmd (ans,"m*ove")) { move(tptr, &status); /* move the tape head on the tape*/ if ( status != OK ) message("",status); } else if (iscmd (ans,"re*ad")) read_file(lptr,mptr); /* read a mac or a tm file*/ else if (iscmd (ans,"wr*ite")) write_file(lptr,mptr); /* write a mac or a tm file*/ else if (iscmd (ans,"ed*macro")) edmacro(mptr); /* edit the macro*/ else if (iscmd (ans,"say")) { getcmd("say what? ",ans); printf("%s\n",ans); } else if (iscmd (ans,"echo")) { getcmd("echo what? ",ans); printf("%s\n",ans); } else if ( iscmd(ans,"?") || iscmd (ans,"h*elp") ) { strcpy(buff,"tm"); /* create the string to send to help prog.*/ while (morecmd() > 0) { strcat(buff," "); getcmd("",ans); strcat(buff,ans); } get_help(buff); /* call help program */ } else if ( iscmd(ans,"#") ) /* a comment. flush the rest of the line*/ { flushcmd("","",0); } else flushcmd("invalid or ambiguous tm command -> ",ans,1); } }