home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 608b.lha / icalc_v1.1a / src / tree.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-30  |  3.3 KB  |  177 lines

  1. /*
  2. *    icalc - complex-expression parser
  3. *
  4. *    Tree creation, deletion and evaluation routines for complex-number
  5. *    parser.
  6. *
  7. *    (C) Martin W Scott, 1991.
  8. */
  9.  
  10. #include <string.h>
  11. #include <stdlib.h>
  12. #include <math.h>
  13. #include "memory.h"
  14. #include "complex.h"
  15. #include "complex.tab.h"
  16.  
  17. #define    allocnode()    rem_malloc(sizeof(Node))
  18.  
  19. Node *n_asgn(sym, arg)            /* node for assignment operator */
  20.     Symbol *sym;
  21.     Node *arg;
  22. {
  23.     Node *n = allocnode();
  24.  
  25.     n->type = '=';
  26.     n->contents.sym = sym;
  27.     n->left = arg;
  28.     n->right = NULL;
  29.  
  30.     return n;
  31. }
  32.  
  33. Node *n_binop(op, left, right)        /* node for binary operator */
  34.     int op;
  35.     Node *left, *right;
  36. {
  37.     Node *n = allocnode();
  38.  
  39.     n->type = op;
  40.     n->left = left;
  41.     n->right = right;
  42.  
  43.     return n;
  44. }
  45.  
  46. Node *n_unop(op, arg)            /* node for unary operator */
  47.     int op;
  48.     Node *arg;
  49. {
  50.     Node *n = allocnode();
  51.  
  52.     n->type = op;
  53.     n->left = arg;
  54.     n->right = NULL;
  55.  
  56.     return n;
  57. }
  58.  
  59. Node *n_func(type, sym, arg)        /* node for function */
  60.     int type;
  61.     Symbol *sym;
  62.     Node *arg;
  63. {
  64.     Node *n = allocnode();
  65.  
  66.     n->type = type;
  67.     n->contents.sym = sym;
  68.     n->left = arg;
  69.     n->right = NULL;
  70.  
  71.     return n;
  72. }
  73.  
  74. Node *n_symbol(type, sym)        /* node for symbol - VAR or CONST */
  75.     int type;
  76.     Symbol *sym;
  77. {
  78.     Node *n = allocnode();
  79.  
  80.     n->type = type;
  81.     n->contents.sym = sym;
  82.     n->left = NULL;
  83.     n->right = NULL;
  84.  
  85.     return n;
  86. }
  87.  
  88. Node *n_number(real, imag)    /* node for number */
  89.     double real, imag;
  90. {
  91.     Node *n = allocnode();
  92.  
  93.     n->type = NUMBER;
  94.     n->contents.val.real = real;
  95.     n->contents.val.imag = imag;
  96.     n->left = NULL;
  97.     n->right = NULL;
  98.  
  99.     return n;
  100. }
  101.  
  102. ArgList *addarg(al, n)        /* add argument (node) to list */
  103.     ArgList *al;
  104.     Node *n;
  105. {
  106.     ArgList *newal;
  107.  
  108.     newal = rem_malloc(sizeof(ArgList));
  109.     newal->node = n;
  110.     newal->next = al;
  111.     return newal;
  112. }
  113.  
  114. static void equateargs(pl,al)    /* equate expression tree (values) with */
  115.     SymList *pl;        /* corresponding parameters */
  116.     ArgList *al;
  117. {
  118.     if (pl && al)    /* both are non-NULL */
  119.     {
  120.         pl->sym->u.val = eval_tree(al->node);
  121.         equateargs(pl->next,al->next);
  122.     }
  123.     else if (pl || al)
  124.         execerror("invalid number of arguments to function", NULL);
  125. }
  126.  
  127. Complex eval_tree(n)        /* evaluate the complex value of a tree */
  128.     Node *n;
  129. {
  130.     switch (n->type)
  131.     {
  132.     case NUMBER:    return n->contents.val;
  133.  
  134.     case C_BLTIN:    return (*(n->contents.sym->u.cptr))(eval_tree(n->left));
  135.  
  136.     case UFUNC:   { UserFunc *uf = &n->contents.sym->u.ufunc;
  137.             equateargs(uf->params,n->left);
  138.             return eval_tree(uf->tree);
  139.               }
  140.  
  141.     case SFUNC:    return (*(n->contents.sym->u.sptr))(n->left);
  142.  
  143.     case VAR:
  144.     case PARAMETER:
  145.     case CONST:    return n->contents.sym->u.val;
  146.  
  147.     case '+':    return cadd(eval_tree(n->left), eval_tree(n->right));
  148.     case '-':    return csub(eval_tree(n->left), eval_tree(n->right));
  149.     case '*':    return cmul(eval_tree(n->left), eval_tree(n->right));
  150.     case '/':    return cdiv(eval_tree(n->left), eval_tree(n->right));
  151.     case '^':    return cpow(eval_tree(n->left), eval_tree(n->right));
  152.  
  153.     case '(':    return eval_tree(n->left);
  154.     case UMINUS:    return cneg(eval_tree(n->left));
  155.     case '\'':    return conj(eval_tree(n->left));
  156.  
  157.     case '=':    return n->contents.sym->u.val = eval_tree(n->left);
  158.  
  159.     default:    /* should NEVER see this... */
  160.             execerror("internal - unknown node-type", NULL);
  161.     }
  162. }
  163.  
  164. /* delete all nodes of a tree */
  165. /* not used in current implementation */
  166. /********
  167. void delete_tree(n)
  168.     Node *n;
  169. {
  170.     if (n)
  171.     {
  172.         delete_tree(n->left);
  173.         delete_tree(n->right);
  174.         free(n);
  175.     }
  176. }
  177. ********/