home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-387-Vol-3of3.iso / d / djdev108.zip / SAMPLES / HEXCALC / LANG.Y < prev    next >
Text File  |  1991-09-02  |  4KB  |  225 lines

  1. %{
  2.  
  3. #include <stdio.h>
  4. #include <math.h>
  5. #include "hc.h"
  6.  
  7. char *bin(double n);
  8. char *oct(double n);
  9. char *rhex(double d);
  10. double do_call(int name, double arg);
  11. double do_power(double a, double b);
  12.  
  13. void lr_save(double d);
  14. double lr_recall(int n);
  15.  
  16. %}
  17.  
  18. %union {
  19.   double d;
  20.   int i;
  21. }
  22.  
  23. %token <i> LAST_RESULT
  24. %token <d> INUM
  25. %token <i> ID
  26.  
  27. %type <d> expr
  28.  
  29. %left '+' '-'
  30. %left '^'
  31. %left '|'
  32. %left '&'
  33. %left '<' '>'
  34. %left '*' '/' '%'
  35. %left UNARYMINUS '~'
  36. %right POWER
  37.  
  38. %start lines
  39.  
  40. %% /***********************************************************************/
  41.  
  42. lines
  43.     :
  44.     | lines stmt '\n'
  45.     ;
  46.  
  47. stmt
  48.     : expr {
  49.              printf("    %lg   %s   %s   %s\n",
  50.                     $1, rhex($1), oct($1), bin($1));
  51.              lr_save($1);
  52.            }
  53.     | error '\n' { yyerrok; }
  54.     | ID '=' expr { id_val[(long)$1] = $3; lr_save($3); }
  55.     ;
  56.  
  57. expr
  58.     : INUM { $$ = $1; }
  59.     | ID { $$ = id_val[$1]; }
  60.     | LAST_RESULT { $$ = lr_recall($1); }
  61.     | expr '+' expr { $$ = $1 + $3; }
  62.     | expr '-' expr { $$ = $1 - $3; }
  63.     | expr '*' expr {  $$ = $1 * $3; }
  64.     | expr '/' expr {  $$ = $1 / $3; }
  65.     | expr '%' expr {  $$ = (long)$1 % (long)$3; }
  66.     | expr '<' expr { $$ = ldexp($1, (long)$3); }
  67.     | expr '>' expr { $$ = ldexp($1, -(long)$3); }
  68.     | expr '&' expr { $$ = (long)$1 & (long)$3; }
  69.     | expr '|' expr { $$ = (long)$1 | (long)$3; }
  70.     | expr '^' expr { $$ = (long)$1 ^ (long)$3; }
  71.     | expr POWER expr { $$ = do_power($1, $3); }
  72.     | '-' expr %prec UNARYMINUS {  $$ = - $2; }
  73.     | '~' expr %prec UNARYMINUS {  $$ = ~ (long)$2; }
  74.     | '(' expr ')' { $$ = $2; }
  75.     | ID '(' expr ')' { $$ = do_call($1, $3); }
  76.     ;
  77.  
  78. %%
  79.  
  80. char *oct(double d)
  81. {
  82.   long n;
  83.   static char buf[30];
  84.   if ((d > 0x7fffffff) || (d < -0x7fffffff))
  85.     return "";
  86.   n = (long)d;
  87.   if (n)
  88.   {
  89.     sprintf(buf, "0%o", n);
  90.     return buf;
  91.   }
  92.   else
  93.     return "0";
  94. }
  95.  
  96. char *bin(double d)
  97. {
  98.   long n;
  99.   static char buf[] = " xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx";
  100.   int i;
  101.   char *rv;
  102.   char *bp = buf+5*8-1;
  103.   if ((d > 0x7fffffff) || (d < -0x7fffffff))
  104.     return "";
  105.   n = (long)d;
  106.   if (n == 0)
  107.     return "0";
  108.   for (i=31; i>=0; i--)
  109.   {
  110.     *bp-- = '0' + (n & 1);
  111.     n >>= 1;
  112.     if (i % 4 == 0)
  113.       bp--;
  114.   }
  115.   rv = buf;
  116.   for (i=0; i<7; i++)
  117.   {
  118.     if (strncmp(rv+1, "0000", 4))
  119.       return rv+1;
  120.     rv += 5;
  121.   }
  122.   return rv+1;
  123. }
  124.  
  125. char *rhex(double d)
  126. {
  127.   static char buf[] = "0x12345678.12345678   ";
  128.   int dleft;
  129.   char *cp, *lastdig;
  130.   if ((d > 0x7fffffff) || (d < -0x7fffffff))
  131.     return "<huge>";
  132.   if ((d < 0) && (d != (long)d))
  133.     d--;
  134.   sprintf(buf, "0x%x", (long)d);
  135.   cp = buf+strlen(buf);
  136.   if (d < 0)
  137.   {
  138.     d -= (long)d;
  139.     if (d) d += 1;
  140.   }
  141.   else
  142.   {
  143.     d -= (long)d;
  144.   }
  145.   dleft = 18 - strlen(buf);
  146.   if (d == 0)
  147.     return buf;
  148.   lastdig = cp;
  149.   *cp++ = '.';
  150.   while (dleft)
  151.   {
  152.     d *= 16;
  153.     *cp++ = "0123456789abcdef"[(long)d];
  154.     if (d)
  155.       lastdig = cp;
  156.     d -= (long)d;
  157.     dleft--;
  158.   }
  159.   *lastdig = 0;
  160.   return buf;
  161. }
  162.  
  163. typedef double (*FUNC)(double);
  164.  
  165. struct {
  166.   char *name;
  167.   FUNC func;
  168. } funclist[] = {
  169.   "sin", sin,
  170.   "sinh", sinh,
  171.   "cos", cos,
  172.   "cosh", cosh,
  173.   "tan", tan,
  174.   "tanh", tanh,
  175.   "asin", asin,
  176.   "asinh", asinh,
  177.   "acos", acos,
  178.   "acosh", acosh,
  179.   "atan", atan,
  180.   "atanh", atanh,
  181.   "exp", exp,
  182.   "log", log,
  183.   "pow10", pow10,
  184.   "log10", log10,
  185.   "pow2", pow2,
  186.   "log2", log2,
  187.   "sqrt", sqrt,
  188.   0,0
  189. };
  190.  
  191. double do_call(int fp, double arg)
  192. {
  193.   int i;
  194.   for (i=0; funclist[i].name; i++)
  195.     if (strcmp(funclist[i].name, id_name[fp]) == 0)
  196.       return (funclist[i].func)(arg);
  197.   printf("Unknown function `%s'\n", id_name[fp]);
  198.   return 0;
  199. }
  200.  
  201. double do_power(double a, double b)
  202. {
  203.   return pow(a, b);
  204. }
  205.  
  206. #define LAST_SIZE 10
  207. double last_result[LAST_SIZE];
  208. int last_idx;
  209.  
  210. void lr_save(double d)
  211. {
  212.   last_result[last_idx] = d;
  213.   last_idx = (last_idx+LAST_SIZE-1) % LAST_SIZE;
  214. }
  215.  
  216. double lr_recall(int n)
  217. {
  218.   if (n > LAST_SIZE)
  219.   {
  220.     printf("Can't recall that far back\n");
  221.     return 0;
  222.   }
  223.   return last_result[(last_idx+n)%LAST_SIZE];
  224. }
  225.