home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
OS/2 Shareware BBS: 8 Other
/
08-Other.zip
/
OS2MNX1.ZIP
/
EXPR.C
< prev
next >
Wrap
Text File
|
1989-12-27
|
6KB
|
256 lines
/* expr(1) -- author Erik Baalbergen */
/* $Header: d:/rcs/D:/RCS/RCS/expr.c 1.2 89/12/27 02:49:00 RCA Exp $
* $Log: expr.c $
* Revision 1.2 89/12/27 02:49:00 RCA
* "&" and "|" operators don't work.
*
* Revision 1.1 89/12/27 02:41:48 RCA
* Initial revision
*
*/
/*
* expr accepts the following grammar: expr ::= primary | primary
* operator expr ; primary ::= '(' expr ')' | signed-integer ;
* where the priority of the operators is taken care of. The
* resulting value is printed on stdout. Note that the
* ":"-operator is not implemented.
*/
#define EOI 0
#define OR 1
#define AND 2
#define LT 3
#define LE 4
#define EQ 5
#define NE 6
#define GE 7
#define GT 8
#define PLUS 9
#define MINUS 10
#define TIMES 11
#define DIV 12
#define MOD 13
#define COLON 14
#define LPAREN 15
#define RPAREN 16
#define OPERAND 20
#define MAXPRIO 6
struct op
{
char *op_text;
short op_num, op_prio;
} ops[] =
{
{
"|", OR, 6
} ,
{
"&", AND, 5
} ,
{
"<", LT, 4
} ,
{
"<=", LE, 4
} ,
{
"=", EQ, 4
} ,
{
"!=", NE, 4
} ,
{
">=", GE, 4
} ,
{
">", GT, 4
} ,
{
"+", PLUS, 3
} ,
{
"-", MINUS, 3
} ,
{
"*", TIMES, 2
} ,
{
"/", DIV, 2
} ,
{
"%", MOD, 2
} ,
/* {":", COLON, 1}, */
{
"(", LPAREN, -1
} ,
{
")", RPAREN, -1
} ,
{
0, 0, 0
}
};
long
eval(), expr();
char *prog;
char **ip;
struct op *ip_op;
main(argc, argv)
char *argv[];
{
long res;
if (argc == 1)
{
printf ("\n █▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀█");
printf ("\n █ EXPR (Do simple math) $Author: RCA $ █");
printf ("\n █ $Date: 89/12/27 02:49:00 $ $Revision: 1.2 $ █");
printf ("\n █ Usage: EXPR num1 operator num2 ... █");
printf ("\n █ All arguments must be seperated by spaces. █");
printf ("\n █ Examples: EXPR 2 + 2 - 1 █");
printf ("\n █ EXPR 4 * 9 █");
printf ("\n █ EXPR 4 * ( 9 + 9 ) █");
printf ("\n █ EXPR 100 % 11 [modulo] █");
printf ("\n █ EXPR 7 > 9 █");
printf ("\n █ EXPR 7 < 9 █");
printf ("\n █ EXPR 7 = 9 █");
printf ("\n █ EXPR 7 >= 9 █");
printf ("\n █ EXPR 7 != 9 █");
printf ("\n █ Purpose: Do simple math from command line, without █");
printf ("\n █ invoking a special environment. █");
printf ("\n █ OS: Works under OS/2 or DOS. █");
printf ("\n █ Credits: Eric Baalbergen █");
printf ("\n █▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄▄█\n");
exit(1);
}
prog = argv[0];
ip = &argv[1];
res = expr(lex(*ip), MAXPRIO);
if (*++ip != 0)
syntax();
printf("%d\n", res);
exit(0);
}
lex(s)
register char *s;
{
register struct op *op = ops;
if (s == 0)
{
ip_op = 0;
return EOI;
}
while (op->op_text)
{
if (strcmp(s, op->op_text) == 0)
{
ip_op = op;
return op->op_num;
}
op++;
}
ip_op = 0;
return OPERAND;
}
long
num(s)
register char *s;
{
long l = 0;
long sign = 1;
if (*s == '\0')
syntax();
if (*s == '-')
{
sign = -1;
s++;
}
while (*s >= '0' && *s <= '9')
l = l *10 + *s++ - '0';
if (*s != '\0')
syntax();
return sign * l;
}
syntax()
{
write(2, prog, strlen(prog));
write(2, ": syntax error\n", 15);
exit(1);
}
long
expr(n, prio)
{
long res;
if (n == EOI)
syntax();
if (n == LPAREN)
{
if (prio == 0)
{
res = expr(lex(*++ip), MAXPRIO);
if (lex(*++ip) != RPAREN)
syntax();
} else
res = expr(n, prio - 1);
} else
if (n == OPERAND)
{
if (prio == 0)
return num(*ip);
res = expr(n, prio - 1);
} else
syntax();
while ((n = lex(*++ip)) && ip_op && ip_op->op_prio == prio)
res = eval(res, n, expr(lex(*++ip), prio - 1));
ip--;
return res;
}
long
eval(l1, op, l2)
long l1, l2;
{
switch (op)
{
case OR:
return l1 ? l1 : l2;
case AND:
return (l1 && l2) ? l1 : 0;
case LT:
return l1 < l2;
case LE:
return l1 <= l2;
case EQ:
return l1 == l2;
case NE:
return l1 != l2;
case GE:
return l1 >= l2;
case GT:
return l1 > l2;
case PLUS:
return l1 + l2;
case MINUS:
return l1 - l2;
case TIMES:
return l1 * l2;
case DIV:
return l1 / l2;
case MOD:
return l1 % l2;
}
fatal();
}
fatal()
{
write(2, "fatal\n", 6);
exit(1);
}