Fix for a crash which happened when a document couldn't be opened.
[AROS-Contrib.git] / fish / icalc / tree.c
blobc1d6d6cf2c6ce41e3bd1463b21fa271978ac8af8
1 /*
2 * tree creation, deletion and evaluation routines for complex-number
3 * parser.
5 * MWS, March 20, 1991.
6 */
8 #include <string.h>
9 #include <stdlib.h>
10 #include <math.h>
11 #include "memory.h"
12 #include "complex.h"
13 #include "complex.tab.h"
15 #define allocnode() rem_malloc(sizeof(Node))
17 Node *n_asgn(sym, arg) /* node for assignment operator */
18 Symbol *sym;
19 Node *arg;
21 Node *n = allocnode();
23 n->type = '=';
24 n->contents.sym = sym;
25 n->left = arg;
26 n->right = NULL;
28 return n;
31 Node *n_binop(op, left, right) /* node for binary operator */
32 int op;
33 Node *left, *right;
35 Node *n = allocnode();
37 n->type = op;
38 n->left = left;
39 n->right = right;
41 return n;
44 Node *n_unop(op, arg) /* node for unary operator */
45 int op;
46 Node *arg;
48 Node *n = allocnode();
50 n->type = op;
51 n->left = arg;
52 n->right = NULL;
54 return n;
57 Node *n_func(type, sym, arg) /* node for function */
58 int type;
59 Symbol *sym;
60 Node *arg;
62 Node *n = allocnode();
64 n->type = type;
65 n->contents.sym = sym;
66 n->left = arg;
67 n->right = NULL;
69 return n;
72 Node *n_symbol(type, sym) /* node for symbol - VAR or CONST */
73 int type;
74 Symbol *sym;
76 Node *n = allocnode();
78 n->type = type;
79 n->contents.sym = sym;
80 n->left = NULL;
81 n->right = NULL;
83 return n;
86 Node *n_number(real, imag) /* node for number */
87 double real, imag;
89 Node *n = allocnode();
91 n->type = NUMBER;
92 n->contents.val.real = real;
93 n->contents.val.imag = imag;
94 n->left = NULL;
95 n->right = NULL;
97 return n;
100 Complex eval_tree(n) /* evaluate the complex value of a tree */
101 Node *n;
103 switch (n->type)
105 case NUMBER: return n->contents.val;
107 case C_BLTIN: return (*(n->contents.sym->u.cptr))(eval_tree(n->left));
109 case R_BLTIN: { Complex rv;
110 rv.real = (*(n->contents.sym->u.rptr))(eval_tree(n->left));
111 rv.imag = 0.0;
112 return rv;
115 case UFUNC: { UserFunc *uf = &n->contents.sym->u.ufunc;
116 uf->param->u.val = eval_tree(n->left);
117 return eval_tree(uf->tree);
120 case VAR:
121 case PARAMETER:
122 case CONST: return n->contents.sym->u.val;
124 case '+': return cadd(eval_tree(n->left), eval_tree(n->right));
125 case '-': return csub(eval_tree(n->left), eval_tree(n->right));
126 case '*': return cmul(eval_tree(n->left), eval_tree(n->right));
127 case '/': return cdiv(eval_tree(n->left), eval_tree(n->right));
128 case '^': return cpow(eval_tree(n->left), eval_tree(n->right));
130 case '(': return eval_tree(n->left);
131 case UMINUS: return cneg(eval_tree(n->left));
132 case '\'': return conj(eval_tree(n->left));
134 case '=': return n->contents.sym->u.val = eval_tree(n->left);
136 default: /* should NEVER see this... */
137 execerror("internal - unknown node-type", NULL);
140 return ({Complex zero={}; zero;});
143 /* delete all nodes of a tree */
144 /* not used in current implementation */
145 /********
146 void delete_tree(n)
147 Node *n;
149 if (n)
151 delete_tree(n->left);
152 delete_tree(n->right);
153 free(n);
156 ********/