home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume9
/
uemacs3.8b
/
part04
/
eval.c
< prev
next >
Wrap
C/C++ Source or Header
|
1987-03-12
|
11KB
|
455 lines
/* EVAL.C: Expresion evaluation functions for
MicroEMACS
written 1986 by Daniel Lawrence */
#include <stdio.h>
#include "estruct.h"
#include "edef.h"
#include "evar.h"
#if MEGAMAX & ST520
overlay "eval"
#endif
char value[80]; /* buffer to return value in */
varinit() /* initialize the user variable list */
{
register int i;
for (i=0; i < MAXVARS; i++)
uv[i].u_name[0] = 0;
}
char *gtfun(fname) /* evaluate a function */
char *fname; /* name of function to evaluate */
{
register int fnum; /* index to function to eval */
register int status; /* return status */
char arg1[NSTRING]; /* value of first argument */
char arg2[NSTRING]; /* value of second argument */
char arg3[NSTRING]; /* value of third argument */
static char result[2 * NSTRING]; /* string result */
/* look the function up in the function table */
fname[3] = 0; /* only first 3 chars significant */
for (fnum = 0; fnum < NFUNCS; fnum++)
if (strcmp(fname, funcs[fnum].f_name) == 0)
break;
/* return errorm on a bad reference */
if (fnum == NFUNCS)
return(errorm);
/* retrieve the first argument */
if ((status = macarg(arg1)) != TRUE)
return(errorm);
/* if needed, retrieve the second argument */
if (funcs[fnum].f_type >= DYNAMIC) {
if ((status = macarg(arg2)) != TRUE)
return(errorm);
/* if needed, retrieve the third argument */
if (funcs[fnum].f_type >= TRINAMIC)
if ((status = macarg(arg3)) != TRUE)
return(errorm);
}
/* and now evaluate it! */
switch (fnum) {
case UFADD: return(itoa(atoi(arg1) + atoi(arg2)));
case UFSUB: return(itoa(atoi(arg1) - atoi(arg2)));
case UFTIMES: return(itoa(atoi(arg1) * atoi(arg2)));
case UFDIV: return(itoa(atoi(arg1) / atoi(arg2)));
case UFMOD: return(itoa(atoi(arg1) % atoi(arg2)));
case UFNEG: return(itoa(-atoi(arg1)));
case UFCAT: strcpy(result, arg1);
return(strcat(result, arg2));
case UFLEFT: return(strncpy(result, arg1, atoi(arg2)));
case UFRIGHT: return(strcpy(result, &arg1[atoi(arg2)-1]));
case UFMID: return(strncpy(result, &arg1[atoi(arg2)-1],
atoi(arg3)));
case UFNOT: return(ltos(stol(arg1) == FALSE));
case UFEQUAL: return(ltos(atoi(arg1) == atoi(arg2)));
case UFLESS: return(ltos(atoi(arg1) < atoi(arg2)));
case UFGREATER: return(ltos(atoi(arg1) > atoi(arg2)));
case UFSEQUAL: return(ltos(strcmp(arg1, arg2) == 0));
case UFSLESS: return(ltos(strcmp(arg1, arg2) < 0));
case UFSGREAT: return(ltos(strcmp(arg1, arg2) > 0));
case UFIND: return(getval(arg1));
}
exit(-11); /* never should get here */
}
char *gtusr(vname) /* look up a user var's value */
char *vname; /* name of user variable to fetch */
{
register int vnum; /* ordinal number of user var */
/* scan the list looking for the user var name */
for (vnum = 0; vnum < MAXVARS; vnum++)
if (strcmp(vname, uv[vnum].u_name) == 0)
break;
/* return errorm on a bad reference */
if (vnum == MAXVARS)
return(errorm);
return(uv[vnum].u_value);
}
char *gtenv(vname)
char *vname; /* name of environment variable to retrieve */
{
register int vnum; /* ordinal number of var refrenced */
/* scan the list, looking for the referenced name */
for (vnum = 0; vnum < NEVARS; vnum++)
if (strcmp(vname, envars[vnum]) == 0)
break;
/* return errorm on a bad reference */
if (vnum == NEVARS)
return(errorm);
/* otherwise, fetch the appropriate value */
switch (vnum) {
case EVFILLCOL: return(itoa(fillcol));
case EVPAGELEN: return(itoa(term.t_nrow + 1));
case EVCURCOL: return(itoa(getccol(FALSE)));
case EVCURLINE: return(itoa(getcline()));
case EVRAM: return(itoa((int)(envram / 1024l)));
case EVFLICKER: return(ltos(flickcode));
case EVCURWIDTH:return(itoa(term.t_nrow));
case EVCBUFNAME:return(curbp->b_bname);
case EVCFNAME: return(curbp->b_fname);
case EVSRES: return(sres);
case EVDEBUG: return(ltos(macbug));
case EVSTATUS: return(ltos(cmdstatus));
}
}
int setvar(f, n) /* set a variable */
int f; /* default flag */
int n; /* numeric arg (can overide prompted value) */
{
register int vnum; /* ordinal number of var refrenced */
register int status; /* status return */
register int vtype; /* type of variable to set */
register char * sp; /* scratch string pointer */
char var[NVSIZE+1]; /* name of variable to fetch */
char value[NSTRING]; /* value to set variable to */
/* first get the variable to set.. */
if (clexec == FALSE) {
status = mlreply("Variable to set: ", &var[0], NVSIZE);
if (status != TRUE)
return(status);
} else { /* macro line argument */
/* grab token and skip it */
execstr = token(execstr, var);
}
/* check the legality and find the var */
sv01: vtype = -1;
switch (var[0]) {
case '$': /* check for legal enviromnent var */
for (vnum = 0; vnum < NEVARS; vnum++)
if (strcmp(&var[1], envars[vnum]) == 0) {
vtype = TKENV;
break;
}
break;
case '%': /* check for existing legal user variable */
for (vnum = 0; vnum < MAXVARS; vnum++)
if (strcmp(&var[1], uv[vnum].u_name) == 0) {
vtype = TKVAR;
break;
}
if (vnum < MAXVARS)
break;
/* create a new one??? */
for (vnum = 0; vnum < MAXVARS; vnum++)
if (uv[vnum].u_name[0] == 0) {
vtype = TKVAR;
strcpy(uv[vnum].u_name, &var[1]);
break;
}
break;
case '&': /* indirect operator? */
var[4] = 0;
if (strcmp(&var[1], "ind") == 0) {
/* grab token, and eval it */
execstr = token(execstr, var);
strcpy(var, getval(var));
goto sv01;
}
}
/* if its not legal....bitch */
if (vtype == -1) {
mlwrite("%%No such variable");
return(FALSE);
}
/* get the value for that variable */
if (f == TRUE)
strcpy(value, itoa(n));
else {
status = mlreply("Value: ", &value[0], NSTRING);
if (status != TRUE)
return(status);
}
/* and set the appropriate value */
status = TRUE;
switch (vtype) {
case TKVAR: /* set a user variable */
if (uv[vnum].u_value != NULL)
free(uv[vnum].u_value);
sp = malloc(strlen(value) + 1);
if (sp == NULL)
return(FALSE);
strcpy(sp, value);
uv[vnum].u_value = sp;
break;
case TKENV: /* set an environment variable */
status = TRUE; /* by default */
switch (vnum) {
case EVFILLCOL: fillcol = atoi(value);
break;
case EVPAGELEN: status = newsize(TRUE, atoi(value));
break;
case EVCURCOL: status = setccol(atoi(value));
break;
case EVCURLINE: status = gotoline(TRUE, atoi(value));
break;
case EVRAM: break;
case EVFLICKER: flickcode = stol(value);
break;
case EVCURWIDTH:status = newwidth(TRUE, atoi(value));
break;
case EVCBUFNAME:strcpy(curbp->b_bname, value);
curwp->w_flag |= WFMODE;
break;
case EVCFNAME: strcpy(curbp->b_fname, value);
curwp->w_flag |= WFMODE;
break;
case EVSRES: status = TTrez(value);
break;
case EVDEBUG: macbug = stol(value);
break;
case EVSTATUS: cmdstatus = stol(value);
break;
}
break;
}
return(status);
}
/* atoi: ascii string to integer......This is too
inconsistant to use the system's */
atoi(st)
char *st;
{
int result; /* resulting number */
int sign; /* sign of resulting number */
char c; /* current char being examined */
result = 0;
sign = 1;
while ((c = *st++)) {
if (c == '-')
sign *= -1;
if (c >= '0' && c <= '9')
result = result * 10 + c - '0';
}
return(result * sign);
}
/* itoa: integer to ascii string.......... This is too
inconsistant to use the system's */
char *itoa(i)
int i; /* integer to translate to a string */
{
register int digit; /* current digit being used */
register char *sp; /* pointer into result */
register int sign; /* sign of resulting number */
static char result[INTWIDTH+1]; /* resulting string */
/* eliminate the trivial 0 */
if (i == 0)
return("0");
/* record the sign...*/
sign = 1;
if (i < 0) {
sign = -1;
i = -i;
}
/* and build the string (backwards!) */
sp = result + INTWIDTH;
*sp = 0;
while (i) {
digit = i % 10;
*(--sp) = '0' + digit; /* and install the new digit */
i = i / 10;
}
/* and fix the sign */
if (sign == -1) {
*(--sp) = '-'; /* and install the minus sign */
}
return(sp);
}
int gettyp(token) /* find the type of a passed token */
char *token; /* token to analyze */
{
register char c; /* first char in token */
/* grab the first char (this is all we need) */
c = *token;
/* no blanks!!! */
if (c == 0)
return(TKNUL);
/* a numeric literal? */
if (c >= '0' && c <= '9')
return(TKLIT);
switch (c) {
case '"': return(TKSTR);
case '!': return(TKDIR);
case '@': return(TKARG);
case '#': return(TKBUF);
case '$': return(TKENV);
case '%': return(TKVAR);
case '&': return(TKFUN);
case '*': return(TKLBL);
default: return(TKCMD);
}
}
char *getval(token) /* find the value of a token */
char *token; /* token to evaluate */
{
register int status; /* error return */
register BUFFER *bp; /* temp buffer pointer */
register int blen; /* length of buffer argument */
char buf[NSTRING]; /* string buffer for some returns */
switch (gettyp(token)) {
case TKNUL: return("");
case TKARG: /* interactive argument */
status = getstring(getval(&token[1]),
buf, NSTRING, ctoec('\n'));
if (status == ABORT)
return(errorm);
return(buf);
case TKBUF: /* buffer contents fetch */
/* grab the right buffer */
bp = bfind(getval(&token[1]), FALSE, 0);
if (bp == NULL)
return(errorm);
/* make sure we are not at the end */
if (bp->b_linep == bp->b_dotp)
return(errorm);
/* grab the line as an argument */
blen = bp->b_dotp->l_used;
if (blen > NSTRING)
blen = NSTRING;
strncpy(buf, bp->b_dotp->l_text, blen);
buf[blen] = 0;
/* and step the buffer's line ptr ahead a line */
bp->b_dotp = bp->b_dotp->l_fp;
bp->b_doto = 0;
/* and return the spoils */
return(buf);
case TKVAR: return(gtusr(token+1));
case TKENV: return(gtenv(token+1));
case TKFUN: return(gtfun(token+1));
case TKDIR: return(errorm);
case TKLBL: return(itoa(gtlbl(token)));
case TKLIT: return(token);
case TKSTR: return(token+1);
case TKCMD: return(token);
}
}
gtlbl(token) /* find the line number of the given label */
char *token; /* label name to find */
{
return(1);
}
int stol(val) /* convert a string to a numeric logical */
char *val; /* value to check for stol */
{
/* check for logical values */
if (val[0] == 'F')
return(FALSE);
if (val[0] == 'T')
return(TRUE);
/* check for numeric truth (!= 0) */
return((atoi(val) != 0));
}
char *ltos(val) /* numeric logical to string logical */
int val; /* value to translate */
{
if (val)
return(truem);
else
return(falsem);
}