home *** CD-ROM | disk | FTP | other *** search
- /* bitwise.c */
- /**********************************************************************
- * File Name : bitwise.c
- * Function : and/or/xor/not/two's complement functions of pac
- * Author : Istvan Mohos, 1987
- ***********************************************************************/
-
-
- #include "defs.h"
- #include "toktab.h"
-
- /* bitwise operators:
- Ignore negative signs, if any.
- Add preceding zeros to match digit count of integral part of numbers.
- Add trailing zeros to match digit count of fractional part of nums.
- Flip bits as appropriate.
- */
-
- char *
- bitwise(oper, operand1, operand2, negflag)
- char *operand1, *operand2;
- int oper, *negflag;
- {
-
- #ifdef BITTEST
- static char debug1[LINEMAX], debug2[LINEMAX];
- static
- #endif
- char buf1[LINEMAX], buf2[LINEMAX];
-
- static char bitbuf[LINEMAX];
- char *bp = bitbuf;
- char *pt1 = operand1;
- char *pt2 = operand2;
- register char *r1, *r2;
- register int ri;
- int leflen1, leflen2;
- int ritlen1 = 0;
- int ritlen2 = 0;
- int dot1 = 0;
- int dot2 = 0;
- int len_of1, len_of2;
- int maxlef, maxrit;
- static char *fid = "bitwise";
-
- _TR
- *bp++ = Base_str[2];
- *bp++ = ' ';
-
- /* ignore signs */
- *negflag = 0;
- if (*pt1 == '-')
- ++pt1;
- len_of1 = strlen(pt1);
- for (r1 = pt1 + len_of1; --r1 >= pt1;)
- if (*r1 == '.') {
- dot1 = 1;
- break;
- }
- if (!dot1)
- leflen1 = len_of1;
- else {
- leflen1 = r1 - pt1;
- ritlen1 = len_of1 - leflen1 - 1;
- }
-
- switch (oper) {
- default:
- case AND:
- case OR:
- case XOR:
- if (*pt2 == '-')
- ++pt2;
- len_of2 = strlen(pt2);
- for (r2 = pt2 + len_of2; --r2 >= pt2;)
- if (*r2 == '.') {
- dot2 = 2;
- break;
- }
- if (!dot2)
- leflen2 = len_of2;
- else {
- leflen2 = r2 - pt2;
- ritlen2 = len_of2 - leflen2 - 2;
- }
-
- maxlef = (leflen1 > leflen2) ? leflen1 : leflen2;
- maxrit = (ritlen1 > ritlen2) ? ritlen1 : ritlen2;
-
- r1 = buf1;
- for (ri = maxlef - leflen1; --ri >= 0; *r1++ = '0');
- strcpy(r1, pt1);
- r1 += len_of1;
- if (dot1 || dot2)
- *r1++ = '.';
- for (ri = maxrit - ritlen1; --ri >= 0; *r1++ = '0');
- *r1 = '\0';
- r1 = buf1;
-
- r2 = buf2;
- for (ri = maxlef - leflen2; --ri >= 0; *r2++ = '0');
- strcpy(r2, pt2);
- r2 += len_of2;
- if (dot1 || dot2)
- *r2++ = '.';
- for (ri = maxrit - ritlen2; --ri >= 0; *r2++ = '0');
- *r2 = '\0';
- ri = r2 - buf2; /* not including the null */
- r2 = buf2;
-
- switch (oper) {
- case AND:
- for (; --ri >= 0; r1++, r2++, bp++)
- if (*r1 == '1' && *r2 == '1')
- *bp = '1';
- else
- *bp = '0';
- break;
- case OR:
- for (; --ri >= 0; r1++, r2++, bp++)
- if (*r1 == '1' || *r2 == '1')
- *bp = '1';
- else
- *bp = '0';
- break;
- case XOR:
- for (; --ri >= 0; r1++, r2++, bp++)
- if ((*r1 == '1' && *r2 == '0') ||
- (*r1 == '0' && *r2 == '1'))
- *bp = '1';
- else
- *bp = '0';
- break;
- }
- *bp = '\0';
- if (dot1 || dot2)
- *(bitbuf + 2 + maxlef) = '.';
-
- #ifdef BITTEST
- strcpy(debug1, pt1);
- strcpy(debug2, pt2);
- if (Trace && Tf != NULL)
- fprintf(Tf,
- "\n<<<%s>>>\n<<<%s>>>\n<<<<%s>>>\n<<<%s>>>\n<<<%s>>>\n",
- debug1, debug2, buf1, buf2, bitbuf);
- #endif
-
- TR_
- return(bitbuf);
-
- case TW:
- if (dot1) {
- TR_
- return(ZERO);
- }
- if (atoi(pt1) == 0) {
- strcpy(bp, "-1");
- TR_
- return(bitbuf);
- }
- /* case continues */
- case NOT:
-
- /* convert second number (in base 10), to size of
- field in which to evaluate the operand */
- if (*pt2 == '-')
- ++pt2;
- if ((len_of2 = atoi(pt2)) > LINEMAX - 4 - ritlen1) {
- TR_
- return(ZERO);
- }
-
- if (*pt1 == '1' && len_of2 == leflen1)
- *negflag = 1;
- if (leflen1 > len_of2) {
- len_of2 = leflen1;
- pac_err("field too small");
- }
- r2 = bp;
- for (ri = len_of2; --ri >= 0; *r2++ = '1');
- *r2++ = '.';
- for (ri = ritlen1; --ri >= 0; *r2++ = '1');
- *r2-- = '\0'; /* end of result in bitbuf */
-
- /* on last digit */
- r1 = pt1 + leflen1 + ritlen1 + dot1 -1;
- for (ri = ritlen1; --ri >= 0; r1--, r2--)
- if (*r1 == '1')
- *r2 = '0';
- if (dot1)
- *r2-- = *r1--;
- else
- *r2-- = '\0';
-
- for (ri = leflen1; --ri >= 0; r1--, r2--)
- if (*r1 == '1')
- *r2 = '0';
- TR_
- return(bitbuf);
- }
- }
-