home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
djsrc106.arj
/
LANG.Y
< prev
next >
Wrap
Text File
|
1991-09-02
|
4KB
|
225 lines
%{
#include <stdio.h>
#include <math.h>
#include "hc.h"
char *bin(double n);
char *oct(double n);
char *rhex(double d);
double do_call(int name, double arg);
double do_power(double a, double b);
void lr_save(double d);
double lr_recall(int n);
%}
%union {
double d;
int i;
}
%token <i> LAST_RESULT
%token <d> INUM
%token <i> ID
%type <d> expr
%left '+' '-'
%left '^'
%left '|'
%left '&'
%left '<' '>'
%left '*' '/' '%'
%left UNARYMINUS '~'
%right POWER
%start lines
%% /***********************************************************************/
lines
:
| lines stmt '\n'
;
stmt
: expr {
printf(" %lg %s %s %s\n",
$1, rhex($1), oct($1), bin($1));
lr_save($1);
}
| error '\n' { yyerrok; }
| ID '=' expr { id_val[(long)$1] = $3; lr_save($3); }
;
expr
: INUM { $$ = $1; }
| ID { $$ = id_val[$1]; }
| LAST_RESULT { $$ = lr_recall($1); }
| expr '+' expr { $$ = $1 + $3; }
| expr '-' expr { $$ = $1 - $3; }
| expr '*' expr { $$ = $1 * $3; }
| expr '/' expr { $$ = $1 / $3; }
| expr '%' expr { $$ = (long)$1 % (long)$3; }
| expr '<' expr { $$ = ldexp($1, (long)$3); }
| expr '>' expr { $$ = ldexp($1, -(long)$3); }
| expr '&' expr { $$ = (long)$1 & (long)$3; }
| expr '|' expr { $$ = (long)$1 | (long)$3; }
| expr '^' expr { $$ = (long)$1 ^ (long)$3; }
| expr POWER expr { $$ = do_power($1, $3); }
| '-' expr %prec UNARYMINUS { $$ = - $2; }
| '~' expr %prec UNARYMINUS { $$ = ~ (long)$2; }
| '(' expr ')' { $$ = $2; }
| ID '(' expr ')' { $$ = do_call($1, $3); }
;
%%
char *oct(double d)
{
long n;
static char buf[30];
if ((d > 0x7fffffff) || (d < -0x7fffffff))
return "";
n = (long)d;
if (n)
{
sprintf(buf, "0%o", n);
return buf;
}
else
return "0";
}
char *bin(double d)
{
long n;
static char buf[] = " xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx.xxxx";
int i;
char *rv;
char *bp = buf+5*8-1;
if ((d > 0x7fffffff) || (d < -0x7fffffff))
return "";
n = (long)d;
if (n == 0)
return "0";
for (i=31; i>=0; i--)
{
*bp-- = '0' + (n & 1);
n >>= 1;
if (i % 4 == 0)
bp--;
}
rv = buf;
for (i=0; i<7; i++)
{
if (strncmp(rv+1, "0000", 4))
return rv+1;
rv += 5;
}
return rv+1;
}
char *rhex(double d)
{
static char buf[] = "0x12345678.12345678 ";
int dleft;
char *cp, *lastdig;
if ((d > 0x7fffffff) || (d < -0x7fffffff))
return "<huge>";
if ((d < 0) && (d != (long)d))
d--;
sprintf(buf, "0x%x", (long)d);
cp = buf+strlen(buf);
if (d < 0)
{
d -= (long)d;
if (d) d += 1;
}
else
{
d -= (long)d;
}
dleft = 18 - strlen(buf);
if (d == 0)
return buf;
lastdig = cp;
*cp++ = '.';
while (dleft)
{
d *= 16;
*cp++ = "0123456789abcdef"[(long)d];
if (d)
lastdig = cp;
d -= (long)d;
dleft--;
}
*lastdig = 0;
return buf;
}
typedef double (*FUNC)(double);
struct {
char *name;
FUNC func;
} funclist[] = {
"sin", sin,
"sinh", sinh,
"cos", cos,
"cosh", cosh,
"tan", tan,
"tanh", tanh,
"asin", asin,
"asinh", asinh,
"acos", acos,
"acosh", acosh,
"atan", atan,
"atanh", atanh,
"exp", exp,
"log", log,
"pow10", pow10,
"log10", log10,
"pow2", pow2,
"log2", log2,
"sqrt", sqrt,
0,0
};
double do_call(int fp, double arg)
{
int i;
for (i=0; funclist[i].name; i++)
if (strcmp(funclist[i].name, id_name[fp]) == 0)
return (funclist[i].func)(arg);
printf("Unknown function `%s'\n", id_name[fp]);
return 0;
}
double do_power(double a, double b)
{
return pow(a, b);
}
#define LAST_SIZE 10
double last_result[LAST_SIZE];
int last_idx;
void lr_save(double d)
{
last_result[last_idx] = d;
last_idx = (last_idx+LAST_SIZE-1) % LAST_SIZE;
}
double lr_recall(int n)
{
if (n > LAST_SIZE)
{
printf("Can't recall that far back\n");
return 0;
}
return last_result[(last_idx+n)%LAST_SIZE];
}