home *** CD-ROM | disk | FTP | other *** search
- /*
- * tree creation, deletion and evaluation routines for complex-number
- * parser.
- *
- * MWS, March 20, 1991.
- */
-
- #include <string.h>
- #include <stdlib.h>
- #include <math.h>
- #include "memory.h"
- #include "complex.h"
- #include "complex.tab.h"
-
- #define allocnode() rem_malloc(sizeof(Node))
-
- Node *n_asgn(sym, arg) /* node for assignment operator */
- Symbol *sym;
- Node *arg;
- {
- Node *n = allocnode();
-
- n->type = '=';
- n->contents.sym = sym;
- n->left = arg;
- n->right = NULL;
-
- return n;
- }
-
- Node *n_binop(op, left, right) /* node for binary operator */
- int op;
- Node *left, *right;
- {
- Node *n = allocnode();
-
- n->type = op;
- n->left = left;
- n->right = right;
-
- return n;
- }
-
- Node *n_unop(op, arg) /* node for unary operator */
- int op;
- Node *arg;
- {
- Node *n = allocnode();
-
- n->type = op;
- n->left = arg;
- n->right = NULL;
-
- return n;
- }
-
- Node *n_func(type, sym, arg) /* node for function */
- int type;
- Symbol *sym;
- Node *arg;
- {
- Node *n = allocnode();
-
- n->type = type;
- n->contents.sym = sym;
- n->left = arg;
- n->right = NULL;
-
- return n;
- }
-
- Node *n_symbol(type, sym) /* node for symbol - VAR or CONST */
- int type;
- Symbol *sym;
- {
- Node *n = allocnode();
-
- n->type = type;
- n->contents.sym = sym;
- n->left = NULL;
- n->right = NULL;
-
- return n;
- }
-
- Node *n_number(real, imag) /* node for number */
- double real, imag;
- {
- Node *n = allocnode();
-
- n->type = NUMBER;
- n->contents.val.real = real;
- n->contents.val.imag = imag;
- n->left = NULL;
- n->right = NULL;
-
- return n;
- }
-
- Complex eval_tree(n) /* evaluate the complex value of a tree */
- Node *n;
- {
- switch (n->type)
- {
- case NUMBER: return n->contents.val;
-
- case C_BLTIN: return (*(n->contents.sym->u.cptr))(eval_tree(n->left));
-
- case R_BLTIN: { Complex rv;
- rv.real = (*(n->contents.sym->u.rptr))(eval_tree(n->left));
- rv.imag = 0.0;
- return rv;
- }
-
- case UFUNC: { UserFunc *uf = &n->contents.sym->u.ufunc;
- uf->param->u.val = eval_tree(n->left);
- return eval_tree(uf->tree);
- }
-
- case VAR:
- case PARAMETER:
- case CONST: return n->contents.sym->u.val;
-
- case '+': return cadd(eval_tree(n->left), eval_tree(n->right));
- case '-': return csub(eval_tree(n->left), eval_tree(n->right));
- case '*': return cmul(eval_tree(n->left), eval_tree(n->right));
- case '/': return cdiv(eval_tree(n->left), eval_tree(n->right));
- case '^': return cpow(eval_tree(n->left), eval_tree(n->right));
-
- case '(': return eval_tree(n->left);
- case UMINUS: return cneg(eval_tree(n->left));
- case '\'': return conj(eval_tree(n->left));
-
- case '=': return n->contents.sym->u.val = eval_tree(n->left);
-
- default: /* should NEVER see this... */
- execerror("internal - unknown node-type", NULL);
- }
- }
-
- /* delete all nodes of a tree */
- /* not used in current implementation */
- /********
- void delete_tree(n)
- Node *n;
- {
- if (n)
- {
- delete_tree(n->left);
- delete_tree(n->right);
- free(n);
- }
- }
- ********/