12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484 |
- /* calc.c */
- /* Keyboard command interpreter */
- /* by Stephen L. Moshier */
- /* Include functions for IEEE special values */
- #define NANS 1
- /* length of command line: */
- #define LINLEN 128
- #define XON 0x11
- #define XOFF 0x13
- #define SALONE 1
- #define DECPDP 0
- #define INTLOGIN 0
- #define INTHELP 1
- #ifndef TRUE
- #define TRUE 1
- #endif
- /* Initialize squirrel printf: */
- #define INIPRINTF 0
- #if DECPDP
- #define TRUE 1
- #endif
- #include <stdio.h>
- #include <string.h>
- static char idterp[] = {
- "\n\nSteve Moshier's command interpreter V1.3\n"};
- #define ISLOWER(c) ((c >= 'a') && (c <= 'z'))
- #define ISUPPER(c) ((c >= 'A') && (c <= 'Z'))
- #define ISALPHA(c) (ISLOWER(c) || ISUPPER(c))
- #define ISDIGIT(c) ((c >= '0') && (c <= '9'))
- #define ISATF(c) (((c >= 'a')&&(c <= 'f')) || ((c >= 'A')&&(c <= 'F')))
- #define ISXDIGIT(c) (ISDIGIT(c) || ISATF(c))
- #define ISOCTAL(c) ((c >= '0') && (c < '8'))
- #define ISALNUM(c) (ISALPHA(c) || (ISDIGIT(c))
- FILE *fopen();
- #include "lcalc.h"
- #include "ehead.h"
- /* space for working precision numbers */
- static long double vs[22];
- /* the symbol table of temporary variables: */
- #define NTEMP 4
- struct varent temp[NTEMP] = {
- {"T", OPR | TEMP, &vs[14]},
- {"T", OPR | TEMP, &vs[15]},
- {"T", OPR | TEMP, &vs[16]},
- {"\0", OPR | TEMP, &vs[17]}
- };
- /* the symbol table of operators */
- /* EOL is interpreted on null, newline, or ; */
- struct symbol oprtbl[] = {
- {"BOL", OPR | BOL, 0},
- {"EOL", OPR | EOL, 0},
- {"-", OPR | UMINUS, 8},
- /*"~", OPR | COMP, 8,*/
- {",", OPR | EOE, 1},
- {"=", OPR | EQU, 2},
- /*"|", OPR | LOR, 3,*/
- /*"^", OPR | LXOR, 4,*/
- /*"&", OPR | LAND, 5,*/
- {"+", OPR | PLUS, 6},
- {"-", OPR | MINUS, 6},
- {"*", OPR | MULT, 7},
- {"/", OPR | DIV, 7},
- /*"%", OPR | MOD, 7,*/
- {"(", OPR | LPAREN, 11},
- {")", OPR | RPAREN, 11},
- {"\0", ILLEG, 0}
- };
- #define NOPR 8
- /* the symbol table of indirect variables: */
- extern long double PIL;
- struct varent indtbl[] = {
- {"t", VAR | IND, &vs[21]},
- {"u", VAR | IND, &vs[20]},
- {"v", VAR | IND, &vs[19]},
- {"w", VAR | IND, &vs[18]},
- {"x", VAR | IND, &vs[10]},
- {"y", VAR | IND, &vs[11]},
- {"z", VAR | IND, &vs[12]},
- {"pi", VAR | IND, &PIL},
- {"\0", ILLEG, 0}
- };
- /* the symbol table of constants: */
- #define NCONST 10
- struct varent contbl[NCONST] = {
- {"C",CONST,&vs[0]},
- {"C",CONST,&vs[1]},
- {"C",CONST,&vs[2]},
- {"C",CONST,&vs[3]},
- {"C",CONST,&vs[4]},
- {"C",CONST,&vs[5]},
- {"C",CONST,&vs[6]},
- {"C",CONST,&vs[7]},
- {"C",CONST,&vs[8]},
- {"\0",CONST,&vs[9]}
- };
- /* the symbol table of string variables: */
- static char strngs[160] = {0};
- #define NSTRNG 5
- struct strent strtbl[NSTRNG] = {
- {0, VAR | STRING, 0},
- {0, VAR | STRING, 0},
- {0, VAR | STRING, 0},
- {0, VAR | STRING, 0},
- {"\0",ILLEG,0},
- };
- /* Help messages */
- #if INTHELP
- static char *intmsg[] = {
- "?",
- "Unkown symbol",
- "Expression ends in illegal operator",
- "Precede ( by operator",
- ")( is illegal",
- "Unmatched )",
- "Missing )",
- "Illegal left hand side",
- "Missing symbol",
- "Must assign to a variable",
- "Divide by zero",
- "Missing symbol",
- "Missing operator",
- "Precede quantity by operator",
- "Quantity preceded by )",
- "Function syntax",
- "Too many function args",
- "No more temps",
- "Arg list"
- };
- #endif
- /* the symbol table of functions: */
- #if SALONE
- long double hex(), cmdh(), cmdhlp();
- long double cmddm(), cmdtm(), cmdem();
- long double take(), mxit(), exit(), bits(), csys();
- long double cmddig(), prhlst(), abmac();
- long double ifrac(), xcmpl();
- long double floorl(), logl(), powl(), sqrtl(), tanhl(), expl();
- long double ellpel(), ellpkl(), incbetl(), incbil();
- long double stdtrl(), stdtril(), zstdtrl(), zstdtril();
- long double sinl(), cosl(), tanl(), asinl(), acosl(), atanl(), atan2l();
- long double tanhl(), atanhl();
- #ifdef NANS
- int isnanl(), isfinitel(), signbitl();
- long double zisnan(), zisfinite(), zsignbit();
- #endif
- struct funent funtbl[] = {
- {"h", OPR | FUNC, cmdh},
- {"help", OPR | FUNC, cmdhlp},
- {"hex", OPR | FUNC, hex},
- /*"view", OPR | FUNC, view,*/
- {"exp", OPR | FUNC, expl},
- {"floor", OPR | FUNC, floorl},
- {"log", OPR | FUNC, logl},
- {"pow", OPR | FUNC, powl},
- {"sqrt", OPR | FUNC, sqrtl},
- {"tanh", OPR | FUNC, tanhl},
- {"sin", OPR | FUNC, sinl},
- {"cos", OPR | FUNC, cosl},
- {"tan", OPR | FUNC, tanl},
- {"asin", OPR | FUNC, asinl},
- {"acos", OPR | FUNC, acosl},
- {"atan", OPR | FUNC, atanl},
- {"atantwo", OPR | FUNC, atan2l},
- {"tanh", OPR | FUNC, tanhl},
- {"atanh", OPR | FUNC, atanhl},
- {"ellpe", OPR | FUNC, ellpel},
- {"ellpk", OPR | FUNC, ellpkl},
- {"incbet", OPR | FUNC, incbetl},
- {"incbi", OPR | FUNC, incbil},
- {"stdtr", OPR | FUNC, zstdtrl},
- {"stdtri", OPR | FUNC, zstdtril},
- {"ifrac", OPR | FUNC, ifrac},
- {"cmp", OPR | FUNC, xcmpl},
- #ifdef NANS
- {"isnan", OPR | FUNC, zisnan},
- {"isfinite", OPR | FUNC, zisfinite},
- {"signbit", OPR | FUNC, zsignbit},
- #endif
- {"bits", OPR | FUNC, bits},
- {"digits", OPR | FUNC, cmddig},
- {"dm", OPR | FUNC, cmddm},
- {"tm", OPR | FUNC, cmdtm},
- {"em", OPR | FUNC, cmdem},
- {"take", OPR | FUNC | COMMAN, take},
- {"system", OPR | FUNC | COMMAN, csys},
- {"exit", OPR | FUNC, mxit},
- /*
- "remain", OPR | FUNC, eremain,
- */
- {"\0", OPR | FUNC, 0}
- };
- /* the symbol table of key words */
- struct funent keytbl[] = {
- {"\0", ILLEG, 0}
- };
- #endif
- void zgets(), init();
- /* Number of decimals to display */
- #define DEFDIS 70
- static int ndigits = DEFDIS;
- /* Menu stack */
- struct funent *menstk[5] = {&funtbl[0], NULL, NULL, NULL, NULL};
- int menptr = 0;
- /* Take file stack */
- FILE *takstk[10] = {0};
- int takptr = -1;
- /* size of the expression scan list: */
- #define NSCAN 20
- /* previous token, saved for syntax checking: */
- struct symbol *lastok = 0;
- /* variables used by parser: */
- static char str[128] = {0};
- int uposs = 0; /* possible unary operator */
- static long double qnc;
- char lc[40] = { '\n' }; /* ASCII string of token symbol */
- static char line[LINLEN] = { '\n','\0' }; /* input command line */
- static char maclin[LINLEN] = { '\n','\0' }; /* macro command */
- char *interl = line; /* pointer into line */
- extern char *interl;
- static int maccnt = 0; /* number of times to execute macro command */
- static int comptr = 0; /* comma stack pointer */
- static long double comstk[5]; /* comma argument stack */
- static int narptr = 0; /* pointer to number of args */
- static int narstk[5] = {0}; /* stack of number of function args */
- /* main() */
- /* Entire program starts here */
- int main()
- {
- /* the scan table: */
- /* array of pointers to symbols which have been parsed: */
- struct symbol *ascsym[NSCAN];
- /* current place in ascsym: */
- register struct symbol **as;
- /* array of attributes of operators parsed: */
- int ascopr[NSCAN];
- /* current place in ascopr: */
- register int *ao;
- #if LARGEMEM
- /* array of precedence levels of operators: */
- long asclev[NSCAN];
- /* current place in asclev: */
- long *al;
- long symval; /* value of symbol just parsed */
- #else
- int asclev[NSCAN];
- int *al;
- int symval;
- #endif
- long double acc; /* the accumulator, for arithmetic */
- int accflg; /* flags accumulator in use */
- long double val; /* value to be combined into accumulator */
- register struct symbol *psym; /* pointer to symbol just parsed */
- struct varent *pvar; /* pointer to an indirect variable symbol */
- struct funent *pfun; /* pointer to a function symbol */
- struct strent *pstr; /* pointer to a string symbol */
- int att; /* attributes of symbol just parsed */
- int i; /* counter */
- int offset; /* parenthesis level */
- int lhsflg; /* kluge to detect illegal assignments */
- struct symbol *parser(); /* parser returns pointer to symbol */
- int errcod; /* for syntax error printout */
- /* Perform general initialization */
- init();
- menstk[0] = &funtbl[0];
- menptr = 0;
- cmdhlp(); /* print out list of symbols */
- /* Return here to get next command line to execute */
- getcmd:
- /* initialize registers and mutable symbols */
- accflg = 0; /* Accumulator not in use */
- acc = 0.0L; /* Clear the accumulator */
- offset = 0; /* Parenthesis level zero */
- comptr = 0; /* Start of comma stack */
- narptr = -1; /* Start of function arg counter stack */
- psym = (struct symbol *)&contbl[0];
- for( i=0; i<NCONST; i++ )
- {
- psym->attrib = CONST; /* clearing the busy bit */
- ++psym;
- }
- psym = (struct symbol *)&temp[0];
- for( i=0; i<NTEMP; i++ )
- {
- psym->attrib = VAR | TEMP; /* clearing the busy bit */
- ++psym;
- }
- pstr = &strtbl[0];
- for( i=0; i<NSTRNG; i++ )
- {
- pstr->spel = &strngs[ 40*i ];
- pstr->attrib = STRING | VAR;
- pstr->string = &strngs[ 40*i ];
- ++pstr;
- }
- /* List of scanned symbols is empty: */
- as = &ascsym[0];
- *as = 0;
- --as;
- /* First item in scan list is Beginning of Line operator */
- ao = &ascopr[0];
- *ao = oprtbl[0].attrib & 0xf; /* BOL */
- /* value of first item: */
- al = &asclev[0];
- *al = oprtbl[0].sym;
- lhsflg = 0; /* illegal left hand side flag */
- psym = &oprtbl[0]; /* pointer to current token */
- /* get next token from input string */
- gettok:
- lastok = psym; /* last token = current token */
- psym = parser(); /* get a new current token */
- /*printf( "%s attrib %7o value %7o\n", psym->spel, psym->attrib & 0xffff,
- psym->sym );*/
- /* Examine attributes of the symbol returned by the parser */
- att = psym->attrib;
- if( att == ILLEG )
- {
- errcod = 1;
- goto synerr;
- }
- /* Push functions onto scan list without analyzing further */
- if( att & FUNC )
- {
- /* A command is a function whose argument is
- * a pointer to the rest of the input line.
- * A second argument is also passed: the address
- * of the last token parsed.
- */
- if( att & COMMAN )
- {
- pfun = (struct funent *)psym;
- ( *(pfun->fun))( interl, lastok );
- abmac(); /* scrub the input line */
- goto getcmd; /* and ask for more input */
- }
- ++narptr; /* offset to number of args */
- narstk[narptr] = 0;
- i = lastok->attrib & 0xffff; /* attrib=short, i=int */
- if( ((i & OPR) == 0)
- || (i == (OPR | RPAREN))
- || (i == (OPR | FUNC)) )
- {
- errcod = 15;
- goto synerr;
- }
- ++lhsflg;
- ++as;
- *as = psym;
- ++ao;
- *ao = FUNC;
- ++al;
- *al = offset + UMINUS;
- goto gettok;
- }
- /* deal with operators */
- if( att & OPR )
- {
- att &= 0xf;
- /* expression cannot end with an operator other than
- * (, ), BOL, or a function
- */
- if( (att == RPAREN) || (att == EOL) || (att == EOE))
- {
- i = lastok->attrib & 0xffff; /* attrib=short, i=int */
- if( (i & OPR)
- && (i != (OPR | RPAREN))
- && (i != (OPR | LPAREN))
- && (i != (OPR | FUNC))
- && (i != (OPR | BOL)) )
- {
- errcod = 2;
- goto synerr;
- }
- }
- ++lhsflg; /* any operator but ( and = is not a legal lhs */
- /* operator processing, continued */
- switch( att )
- {
- case EOE:
- lhsflg = 0;
- break;
- case LPAREN:
- /* ( must be preceded by an operator of some sort. */
- if( ((lastok->attrib & OPR) == 0) )
- {
- errcod = 3;
- goto synerr;
- }
- /* also, a preceding ) is illegal */
- if( (unsigned short )lastok->attrib == (OPR|RPAREN))
- {
- errcod = 4;
- goto synerr;
- }
- /* Begin looking for illegal left hand sides: */
- lhsflg = 0;
- offset += RPAREN; /* new parenthesis level */
- goto gettok;
- case RPAREN:
- offset -= RPAREN; /* parenthesis level */
- if( offset < 0 )
- {
- errcod = 5; /* parenthesis error */
- goto synerr;
- }
- goto gettok;
- case EOL:
- if( offset != 0 )
- {
- errcod = 6; /* parenthesis error */
- goto synerr;
- }
- break;
- case EQU:
- if( --lhsflg ) /* was incremented before switch{} */
- {
- errcod = 7;
- goto synerr;
- }
- case UMINUS:
- case COMP:
- goto pshopr; /* evaluate right to left */
- default: ;
- }
- /* evaluate expression whenever precedence is not increasing */
- symval = psym->sym + offset;
- while( symval <= *al )
- {
- /* if just starting, must fill accumulator with last
- * thing on the line
- */
- if( (accflg == 0) && (as >= ascsym) && (((*as)->attrib & FUNC) == 0 ))
- {
- pvar = (struct varent *)*as;
- /*
- if( pvar->attrib & STRING )
- strcpy( (char *)&acc, (char *)pvar->value );
- else
- */
- acc = *pvar->value;
- --as;
- accflg = 1;
- }
- /* handle beginning of line type cases, where the symbol
- * list ascsym[] may be empty.
- */
- switch( *ao )
- {
- case BOL:
- /* printf( "%.16e\n", (double )acc ); */
- #if NE == 6
- e64toasc( &acc, str, 100 );
- #else
- e113toasc( &acc, str, 100 );
- #endif
- printf( "%s\n", str );
- goto getcmd; /* all finished */
- case UMINUS:
- acc = -acc;
- goto nochg;
- /*
- case COMP:
- acc = ~acc;
- goto nochg;
- */
- default: ;
- }
- /* Now it is illegal for symbol list to be empty,
- * because we are going to need a symbol below.
- */
- if( as < &ascsym[0] )
- {
- errcod = 8;
- goto synerr;
- }
- /* get attributes and value of current symbol */
- att = (*as)->attrib;
- pvar = (struct varent *)*as;
- if( att & FUNC )
- val = 0.0L;
- else
- {
- /*
- if( att & STRING )
- strcpy( (char *)&val, (char *)pvar->value );
- else
- */
- val = *pvar->value;
- }
- /* Expression evaluation, continued. */
- switch( *ao )
- {
- case FUNC:
- pfun = (struct funent *)*as;
- /* Call the function with appropriate number of args */
- i = narstk[ narptr ];
- --narptr;
- switch(i)
- {
- case 0:
- acc = ( *(pfun->fun) )(acc);
- break;
- case 1:
- acc = ( *(pfun->fun) )(acc, comstk[comptr-1]);
- break;
- case 2:
- acc = ( *(pfun->fun) )(acc, comstk[comptr-2],
- comstk[comptr-1]);
- break;
- case 3:
- acc = ( *(pfun->fun) )(acc, comstk[comptr-3],
- comstk[comptr-2], comstk[comptr-1]);
- break;
- default:
- errcod = 16;
- goto synerr;
- }
- comptr -= i;
- accflg = 1; /* in case at end of line */
- break;
- case EQU:
- if( ( att & TEMP) || ((att & VAR) == 0) || (att & STRING) )
- {
- errcod = 9;
- goto synerr; /* can only assign to a variable */
- }
- pvar = (struct varent *)*as;
- *pvar->value = acc;
- break;
- case PLUS:
- acc = acc + val; break;
- case MINUS:
- acc = val - acc; break;
- case MULT:
- acc = acc * val; break;
- case DIV:
- if( acc == 0.0L )
- {
- /*
- divzer:
- */
- errcod = 10;
- goto synerr;
- }
- acc = val / acc; break;
- /*
- case MOD:
- if( acc == 0 )
- goto divzer;
- acc = val % acc; break;
- case LOR:
- acc |= val; break;
- case LXOR:
- acc ^= val; break;
- case LAND:
- acc &= val; break;
- */
- case EOE:
- if( narptr < 0 )
- {
- errcod = 18;
- goto synerr;
- }
- narstk[narptr] += 1;
- comstk[comptr++] = acc;
- /* printf( "\ncomptr: %d narptr: %d %d\n", comptr, narptr, acc );*/
- acc = val;
- break;
- }
- /* expression evaluation, continued */
- /* Pop evaluated tokens from scan list: */
- /* make temporary variable not busy */
- if( att & TEMP )
- (*as)->attrib &= ~BUSY;
- if( as < &ascsym[0] ) /* can this happen? */
- {
- errcod = 11;
- goto synerr;
- }
- --as;
- nochg:
- --ao;
- --al;
- if( ao < &ascopr[0] ) /* can this happen? */
- {
- errcod = 12;
- goto synerr;
- }
- /* If precedence level will now increase, then */
- /* save accumulator in a temporary location */
- if( symval > *al )
- {
- /* find a free temp location */
- pvar = &temp[0];
- for( i=0; i<NTEMP; i++ )
- {
- if( (pvar->attrib & BUSY) == 0)
- goto temfnd;
- ++pvar;
- }
- errcod = 17;
- printf( "no more temps\n" );
- pvar = &temp[0];
- goto synerr;
- temfnd:
- pvar->attrib |= BUSY;
- *pvar->value = acc;
- /*printf( "temp %d\n", acc );*/
- accflg = 0;
- ++as; /* push the temp onto the scan list */
- *as = (struct symbol *)pvar;
- }
- } /* End of evaluation loop */
- /* Push operator onto scan list when precedence increases */
- pshopr:
- ++ao;
- *ao = psym->attrib & 0xf;
- ++al;
- *al = psym->sym + offset;
- goto gettok;
- } /* end of OPR processing */
- /* Token was not an operator. Push symbol onto scan list. */
- if( (lastok->attrib & OPR) == 0 )
- {
- errcod = 13;
- goto synerr; /* quantities must be preceded by an operator */
- }
- if( (unsigned short )lastok->attrib == (OPR | RPAREN) ) /* ...but not by ) */
- {
- errcod = 14;
- goto synerr;
- }
- ++as;
- *as = psym;
- goto gettok;
- synerr:
- #if INTHELP
- printf( "%s ", intmsg[errcod] );
- #endif
- printf( " error %d\n", errcod );
- abmac(); /* flush the command line */
- goto getcmd;
- } /* end of program */
- /* parser() */
- /* Get token from input string and identify it. */
- static char number[128];
- struct symbol *parser( )
- {
- register struct symbol *psym;
- register char *pline;
- struct varent *pvar;
- struct strent *pstr;
- char *cp, *plc, *pn;
- long lnc;
- int i;
- long double tem;
- /* reference for old Whitesmiths compiler: */
- /*
- *extern FILE *stdout;
- */
- pline = interl; /* get current location in command string */
- /* If at beginning of string, must ask for more input */
- if( pline == line )
- {
- if( maccnt > 0 )
- {
- --maccnt;
- cp = maclin;
- plc = pline;
- while( (*plc++ = *cp++) != 0 )
- ;
- goto mstart;
- }
- if( takptr < 0 )
- { /* no take file active: prompt keyboard input */
- printf("* ");
- }
- /* Various ways of typing in a command line. */
- /*
- * Old Whitesmiths call to print "*" immediately
- * use RT11 .GTLIN to get command string
- * from command file or terminal
- */
- /*
- * fflush(stdout);
- * gtlin(line);
- */
-
- zgets( line, TRUE ); /* keyboard input for other systems: */
- mstart:
- uposs = 1; /* unary operators possible at start of line */
- }
- ignore:
- /* Skip over spaces */
- while( *pline == ' ' )
- ++pline;
- /* unary minus after operator */
- if( uposs && (*pline == '-') )
- {
- psym = &oprtbl[2]; /* UMINUS */
- ++pline;
- goto pdon3;
- }
- /* COMP */
- /*
- if( uposs && (*pline == '~') )
- {
- psym = &oprtbl[3];
- ++pline;
- goto pdon3;
- }
- */
- if( uposs && (*pline == '+') ) /* ignore leading plus sign */
- {
- ++pline;
- goto ignore;
- }
- /* end of null terminated input */
- if( (*pline == '\n') || (*pline == '\0') || (*pline == '\r') )
- {
- pline = line;
- goto endlin;
- }
- if( *pline == ';' )
- {
- ++pline;
- endlin:
- psym = &oprtbl[1]; /* EOL */
- goto pdon2;
- }
- /* parser() */
- /* Test for numeric input */
- if( (ISDIGIT(*pline)) || (*pline == '.') )
- {
- lnc = 0; /* initialize numeric input to zero */
- qnc = 0.0L;
- if( *pline == '0' )
- { /* leading "0" may mean octal or hex radix */
- ++pline;
- if( *pline == '.' )
- goto decimal; /* 0.ddd */
- /* leading "0x" means hexadecimal radix */
- if( (*pline == 'x') || (*pline == 'X') )
- {
- ++pline;
- while( ISXDIGIT(*pline) )
- {
- i = *pline++ & 0xff;
- if( i >= 'a' )
- i -= 047;
- if( i >= 'A' )
- i -= 07;
- i -= 060;
- lnc = (lnc << 4) + i;
- qnc = lnc;
- }
- goto numdon;
- }
- else
- {
- while( ISOCTAL( *pline ) )
- {
- i = ((*pline++) & 0xff) - 060;
- lnc = (lnc << 3) + i;
- qnc = lnc;
- }
- goto numdon;
- }
- }
- else
- {
- /* no leading "0" means decimal radix */
- /******/
- decimal:
- pn = number;
- while( (ISDIGIT(*pline)) || (*pline == '.') )
- *pn++ = *pline++;
- /* get possible exponent field */
- if( (*pline == 'e') || (*pline == 'E') )
- *pn++ = *pline++;
- else
- goto numcvt;
- if( (*pline == '-') || (*pline == '+') )
- *pn++ = *pline++;
- while( ISDIGIT(*pline) )
- *pn++ = *pline++;
- numcvt:
- *pn++ = ' ';
- *pn++ = 0;
- #if NE == 6
- asctoe64( number, &qnc );
- #else
- asctoe113( number, &qnc );
- #endif
- /* sscanf( number, "%le", &nc ); */
- }
- /* output the number */
- numdon:
- /* search the symbol table of constants */
- pvar = &contbl[0];
- for( i=0; i<NCONST; i++ )
- {
- if( (pvar->attrib & BUSY) == 0 )
- goto confnd;
- tem = *pvar->value;
- if( tem == qnc )
- {
- psym = (struct symbol *)pvar;
- goto pdon2;
- }
- ++pvar;
- }
- printf( "no room for constant\n" );
- psym = (struct symbol *)&contbl[0];
- goto pdon2;
- confnd:
- pvar->spel= contbl[0].spel;
- pvar->attrib = CONST | BUSY;
- *pvar->value = qnc;
- psym = (struct symbol *)pvar;
- goto pdon2;
- }
- /* check for operators */
- psym = &oprtbl[3];
- for( i=0; i<NOPR; i++ )
- {
- if( *pline == *(psym->spel) )
- goto pdon1;
- ++psym;
- }
- /* if quoted, it is a string variable */
- if( *pline == '"' )
- {
- /* find an empty slot for the string */
- pstr = strtbl; /* string table */
- for( i=0; i<NSTRNG-1; i++ )
- {
- if( (pstr->attrib & BUSY) == 0 )
- goto fndstr;
- ++pstr;
- }
- printf( "No room for string\n" );
- pstr->attrib |= ILLEG;
- psym = (struct symbol *)pstr;
- goto pdon0;
- fndstr:
- pstr->attrib |= BUSY;
- plc = pstr->string;
- ++pline;
- for( i=0; i<39; i++ )
- {
- *plc++ = *pline;
- if( (*pline == '\n') || (*pline == '\0') || (*pline == '\r') )
- {
- illstr:
- pstr = &strtbl[NSTRNG-1];
- pstr->attrib |= ILLEG;
- printf( "Missing string terminator\n" );
- psym = (struct symbol *)pstr;
- goto pdon0;
- }
- if( *pline++ == '"' )
- goto finstr;
- }
- goto illstr; /* no terminator found */
- finstr:
- --plc;
- *plc = '\0';
- psym = (struct symbol *)pstr;
- goto pdon2;
- }
- /* If none of the above, search function and symbol tables: */
- /* copy character string to array lc[] */
- plc = &lc[0];
- while( ISALPHA(*pline) )
- {
- /* convert to lower case characters */
- if( ISUPPER( *pline ) )
- *pline += 040;
- *plc++ = *pline++;
- }
- *plc = 0; /* Null terminate the output string */
- /* parser() */
- psym = (struct symbol *)menstk[menptr]; /* function table */
- plc = &lc[0];
- cp = psym->spel;
- do
- {
- if( strcmp( plc, cp ) == 0 )
- goto pdon3; /* following unary minus is possible */
- ++psym;
- cp = psym->spel;
- }
- while( *cp != '\0' );
- psym = (struct symbol *)&indtbl[0]; /* indirect symbol table */
- plc = &lc[0];
- cp = psym->spel;
- do
- {
- if( strcmp( plc, cp ) == 0 )
- goto pdon2;
- ++psym;
- cp = psym->spel;
- }
- while( *cp != '\0' );
- pdon0:
- pline = line; /* scrub line if illegal symbol */
- goto pdon2;
- pdon1:
- ++pline;
- if( (psym->attrib & 0xf) == RPAREN )
- pdon2: uposs = 0;
- else
- pdon3: uposs = 1;
- interl = pline;
- return( psym );
- } /* end of parser */
- /* exit from current menu */
- long double cmdex()
- {
- if( menptr == 0 )
- {
- printf( "Main menu is active.\n" );
- }
- else
- --menptr;
- cmdh();
- return(0.0L);
- }
- /* gets() */
- void zgets( gline, echo )
- char *gline;
- int echo;
- {
- register char *pline;
- register int i;
- scrub:
- pline = gline;
- getsl:
- if( (pline - gline) >= LINLEN )
- {
- printf( "\nLine too long\n *" );
- goto scrub;
- }
- if( takptr < 0 )
- { /* get character from keyboard */
- /*
- if DECPDP
- gtlin( gline );
- return(0);
- else
- */
- *pline = getchar();
- /*endif*/
- }
- else
- { /* get a character from take file */
- i = fgetc( takstk[takptr] );
- if( i == -1 )
- { /* end of take file */
- if( takptr >= 0 )
- { /* close file and bump take stack */
- fclose( takstk[takptr] );
- takptr -= 1;
- }
- if( takptr < 0 ) /* no more take files: */
- printf( "*" ); /* prompt keyboard input */
- goto scrub; /* start a new input line */
- }
- *pline = i;
- }
- *pline &= 0x7f;
- /* xon or xoff characters need filtering out. */
- if ( *pline == XON || *pline == XOFF )
- goto getsl;
- /* control U or control C */
- if( (*pline == 025) || (*pline == 03) )
- {
- printf( "\n" );
- goto scrub;
- }
- /* Backspace or rubout */
- if( (*pline == 010) || (*pline == 0177) )
- {
- pline -= 1;
- if( pline >= gline )
- {
- if ( echo )
- printf( "\010\040\010" );
- goto getsl;
- }
- else
- goto scrub;
- }
- if ( echo )
- printf( "%c", *pline );
- if( (*pline != '\n') && (*pline != '\r') )
- {
- ++pline;
- goto getsl;
- }
- *pline = 0;
- if ( echo )
- printf( "%c", '\n' ); /* \r already echoed */
- }
- /* help function */
- long double cmdhlp()
- {
- printf( "%s", idterp );
- printf( "\nFunctions:\n" );
- prhlst( &funtbl[0] );
- printf( "\nVariables:\n" );
- prhlst( &indtbl[0] );
- printf( "\nOperators:\n" );
- prhlst( &oprtbl[2] );
- printf("\n");
- return(0.0L);
- }
- long double cmdh()
- {
- prhlst( menstk[menptr] );
- printf( "\n" );
- return(0.0L);
- }
- /* print keyword spellings */
- long double prhlst(ps)
- register struct symbol *ps;
- {
- register int j, k;
- int m;
- j = 0;
- while( *(ps->spel) != '\0' )
- {
- k = strlen( ps->spel ) - 1;
- /* size of a tab field is 2**3 chars */
- m = ((k >> 3) + 1) << 3;
- j += m;
- if( j > 72 )
- {
- printf( "\n" );
- j = m;
- }
- printf( "%s\t", ps->spel );
- ++ps;
- }
- return(0.0L);
- }
- #if SALONE
- void init(){}
- #endif
- /* macro commands */
- /* define macro */
- long double cmddm()
- {
- zgets( maclin, TRUE );
- return(0.0L);
- }
- /* type (i.e., display) macro */
- long double cmdtm()
- {
- printf( "%s\n", maclin );
- return(0.0L);
- }
- /* execute macro # times */
- long double cmdem( arg )
- long double arg;
- {
- long double f;
- long n;
- long double floorl();
- f = floorl(arg);
- n = f;
- if( n <= 0 )
- n = 1;
- maccnt = n;
- return(0.0L);
- }
- /* open a take file */
- long double take( fname )
- char *fname;
- {
- FILE *f;
- while( *fname == ' ' )
- fname += 1;
- f = fopen( fname, "r" );
- if( f == 0 )
- {
- printf( "Can't open take file %s\n", fname );
- takptr = -1; /* terminate all take file input */
- return(0.0L);
- }
- takptr += 1;
- takstk[ takptr ] = f;
- printf( "Running %s\n", fname );
- return(0.0L);
- }
- /* abort macro execution */
- long double abmac()
- {
- maccnt = 0;
- interl = line;
- return(0.0L);
- }
- /* display integer part in hex, octal, and decimal
- */
- long double hex(qx)
- long double qx;
- {
- long double f;
- long z;
- long double floorl();
- f = floorl(qx);
- z = f;
- printf( "0%lo 0x%lx %ld.\n", z, z, z );
- return(qx);
- }
- #define NASC 16
- long double bits( x )
- long double x;
- {
- int i, j;
- unsigned short dd[4], ee[10];
- char strx[40];
- unsigned short *p;
- p = (unsigned short *) &x;
- for( i=0; i<NE; i++ )
- ee[i] = *p++;
- j = 0;
- for( i=0; i<NE; i++ )
- {
- printf( "0x%04x,", ee[i] & 0xffff );
- if( ++j > 7 )
- {
- j = 0;
- printf( "\n" );
- }
- }
- printf( "\n" );
- /* double conversions
- */
- *((double *)dd) = x;
- printf( "double: " );
- for( i=0; i<4; i++ )
- printf( "0x%04x,", dd[i] & 0xffff );
- printf( "\n" );
- #if 1
- printf( "double -> long double: " );
- *(long double *)ee = *(double *)dd;
- for( i=0; i<6; i++ )
- printf( "0x%04x,", ee[i] & 0xffff );
- printf( "\n" );
- e53toasc( dd, strx, NASC );
- printf( "e53toasc: %s\n", strx );
- printf( "Native printf: %.17e\n", *(double *)dd );
- /* float conversions
- */
- *((float *)dd) = x;
- printf( "float: " );
- for( i=0; i<2; i++ )
- printf( "0x%04x,", dd[i] & 0xffff );
- printf( "\n" );
- e24toe( dd, ee );
- printf( "e24toe: " );
- for( i=0; i<NE; i++ )
- printf( "0x%04x,", ee[i] & 0xffff );
- printf( "\n" );
- e24toasc( dd, strx, NASC );
- printf( "e24toasc: %s\n", strx );
- /* printf( "Native printf: %.16e\n", (double) *(float *)dd ); */
- #ifdef DEC
- printf( "etodec: " );
- etodec( x, dd );
- for( i=0; i<4; i++ )
- printf( "0x%04x,", dd[i] & 0xffff );
- printf( "\n" );
- printf( "dectoe: " );
- dectoe( dd, ee );
- for( i=0; i<NE; i++ )
- printf( "0x%04x,", ee[i] & 0xffff );
- printf( "\n" );
- printf( "DEC printf: %.16e\n", *(double *)dd );
- #endif
- #endif /* 0 */
- return(x);
- }
- /* Exit to monitor. */
- long double mxit()
- {
- exit(0);
- return(0.0L);
- }
- long double cmddig( x )
- long double x;
- {
- long double f;
- long lx;
- f = floorl(x);
- lx = f;
- ndigits = lx;
- if( ndigits <= 0 )
- ndigits = DEFDIS;
- return(f);
- }
- long double csys(x)
- char *x;
- {
- void system();
- system( x+1 );
- cmdh();
- return(0.0L);
- }
- long double ifrac(x)
- long double x;
- {
- unsigned long lx;
- long double y, z;
- z = floorl(x);
- lx = z;
- y = x - z;
- printf( " int = %lx\n", lx );
- return(y);
- }
- long double xcmpl(x,y)
- long double x,y;
- {
- long double ans;
- char str[40];
- #if NE == 6
- e64toasc( &x, str, 100 );
- printf( "x = %s\n", str );
- e64toasc( &y, str, 100 );
- printf( "y = %s\n", str );
- #else
- e113toasc( &x, str, 100 );
- printf( "x = %s\n", str );
- e113toasc( &y, str, 100 );
- printf( "y = %s\n", str );
- #endif
- ans = -2.0;
- if( x == y )
- {
- printf( "x == y " );
- ans = 0.0;
- }
- if( x < y )
- {
- printf( "x < y" );
- ans = -1.0;
- }
- if( x > y )
- {
- printf( "x > y" );
- ans = 1.0;
- }
- return( ans );
- }
- long double zstdtrl(k,t)
- long double k, t;
- {
- int ki;
- long double y;
- ki = k;
- y = stdtrl(ki,t);
- return(y);
- }
- long double zstdtril(k,t)
- long double k, t;
- {
- int ki;
- long double y;
- ki = k;
- y = stdtril(ki,t);
- return(y);
- }
- #ifdef NANS
- long double zisnan(x)
- long double x;
- {
- long double y;
- int k;
- k = isnanl(x);
- y = k;
- return(y);
- }
- long double zisfinite(x)
- long double x;
- {
- long double y;
- int k;
- k = isfinitel(x);
- y = k;
- return(y);
- }
- long double zsignbit(x)
- long double x;
- {
- long double y;
- int k;
- k = signbitl(x);
- y = k;
- return(y);
- }
- #endif
|