home *** CD-ROM | disk | FTP | other *** search
/ cs.rhul.ac.uk / www.cs.rhul.ac.uk.zip / www.cs.rhul.ac.uk / pub / rdp / rdp_cs3460.tar / mt_aux.c < prev    next >
C/C++ Source or Header  |  1998-05-07  |  7KB  |  197 lines

  1. /*******************************************************************************
  2. *
  3. * RDP release 1.50 by Adrian Johnstone (A.Johnstone@rhbnc.ac.uk) 20 December 1997
  4. *
  5. * mt_aux.c - Minitree multiple pass compiler semantic routines
  6. *
  7. * This file may be freely distributed. Please mail improvements to the author.
  8. *
  9. *******************************************************************************/
  10. #include <stdarg.h>
  11. #include <stdio.h>
  12. #include <string.h>
  13. #include "graph.h"
  14. #include "memalloc.h"
  15. #include "textio.h"
  16. #include "minitree.h"
  17. #include "ml_aux.h"
  18. #include "mt_aux.h"
  19.  
  20. char * expression_walk(rdp_tree_data * root)
  21. {
  22.   /* Postorder expression walk */
  23.   if (root->token == SCAN_P_ID)
  24.     return root->id; 
  25.   else if (root->token == SCAN_P_INTEGER)
  26.   {
  27.     char * result =(char *) mem_malloc(12); 
  28.     
  29.     sprintf(result, "#%lu", root->data.u); 
  30.     return result; 
  31.   }
  32.   else
  33.   {
  34.     void * left_edge = graph_get_next_edge(root); 
  35.     void * right_edge = graph_get_next_edge(left_edge); 
  36.     
  37.     char * left = expression_walk((rdp_tree_data *) graph_get_edge_target(left_edge)); 
  38.     
  39.     if (right_edge == NULL)   /* monadic operator */
  40.     {
  41.       char * dst = new_temporary(); 
  42.       
  43.       switch (root->token)
  44.       {
  45.         case RDP_T_26         /* - */ : emit("SUB", "-", dst, "0", left); break; 
  46.         default: 
  47.         text_message(TEXT_FATAL, "unexpected monadic operator found in expression walk: "
  48.         "token number %i, identifier \'%s\'\n", root->token, root->id); 
  49.       }
  50.       return dst; 
  51.     }
  52.     else
  53.     {
  54.       char * right = expression_walk((rdp_tree_data *) graph_get_edge_target(right_edge)); 
  55.       char * dst = new_temporary(); 
  56.       
  57.       switch (root->token)
  58.       {
  59.         case RDP_T_17         /* != */ : emit("NE ", "!=", dst, left, right); break; 
  60.         case RDP_T_22         /* * */ : emit("MUL", "*", dst, left, right); break; 
  61.         case RDP_T_23         /* ** */ : emit("EXP", "**", dst, left, right); break; 
  62.         case RDP_T_24         /* + */ : emit("ADD", "+", dst, left, right); break; 
  63.         case RDP_T_26         /* - */ : emit("SUB", "-", dst, left, right); break; 
  64.         case RDP_T_27         /* / */ : emit("DIV", "/", dst, left, right); break; 
  65.         case RDP_T_29         /* < */ : emit("LT ", "<", dst, left, right); break; 
  66.         case RDP_T_30         /* <= */ : emit("LE ", "<=", dst, left, right); break; 
  67.         case RDP_T_32         /* == */ : emit("EQ ", "==", dst, left, right); break; 
  68.         case RDP_T_33         /* > */ : emit("GT ", ">", dst, left, right); break; 
  69.         case RDP_T_34         /* >= */ : emit("GE ", ">=", dst, left, right); break; 
  70.         default: text_message(TEXT_FATAL, "unexpected diadic operator found in expression walk: "
  71.         "token number %i, identifier \'%s\'\n", root->token, root->id); 
  72.       }
  73.       return dst; 
  74.     }
  75.   }
  76. }
  77.  
  78. void tree_walk(rdp_tree_data * root)
  79. {
  80.   /* Preorder tree walk */
  81.   if (root == NULL)
  82.     return; 
  83.   else
  84.   {
  85.     void * this_edge = graph_get_next_edge(root); 
  86.     
  87.     switch (root->token)
  88.     {
  89.       case 0:                 /* scan root or begin node's children */
  90.       case RDP_T_begin: 
  91.       {
  92.         void * this_edge = graph_get_next_edge(root); 
  93.         
  94.         while (this_edge != NULL) /* walk children, printing results */
  95.         {
  96.           tree_walk((rdp_tree_data *) graph_get_edge_target(this_edge)); 
  97.           this_edge = graph_get_next_edge(this_edge); 
  98.         }
  99.         break; 
  100.       }
  101.       
  102.       case RDP_T_31           /* = */ : 
  103.       emit("CPY", 
  104.       "", 
  105.       ((rdp_tree_data *) graph_get_edge_target(this_edge))->id, 
  106.       expression_walk((rdp_tree_data *) graph_get_edge_target(graph_get_next_edge(this_edge))), NULL); 
  107.       break; 
  108.       
  109.       case RDP_T_int: 
  110.       {
  111.         void * this_edge = graph_get_next_edge(root); 
  112.         
  113.         while (this_edge != NULL) /* walk children, declaring each variable */
  114.         {
  115.           void * child_edge; 
  116.           rdp_tree_data * this_node =(rdp_tree_data *) graph_get_edge_target(this_edge); 
  117.           
  118.           emitf(" \n DATA\n%s: WORD 1\n\n CODE\n", this_node->id); 
  119.           if ((child_edge = graph_get_next_edge(this_node))!= NULL)
  120.             emit("CPY", "", this_node->id, 
  121.           expression_walk((rdp_tree_data *) graph_get_edge_target(child_edge)), NULL); 
  122.           this_edge = graph_get_next_edge(this_edge); 
  123.         }
  124.         break; 
  125.       }
  126.       
  127.       case RDP_T_print: 
  128.       {
  129.         void * this_edge = graph_get_next_edge(root); 
  130.         
  131.         while (this_edge != NULL) /* walk children, printing results */
  132.         {
  133.           rdp_tree_data * this_node =(rdp_tree_data *) graph_get_edge_target(this_edge); 
  134.           
  135.           if (this_node->token == RDP_T_18 /* " */)
  136.             emit_print('S', this_node->id); 
  137.           else
  138.             emit_print('I', expression_walk(this_node)); 
  139.           
  140.           this_edge = graph_get_next_edge(this_edge); 
  141.         }
  142.       }
  143.       break; 
  144.       
  145.       case RDP_T_if: 
  146.       {
  147.         char * relation; 
  148.         rdp_tree_data
  149.         * rel_stat =(rdp_tree_data *) graph_get_edge_target(this_edge), 
  150.         * then_stat =(rdp_tree_data *) graph_get_edge_target(graph_get_next_edge(this_edge)), 
  151.         * else_stat =(rdp_tree_data *) graph_get_edge_target(graph_get_next_edge(
  152.         graph_get_next_edge(this_edge))); 
  153.         
  154.         integer label = new_label(); 
  155.         emitf("__IF_%lu:\n", label); 
  156.         relation = expression_walk(rel_stat); 
  157.         emitf(" BEQ  %s,__ELSE_%lu\t;ifn %s go to __ELSE_%lu \n", relation, label, relation, label); 
  158.         tree_walk(then_stat); 
  159.         emitf(" BRA  __FI_%lu\t;go to __FI_%lu\n__ELSE_%lu:\n", label, label, label); 
  160.         tree_walk(else_stat); 
  161.         emitf("__FI_%lu:\n", label); 
  162.         break; 
  163.       }
  164.       
  165.       case RDP_T_while: 
  166.       {
  167.         char * relation; 
  168.         rdp_tree_data
  169.         * rel_stat =(rdp_tree_data *) graph_get_edge_target(this_edge), 
  170.         * do_stat =(rdp_tree_data *) graph_get_edge_target(graph_get_next_edge(this_edge)); 
  171.         
  172.         integer label = new_label(); 
  173.         emitf("__DO_%lu:\n", label); 
  174.         relation = expression_walk(rel_stat); 
  175.         emitf(" BEQ  %s,__OD_%lu\t;ifn %s go to __OD_%lu \n", relation, label, relation, label); 
  176.         tree_walk(do_stat); 
  177.         emitf(" BRA  __DO_%lu\t;go to __DO_%lu\n__OD_%lu:\n", label, label, label); 
  178.         break; 
  179.       }
  180.       
  181.       default: 
  182.       text_message(TEXT_FATAL, "unexpected tree node found: "
  183.       "token number %i, identifier \'%s\'\n", root->token, root->id); 
  184.     }
  185.   }
  186. }
  187.  
  188. void code_generate(char * source, char * output, void * tree_root)
  189. {
  190.   emit_open(source, output); 
  191.   tree_walk((rdp_tree_data *) graph_get_next_node(tree_root)); 
  192.   emit_close(); 
  193. }
  194.  
  195. /* End of mt_aux.c */
  196.  
  197.