#define NSTRNG 5 struct strent strtbl[NSTRNG] = { #if DECPDP
{&strngs[0][0], VAR | STRING, &strngs[0][0],},
{&strngs[1][0], VAR | STRING, &strngs[1][0],},
{&strngs[2][0], VAR | STRING, &strngs[2][0],},
{&strngs[3][0], VAR | STRING, &strngs[3][0],}, #else
{&strngs[0][0], VAR | STRING, &strngs[0][0],},
{&strngs[1][0], VAR | STRING, &strngs[1][0],},
{&strngs[2][0], VAR | STRING, &strngs[2][0],},
{&strngs[3][0], VAR | STRING, &strngs[3][0],}, #endif
{"\0",ILLEG,0,},
};
/* Help messages */ #if INTHELP staticchar *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
#ifdef ANSIPROT int hex(QELT *), cmdh(void), cmdhlp(void), remark(char *), qsys(char *); int qsave(char *); int hexinput(QELT *, QELT *, QELT *), cmddig(QELT *); int cmddm(QELT *), cmdtm(QELT *), cmdem(QELT *); int take(char *), mxit(void), bits(QELT *), cmp(QELT *, QELT *, QELT *); int intcvts (QELT *, QELT *), todouble (QELT *, QELT *); int tolongdouble (QELT *, QELT *), tofloat (QELT *, QELT *); int zfrexp (QELT *, QELT *); int zldexp (QELT *, QELT *, QELT *); struct symbol *parser(void); /* parser returns pointer to symbol */ int init(void), abmac(void), zgets(char *, int), prhlst(struct symbol *); int qmovz(QELT *, QELT *); int zpdtr(QELT *, QELT *, QELT *), zpdtri(QELT *, QELT *, QELT *); int zpolylog(QELT *, QELT *, QELT *); int zzeta(QELT *, QELT *); int qjypn(QELT *, QELT *, QELT *), qjyqn(QELT *, QELT *, QELT *); double fabs(double); #else/* not ANSIPROT */ int init(), abmac(), qtoasc(), zgets(), asctoq(), etoq(), prhlst(); int hex(), hexinput(), cmdh(), cmdhlp(), remark(); int cmddm(), cmdtm(), cmdem(); int take(), mxit(), bits(), cmp(); int intcvts (), todouble (), tolongdouble (), tofloat (); int qlog(), qfac(), cmddig(), qfloor(), qremain(), qfrexp(), qldexp(); int qsqrt(), qlog(), qexp(), qsin(), qcos(), qatn(), qatn2(); int qasin(), qtan(), qpow(), zfrexp(), zldexp(); int qacos(), qcot(), qcbrt(); int qlog10(), qexp10(), qsave(), qsys(); int qtanh(), qatanh(), qcosh(), qsinh(), qasinh(), qacosh(); int qgamma(), qlgam(), qpsi(), qjn(), qyn(); struct symbol *parser(); /* parser returns pointer to symbol */ int qmovz(), shup1(), shdn1(), qtoe113(), e113toq(), qtoe64(), e64toq(); int e24toq(), qtoe24(); double fabs(); #if MOREFUNS int qincb(), qincbi(), qigamc(), qigami(); int qndtr(), qndtri(), qin(), zpdtr(), zpdtri(), qerf(), qerfc(); int qellie(), qellik(), qellpe(), qellpk(); int qhy2f1(), qhyp(), zpolylog(), zzeta(); int qjypn(), qjyqn(); #endif #endif/* not ANSIPROT */
/* the symbol table of key words */ struct funent keytbl[] = {
{"\0", ILLEG, 0},
}; #endif/* SALONE */
/* Number of decimals to display */ #define DEFDIS 70 staticint 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;
/* Cope with strong type checking rules. */ staticunion
{ struct varent *pvar; struct funent *pfun; struct strent *pstr; struct symbol *psym;
} pvfs;
/* variables used by parser: */ staticchar str[128] = {0}; int uposs = 0; /* possible unary operator */
/* numeric value of symbol */ union
{ unsignedshort s[4]; double d;
} nc;
static QELT qnc[NQ]; char lc[40] = { '\n' }; /* ASCII string of token symbol */ staticchar line[LINLEN] = { '\n','\0' }; /* input command line */ staticchar maclin[LINLEN] = { '\n','\0' }; /* macro command */ char *interl = line; /* pointer into line */ externchar *interl; staticint maccnt = 0; /* number of times to execute macro command */ staticint comptr = 0; /* comma stack pointer */ static QELT comstk[5][NQ]; /* comma argument stack */ staticint narptr = 0; /* pointer to number of args */ staticint 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: */ registerstruct symbol **as;
/* array of attributes of operators parsed: */ int ascopr[NSCAN];
/* current place in ascopr: */ registerint *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
QELT acc[NQ]; /* the accumulator, for arithmetic */ int accflg; /* flags accumulator in use */
QELT val[NQ]; /* value to be combined into accumulator */ registerstruct symbol *psym; /* pointer to symbol just parsed */ struct varent *pvar; /* pointer to an indirect variable symbol */ struct funent *pfun; /* pointer to a function symbol */ int att; /* attributes of symbol just parsed */ int i; /* counter */ int offset; /* parenthesis level */ int lhsflg; /* kluge to detect illegal assignments */ int errcod; /* for syntax error printout */
/* 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 *apointertotherestoftheinputline. *Asecondargumentisalsopassed:theaddress *ofthelasttokenparsed.
*/ if( att & COMMAN )
{ /* pfun = (struct funent *)psym; */
pvfs.psym = psym;
pfun = pvfs.pfun;
( *(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;
}
/* deal with operators */ if( att & OPR )
{
att &= 0xf; /* expression cannot end with an operator other than *(,),BOL,orafunction
*/ 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( (unsignedshort )lastok->attrib
== (unsignedshort)(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 *thingontheline
*/ if( (accflg == 0) && (as >= ascsym) && (((*as)->attrib & FUNC) == 0 ))
{
pvar = (struct varent *)*as;
qmov( pvar->value, acc );
--as;
accflg = 1;
}
/* handle beginning of line type cases, where the symbol *listascsym[]maybeempty.
*/ switch( *ao )
{ case BOL:
qtoasc( acc, str, ndigits );
printf( "%s\n", str ); /* This is the answer */ if( savfil )
fprintf( savfil, "%s\n", str ); goto getcmd; /* all finished */ case UMINUS:
qneg( acc ); goto nochg; /* caseCOMP: acc=~acc; gotonochg;
*/ default: ;
} /* Now it is illegal for symbol list to be empty, *becausewearegoingtoneedasymbolbelow.
*/ 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 )
qclear( val ); else
qmov( pvar->value, val );
/* 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)
{ case0:
( *(pfun->fun) )(acc, acc); break; case1:
( *(pfun->fun) )(acc,comstk[comptr-1],acc); break; case2:
( *(pfun->fun) )(acc, comstk[comptr-2],
comstk[comptr-1],acc); break; case3:
( *(pfun->fun) )(acc, comstk[comptr-3],
comstk[comptr-2], comstk[comptr-1],acc); 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;
qmov( acc, pvar->value ); break; case PLUS:
qadd( acc, val, acc ); break; case MINUS:
qsub( acc, val, acc ); break; case MULT:
qmul( acc, val, acc ); break; case DIV: if( acc[1] == 0 )
{ /* divzer: */
errcod = 10; goto synerr;
}
qdiv( acc, val, acc ); break; /* caseMOD: if(acc==0) gotodivzer; acc=val%acc;break; caseLOR: acc|=val;break; caseLXOR: acc^=val;break; caseLAND: acc&=val;break;
*/ case EOE: if( narptr < 0 )
{
errcod = 18; goto synerr;
}
narstk[narptr] += 1;
qmov( acc, comstk[comptr++] ); /* printf( "\ncomptr: %d narptr: %d %d\n", comptr, narptr, acc );*/
qmov( val, acc ); 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;
qmov( acc, pvar->value ); /*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 */
#if USE_READLINE if (takptr < 0)
{ if (line_read)
{
free (line_read);
line_read = (char *)NULL;
} /* Get a line from the user. */
line_read = readline (""); /* If the line has any text in it, save it on the history. */ if (line_read && *line_read)
add_history (line_read); /* Copy to local buffer. */
strcpy(line,line_read);
free (line_read);
line_read = (char *) NULL;
} else #endif
zgets( line, TRUE ); /* keyboard input for other systems: */
mstart:
uposs = 1; /* unary operators possible at start of line */
}
finstr:
*(--plc) = '\0';
pstr->attrib |= BUSY; /* psym = (struct symbol *)pstr; */
pvfs.pstr = pstr;
psym = pvfs.psym; 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 */
pvfs.pfun = menstk[menptr];
psym = pvfs.psym;
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' );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.