home *** CD-ROM | disk | FTP | other *** search
Lex Description | 1994-04-05 | 8.1 KB | 281 lines |
- %{
- /*
- Auto: smake MCalc
- */
-
- static void __yy_bcopy(char *from, char *to, int count);
-
- #undef alloca
- #define alloca(x) AllocVecPool(ParsePool, x)
- #undef malloc
- #define malloc(x) AllocVecPool(ParsePool, x)
- #undef free
- #define free(x) FreeVecPool(ParsePool, x)
-
- #undef YYINITDEPTH
- #define YYINITDEPTH 512
-
- #undef _STDC_
- #define _STDC_
-
- #undef error
- #define error
-
- extern APTR ParsePool;
- extern double Value;
- extern double XMem, YMem, ZMem;
-
- #define outputr(x) {Value = x;}
- #define outputx(x) {Value = XMem = x;}
- #define outputy(x) {Value = YMem = x;}
- #define outputz(x) {Value = ZMem = x;}
- #define errout(x) ;
- #define erroutm(x, y) ;
-
-
- /**********************************************************************/
- /* Chars read and read-position */
- /**********************************************************************/
- extern UWORD PColumn;
- extern UWORD PCharRead;
-
-
- // This is for the wanted angle
-
- extern UWORD IntAngle;
-
-
- /**********************************************************************/
- /* Error-Value */
- /**********************************************************************/
- UWORD PError;
- %}
-
-
-
- /**********************************************************************/
- /* Possible Return-Value */
- /**********************************************************************/
- %union
- {
- double Real;
- }
-
-
- /**********************************************************************/
- /* Token which returns Real */
- /**********************************************************************/
- %token <Real> INT_CONSTANT
- %token <Real> X_MEM Y_MEM Z_MEM
-
-
-
- /**********************************************************************/
- /* Non-Priority functions */
- /**********************************************************************/
- %token EQU_OP OPEN_OP CLOSE_OP
-
-
-
- /**********************************************************************/
- /* Set priorities */
- /**********************************************************************/
- %left AND_OP OR_OP XOR_OP ASL ASR LSL LSR ROL ROR
- %left ADD_OP SUB_OP
- %left MUL_OP DIV_OP MOD_OP
- %left NEG_OP NOT_OP
- %left POW
- %nonassoc MY_ABS COS SIN TAN ACOS ASIN ATAN EXP LOG LOG10 SQRT SINH COSH TANH FAK COT
-
-
-
- /**********************************************************************/
- /* Return-Value of my terminal */
- /**********************************************************************/
- %type <Real> int_expr
-
- %%
-
-
-
- /**********************************************************************/
- /* Main "sentence" */
- /**********************************************************************/
- eingabe
- : int_expr {outputr($1);}
- | X_MEM EQU_OP int_expr {outputx($3);}
- | Y_MEM EQU_OP int_expr {outputy($3);}
- | Z_MEM EQU_OP int_expr {outputz($3);}
- | error
- ;
-
-
-
-
- /**********************************************************************/
- /* Do the grammar */
- /**********************************************************************/
- int_expr
- : OPEN_OP int_expr CLOSE_OP {$$ = $2;}
- | int_expr AND_OP int_expr {$$ = (make_ulong($1)) & (make_ulong($3));}
- | int_expr OR_OP int_expr {$$ = (make_ulong($1)) | (make_ulong($3));}
- | int_expr XOR_OP int_expr {$$ = MyXOR(make_ulong($1),make_ulong($3));}
- | int_expr NOT_OP AND_OP int_expr {$$ = MyNAND(make_ulong($1), make_ulong($4));}
- | int_expr NOT_OP OR_OP int_expr {$$ = MyNOR(make_ulong($1), make_ulong($4));}
- | int_expr NOT_OP XOR_OP int_expr {$$ = MyNXOR(make_ulong($1), make_ulong($4));}
- | int_expr ADD_OP int_expr {$$ = $1 + $3;}
- | int_expr SUB_OP int_expr {$$ = $1 - $3;}
- | int_expr MUL_OP int_expr {$$ = $1 * $3;}
- | int_expr DIV_OP int_expr {if($3 == 0.0) {PError = ERR_DIVBY0; yyerror(NULL); } else $$ = $1 / $3;}
- | int_expr MOD_OP int_expr {if($3 == 0.0) {PError = ERR_DIVBY0; yyerror(NULL); } else $$ = fmod($1,$3);}
- | SUB_OP int_expr %prec NEG_OP {$$ = -$2; }
- | NOT_OP int_expr {$$ = (~make_ulong($2)); }
- | int_expr ASL int_expr {$$ = (double)MyASL(make_ulong($1),make_ulong($3)); }
- | int_expr ASR int_expr {$$ = (double)MyASR(make_ulong($1),make_ulong($3)); }
- | int_expr LSL int_expr {$$ = (double)MyLSL(make_ulong($1),make_ulong($3)); }
- | int_expr LSR int_expr {$$ = (double)MyLSR(make_ulong($1),make_ulong($3)); }
- | int_expr ROL int_expr {$$ = (double)MyROL(make_ulong($1),make_ulong($3)); }
- | int_expr ROR int_expr {$$ = (double)MyROR(make_ulong($1),make_ulong($3)); }
- | int_expr POW int_expr {$$ = pow($1,$3); }
- | SIN int_expr {$$ = sin(calc_angle($2)); }
- | COS int_expr {$$ = cos(calc_angle($2)); }
- | TAN int_expr {if(!check_angle($2, TAN)) yyerror(NULL); else $$ = tan(calc_angle($2)); }
- | ASIN int_expr {if(!check_angle($2, ASIN)) yyerror(NULL); else $$ = asin(calc_angle($2)); }
- | ACOS int_expr {if(!check_angle($2, ACOS)) yyerror(NULL); else $$ = acos(calc_angle($2)); }
- | ATAN int_expr {if(!check_angle($2, ATAN)) yyerror(NULL); else $$ = atan(calc_angle($2)); }
- | COT int_expr {if(!check_angle($2, COT)) yyerror(NULL); else $$ = cot(calc_angle($2)); }
- | SINH int_expr {$$ = sinh(calc_angle($2)); }
- | COSH int_expr {$$ = cosh(calc_angle($2)); }
- | TANH int_expr {if(!check_angle($2, TANH)) yyerror(NULL); else $$ = tanh(calc_angle($2)); }
- | EXP int_expr {$$ = exp($2); }
- | LOG int_expr {$$ = log($2); }
- | LOG10 int_expr {$$ = log10($2); }
- | MY_ABS int_expr {$$ = fabs($2); }
- | SQRT int_expr {if($2 < 0.0) {PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = sqrt($2);}
- | int_expr FAK {if($1 > 170.0) { PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = calc_fak($1);}
- | FAK int_expr {if($2 > 170.0) { PError = ERR_OVERFLOW; yyerror(NULL); } else $$ = calc_fak($2);}
- | INT_CONSTANT
- | X_MEM
- | Y_MEM
- | Z_MEM
- ;
-
- %%
-
-
-
-
- /**********************************************************************/
- /* Convert a double to a long (the hard way) */
- /**********************************************************************/
- ULONG make_ulong(double OldVal)
- {
- char Buffer[26];
- ULONG Dummy;
-
- sprintf(Buffer, "%f", OldVal);
- stcd_l(Buffer, (LONG *)&Dummy);
- return(Dummy);
- }
-
-
-
-
-
- /**********************************************************************/
- /* Calculate Fak */
- /**********************************************************************/
- double calc_fak(double Fak)
- {
- double RetVal = 1.0, i = 1.0;
-
- while(i <= Fak)
- {
- RetVal *= i;
- i++;
- }
-
- return(RetVal);
- }
-
-
-
-
-
- /**********************************************************************/
- /* Calculate correct angle value (rad, deg) */
- /**********************************************************************/
- double calc_angle(double Value)
- {
- if(IntAngle == ID_DEG)
- Value = Value / 180.0 * PI;
-
- return(Value);
- }
-
-
-
-
-
- /**********************************************************************/
- /* Check if input is within bounds */
- /**********************************************************************/
- BOOL check_angle(double Value, int Mode)
- {
- Value = calc_angle(Value);
-
- switch(Mode)
- {
- case TAN :
- case TANH :
- {
- if(Value < -(PI / 2) || Value > (PI / 2))
- {
- PError = ERR_OVERFLOW;
- return(FALSE);
- }
- }
- case COT :
- {
- if(Value < -PI || Value > PI)
- {
- PError = ERR_OVERFLOW;
- return(FALSE);
- }
- }
- case ASIN :
- case ACOS :
- {
- if(Value < -1.0 || Value > 1.0)
- {
- PError = ERR_OVERFLOW;
- return(FALSE);
- }
- break;
- }
- case ATAN :
- {
- if(Value <= -1.0 || Value >= 1.0)
- {
- PError = ERR_OVERFLOW;
- return(FALSE);
- }
- break;
- }
- }
-
- return(TRUE);
- }
-
-
-
-
-
- /**********************************************************************/
- /* Error-Routine ;) */
- /**********************************************************************/
- int yyerror(char *s)
- {
- return(0);
- }
-