rendered paste body/***************** MAIN.C ***************/#include <stdio.h>#include <stdlib.h>#include "sdata.h"#include "parse.h"#include "eval.h"#include "errors.h"int main () { char *code; while (1) { code = malloc (100*sizeof(char)); printf ("> "); gets (code); list *expr = parse (code); while (errorcount ("parse")) { printerror ("parse"); poperror ("parse"); } printsdata (run(expr)); printf ("\n"); freelist (expr); free (expr); free (code); } return 0;}/***************** SDATA.C ***************/#include <stdlib.h>#include <stdio.h>#include "sdata.h"#include "bignum.h"#include "errors.h"struct sdata { S_type tag; void *data;};struct list { sdata *contents; struct list *cdr;};sdata *car (list *lst) { if (lst == 0) { adderror ("car", "no car of the empty list"); printerror ("car"); exit (-1); } return lst->contents; }list *cdr (list *lst) { if (lst == 0) { adderror ("cdr", "no cdr of the empty list"); printerror ("cdr"); exit (-1); } return lst->cdr; }/* instead of cons accepting a void*, a type tag and a list, the function is overloaded for seperate types. this will provide a cleaner api */list *cons (void *newdata, S_type ntype, list *lst) { list *newlst = malloc (sizeof(list)); newlst->contents = malloc (sizeof (sdata)); if (newlst == 0 || newlst->contents == 0) { adderror ("cons", "malloc error, out of memory"); printerror ("cons"); exit (-1); } newlst->contents->tag = ntype; newlst->contents->data = newdata; newlst->cdr = lst; return newlst;}list *reverse (list *lst) { list *prev = 0; list *head = lst; list *tmp; while (head) { tmp = head->cdr; head->cdr = prev; prev = head; head = tmp; } return prev;}unsigned int length (list *lst) { unsigned int i = 0; list *ptr = lst; while (ptr) { i++; ptr = cdr(ptr); } return i;}void freesdata (sdata *d) { free (d->data);}void freelist (list *lst) { if (lst != 0) { freesdata (lst->contents); freelist (lst->cdr); }}void printlist (list *lst) { list *ptr = lst; printf ("("); while (ptr != 0) { printsdata (car (ptr)); ptr = cdr(ptr); if (ptr) { printf (" "); } } printf (")");}void printsdata (sdata *s) { if (s == 0) return; switch (s->tag) { case sNUMBER: printf ("%s", bn_numbertostring(s->data)); break; case sSYMBOL: printf ("%s", (char*)s->data); break; case sCONS: printlist ((list*)s->data); break; }}/***************** BIGNUM.C ***************/#include <stdlib.h>#include <stdio.h> // for sprintf#include <math.h>#include "errors.h"#include "bignum.h"typedef enum Numtype { INTEGER, /* base */ REAL, /* base */ RATIONAL, /* compound */ COMPLEX /* compound */} Numtype;typedef struct { Numtype tag; int exact; void *num;} bignum;typedef struct { void *data;} big_inexact; typedef struct { bignum *data1; bignum *data2;} big_binary;/* Assumes num is a properly formatted string */void *bn_create(char *num, int type, int exact) { bignum *ans = malloc (sizeof (bignum)); ans->exact = exact; ans->tag = type; switch (type) { case INTEGER: ans = 0; break; case REAL: ans->num = malloc (sizeof(big_inexact)); ((big_inexact *)ans->num)->data = malloc (sizeof(double)); *(double *)((big_inexact *)ans->num)->data = atof (num); break; case RATIONAL: if (exact) { } else { } ans = 0; break; case COMPLEX: if (exact) { } else { } ans = 0; break; } return ans;}void *bn_copy (void *n) { bignum *ans = malloc (sizeof (bignum)); if (ans == 0) malloc_error ("bn_copy"); switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: break; case RATIONAL: break; case COMPLEX: break; } return ans;}void freebn (void *n) { switch (((bignum *)n)->tag) { case INTEGER: /* ... */ //free ((big_exact *)(((bignum *)n)->num)); break; case REAL: free ((double *)((big_inexact *)((bignum *)n)->num)->data); free ((big_inexact *)(((bignum *)n)->num)); break; case RATIONAL: case COMPLEX: freebn ( (bignum *)((big_binary *)n)->data1); freebn ( (bignum *)((big_binary *)n)->data2); free ((big_binary *)((bignum *)n)->num); break; } }void bn_negate (void *n) { switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: *(double *)((big_inexact *)((bignum *)n)->num)->data *= -1; break; case RATIONAL: bn_negate (((big_binary *)((bignum *)n)->num)->data1); break; case COMPLEX: bn_negate (((big_binary *)((bignum *)n)->num)->data1); bn_negate (((big_binary *)((bignum *)n)->num)->data2); break; }}void bn_add (void *n, void *m) { switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: *(double *)((big_inexact *)((bignum *)n)->num)->data += *(double *)((big_inexact *)((bignum *)m)->num)->data; break; case RATIONAL: break; case COMPLEX: break; }}void bn_multiply (void *n, void *m) { switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: *(double *)((big_inexact *)((bignum *)n)->num)->data *= *(double *)((big_inexact *)((bignum *)m)->num)->data; break; case RATIONAL: break; case COMPLEX: break; }}void bn_divide (void *n, void *m) { switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: *(double *)((big_inexact *)((bignum *)n)->num)->data /= *(double *)((big_inexact *)((bignum *)m)->num)->data; break; case RATIONAL: break; case COMPLEX: break; } }void bn_expt (void *n, void *m) { switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: *(double *)((big_inexact *)((bignum *)n)->num)->data = pow (*(double *)((big_inexact *)((bignum *)n)->num)->data, *(double *)((big_inexact *)((bignum *)m)->num)->data); break; case RATIONAL: break; case COMPLEX: break; } }int bn_equal (void *n, void*m) { int ans; if (((bignum *)n)->tag != ((bignum *)n)->tag) matchtags (n, m); switch (((bignum *)n)->tag) { case INTEGER: ans = 0; break; case REAL: ans = (*(double *)((big_inexact *)((bignum *)n)->num)->data == *(double *)((big_inexact *)((bignum *)m)->num)->data); break; case RATIONAL: ans = 0; break; case COMPLEX: ans = 0; break; } return ans;}int bn_lessthan (void *n, void*m) { return 0; /* FIX */ }int bn_lessthanequal (void *n, void*m) { return 0; /* FIX */ }int bn_greaterthan (void *n, void*m) { return 0; /* FIX */ }int bn_greaterthanequal (void *n, void*m) { return 0; /* FIX */}void bn_abs (void *n) { /* ... */ }void bn_acos (void *n) { /* ... */}void bn_add1 (void *n) { /* ... */}void bn_angle (void *n) { /* ... */}void bn_asin (void *n) { /* ... */}void bn_atan (void *n) { /* ... */}void bn_ceiling (void *n) { /* ... */}void bn_conjugate (void *n) { /* ... */ }void bn_cos (void *n) { /* ... */}void bn_denominator (void *n) { if (bn_integer (n)) { // return bn_create ("1", INTEGER, 1); } if (((bignum *)n)->tag != RATIONAL) { adderror ("bn_denominator", "number not rational or integer"); printerror ("bn_denominator"); exit (-1); } //return 0;//(bignum *)((big_rational *)(((bignum *)n)->num)->denominator);}int bn_even (void *n) { if (!bn_integer (n)) { adderror ("bn_even/bn_odd", "expects integer argument"); printerror ("bn_even/bn_odd"); exit (-1); } return 0; /* FIX: Fill me! */ }void bn_exact_to_inexact (void *n) { /* ... */} void bn_exp (void *n) { /* ... */ }void bn_floor (void *n) { /* ... */ }void bn_gcd (void *n, void *m) { /* ... */}void bn_imagpart (void *n) { //if ( ((bignum *)n)->tag == COMPLEX) // return 0;//(bignum *)((big_complex *)((bignum *)n->num)->im); //else // return bn_create ("0", INTEGER, 1);}void bn_inexact_to_exact (void *n) { /* ... */ }void bn_lcm (void *n) { /* ... */}void bn_log (void *n) { /* ... */}void bn_magnitude (void *n) { /* ... */}void bn_makepolar (void *n, void *m) { /* ... */}void bn_max (void *n, void *m) { //if (bn_greaterthan (n, m)) // return n; //return m;}void bn_min (void *n, void *m) { //if (bn_lessthan (n, m)) // return n; //return m;}void bn_modulo (void *n, void *m) { /* ... */}int bn_negative (void *n) { int ans = 0; switch (((bignum *)n)->tag) { case INTEGER: break; case REAL: ans = (0 > *(double *)(((big_inexact *)(((bignum *)n)->num))->data)); break; case RATIONAL: break; case COMPLEX: break; } return ans;}char *bn_numbertostring (void *n) { char *ans; switch (((bignum *)n)->tag) { case INTEGER: ans = 0; break; case REAL: ans = malloc (80*sizeof(char)); snprintf (ans, 79, "%.10G", *(double *)((big_inexact *)((bignum *)n)->num)->data); break; case RATIONAL: ans = 0; break; case COMPLEX: ans = 0; break; } return ans;}void bn_numerator (void *n) { //if (bn_integer (n)) { // return n; //} //if (((bignum *)n)->tag != RATIONAL) { // adderror ("bn_numerator", "number not rational or integer"); // printerror ("bn_numerator"); // exit (-1); //} //return 0;//(bignum *)((big_rational *)(((bignum *)n)->num)->numerator);}int bn_odd (void *n) { if (bn_even (n)) return 0; return 1;}int bn_positive (void *n) { if (bn_negative (n)) return 0; return 1;}void bn_quotient (void *n, void *m) { //return bn_floor (bn_divide (n, m));}void bn_realpart (void *n) { //if ( ((bignum *)n)->tag == COMPLEX) // return ((big_binary *)(((bignum *)n)->num))->data1; //else // return n;}void bn_remainder (void *n, void *m) { /* ... */}void bn_round (void *n) { //bignum *ans = 0; //switch (((bignum *)n)->tag) { // case INTEGER: // ans = bn_copy (n); // break; /* already rounded */ // case REAL: // int *newval = malloc (sizeof (int)); // *newval = round ((double *)((big_inexact *)(((bignum *)n)->num))); // char *tmp[80]; // sprintf (tmp, 79, "%i", newval); // ans = bn_create (tmp, INTEGER, 1); // free (tmp); // break; // case RATIONAL: // ans = 0; // break; // case COMPLEX: // ans = 0; // break; //} //return 0;}void bn_sgn (void *n) { /* ... */}void bn_sin (void *n) { bignum *ans; switch (((bignum *)n)->tag) { case INTEGER: ans = 0; break; case REAL: ans = bn_copy (n); *(float *)(((big_inexact *)ans->num)->data) = sin (*(float *)(((big_inexact *)ans->num)->data)); break; case RATIONAL: ans = 0; break; } //return ans;}void bn_sqrt (void *n) { /* ... */}void bn_sub1 (void *n) { /* ... */}void bn_tan (void *n){ /* ... */}int bn_zero (void *n) { return 0; /* FIX */}int bn_exact (void *n) { if (((bignum *)n)->exact) return 1; else if (((bignum *)n)->tag == RATIONAL) { if (bn_exact (0) && bn_exact (0)) /* FIX */ return 1; } else if (((bignum *)n)->tag == COMPLEX) { if (bn_exact (0) && bn_exact (0)) /* FIX: lazy */ return 1; } return 0;}int bn_inexact (void *n) { if (bn_exact (n)) return 0; return 1;}int bn_integer (void *n) { if (((bignum *)n)->exact == 1) { return 1; /* FIX: wrong, do actual test */ } return 0;}int bn_rational (void *n) { if (((bignum *)n)->tag == RATIONAL || bn_integer (n)) return 1; return 0;}int bn_real (void *n) { if (((bignum *)n)->tag == COMPLEX) return 0; return 1;}/***************** PARSE.C ***************/#include <stdlib.h>#include <string.h>#include "sdata.h"#include "errors.h"#include <stdio.h>#define LPAREN 1#define LSQRPAREN 2#define RPAREN 3#define RSQRPAREN 4/* pattern matching */int isparen (char a) { if (a == '(') return LPAREN; if (a == '[') return LSQRPAREN; if (a == ')') return RPAREN; if (a == ']') return RSQRPAREN; return 0; }int isnum (char a) { if (a >= '0' && a<= '9') return 1; return 0; }int iswhite (char a) { if (a == ' ' || a == '\t' || a == '\n') return 1; return 0; }int isnamechar (char a) { if (!(iswhite(a) || isparen(a) || a == '\"' || a == ','|| a == '\'' || a == '`' || a == '|' || a == ';' || a == '#')) return 1; return 0; }/* CONTRACT: parse: string -> listof (expr) PURPOSE: Consume a string and parse it into a list of expr's, made of sdata EFFECTS: None usually. Critical errors print to stdout and halt. ERRORS: Non critical errors are added to the error stack and the function returns 0. NOTES: */list *parse (char *code) { enum State { START, NUMBER, IDENTIFIER } state; enum Numstate { INTEGER, REAL, /* restricts numbers to one decimal point per number, and fractions to int/int */ RATIONAL, /* restricts fractions to only have 1 numerator and 1 denominator */ COMPLEX /* restricts complex numbers to have 1 real part and 1 imaginary part */ } numstate; list *expr = 0; int i = 0, k = 0; /* when we start parsing something interesting, 'i' will point to the front of the token, 'k' to the end */ int imagrational = 0; int imagnegative = 0; int imagreal = 0; /* place to temporarily store data */ char *cdata; state = START; int done = 0; while (!done) { switch (state) { case START: if (code[k] == '\0') done = 1; else if (isnum(code[k]) || code[k] == '-') { state = NUMBER; numstate = INTEGER; i = k; } else if (isnamechar(code[k])) { state = IDENTIFIER; i = k; } else if (isparen (code[k])) { /* catch stray close parens */ if (isparen (code[k]) == RPAREN) { adderror ("parse", "unexpected )"); return 0; } if (isparen (code[k]) == RSQRPAREN) { adderror ("parse", "unexpected ]"); return 0; } int opens = 1; int m; i = k; k++; while (opens > 0) { m = isparen (code[k]); if (code[k] == '\0') { if (code[i] == '(') adderror ("parse", "unexpected end of file: expected )"); if (code[i] == '[') adderror ("parse", "unexpected end of file: expected ]"); return 0; } else if (m == LPAREN || m == LSQRPAREN) opens++; else if (m == RPAREN || m == RSQRPAREN) opens--; k++; } k--; cdata = malloc ((k - i - 1)*sizeof(char)); if (cdata == 0) malloc_error ("parse"); strncpy (cdata, &code[i+1], k - i - 1); /* exclude the outermost open/close parens */ cdata[k - i - 1] = '\0'; expr = cons (parse (cdata), sCONS, expr); free (cdata); } else if (iswhite(code[k])) i = k; /* extra whitespace is ignored */ else { adderror ("parse", "in state START, found unexpected character"); return 0; } break; case NUMBER: /* check to see if we are done parsing the number */ if (iswhite(code[k]) || code[k] == '\0' || isparen(code[k]) || code[k] == 'i') { cdata = malloc ((k - i + 1)*sizeof(char)); if (cdata == 0) malloc_error ("parse"); strncpy (cdata, &code[i], k - i); cdata[k - i] = '\0'; int exact = 1; if (numstate == COMPLEX && imagreal) exact = 0; if (numstate == REAL) exact = 0; void *newnum = bn_create (cdata, numstate, exact); expr = cons (newnum, sNUMBER, expr); free (cdata); if (code[k] == '\0') done = 1; if (isparen (code[k])) k--; /* seeing it was an accident, someone else has to deal with it */ state = START; imagreal = 0; } else { /* we are not done, handle the next char */ switch (numstate) { case REAL: if (isnum (code[k])) { /* do nothing */ } else if (code[k] == '+' || code[k] == '-') { numstate = COMPLEX; imagrational = 0; if (code[i] == '-') imagnegative = 1; else imagnegative = 0; imagreal = 1; } else if (isnamechar (code[k])) state = IDENTIFIER; else { adderror ("parse", "in state REAL, found unexpected character"); return 0; } break; case INTEGER: if (code[k] == '.') numstate = REAL; else if (isnum (code[k])) { /* do nothing */ } else if (code[k] == '/') numstate = RATIONAL; else if (code[k] == '+' || code[k] == '-') { numstate = COMPLEX; imagrational = 0; if (code[i] == '-') imagnegative = 1; else imagnegative = 0; imagreal = 0; } else if (isnamechar (code[k])) state = IDENTIFIER; else { adderror ("parse", "in state NUMBER, numstate INTEGER, found unexpected character"); return 0; } break; case RATIONAL: if (isnum (code[k])) { /* do nothing */ } else if (code[k] == '+' || code[k] == '-') { numstate = COMPLEX; imagrational = 0; if (code[i] == '-') imagnegative = 1; else imagnegative = 0; imagreal = 0; } else if (isnamechar (code[k])) state = IDENTIFIER; else { adderror ("parse", "in state NUMBER, numstate RATIONAL, found unexpected character"); return 0; } break; case COMPLEX: if (isnum (code[k])) { /* do nothing */ } else if (code[k] == '.' && imagreal == 0) imagreal = 1; else if (code[k] == '/' && imagrational == 0) imagrational = 1; else if (isnamechar (code[k])) state = IDENTIFIER; else { adderror ("parse", "in state NUMBER, substate COMPLEX, found unexpected character"); return 0; } break; } } break; case IDENTIFIER: if (iswhite (code[k]) || code[k] == '\0' || isparen(code[k])) { /* parse string */ cdata = malloc ((k - i + 1)*sizeof(char)); if (cdata == 0) malloc_error ("parse"); strncpy (cdata, &code[i], k - i); cdata[k - i] = '\0'; expr = cons (cdata, sSYMBOL, expr); state = START; if (code[k] == '\0') done = 1; if (isparen (code[k])) k--; /* seeing it was an accident, someone else has to deal with it */ } else if (isnum (code[k]) || isnamechar (code[k])) { /* do nothing */ } else { adderror ("parse", "in state SYMBOL, found unexpected character"); return 0; } break; } k++; } expr = reverse (expr); return expr;}/***************** EVAL.C ***************/#include <stdlib.h>#include "sdata.h"sdata *lookup (char *key, char **env_names, sdata **defs, unsigned int nsize) { int i; for (i = 0; i < nsize; i++) { if (strcmp(key, env_names[i]) == 0) { return defs[i]; } } return 0;}int is_prm (char *key) { static char *prm_list[] = { "+", "-", "*", "/", "=", "expt", "add1", "sub1", "cons", "empty", "car", "cdr", "remainder", "equal?", "number?", "symbol?" }; int i; for (i = 0; i < 16; i++) { if (strcmp(prm_list[i], key)) { return 1; } } return 0; }sdata *eval (sdata *expr, char **env_names, sdata **defs, unsigned int envsize) { if (expr->data == 0 || expr->tag == sNUMBER) { return expr; /* a number or the empty list */ } if (expr->tag == sSYMBOL) { sdata *look = lookup ((char *)expr->data, env_names, defs, envsize); printsdata (look); if (look == 0) { if (is_prm ((char *)expr->data)) { return expr; } else { adderror ("eval", "could not find symbol"); printerror ("eval"); exit (-1); } } return look; } /* therefore, it must be a cons */ /* should check if first thing is actually a symbol! */ list *lst = (list *)expr->data; char *ident = (char *)car(lst)->data; if (is_prm(ident)) { if (strcmp("+", ident) == 0) { sdata *acc = malloc (sizeof (sdata)); acc = eval(car(cdr(lst)), env_names, defs, envsize); list *ptr = cdr(cdr(lst)); while (ptr) { bn_add (acc->data, eval(car(ptr), env_names, defs, envsize)->data); ptr = cdr(ptr); } return acc; } if (strcmp("*", ident) == 0) { sdata *acc = malloc (sizeof (sdata)); acc = eval(car(cdr(lst)), env_names, defs, envsize); list *ptr = cdr(cdr(lst)); while (ptr) { bn_multiply (acc->data, eval(car(ptr), env_names, defs, envsize)->data); ptr = cdr(ptr); } return acc; } else { adderror ("eval", "prm not found"); printerror ("eval"); exit (-1); } } else { adderror ("eval", "unrecognized syntax"); printerror ("eval"); exit (-1); }}sdata *run (list *code) { list *answers = 0; char **env_names = 0; sdata **defs = 0; unsigned int envsize = 0; list *ptr = code; sdata *tmp; while (ptr) { if (0) { /* it's a definition */ return 0; } else { tmp = eval( car(code), env_names, defs, envsize); answers = cons (tmp->data, tmp->tag, answers); } ptr = cdr (ptr); } if (length(answers) == 1) { return car (answers); } else { sdata *ans = malloc (sizeof (sdata)); ans->tag = sCONS; ans->data = answers; return ans; }}/***************** ERRORS.C ***************/#include <stdlib.h>#include <stdio.h>#include <string.h>#include "sdata.h"#include "errors.h"list *errorstack = 0;void adderror (char *funcname, char *desc) { char *internal_funcname = malloc ((1+strlen(funcname))*sizeof(char)); char *internal_desc = malloc ((1+strlen(desc))*sizeof(char)); if (internal_funcname == 0 || internal_desc == 0) { printf ("In adderror: malloc failure"); exit (-1); } strcpy (internal_funcname, funcname); strcpy (internal_desc, desc); list *newerror = 0; newerror = cons (internal_desc, sSYMBOL, newerror); newerror = cons (internal_funcname, sSYMBOL, newerror); errorstack = cons (newerror, sCONS, errorstack);}void poperror (char *funcname) { list *prev = 0; list *ptr = errorstack; while (ptr) { if (strcmp((char *)car((list *)car(ptr)->data)->data, funcname) == 0) { if (prev == 0) { /* its the first thing on the "stack" */ errorstack = cdr (errorstack); freelist (ptr); free (ptr); return; } else { errorstack = cons (prev, sCONS, cdr(ptr)); freesdata (car(ptr)); free ((list *)car(ptr)); return; } } ptr = (list *)cdr(ptr); }}char *get_error_desc (char *funcname) { list *ptr = errorstack; while (ptr) { if (strcmp((char *)car((list *)car(ptr)->data)->data, funcname) == 0) { return (char *)car(cdr((list *)car(ptr)->data))->data; } ptr = cdr(ptr); } printf ("Error: in get_error_desc: no errors for function %s\n", funcname); exit (ERROR_ERROR); /* error wasn't found, error! */}unsigned int errorcount (char *funcname) { list *ptr = errorstack; int ans = 0; while (ptr) { if (strcmp((char *)car((list *)car(ptr)->data)->data, funcname) == 0) { ans++; } ptr = cdr (ptr); } return ans;}void printerror (char *funcname) { printf ("Error in %s: %s\n", funcname, get_error_desc (funcname));}void malloc_error (char *f) { printf ("Error in %s: malloc error, out of memory?", f); exit (-1);}/***************** SDATA.H ***************/#ifndef SDATA_INCLUDED#define SDATA_INCLUDED#include "bignum.h"/* Definitions */typedef enum S_type { sNUMBER, sSYMBOL, sCONS } S_type;typedef struct { S_type tag; void *data;} sdata;typedef struct list list;/* lists */sdata *car (list *);list *cdr (list *);list *cons (void *, S_type, list *); list *reverse (list *);unsigned int length (list *);void freelist (list *);void printlist (list *);/* sdata */void printsdata (sdata *);void freesdata (sdata *); #endif /* SDATA_INCLUDED *//***************** BIGNUM.H ***************/#ifndef BIGNUM_INCLUDED#define BIGNUM_INCLUDED/* boring things*/void *bn_create (char *, int, int);void *bn_copy (void *);void freebn (void *);/* basic arithmetic */void bn_negate (void *);void bn_add (void *, void *);void bn_multiply (void *, void *);void bn_divide (void *, void *);void bn_expt (void *, void *);/* comparison */int bn_equal (void *, void*);int bn_lessthan (void *, void*);int bn_lessthanequal (void *, void*);int bn_greaterthan (void *, void*);int bn_greaterthanequal (void *, void*);/* other math */void bn_abs (void *);void bn_acos (void *);void bn_add1 (void *);void bn_angle (void *);void bn_asin (void *);void bn_atan (void *);void bn_ceiling (void *);void bn_conjugate (void *);void bn_cos (void *);// void bn_cosh (void *);void bn_denominator (void *);int bn_even (void *);void bn_exact_to_inexact (void *);void bn_exp (void *);void bn_floor (void *);void bn_gcd (void *, void *);void bn_imagpart (void *);void bn_inexact_to_exact (void *);void bn_lcm (void *);void bn_log (void *);void bn_magnitude (void *);void bn_makepolar (void *, void *);void bn_max (void *, void *);void bn_min (void *, void *);void bn_modulo (void *, void *);int bn_negative (void *);char *bn_numbertostring (void *);void bn_numerator (void *);int bn_odd (void *);int bn_positive (void *);void bn_quotient (void *, void *);void bn_realpart (void *);void bn_remainder (void *, void *);void bn_round (void *);void bn_sgn (void *);void bn_sin (void *);// void bn_sinh (void *);void bn_sqrt (void *);void bn_sub1 (void *);void bn_tan (void *);int bn_zero (void *);/* type predicates */int bn_exact (void *);int bn_inexact (void *);int bn_integer (void *);int bn_rational (void *);int bn_real (void *);#endif // BIGNUM_INCLUDED/***************** PARSE.H ***************/#ifndef PARSE_INCLUDED#define PARSE_INCLUDED#include "sdata.h"list *parse (char *);#endif // PARSE_INCLUDED/***************** EVAL.H ***************/#ifndef EVAL_INCLUDED#define EVAL_INCLUDED#include "sdata.h"sdata *run (list *);#endif /* EVAL_INCLUDED *//***************** ERRORS.H ***************/#ifndef ERRORS_INCLUDED#define ERRORS_INCLUDEDvoid adderror (char *, char *);unsigned int errorcount (char *);char *geterrordesc (char *);void poperror (char *);void printerror (char *);void malloc_error (char *);#define MALLOC_ERROR 0#define PARSE_ERROR 1#define EVAL_ERROR 2#define ERROR_ERROR 3#endif // ERRORS_INCLUDED