/*
*	icalc - complex-expression parser
*
*	Header for complex-number expression parser.
*	Contains all global structure definitions.
*
*	(C) Martin W Scott, 1991.
*/

#include <stdio.h>
#ifndef NULL
#define NULL (0L)
#endif

typedef struct complex {	/* our complex-number representation */
	double	real,
		imag;
} Complex;

typedef struct symlist {	/* parameter-list for a user-function */
	struct symbol	*sym;
	struct symlist	*next;
} SymList;

typedef struct arglist {	/* parameter-list for a user-function */
	struct node	*node;		/* each node is tree expression of parameter */
	struct arglist	*next;
} ArgList;

typedef struct userfunction {
	struct remember	*remkey;/* stores memory allocation list of tree */
	struct node *tree;	/* the 'body' of the function */
	struct symlist *params;	/* parameters to function */
} UserFunc;

typedef struct symbol {		/* general symbol - numerous types */
	char	*name;
	short	type;		/* VAR, CONST, BLTIN etc */
	union {
		Complex	val;		/* if VAR or CONST */
		Complex	(*cptr)();	/* C_BLTIN Complex-valued function */
		Complex	(*sptr)();	/* pointer to complex-valued function */
		void	(*vptr)();	/* COMMAND */
		UserFunc ufunc;		/* USER FUNCTION */
	} u;
	struct Symbol	*left, *right;	/* children */
} Symbol;


typedef union {
	Complex	val;		/* a complex number */
	Symbol	*sym;		/* a symbol */
} Contents;

typedef struct node {
	int	type;			/* type of node */
	Contents contents;		/* contents of node */
	struct node *left, *right;	/* children */
} Node;

/*
*	Convention: if node type is a builtin or unary operator,
*	the left child will hold the expression that is the
*	argument to the function.
*/

#define	sqr(x)	(x)*(x)
#define sign(x)	((x) >= 0.0 ? '+' : '-')

/* Lattice-generated prototypes (some of them) */

/* Prototypes for functions defined in function.c */
void cprin(FILE *, char *prefix, char *suffix, Complex z);
Complex printres(Complex z);
Complex precision(Complex z), cinteger(Complex z),
	cceil(Complex z), cfloor(Complex z),
	csign(Complex z), gettime(Complex lasttime);

/* Prototypes for functions defined in cmath.c */
Complex	Re(Complex z), Im(Complex z),
	arg(Complex z), norm(Complex z),
	cabs(Complex z), cadd(Complex w, Complex z),
	csub(Complex w, Complex z), cmul(Complex w, Complex z),
	cdiv(Complex w, Complex z), cneg(Complex z),
	csqr(Complex z), csqrt(Complex z),
	conj(Complex z), cexp(Complex z),
	clog(Complex z), cpow(Complex w, Complex z),
	csin(Complex z), ccos(Complex z),
	ctan(Complex z), casin(Complex z),
	cacos(Complex z), catan(Complex z),
	csinh(Complex z), ccosh(Complex z),
	ctanh(Complex z)
	;

/* Prototypes for functions defined in complex.y */
int	yylex(void);
void	warning(char *, char *),
	yyerror(char *),
	execerror(char *, char *),
	welcome(void),
	prompt(void),
	main(int, char **);

/* Prototypes for functions defined in symbol.c */
Symbol *lookup(char *s);
Symbol *allocsym(char *s, int t);
Symbol *install(char *s, int t, Complex cval);
void printlist(int type);

/* Prototypes for functions defined in init.c */
void init(void);

/* Prototypes for functions defined in command.c */
void	besilent(),
	beverbose(),
	quiticalc(),
	builtins(void),
	userfuncs(void),
	consts(void),
	vars(void),
	help(void);

/* Prototypes for functions defined in tree.c */
Node *n_asgn(Symbol *sym, Node *arg);
Node *n_binop(int op, Node *left, Node *right);
Node *n_unop(int op, Node *arg); 
Node *n_func(int type, Symbol *sym, Node *arg);
Node *n_symbol(int type, Symbol *sym);
Node *n_number(double real, double imag);
ArgList *addarg(ArgList *al, Node *n);
Complex eval_tree(Node *n);
void delete_tree(Node *n);

/* Prototypes for functions defined in function.c */
void clear_ufunc(UserFunc *func);
SymList *addparam(SymList *sl, Symbol *s);
void init_ufunc(UserFunc *func);
Symbol *findsym(SymList *sl, char *s);

/* Prototypes for functions defined in special.c */
Complex spec_sum(ArgList *al);
Complex spec_prod(ArgList *al);
Complex spec_every(ArgList *al);
Complex spec_vevery(ArgList *al);
Complex spec_multi(ArgList *al);
Complex spec_max(ArgList *al);
Complex spec_min(ArgList *al);
