home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 2: PC / frozenfish_august_1995.bin / bbs / d09xx / d0987.lha / MCalc / Source / Parser.y < prev    next >
Text File  |  1994-04-05  |  8KB  |  281 lines

  1. %{
  2. /*
  3. Auto:        smake MCalc
  4. */
  5.  
  6. static void    __yy_bcopy(char *from, char *to, int count);
  7.  
  8. #undef        alloca
  9. #define        alloca(x) AllocVecPool(ParsePool, x)
  10. #undef        malloc
  11. #define        malloc(x) AllocVecPool(ParsePool, x)
  12. #undef        free
  13. #define        free(x) FreeVecPool(ParsePool, x)
  14.  
  15. #undef        YYINITDEPTH
  16. #define        YYINITDEPTH 512
  17.  
  18. #undef        _STDC_
  19. #define        _STDC_
  20.  
  21. #undef        error
  22. #define        error
  23.  
  24. extern        APTR        ParsePool;
  25. extern        double        Value;
  26. extern        double        XMem, YMem, ZMem;
  27.  
  28. #define        outputr(x)    {Value = x;}
  29. #define        outputx(x)    {Value = XMem = x;}
  30. #define        outputy(x)    {Value = YMem = x;}
  31. #define        outputz(x)    {Value = ZMem = x;}
  32. #define        errout(x)    ;
  33. #define        erroutm(x, y)    ;
  34.  
  35.  
  36. /**********************************************************************/
  37. /*                    Chars read and read-position                    */
  38. /**********************************************************************/
  39. extern    UWORD    PColumn;
  40. extern    UWORD    PCharRead;
  41.  
  42.  
  43.     // This is for the wanted angle
  44.  
  45. extern    UWORD        IntAngle;
  46.  
  47.  
  48. /**********************************************************************/
  49. /*                            Error-Value                             */
  50. /**********************************************************************/
  51. UWORD        PError;
  52. %}
  53.  
  54.  
  55.  
  56. /**********************************************************************/
  57. /*                       Possible Return-Value                        */
  58. /**********************************************************************/
  59. %union
  60. {
  61.     double    Real;
  62. }
  63.  
  64.  
  65. /**********************************************************************/
  66. /*                      Token which returns Real                      */
  67. /**********************************************************************/
  68. %token <Real>   INT_CONSTANT
  69. %token <Real>   X_MEM Y_MEM Z_MEM
  70.  
  71.  
  72.  
  73. /**********************************************************************/
  74. /*                       Non-Priority functions                       */
  75. /**********************************************************************/
  76. %token EQU_OP OPEN_OP CLOSE_OP
  77.  
  78.  
  79.  
  80. /**********************************************************************/
  81. /*                           Set priorities                           */
  82. /**********************************************************************/
  83. %left AND_OP OR_OP XOR_OP ASL ASR LSL LSR ROL ROR
  84. %left ADD_OP SUB_OP
  85. %left MUL_OP DIV_OP MOD_OP
  86. %left NEG_OP NOT_OP
  87. %left POW
  88. %nonassoc MY_ABS COS SIN TAN ACOS ASIN ATAN EXP LOG LOG10 SQRT SINH COSH TANH FAK COT
  89.  
  90.  
  91.  
  92. /**********************************************************************/
  93. /*                    Return-Value of my terminal                     */
  94. /**********************************************************************/
  95. %type <Real>   int_expr
  96.  
  97. %%
  98.  
  99.  
  100.  
  101. /**********************************************************************/
  102. /*                          Main "sentence"                           */
  103. /**********************************************************************/
  104. eingabe
  105.     : int_expr                    {outputr($1);}
  106.     | X_MEM EQU_OP int_expr                {outputx($3);}
  107.     | Y_MEM EQU_OP int_expr                {outputy($3);}
  108.     | Z_MEM EQU_OP int_expr                {outputz($3);}
  109.     | error
  110.     ;
  111.  
  112.  
  113.  
  114.  
  115. /**********************************************************************/
  116. /*                           Do the grammar                           */
  117. /**********************************************************************/
  118. int_expr
  119.     : OPEN_OP int_expr CLOSE_OP            {$$ = $2;}
  120.     | int_expr AND_OP int_expr            {$$ = (make_ulong($1)) & (make_ulong($3));}
  121.     | int_expr OR_OP int_expr            {$$ = (make_ulong($1)) | (make_ulong($3));}
  122.     | int_expr XOR_OP int_expr            {$$ = MyXOR(make_ulong($1),make_ulong($3));}
  123.     | int_expr NOT_OP AND_OP int_expr        {$$ = MyNAND(make_ulong($1), make_ulong($4));}
  124.     | int_expr NOT_OP OR_OP int_expr        {$$ = MyNOR(make_ulong($1), make_ulong($4));}
  125.     | int_expr NOT_OP XOR_OP int_expr        {$$ = MyNXOR(make_ulong($1), make_ulong($4));}
  126.     | int_expr ADD_OP int_expr            {$$ = $1 + $3;}
  127.     | int_expr SUB_OP int_expr            {$$ = $1 - $3;}
  128.     | int_expr MUL_OP int_expr            {$$ = $1 * $3;}
  129.     | int_expr DIV_OP int_expr            {if($3 == 0.0) {PError = ERR_DIVBY0; yyerror(NULL); } else $$ = $1 / $3;}
  130.     | int_expr MOD_OP int_expr            {if($3 == 0.0) {PError = ERR_DIVBY0; yyerror(NULL); } else $$ = fmod($1,$3);}
  131.     | SUB_OP int_expr %prec NEG_OP            {$$ = -$2; }
  132.     | NOT_OP int_expr                {$$ = (~make_ulong($2)); }
  133.     | int_expr ASL int_expr                {$$ = (double)MyASL(make_ulong($1),make_ulong($3)); }
  134.     | int_expr ASR int_expr                {$$ = (double)MyASR(make_ulong($1),make_ulong($3)); }
  135.     | int_expr LSL int_expr                {$$ = (double)MyLSL(make_ulong($1),make_ulong($3)); }
  136.     | int_expr LSR int_expr                {$$ = (double)MyLSR(make_ulong($1),make_ulong($3)); }
  137.     | int_expr ROL int_expr                {$$ = (double)MyROL(make_ulong($1),make_ulong($3)); }
  138.     | int_expr ROR int_expr                {$$ = (double)MyROR(make_ulong($1),make_ulong($3)); }
  139.     | int_expr POW int_expr                {$$ = pow($1,$3); }
  140.     | SIN int_expr                    {$$ = sin(calc_angle($2)); }
  141.     | COS int_expr                    {$$ = cos(calc_angle($2)); }
  142.     | TAN int_expr                    {if(!check_angle($2, TAN)) yyerror(NULL); else $$ = tan(calc_angle($2)); }
  143.     | ASIN int_expr                    {if(!check_angle($2, ASIN)) yyerror(NULL); else $$ = asin(calc_angle($2)); }
  144.     | ACOS int_expr                    {if(!check_angle($2, ACOS)) yyerror(NULL); else $$ = acos(calc_angle($2)); }
  145.     | ATAN int_expr                    {if(!check_angle($2, ATAN)) yyerror(NULL); else $$ = atan(calc_angle($2)); }
  146.     | COT int_expr                    {if(!check_angle($2, COT)) yyerror(NULL); else $$ = cot(calc_angle($2)); }
  147.     | SINH int_expr                    {$$ = sinh(calc_angle($2)); }
  148.     | COSH int_expr                    {$$ = cosh(calc_angle($2)); }
  149.     | TANH int_expr                    {if(!check_angle($2, TANH)) yyerror(NULL); else $$ = tanh(calc_angle($2)); }
  150.     | EXP int_expr                    {$$ = exp($2); }
  151.     | LOG int_expr                    {$$ = log($2); }
  152.     | LOG10 int_expr                {$$ = log10($2); }
  153.     | MY_ABS int_expr                {$$ = fabs($2); }
  154.     | SQRT int_expr                    {if($2 < 0.0) {PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = sqrt($2);}
  155.     | int_expr FAK                    {if($1 > 170.0) { PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = calc_fak($1);}
  156.     | FAK int_expr                    {if($2 > 170.0) { PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = calc_fak($2);}
  157.     | INT_CONSTANT
  158.     | X_MEM
  159.     | Y_MEM
  160.     | Z_MEM
  161.     ;
  162.  
  163. %%
  164.  
  165.  
  166.  
  167.  
  168. /**********************************************************************/
  169. /*             Convert a double to a long (the hard way)              */
  170. /**********************************************************************/
  171. ULONG make_ulong(double OldVal)
  172. {
  173.     char    Buffer[26];
  174.     ULONG    Dummy;
  175.  
  176.     sprintf(Buffer, "%f", OldVal);
  177.     stcd_l(Buffer, (LONG *)&Dummy);
  178.     return(Dummy);
  179. }
  180.  
  181.  
  182.  
  183.  
  184.  
  185. /**********************************************************************/
  186. /*                           Calculate Fak                            */
  187. /**********************************************************************/
  188. double calc_fak(double Fak)
  189. {
  190.     double    RetVal = 1.0, i = 1.0;
  191.  
  192.     while(i <= Fak)
  193.     {
  194.         RetVal *= i;
  195.         i++;
  196.     }
  197.  
  198.     return(RetVal);
  199. }
  200.  
  201.  
  202.  
  203.  
  204.  
  205. /**********************************************************************/
  206. /*              Calculate correct angle value (rad, deg)              */
  207. /**********************************************************************/
  208. double calc_angle(double Value)
  209. {
  210.     if(IntAngle == ID_DEG)
  211.         Value = Value / 180.0 * PI;
  212.  
  213.     return(Value);
  214. }
  215.  
  216.  
  217.  
  218.  
  219.  
  220. /**********************************************************************/
  221. /*                  Check if input is within bounds                   */
  222. /**********************************************************************/
  223. BOOL check_angle(double Value, int Mode)
  224. {
  225.     Value    = calc_angle(Value);
  226.  
  227.     switch(Mode)
  228.     {
  229.         case TAN :
  230.         case TANH :
  231.         {
  232.             if(Value < -(PI / 2) || Value > (PI / 2))
  233.             {
  234.                 PError = ERR_OVERFLOW;
  235.                 return(FALSE);
  236.             }
  237.         }
  238.         case COT :
  239.         {
  240.             if(Value < -PI || Value > PI)
  241.             {
  242.                 PError = ERR_OVERFLOW;
  243.                 return(FALSE);
  244.             }
  245.         }
  246.         case ASIN :
  247.         case ACOS :
  248.         {
  249.             if(Value < -1.0 || Value > 1.0)
  250.             {
  251.                 PError = ERR_OVERFLOW;
  252.                 return(FALSE);
  253.             }
  254.             break;
  255.         }
  256.         case ATAN :
  257.         {
  258.             if(Value <= -1.0 || Value >= 1.0)
  259.             {
  260.                 PError = ERR_OVERFLOW;
  261.                 return(FALSE);
  262.             }
  263.             break;
  264.         }
  265.     }
  266.  
  267.     return(TRUE);
  268. }
  269.  
  270.  
  271.  
  272.  
  273.  
  274. /**********************************************************************/
  275. /*                          Error-Routine ;)                          */
  276. /**********************************************************************/
  277. int yyerror(char *s)
  278. {
  279.     return(0);
  280. }
  281.