| 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 4struct 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 10struct 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 5struct 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 INTHELPstatic 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 SALONElong 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 NANSint isnanl(), isfinitel(), signbitl();long double zisnan(), zisfinite(), zsignbit();#endifstruct 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}};#endifvoid zgets(), init();/* Number of decimals to display */#define DEFDIS 70static 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 */#elseint asclev[NSCAN];int *al;int symval;#endiflong 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 INTHELPprintf( "%s ", intmsg[errcod] );#endifprintf( " 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;elsepdon3:	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 SALONEvoid 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 16long 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 1printf( "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 DECprintf( "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 );#endifans = -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 NANSlong 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
 |