home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / intercal.zip / src / fiddle.c < prev    next >
C/C++ Source or Header  |  1996-06-09  |  5KB  |  251 lines

  1. /*
  2.  * fiddle.c -- functions that implement the five INTERCAL operators
  3.  *
  4.  * We link these to the compiler, too, in order to do constant folding
  5.  *
  6. LICENSE TERMS
  7.     Copyright (C) 1996 Eric S. Raymond 
  8.  
  9.     This program is free software; you can redistribute it and/or modify
  10.     it under the terms of the GNU General Public License as published by
  11.     the Free Software Foundation; either version 2 of the License, or
  12.     (at your option) any later version.
  13.  
  14.     This program is distributed in the hope that it will be useful,
  15.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.     GNU General Public License for more details.
  18.  
  19.     You should have received a copy of the GNU General Public License
  20.     along with this program; if not, write to the Free Software
  21.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  22.  */
  23.  
  24. #include "fiddle.h"
  25. #include "sizes.h"
  26.  
  27. unsigned int mingle(register unsigned int r, register unsigned int s)
  28. {
  29.   if (Base == 2) {
  30.     r = ((r & 0x0000ff00) << 8) | (r & 0x000000ff);
  31.     r = ((r & 0x00f000f0) << 4) | (r & 0x000f000f);
  32.     r = ((r & 0x0c0c0c0c) << 2) | (r & 0x03030303);
  33.     r = ((r & 0x22222222) << 1) | (r & 0x11111111);
  34.     s = ((s & 0x0000ff00) << 8) | (s & 0x000000ff);
  35.     s = ((s & 0x00f000f0) << 4) | (s & 0x000f000f);
  36.     s = ((s & 0x0c0c0c0c) << 2) | (s & 0x03030303);
  37.     s = ((s & 0x22222222) << 1) | (s & 0x11111111);
  38.     return (r << 1) | s;
  39.   }
  40.   else {
  41.     unsigned int result = 0, fac = 1;
  42.     int i;
  43.     for (i = 0 ; i < Small_digits ; i++) {
  44.       result += fac * (s % Base);
  45.       s /= Base;
  46.       fac *= Base;
  47.       result += fac * (r % Base);
  48.       r /= Base;
  49.       fac *= Base;
  50.     }
  51.     return result;
  52.   }
  53. }
  54.  
  55. unsigned int iselect(register unsigned int r, register unsigned int s)
  56. {
  57.   if (Base == 2) {
  58.     register unsigned int i = 1, t = 0;
  59.     while (s) {
  60.       if (s & i) {
  61.     t |= r & i;
  62.     s ^= i;
  63.     i <<= 1;
  64.       }
  65.       else {
  66.     s >>= 1;
  67.     r >>= 1;
  68.       }
  69.     }
  70.     return(t);
  71.   }
  72.   else {
  73.     unsigned int j, result = 0, fac, digit, ofac = 1;
  74.     for (j = Base - 1 ; j > 0 ; j--) {
  75.       int i;
  76.       fac = 1;
  77.       for (i = 0; i < Large_digits ; i++) {
  78.     if ((s / fac) % Base == j) {
  79.       digit = (r / fac) % Base;
  80.       if (digit)
  81.         result += ofac * (digit > j ? digit : j);
  82.       ofac *= Base;
  83.     }
  84.     fac *= Base;
  85.       }
  86.     }
  87.     return result;
  88.   }
  89. }
  90.  
  91. static unsigned int whirl(unsigned int len, unsigned int p, unsigned int n)
  92. {
  93.   unsigned int i, fac = 1, result = 0, d1, d2, dsave;
  94.   d1 = n % Base;
  95.   dsave = d1;
  96.   for (i = 1 ; i <= len ; i++) {
  97.     d2 = d1;
  98.     d1 = (i < len) ? (n /= Base, n % Base) : dsave;
  99.     if (d1 <= p)
  100.       result += fac * ((d2 < d1 || d2 > p) ? d1 : d2);
  101.     else
  102.       result += fac * ((d2 < d1 && d2 > p) ? d1 : d2);
  103.     fac *= Base;
  104.   }
  105.   return result;
  106. }
  107.  
  108. unsigned int and16(unsigned int n)
  109. {
  110.   if (Base == 2) {
  111.     unsigned int m = (n >> 1);
  112.     if (n & 1)
  113.       m |= 0x8000;
  114.     return(m & n);
  115.   }
  116.   else {
  117.     return whirl(Small_digits,0,n);
  118.   }
  119. }
  120.  
  121. unsigned int or16(unsigned int n)
  122. {
  123.   if (Base == 2) {
  124.     unsigned int m = (n >> 1);
  125.     if (n & 1)
  126.       m |= 0x8000;
  127.     return(m | n);
  128.   }
  129.   else {
  130.     return whirl(Small_digits,Base-1,n);
  131.   }
  132. }
  133.  
  134. unsigned int whirl16(unsigned int p, unsigned int n)
  135. {
  136.   return whirl(Small_digits,p,n);
  137. }
  138.  
  139. unsigned int and32(unsigned int n)
  140. {
  141.   if (Base == 2) {
  142.     unsigned int m = (n >> 1);
  143.     if (n & 1)
  144.       m |= 0x80000000;
  145.     return(m & n);
  146.   }
  147.   else {
  148.     return whirl(Large_digits,0,n);
  149.   }
  150. }
  151.  
  152. unsigned int or32(unsigned int n)
  153. {
  154.   if (Base == 2) {
  155.     unsigned int m = (n >> 1);
  156.     if (n & 1)
  157.       m |= 0x80000000;
  158.     return(m | n);
  159.   }
  160.   else {
  161.     return whirl(Large_digits,Base-1,n);
  162.   }
  163. }
  164.  
  165. unsigned int whirl32(unsigned int p, unsigned int n)
  166. {
  167.   return whirl(Large_digits,p,n);
  168. }
  169.  
  170. unsigned int xor(unsigned int len, unsigned int n)
  171. {
  172.   unsigned int i, fac = 1, result = 0, d1, d2, dsave;
  173.   d1 = n % Base;
  174.   dsave = d1;
  175.   for (i = 1 ; i <= len ; i++) {
  176.     d2 = d1;
  177.     d1 = (i < len) ? (n /= Base, n % Base) : dsave;
  178.     result += fac * ((Base + d1 - d2) % Base);
  179.     fac *= Base;
  180.   }
  181.   return result;
  182. }
  183.  
  184. unsigned int xor16(unsigned int n)
  185. {
  186.   if (Base == 2) {
  187.     unsigned int m = (n >> 1);
  188.     if (n & 1)
  189.       m |= 0x8000;
  190.     return(m ^ n);
  191.   }
  192.   else {
  193.     return xor(Small_digits,n);
  194.   }
  195. }
  196.  
  197. unsigned int xor32(unsigned int n)
  198. {
  199.   if (Base == 2) {
  200.     unsigned int m = (n >> 1);
  201.     if (n & 1)
  202.       m |= 0x80000000;
  203.     return(m ^ n);
  204.   }
  205.   else {
  206.     return xor(Large_digits,n);
  207.   }
  208. }
  209.  
  210. static unsigned int fin(unsigned int len, unsigned int n)
  211. {
  212.   unsigned int i, fac = 1, result = 0, d1, d2, dsave;
  213.   d1 = n % Base;
  214.   dsave = d1;
  215.   for (i = 1 ; i <= len ; i++) {
  216.     d2 = d1;
  217.     d1 = (i < len) ? (n /= Base, n % Base) : dsave;
  218.     result += fac * ((d1 + d2) % Base);
  219.     fac *= Base;
  220.   }
  221.   return result;
  222. }
  223.  
  224. unsigned int fin16(unsigned int n)
  225. {
  226.   if (Base == 2) {
  227.     unsigned int m = (n >> 1);
  228.     if (n & 1)
  229.       m |= 0x8000;
  230.     return(m ^ n);
  231.   }
  232.   else {
  233.     return fin(Small_digits,n);
  234.   }
  235. }
  236.  
  237. unsigned int fin32(unsigned int n)
  238. {
  239.   if (Base == 2) {
  240.     unsigned int m = (n >> 1);
  241.     if (n & 1)
  242.       m |= 0x80000000;
  243.     return(m ^ n);
  244.   }
  245.   else {
  246.     return fin(Large_digits,n);
  247.   }
  248. }
  249.  
  250. /* fiddle.c */
  251.