C:/Users/Dennis/src/lang/russell.orig/src/pass1/applinfer/outermost_op.c

Go to the documentation of this file.
00001 # include "parm.h"
00002 
00003 # include "stree/ststructs.mh"
00004 
00005 # include "precedence.h"
00006 
00007 /*
00008  * outermost_op(h,t)
00009  *
00010  * input: A denotation in the form of an array of pointers to primaries.
00011  *        h points to the start of the array, t to the end. The array
00012  *        should not be empty.
00013  *
00014  * output: A pointer to the outermost operator in the array, as determined
00015  *         by the heuristic.
00016  *
00017  * heuristic: 1) If the denotation contains primaries of less than
00018  *               "infinite" precedence, then the outermost operator
00019  *               is the leftmost primary in the rightmost sequence of
00020  *               of primaries of lowest precedence.
00021  *               In the case where the lowest precedence is that of the
00022  *               exponentiation operator, the outermost operator is just
00023  *               the leftmost operator of lowest precedence.
00024  *            2) If the denotation does not contain any primaries of less
00025  *               than infinite precedence, then the outermost operator
00026  *               is the only primary which is not bracketed (i.e. is not
00027  *               a list of primaries), and it may have no more than one 
00028  *               right arg and one left arg.
00029  *            3) If there is no such primary, then this routine fails.
00030  *               Mkappl2 will usually use the first primary in this case.
00031  *
00032  *      WARNING: This is a HORRIBLE algorithm.  But we don't have the
00033  *              time to fix it.
00034  */
00035 
00036 NODE ** outermost_op(h, t)
00037 NODE **h, **t;
00038 {
00039     NODE ** op;
00040     int  lowest_prec;   /* the lowest precedence of a primary 
00041                            in the denotation                  */
00042          
00043 
00044     /* Determine the lowest precedence in the denotation */
00045         {   int i;
00046             NODE ** p;
00047 
00048             lowest_prec = INFINITE;
00049             for (p = h; p != t+1; p++) {
00050                 i = precedence(*p);
00051                 if ( i < lowest_prec )
00052                     lowest_prec = i;
00053             }
00054         }
00055 
00056 
00057     switch ( lowest_prec ) {
00058         case INFINITE:
00059             /* Find unbracketed primary and check if ok */
00060                 {   NODE ** p;
00061                     boolean has_left_arg,   /* op has a bracketed left arg */
00062                             has_right_arg;
00063                     int len;                /* # of primaries in array */
00064 
00065                     op = NIL;
00066                     for (p = h; p != t+1; p++) {
00067                         if ( !is_list(*p) )
00068                             op = p;
00069                     }
00070                     if ( op == NIL ) {
00071                         /* there's no reasonable operator, return the NIL */
00072                             break;
00073                     }
00074 
00075                     len = t - h + 1;
00076                     has_left_arg =  ( op == h ? FALSE : is_list(*h) );
00077                     has_right_arg = ( op == t ? FALSE : is_list(*t) );
00078                     if ( !(    has_left_arg &&  has_right_arg && len == 3
00079                            || !has_left_arg &&  has_right_arg && len == 2
00080                            ||  has_left_arg && !has_right_arg && len == 2
00081                           ) ) {
00082                         /* Cant uniquely determine operator */
00083                             op = NIL;
00084                             break;
00085                     }
00086                 }
00087             break;
00088 
00089         case EXPLEVEL:
00090         case ASGNLEVEL:
00091         case DEREFLEVEL:
00092             /* Find leftmost primary */
00093                 {   NODE ** p;
00094 
00095                     for (p = h;;p++)
00096                         if ( precedence(*p) == lowest_prec ) {
00097                             op = p;
00098                             break;
00099                         }
00100                 }
00101             break;
00102 
00103         default:
00104             /* Find leftmost primary in rightmost sequence */
00105                 {   NODE ** p;
00106                     boolean in_seq;
00107 
00108                     in_seq = FALSE;
00109                     for (p = h; p != t+1; p++) {
00110                         if ( precedence(*p) == lowest_prec ) {
00111                             if ( !in_seq )
00112                                 op = p;
00113                         } else
00114                             in_seq = FALSE;
00115                     }
00116                 }
00117     }
00118 
00119     return ( op );
00120 
00121 }

Generated on Fri Jan 25 10:39:46 2008 for russell by  doxygen 1.5.4