/* * tree creation, deletion and evaluation routines for complex-number * parser. * * MWS, March 20, 1991. */ #include #include #include #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); } } ********/