home *** CD-ROM | disk | FTP | other *** search
/ Graphics 16,000 / graphics-16000.iso / msdos / animutil / pvquan / animdat / symtab.c < prev    next >
C/C++ Source or Header  |  1992-11-30  |  5KB  |  201 lines

  1. /*--------------------------------------------------------------*/
  2. /*            ANIMDAT 1.1                */
  3. /*        copyright 1992 - TODD SANKEY            */
  4. /*                                */
  5. /*  The author hereby grants permission for the use and sharing    */
  6. /* of both source code end executable versions of this software    */
  7. /* at no charge. This software is not for sale and no other    */
  8. /* shall charge for it without the expressed consent of the    */
  9. /* author.                            */
  10. /*                                */
  11. /*  The source code can be freely modified, but it must retain    */
  12. /* the original copyright notice, and the author must be    */
  13. /* notified of these changes if the altered code is to be    */
  14. /* distributed.                            */
  15. /*--------------------------------------------------------------*/
  16. /*------------------------------------------------------*/
  17. /* symtab.c    Routines for interfacing to a symbol    */
  18. /*        table organized as a binary tree.    */
  19. /*------------------------------------------------------*/
  20.  
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <stdio.h>
  24. #include "common.h"
  25.  
  26. /*------------------------------------------------------*/
  27. /* alloc_symbol        Allocate a symbol node.        */
  28. /*------------------------------------------------------*/
  29. static sym_ptr alloc_symbol(void)
  30. {
  31.  sym_ptr sp;
  32.  
  33.  sp = (sym_ptr)malloc(sizeof(sym));
  34.  if (sp == NULL)
  35.     error(FAILED_MALLOC,NULL);
  36.  
  37.  sp->left = NULL;
  38.  sp->right = NULL;
  39.  sp->name = NULL;
  40.  sp->sym_info = NULL;
  41.  return (sp);
  42. }
  43.  
  44.  
  45. /*------------------------------------------------------*/
  46. /* search_symtab    Search a symbol table for a    */
  47. /*            named symbol.            */
  48. /*------------------------------------------------------*/
  49. sym_ptr search_symtab(sym_ptr symtab, char *name)
  50. {
  51.  int comp;
  52.  
  53.  if (symtab!=NULL)
  54.     do {
  55.         comp=strcmp(name,symtab->name);
  56.         if (comp < 0)
  57.             symtab = symtab->left;
  58.         else if (comp > 0)
  59.             symtab = symtab->right;
  60.         } while (comp && symtab!=NULL);
  61.  
  62.  return (symtab);
  63. }
  64.  
  65. /*------------------------------------------------------*/
  66. /* add_symbol        Add a symbol to a symbol table    */
  67. /*            provided an equivalently named    */
  68. /*            symbol does not already exist.    */
  69. /*------------------------------------------------------*/
  70. sym_ptr add_symbol(sym_ptr *symtab, char *name)
  71. {
  72.  sym_ptr sp,osp;
  73.  int comp;
  74.  
  75.  if ((*symtab) == NULL) {
  76.     *symtab = alloc_symbol();
  77.     sp = (*symtab);
  78.     }
  79.  
  80.  else {
  81.     sp = (*symtab);
  82.     do {
  83.         comp=strcmp(name,sp->name);
  84.         osp = sp;
  85.         if (comp < 0)
  86.             sp = sp->left;
  87.         else if (comp > 0)
  88.             sp = sp->right;
  89.         } while (comp && (sp != NULL) );
  90.  
  91.     if (comp < 0) {
  92.         osp->left = alloc_symbol();
  93.         sp = osp->left;
  94.         }
  95.     else if (comp > 0) {
  96.         osp->right = alloc_symbol();
  97.         sp = osp->right;
  98.         }
  99.     else
  100.         error(SYMBOL_REDEFINED,name);
  101.     }
  102.  
  103.  sp->name = (char *)malloc(strlen(name)+1);
  104.  strcpy(sp->name,name);
  105.  
  106.  return (sp);
  107. }
  108.  
  109.  
  110.  
  111.  
  112. /*------------------------------------------------------*/
  113. /* traverse_symtab    Call a function once for each    */
  114. /*            node in a symbol table.        */
  115. /*------------------------------------------------------*/
  116. void traverse_symtab(sym_ptr symtab,void (*f)(sym_ptr symbol))
  117. {
  118.  if (symtab != NULL) {
  119.     traverse_symtab(symtab->left,f);
  120.     (*f)(symtab);
  121.     traverse_symtab(symtab->right,f);
  122.     }
  123. }
  124.  
  125.  
  126.  
  127. /*------------------------------------------------------*/
  128. /* display_symbol    Display a symbol's name.    */
  129. /*------------------------------------------------------*/
  130. static void display_symbol(sym_ptr symbol)
  131. {
  132.  printf(" %s",symbol->name);
  133. }
  134.  
  135.  
  136. /*------------------------------------------------------*/
  137. /* display_symtab    Display every name in a symbol    */
  138. /*            table.                */
  139. /*------------------------------------------------------*/
  140. void display_symtab(sym_ptr symtab)
  141. {
  142.  traverse_symtab(symtab,display_symbol);
  143. }
  144.  
  145.  
  146.  
  147. /*------------------------------------------------------*/
  148. /* eval_symbol        Evaluate a mathematical symbol. */
  149. /*------------------------------------------------------*/
  150. double eval_symbol(char *name)
  151. {
  152.  sym_ptr symbol;
  153.  
  154.  symbol = search_symtab(symbol_table,name);
  155.  if (symbol == NULL)
  156.     error(UNDEFINED_SYMBOL,name);
  157.  
  158.  if (!symbol->update_flag) {
  159.     symbol->update_flag = 1;
  160.     switch (symbol->sym_type) {
  161.         case SYM_DOUBLE :
  162.             symbol->cur_val = eval_btree((btree_node_ptr)(symbol->sym_info));
  163.             break;
  164.         case SYM_FILE :
  165.             fscanf((FILE *)symbol->sym_info,"%lf",&(symbol->cur_val));
  166.             break;
  167.         default :
  168.             sprintf(cur_line,"Symbol -%s- could not be evaluated numerically",name);
  169.             error(SYNTAX_ERROR,cur_line);
  170.         }
  171.     }
  172.  
  173.  return (symbol->cur_val);
  174. }
  175.  
  176.  
  177. /*------------------------------------------------------*/
  178. /* print_symbol        Print the value for a symbol    */
  179. /*            of any type.            */
  180. /*------------------------------------------------------*/
  181. void print_symbol(FILE *ofile,char *name)
  182. {
  183.  sym_ptr symbol;
  184.  
  185.  symbol = search_symtab(symbol_table, name);
  186.  if (symbol == NULL)
  187.     error(UNDEFINED_SYMBOL, name);
  188.  
  189.  switch (symbol->sym_type) {
  190.     case SYM_DOUBLE:
  191.     case SYM_FILE:
  192.             fprintf(ofile,"%lf",eval_symbol(name));
  193.             break;
  194.     case SYM_STRING:
  195.             fprintf(ofile,"%s",(char *)symbol->sym_info);
  196.             break;
  197.     default:
  198.             error(SYNTAX_ERROR,"Bad symbol type");
  199.     }
  200. }
  201.