home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.2 (Developer) / NS_dev_3.2.iso / NextDeveloper / Source / GNU / cctools / as / expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-04  |  40.6 KB  |  1,339 lines

  1. /* expr.c -operands, expressions-
  2.    Copyright (C) 1987 Free Software Foundation, Inc.
  3.  
  4. This file is part of GAS, the GNU Assembler.
  5.  
  6. GAS is free software; you can redistribute it and/or modify
  7. it under the terms of the GNU General Public License as published by
  8. the Free Software Foundation; either version 1, or (at your option)
  9. any later version.
  10.  
  11. GAS is distributed in the hope that it will be useful,
  12. but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. GNU General Public License for more details.
  15.  
  16. You should have received a copy of the GNU General Public License
  17. along with GAS; see the file COPYING.  If not, write to
  18. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  19.  
  20. /*
  21.  * This is really a branch office of as-read.c. I split it out to clearly
  22.  * distinguish the world of expressions from the world of statements.
  23.  * (It also gives smaller files to re-compile.)
  24.  * Here, "operand"s are of expressions, not instructions.
  25.  */
  26.  
  27. #include <ctype.h>
  28. #include "as.h"
  29. #include "flonum.h"
  30. #include "read.h"
  31. #include "struc-symbol.h"
  32. #include "expr.h"
  33. #include "obstack.h"
  34. #include "symbols.h"
  35.  
  36. static void clean_up_expression();    /* Internal. */
  37. extern char EXP_CHARS[];    /* JF hide MD floating pt stuff all the same place */
  38. extern char FLT_CHARS[];
  39.  
  40. #ifdef SUN_ASM_SYNTAX
  41. extern int local_label_defined[];
  42. #endif
  43.  
  44. /*
  45.  * Build any floating-point literal here.
  46.  * Also build any bignum literal here.
  47.  */
  48.  
  49. /* LITTLENUM_TYPE    generic_buffer [6];    /* JF this is a hack */
  50. /* Seems atof_machine can backscan through generic_bignum and hit whatever
  51.    happens to be loaded before it in memory.  And its way too complicated
  52.    for me to fix right.  Thus a hack.  JF:  Just make generic_bignum bigger,
  53.    and never write into the early words, thus they'll always be zero.
  54.    I hate Dean's floating-point code.  Bleh.
  55.  */
  56. LITTLENUM_TYPE    generic_bignum [SIZE_OF_LARGE_NUMBER+6];
  57. FLONUM_TYPE    generic_floating_point_number =
  58. {
  59.   & generic_bignum [6],        /* low (JF: Was 0) */
  60.   & generic_bignum [SIZE_OF_LARGE_NUMBER+6 - 1], /* high JF: (added +6) */
  61.   0,                /* leader */
  62.   0,                /* exponent */
  63.   0                /* sign */
  64. };
  65. /* If nonzero, we've been asked to assemble nan, +inf or -inf */
  66. int generic_floating_point_magic;
  67.  
  68. /*
  69.  * Summary of operand().
  70.  *
  71.  * in:    Input_line_pointer points to 1st char of operand, which may
  72.  *    be a space.
  73.  *
  74.  * out:    A expressionS. X_seg determines how to understand the rest of the
  75.  *    expressionS.
  76.  *    The operand may have been empty: in this case X_seg == SEG_NONE.
  77.  *    Input_line_pointer -> (next non-blank) char after operand.
  78.  *
  79.  */
  80.  
  81. static segT
  82. operand (expressionP)
  83.      register expressionS *    expressionP;
  84. {
  85.   register char        c;
  86.   register char *name;    /* points to name of symbol */
  87.   register struct symbol *    symbolP; /* Points to symbol */
  88.  
  89.   extern  char hex_value[];    /* In hex_value.c */
  90.   char    *local_label_name();
  91.  
  92.   SKIP_WHITESPACE();        /* Leading whitespace is part of operand. */
  93.   c = * input_line_pointer ++;    /* Input_line_pointer -> past char in c. */
  94.   if (isdigit(c))
  95.     {
  96.       register valueT    number;    /* offset or (absolute) value */
  97.       register short int digit;    /* value of next digit in current radix */
  98.                 /* invented for humans only, hope */
  99.                 /* optimising compiler flushes it! */
  100.       register short int radix;    /* 8, 10 or 16 */
  101.                 /* 0 means we saw start of a floating- */
  102.                 /* point constant. */
  103.       register short int maxdig;/* Highest permitted digit value. */
  104.       register int    too_many_digits; /* If we see >= this number of */
  105.                 /* digits, assume it is a bignum. */
  106.       register char *    digit_2; /* -> 2nd digit of number. */
  107.                int    small;    /* TRUE if fits in 32 bits. */
  108. #ifdef NeXT    /* fix for bug #8331 */
  109.                int    force_bignum; /* TRUE if number is 0xb...  */
  110.       force_bignum = FALSE;
  111. #endif NeXT    /* fix for bug #8331 */
  112.  
  113.       if (c=='0')
  114.     {            /* non-decimal radix */
  115.       if ((c = * input_line_pointer ++)=='x' || c=='X')
  116.         {
  117.           c = * input_line_pointer ++; /* read past "0x" or "0X" */
  118.           maxdig = radix = 16;
  119.           too_many_digits = 9;
  120.         }
  121. #ifdef NeXT    /* fix for bug #8331 */
  122.       else if (c=='b' || c=='B')
  123.         {
  124.           force_bignum = TRUE;
  125.           c = * input_line_pointer ++; /* read past "0b" or "0B" */
  126.           maxdig = radix = 16;
  127.           too_many_digits = 9;
  128.         }
  129. #endif NeXT    /* fix for bug #8331 */
  130.       else
  131.         {
  132.           /* If it says '0f' and the line ends or it DOESN'T look like
  133.              a floating point #, its a local label ref.  DTRT */
  134.           if(c=='f' && (! *input_line_pointer ||
  135.                 (!index("+-.0123456789",*input_line_pointer) &&
  136.                  !index(EXP_CHARS,*input_line_pointer))))
  137.         {
  138.               maxdig = radix = 10;
  139.           too_many_digits = 11;
  140.           c='0';
  141.           input_line_pointer-=2;
  142.         }
  143.           else if (c && index (FLT_CHARS,c))
  144.         {
  145.           radix = 0;    /* Start of floating-point constant. */
  146.                 /* input_line_pointer -> 1st char of number. */
  147.           expressionP -> X_add_number =  - (isupper(c) ? tolower(c) : c);
  148.         }
  149.           else
  150.         {        /* By elimination, assume octal radix. */
  151.           radix = 8;
  152.           maxdig = 10;    /* Un*x sux. Compatibility. */
  153.           too_many_digits = 11;
  154.         }
  155.         }
  156.       /* c == char after "0" or "0x" or "0X" or "0e" etc.*/
  157.     }
  158.       else
  159.     {
  160.       maxdig = radix = 10;
  161.       too_many_digits = 11;
  162.     }
  163.       if (radix)
  164.     {            /* Fixed-point integer constant. */
  165.                 /* May be bignum, or may fit in 32 bits. */
  166. /*
  167.  * Most numbers fit into 32 bits, and we want this case to be fast.
  168.  * So we pretend it will fit into 32 bits. If, after making up a 32
  169.  * bit number, we realise that we have scanned more digits than
  170.  * comfortably fit into 32 bits, we re-scan the digits coding
  171.  * them into a bignum. For decimal and octal numbers we are conservative: some
  172.  * numbers may be assumed bignums when in fact they do fit into 32 bits.
  173.  * Numbers of any radix can have excess leading zeros: we strive
  174.  * to recognise this and cast them back into 32 bits.
  175.  * We must check that the bignum really is more than 32
  176.  * bits, and change it back to a 32-bit number if it fits.
  177.  * The number we are looking for is expected to be positive, but
  178.  * if it fits into 32 bits as an unsigned number, we let it be a 32-bit
  179.  * number. The cavalier approach is for speed in ordinary cases.
  180.  */
  181.       digit_2 = input_line_pointer;
  182.       for (number=0;  (digit=hex_value[c])<maxdig;  c = * input_line_pointer ++)
  183.         {
  184.           number = number * radix + digit;
  185.         }
  186.       /* C contains character after number. */
  187.       /* Input_line_pointer -> char after C. */
  188.       small = input_line_pointer - digit_2 < too_many_digits;
  189. #ifdef NeXT    /* fix for bug #8331 */
  190.       if (force_bignum == TRUE)
  191.         small = FALSE;
  192. #endif NeXT    /* fix for bug #8331 */
  193.       if ( ! small)
  194.         {
  195.           /*
  196.            * We saw a lot of digits. Manufacture a bignum the hard way.
  197.            */
  198.           LITTLENUM_TYPE *    leader;    /* -> high order littlenum of the bignum. */
  199.           LITTLENUM_TYPE *    pointer; /* -> littlenum we are frobbing now. */
  200.           long int        carry;
  201.  
  202.           leader = generic_bignum;
  203.           generic_bignum [0] = 0;
  204.                 /* We could just use digit_2, but lets be mnemonic. */
  205.           input_line_pointer = -- digit_2; /* -> 1st digit. */
  206.           c = *input_line_pointer ++;
  207.           for (;   (carry = hex_value [c]) < maxdig;   c = * input_line_pointer ++)
  208.         {
  209.           for (pointer = generic_bignum;
  210.                pointer <= leader;
  211.                pointer ++)
  212.             {
  213.               long int    work;
  214.  
  215.               work = carry + radix * * pointer;
  216.               * pointer = work & LITTLENUM_MASK;
  217.               carry = work >> LITTLENUM_NUMBER_OF_BITS;
  218.             }
  219.           if (carry)
  220.             {
  221.               if (leader < generic_bignum + SIZE_OF_LARGE_NUMBER - 1)
  222.             {    /* Room to grow a longer bignum. */
  223.               * ++ leader = carry;
  224.             }
  225.             }
  226.         }
  227.           /* Again, C is char after number, */
  228.           /* input_line_pointer -> after C. */
  229.           know( BITS_PER_INT == 32 );
  230.           know( LITTLENUM_NUMBER_OF_BITS == 16 );
  231.           /* Hence the constant "2" in the next line. */
  232. #ifdef NeXT    /* fix for bug #8331 */
  233.           if (leader < generic_bignum + 2 && force_bignum == FALSE)
  234. #else NeXT    /* fix for bug #8331 */
  235.           if (leader < generic_bignum + 2)
  236. #endif NeXT     /* fix for bug #8331 */
  237.         {        /* Will fit into 32 bits. */
  238.           number =
  239.             ( (generic_bignum [1] & LITTLENUM_MASK) << LITTLENUM_NUMBER_OF_BITS )
  240.             | (generic_bignum [0] & LITTLENUM_MASK);
  241.           small = TRUE;
  242.         }
  243.           else
  244.         {
  245.           number = leader - generic_bignum + 1;    /* Number of littlenums in the bignum. */
  246.         }
  247.         }
  248.       if (small)
  249.         {
  250.           /*
  251.            * Here with number, in correct radix. c is the next char.
  252.            * Note that unlike Un*x, we allow "011f" "0x9f" to
  253.            * both mean the same as the (conventional) "9f". This is simply easier
  254.            * than checking for strict canonical form. Syntax sux!
  255.            */
  256.           if (number<10)
  257.         {
  258. #ifdef SUN_ASM_SYNTAX
  259.           if (c=='b' || (c=='$' && local_label_defined[number]))
  260. #else
  261.           if (c=='b')
  262. #endif
  263.             {
  264.               /*
  265.                * Backward ref to local label.
  266.                * Because it is backward, expect it to be DEFINED.
  267.                */
  268.               /*
  269.                * Construct a local label.
  270.                */
  271.               name = local_label_name ((int)number, 0);
  272.               if ( (symbolP = symbol_table_lookup(name)) /* seen before */
  273.               && (symbolP -> sy_type & N_TYPE) != N_UNDF /* symbol is defined: OK */
  274.               )
  275.             {        /* Expected path: symbol defined. */
  276.               /* Local labels are never absolute. Don't waste time checking absoluteness. */
  277.               know(   (symbolP -> sy_type & N_TYPE) == N_DATA
  278.                    || (symbolP -> sy_type & N_TYPE) == N_TEXT );
  279.               expressionP -> X_add_symbol = symbolP;
  280.               expressionP -> X_add_number = 0;
  281.               expressionP -> X_seg          = N_TYPE_seg [symbolP -> sy_type];
  282.             }
  283.               else
  284.             {        /* Either not seen or not defined. */
  285.               as_warn( "Backw. ref to unknown label \"%d:\", 0 assumed.",
  286.                   number
  287.                   );
  288.               expressionP -> X_add_number = 0;
  289.               expressionP -> X_seg        = SEG_ABSOLUTE;
  290.             }
  291.             }
  292.           else
  293.             {
  294. #ifdef SUN_ASM_SYNTAX
  295.               if (c=='f' || (c=='$' && !local_label_defined[number]))
  296. #else
  297.               if (c=='f')
  298. #endif
  299.             {
  300.               /*
  301.                * Forward reference. Expect symbol to be undefined or
  302.                * unknown. Undefined: seen it before. Unknown: never seen
  303.                * it in this pass.
  304.                * Construct a local label name, then an undefined symbol.
  305.                * Don't create a XSEG frag for it: caller may do that.
  306.                * Just return it as never seen before.
  307.                */
  308.               name = local_label_name ((int)number, 1);
  309.               if ( symbolP = symbol_table_lookup( name ))
  310.                 {
  311.                   /* We have no need to check symbol properties. */
  312.                   know(   (symbolP -> sy_type & N_TYPE) == N_UNDF
  313.                    || (symbolP -> sy_type & N_TYPE) == N_DATA
  314.                    || (symbolP -> sy_type & N_TYPE) == N_TEXT);
  315.                 }
  316.               else
  317.                 {
  318.                   symbolP = symbol_new (name, N_UNDF, 0,0,0, & zero_address_frag);
  319.                   symbol_table_insert (symbolP);
  320.                 }
  321.               expressionP -> X_add_symbol      = symbolP;
  322.               expressionP -> X_seg             = SEG_UNKNOWN;
  323.               expressionP -> X_subtract_symbol = NULL;
  324.               expressionP -> X_add_number      = 0;
  325.             }
  326.               else
  327.             {        /* Really a number, not a local label. */
  328.               expressionP -> X_add_number = number;
  329.               expressionP -> X_seg        = SEG_ABSOLUTE;
  330.               input_line_pointer --; /* Restore following character. */
  331.             }        /* if (c=='f') */
  332.             }            /* if (c=='b') */
  333.         }
  334.           else
  335.         {            /* Really a number. */
  336.           expressionP -> X_add_number = number;
  337.           expressionP -> X_seg        = SEG_ABSOLUTE;
  338.           input_line_pointer --; /* Restore following character. */
  339.         }            /* if (number<10) */
  340.         }
  341.       else
  342.         {
  343.           expressionP -> X_add_number = number;
  344.           expressionP -> X_seg = SEG_BIG;
  345.           input_line_pointer --; /* -> char following number. */
  346.         }            /* if (small) */
  347.     }            /* (If integer constant) */
  348.       else
  349.     {            /* input_line_pointer -> */
  350.                 /* floating-point constant. */
  351.       int error_code;
  352.  
  353.       error_code = atof_generic
  354.         (& input_line_pointer, ".", EXP_CHARS,
  355.          & generic_floating_point_number);
  356.  
  357.       if (error_code)
  358.         {
  359.           if (error_code == ERROR_EXPONENT_OVERFLOW)
  360.         {
  361.           as_warn( "Bad floating-point constant: exponent overflow, probably assembling junk" );
  362.         }
  363.           else
  364.         {          
  365.           as_warn( "Bad floating-point constant: unknown error code=%d.", error_code);
  366.         }
  367.         }
  368.       expressionP -> X_seg = SEG_BIG;
  369.                 /* input_line_pointer -> just after constant, */
  370.                 /* which may point to whitespace. */
  371.       know( expressionP -> X_add_number < 0 ); /* < 0 means "floating point". */
  372.     }            /* if (not floating-point constant) */
  373.     }
  374.   else if(c=='.' && !is_part_of_name(*input_line_pointer)) {
  375.     extern struct obstack frags;
  376.  
  377.     /*
  378.        JF:  '.' is pseudo symbol with value of current location in current
  379.        segment. . .
  380.      */
  381.     symbolP = symbol_new("L0\001",
  382.              (unsigned char)(seg_N_TYPE[(int)now_seg]),
  383. #ifdef Mach_O
  384.              seg_n_sect(now_seg, now_subseg),
  385. #else !defined(Mach_O)
  386.              0,
  387. #endif Mach_O
  388.              0,
  389.              (valueT)(obstack_next_free(&frags)-frag_now->fr_literal),
  390.              frag_now);
  391.     expressionP->X_add_number=0;
  392.     expressionP->X_add_symbol=symbolP;
  393.     expressionP->X_seg = now_seg;
  394.  
  395. #ifdef NeXT
  396.   } else if ( is_name_beginner(c) || c == '"') /* here if did not begin with a digit */
  397. #else !defined(NeXT)
  398.   } else if ( is_name_beginner(c) ) /* here if did not begin with a digit */
  399. #endif NeXT
  400.     {
  401.       /*
  402.        * Identifier begins here.
  403.        * This is kludged for speed, so code is repeated.
  404.        */
  405. #ifdef NeXT
  406.       if(c == '"')
  407.       name = input_line_pointer -- ;
  408.       else
  409. #endif NeXT
  410.       name =  -- input_line_pointer;
  411.       c = get_symbol_end();
  412.       symbolP = symbol_table_lookup(name);
  413.       if (symbolP)
  414.         {
  415.           /*
  416.            * If we have an absolute symbol, then we know it's value now.
  417.            */
  418.           register segT        seg;
  419.  
  420.           seg = N_TYPE_seg [(int) symbolP -> sy_type & N_TYPE];
  421.           if ((expressionP -> X_seg = seg) == SEG_ABSOLUTE )
  422.         {
  423.           expressionP -> X_add_number = symbolP -> sy_value;
  424.         }
  425.       else
  426.         {
  427.           expressionP -> X_add_number  = 0;
  428.           expressionP -> X_add_symbol  = symbolP;
  429.         }
  430.     }
  431.       else
  432.     {
  433.       expressionP -> X_add_symbol
  434.         = symbolP
  435.         = symbol_new (name, N_UNDF, 0,0,0, & zero_address_frag);
  436.  
  437.       expressionP -> X_add_number  = 0;
  438.       expressionP -> X_seg         = SEG_UNKNOWN;
  439.       symbol_table_insert (symbolP);
  440.     }
  441.       * input_line_pointer = c;
  442.       expressionP -> X_subtract_symbol = NULL;
  443.     }
  444.   else if (c=='(')/* didn't begin with digit & not a name */
  445.     {
  446.       (void)expression( expressionP );
  447.       /* Expression() will pass trailing whitespace */
  448.       if ( * input_line_pointer ++ != ')' )
  449.     {
  450.       as_warn( "Missing ')' assumed");
  451.       input_line_pointer --;
  452.     }
  453.       /* here with input_line_pointer -> char after "(...)" */
  454.     }
  455. #ifdef NeXT    /* logical negation feature */
  456.   else if ( c=='~' || c=='-' || c== '!' )
  457. #else NeXT    /* logical negation feature */
  458.   else if ( c=='~' || c=='-' )
  459. #endif NeXT    /* logical negation feature */
  460.     {        /* unary operator: hope for SEG_ABSOLUTE */
  461.       switch(operand (expressionP)) {
  462.       case SEG_ABSOLUTE:
  463.             /* input_line_pointer -> char after operand */
  464.     if ( c=='-' )
  465.       {
  466.         expressionP -> X_add_number = - expressionP -> X_add_number;
  467. /*
  468.  * Notice: '-' may  overflow: no warning is given. This is compatible
  469.  * with other people's assemblers. Sigh.
  470.  */
  471.       }
  472. #ifdef NeXT    /* logical negation feature */
  473.     else if ( c=='!' )
  474.       {
  475.         expressionP -> X_add_number = ! expressionP -> X_add_number;
  476.       }
  477. #endif NeXT    /* logical negation feature */
  478.     else
  479.       {
  480.         expressionP -> X_add_number = ~ expressionP -> X_add_number;
  481.       }
  482.       break;
  483.  
  484.       case SEG_TEXT:
  485.       case SEG_DATA:
  486.       case SEG_BSS:
  487.       case SEG_PASS1:
  488.       case SEG_UNKNOWN:
  489.     if(c=='-') {        /* JF I hope this hack works */
  490.       expressionP->X_subtract_symbol=expressionP->X_add_symbol;
  491.       expressionP->X_add_symbol=0;
  492.       expressionP->X_seg=SEG_DIFFERENCE;
  493.       break;
  494.     }
  495.       default:        /* unary on non-absolute is unsuported */
  496.     as_warn("Unary operator %c ignored because bad operand follows", c);
  497.     break;
  498.     /* Expression undisturbed from operand(). */
  499.       }
  500.     }
  501.   else if (c=='\'')
  502.     {
  503. /*
  504.  * Warning: to conform to other people's assemblers NO ESCAPEMENT is permitted
  505.  * for a single quote. The next character, parity errors and all, is taken
  506.  * as the value of the operand. VERY KINKY.
  507.  */
  508.       expressionP -> X_add_number = * input_line_pointer ++;
  509.       expressionP -> X_seg        = SEG_ABSOLUTE;
  510.     }
  511.   else
  512.     {
  513.               /* can't imagine any other kind of operand */
  514.       expressionP -> X_seg = SEG_NONE;
  515.       input_line_pointer --;
  516.     }
  517. /*
  518.  * It is more 'efficient' to clean up the expressions when they are created.
  519.  * Doing it here saves lines of code.
  520.  */
  521.   clean_up_expression (expressionP);
  522.   SKIP_WHITESPACE();        /* -> 1st char after operand. */
  523.   know( * input_line_pointer != ' ' );
  524.   return (expressionP -> X_seg);
  525. }                /* operand */
  526.  
  527. /* Internal. Simplify a struct expression for use by expr() */
  528.  
  529. /*
  530.  * In:    address of a expressionS.
  531.  *    The X_seg field of the expressionS may only take certain values.
  532.  *    Now, we permit SEG_PASS1 to make code smaller & faster.
  533.  *    Elsewise we waste time special-case testing. Sigh. Ditto SEG_NONE.
  534.  * Out:    expressionS may have been modified:
  535.  *    'foo-foo' symbol references cancelled to 0,
  536.  *        which changes X_seg from SEG_DIFFERENCE to SEG_ABSOLUTE;
  537.  *    Unused fields zeroed to help expr().
  538.  */
  539.  
  540. static void
  541. clean_up_expression (expressionP)
  542.      register expressionS * expressionP;
  543. {
  544.   switch (expressionP -> X_seg)
  545.     {
  546.     case SEG_NONE:
  547.     case SEG_PASS1:
  548.       expressionP -> X_add_symbol    = NULL;
  549.       expressionP -> X_subtract_symbol    = NULL;
  550.       expressionP -> X_add_number    = 0;
  551.       break;
  552.  
  553.     case SEG_BIG:
  554.     case SEG_ABSOLUTE:
  555.       expressionP -> X_subtract_symbol    = NULL;
  556.       expressionP -> X_add_symbol    = NULL;
  557.       break;
  558.  
  559.     case SEG_TEXT:
  560.     case SEG_DATA:
  561.     case SEG_BSS:
  562.     case SEG_UNKNOWN:
  563.       expressionP -> X_subtract_symbol    = NULL;
  564.       break;
  565.  
  566.     case SEG_DIFFERENCE:
  567.       /*
  568.        * It does not hurt to 'cancel' NULL==NULL
  569.        * when comparing symbols for 'eq'ness.
  570.        * It is faster to re-cancel them to NULL
  571.        * than to check for this special case.
  572.        */
  573.       if (expressionP -> X_subtract_symbol == expressionP -> X_add_symbol)
  574.     {
  575.       expressionP -> X_subtract_symbol    = NULL;
  576.       expressionP -> X_add_symbol        = NULL;
  577.       expressionP -> X_seg            = SEG_ABSOLUTE;
  578.     }
  579.       break;
  580.  
  581.     default:
  582.       BAD_CASE( expressionP -> X_seg);
  583.       break;
  584.     }
  585. }
  586.  
  587. /*
  588.  *            expr_part ()
  589.  *
  590.  * Internal. Made a function because this code is used in 2 places.
  591.  * Generate error or correct X_?????_symbol of expressionS.
  592.  */
  593.  
  594. /*
  595.  * symbol_1 += symbol_2 ... well ... sort of.
  596.  */
  597.  
  598. static segT
  599. expr_part (symbol_1_PP, symbol_2_P)
  600.      struct symbol **    symbol_1_PP;
  601.      struct symbol *    symbol_2_P;
  602. {
  603.   segT            return_value;
  604.  
  605.   know(    (* symbol_1_PP)                   == NULL
  606.        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_TEXT
  607.        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_DATA
  608.        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_BSS
  609.        || ((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF
  610.        );
  611.   know(      symbol_2_P             == NULL
  612.        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_TEXT
  613.        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_DATA
  614.        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_BSS
  615.        ||    (symbol_2_P   -> sy_type & N_TYPE) == N_UNDF
  616.        );
  617.   if (* symbol_1_PP)
  618.     {
  619.       if (((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF)
  620.     {
  621.       if (symbol_2_P)
  622.         {
  623.           return_value = SEG_PASS1;
  624.           * symbol_1_PP = NULL;
  625.         }
  626.       else
  627.         {
  628.           know( ((* symbol_1_PP) -> sy_type & N_TYPE) == N_UNDF)
  629.           return_value = SEG_UNKNOWN;
  630.         }
  631.     }
  632.       else
  633.     {
  634.       if (symbol_2_P)
  635.         {
  636.           if ((symbol_2_P -> sy_type & N_TYPE) == N_UNDF)
  637.         {
  638.           * symbol_1_PP = NULL;
  639.           return_value = SEG_PASS1;
  640.         }
  641.           else
  642.         {
  643.           /* {seg1} - {seg2} */
  644.           as_warn( "Expression too complex, 2 symbols forgotten: \"%s\" \"%s\"",
  645.               (* symbol_1_PP) -> sy_name, symbol_2_P -> sy_name );
  646.           * symbol_1_PP = NULL;
  647.           return_value = SEG_ABSOLUTE;
  648.         }
  649.         }
  650.       else
  651.         {
  652.           return_value = N_TYPE_seg [(* symbol_1_PP) -> sy_type & N_TYPE];
  653.         }
  654.     }
  655.     }
  656.   else
  657.     {                /* (* symbol_1_PP) == NULL */
  658.       if (symbol_2_P)
  659.     {
  660.       * symbol_1_PP = symbol_2_P;
  661.       return_value = N_TYPE_seg [(symbol_2_P) -> sy_type & N_TYPE];
  662.     }
  663.       else
  664.     {
  665.       * symbol_1_PP = NULL;
  666.       return_value = SEG_ABSOLUTE;
  667.     }
  668.     }
  669.   know(   return_value == SEG_ABSOLUTE            
  670.        || return_value == SEG_TEXT            
  671.        || return_value == SEG_DATA            
  672.        || return_value == SEG_BSS            
  673.        || return_value == SEG_UNKNOWN            
  674.        || return_value == SEG_PASS1            
  675.        );
  676.   know(   (* symbol_1_PP) == NULL                
  677.        || ((* symbol_1_PP) -> sy_type & N_TYPE) == seg_N_TYPE [(int) return_value] );
  678.   return (return_value);
  679. }                /* expr_part() */
  680.  
  681. #ifdef NeXT    /* feature to try to make expressions absolute */
  682. /*
  683.  *  DJA -- Here we make a last ditch effort to turn expressions into
  684.  *    absolutes.  This is particularly useful for doing arithemtic
  685.  *    on already declared labels, for example in going through the
  686.  *    following table the moveq can really be evaluated.  We print
  687.  *    a warning when relaxation might cause cause the symbols to
  688.  *    change.
  689.  *
  690.  *    start:    .word    1
  691.  *        .word    2
  692.  *        .word    3
  693.  *    end:
  694.  *        lea    start,a0
  695.  *        moveq    #((end-start) / 2) + 1,d0
  696.  *    loop:    cmpw    d1,a0@+
  697.  *        dbra    d0,loop
  698.  */
  699.  
  700. segT                /* Return expressionP -> X_seg. */
  701. try_to_make_absolute (expressionP)
  702.      register expressionS    * expressionP; /* Deliver result here. */
  703. {
  704.   if (expressionP -> X_seg == SEG_DIFFERENCE)
  705.     {
  706.       register symbolS    * add_symbol;
  707.       register symbolS    * subtract_symbol;
  708.       register int      add_type;
  709.       register int      subtract_type;
  710. #ifdef RISC
  711.       unsigned long number, size, fail;
  712.       struct frag *frag;
  713. #endif
  714.       
  715.       if ( ! (add_symbol = expressionP -> X_add_symbol) )
  716.     goto vomit;
  717.       if ( ! (subtract_symbol = expressionP -> X_subtract_symbol) )
  718.     goto vomit;
  719.       add_type = add_symbol->sy_type & N_TYPE;
  720.       subtract_type = subtract_symbol->sy_type & N_TYPE;
  721.       if (
  722.        ! (
  723.            (add_type == N_TEXT && subtract_type == N_TEXT)
  724.          ||
  725.            (add_type == N_DATA && subtract_type == N_DATA)
  726.          )
  727.      )
  728.     goto vomit;
  729.  
  730.       if(add_symbol->sy_frag == subtract_symbol->sy_frag){
  731.     if(add_symbol->sy_frag != NULL &&
  732.        expressionP->X_add_number + add_symbol->sy_value -
  733.                      subtract_symbol->sy_value >= 0){
  734.       expressionP->X_add_number += add_symbol->sy_value -
  735.                        subtract_symbol->sy_value;
  736.       expressionP -> X_seg = SEG_ABSOLUTE;
  737.     }
  738.       }
  739. #ifdef RISC
  740.       /*
  741.        * On a RISC machine with no machine depentant frags of variable length
  742.        * try to see if the chain of frags between the subtract symbol and the
  743.        * add symbol is made up of only rs_fill and rs_align frags and then
  744.        * calculate the difference.
  745.        */
  746.       else{
  747.     if(add_symbol->sy_frag != NULL && subtract_symbol->sy_frag != NULL){
  748.       fail = 0;
  749.       size = 0;
  750.       frag = subtract_symbol->sy_frag;
  751.       while(!fail && frag != NULL && frag != add_symbol->sy_frag){
  752.         if(frag->fr_type == rs_align)
  753.           size = round(size + frag->fr_fix, 1 << frag->fr_offset);
  754.         else if(frag->fr_type == rs_fill)
  755.           size += frag->fr_fix;
  756.         else
  757.           fail = 1;
  758.         frag = frag->fr_next;
  759.       }
  760.  
  761.       if(!fail && frag == add_symbol->sy_frag){
  762.         expressionP->X_add_number =
  763.         size + add_symbol->sy_value - subtract_symbol->sy_value;
  764.         expressionP->X_seg = SEG_ABSOLUTE;
  765.       }
  766.     }
  767.       }
  768. #endif
  769.  
  770. /*
  771.       if (!( (expressionP->X_add_number >= 0) &&
  772.          (add_symbol->sy_frag == subtract_symbol->sy_frag) &&
  773.          (add_symbol->sy_frag) ) )
  774.     as_warn ("Value may change due to relaxation");
  775.       expressionP -> X_seg = SEG_ABSOLUTE;
  776. */
  777.     }
  778. vomit:
  779.   return expressionP -> X_seg;
  780. } /* try_to_make_absolute */
  781. #endif NeXT    /* feature to try to make expressions absolute */
  782.  
  783. /* Expression parser. */
  784.  
  785. /*
  786.  * We allow an empty expression, and just assume (absolute,0) silently.
  787.  * Unary operators and parenthetical expressions are treated as operands.
  788.  * As usual, Q==quantity==operand, O==operator, X==expression mnemonics.
  789.  *
  790.  * We used to do a aho/ullman shift-reduce parser, but the logic got so
  791.  * warped that I flushed it and wrote a recursive-descent parser instead.
  792.  * Now things are stable, would anybody like to write a fast parser?
  793.  * Most expressions are either register (which does not even reach here)
  794.  * or 1 symbol. Then "symbol+constant" and "symbol-symbol" are common.
  795.  * So I guess it doesn't really matter how inefficient more complex expressions
  796.  * are parsed.
  797.  *
  798.  * After expr(RANK,resultP) input_line_pointer -> operator of rank <= RANK.
  799.  * Also, we have consumed any leading or trailing spaces (operand does that)
  800.  * and done all intervening operators.
  801.  */
  802.  
  803. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  804. typedef enum
  805. {
  806. O_illegal = 0,            /* (0)  what we get for illegal op */
  807.  
  808. O_multiply,            /* (1)  *  Ordered by rank*/
  809. O_divide,            /* (2)  /  */
  810. O_modulus,            /* (3)  %  */
  811.  
  812. O_add,                /* (4)  +  */
  813. O_subtract,            /* (5)  -  */
  814.  
  815. O_right_shift,            /* (6)  >> */
  816. O_left_shift,            /* (7)  << */
  817.  
  818. O_less_than,            /* (8)  <  */
  819. O_greater_than,            /* (9)  >  */
  820. O_less_than_or_equal,        /* (10) <= */
  821. O_greater_than_or_equal,    /* (11) >= */
  822.  
  823. O_equal,            /* (12) == */
  824. O_not_equal,            /* (13) != */ /* or <> */
  825.  
  826. O_bit_and,            /* (14) &  */
  827.  
  828. O_bit_exclusive_or,        /* (15) ^  */
  829.  
  830. O_bit_inclusive_or,        /* (16) |  */
  831. O_bit_or_not,            /* (17) !  */
  832. two_char_operator        /* (18) encoding for two char operator */
  833. }
  834. operatorT;
  835.  
  836. /* op_size is indexed by an operatorT and tells the size of the operator
  837.  * which is used to advance the input_line_pointer over the operator */
  838. static int 
  839. op_size [] = { 0, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1 };
  840.  
  841. #else NeXT    /* added relational ops, changed precedence to be same as C */
  842. typedef enum
  843. {
  844. O_illegal,            /* (0)  what we get for illegal op */
  845.  
  846. O_multiply,            /* (1)  * */
  847. O_divide,            /* (2)  / */
  848. O_modulus,            /* (3)  % */
  849. O_left_shift,            /* (4)  < */
  850. O_right_shift,            /* (5)  > */
  851. O_bit_inclusive_or,        /* (6)  | */
  852. O_bit_or_not,            /* (7)  ! */
  853. O_bit_exclusive_or,        /* (8)  ^ */
  854. O_bit_and,            /* (9)  & */
  855. O_add,                /* (10) + */
  856. O_subtract            /* (11) - */
  857. }
  858. operatorT;
  859. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  860.  
  861. #define __ O_illegal
  862.  
  863. static const operatorT op_encoding [256] = {    /* maps ASCII -> operators */
  864.  
  865. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  866. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  867.  
  868. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  869. __, two_char_operator, __, __, __, O_modulus, O_bit_and, __,
  870. #else NeXT    /* added relational ops, changed precedence to be same as C */
  871. __, O_bit_or_not, __, __, __, O_modulus, O_bit_and, __,
  872. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  873. __, __, O_multiply, O_add, __, O_subtract, __, O_divide,
  874. __, __, __, __, __, __, __, __,
  875. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  876. __, __, __, __, two_char_operator, two_char_operator, two_char_operator, __,
  877. #else NeXT    /* added relational ops, changed precedence to be same as C */
  878. __, __, __, __, O_left_shift, __, O_right_shift, __,
  879. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  880. __, __, __, __, __, __, __, __,
  881. __, __, __, __, __, __, __, __,
  882. __, __, __, __, __, __, __, __,
  883. __, __, __, __, __, __, O_bit_exclusive_or, __,
  884. __, __, __, __, __, __, __, __,
  885. __, __, __, __, __, __, __, __,
  886. __, __, __, __, __, __, __, __,
  887. __, __, __, __, O_bit_inclusive_or, __, __, __,
  888.  
  889. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  890. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  891. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  892. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  893. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  894. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  895. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __,
  896. __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __
  897. };
  898.  
  899.  
  900. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  901. /*
  902.  *    Rank    Examples
  903.  *    8    * / %
  904.  *    7    + -
  905.  *    6    >> <<
  906.  *    5    < > <= >=
  907.  *    4    == !=
  908.  *    3    &
  909.  *    2    ^
  910.  *    1    | !
  911.  *    0    operand, (expression)
  912.  */
  913. #else NeXT    /* added relational ops, changed precedence to be same as C */
  914. /*
  915.  *    Rank    Examples
  916.  *    0    operand, (expression)
  917.  *    1    + -
  918.  *    2    & ^ ! |
  919.  *    3    * / % < >
  920.  */
  921. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  922. typedef char operator_rankT;
  923. static operator_rankT
  924. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  925. op_rank [] = { 0, 8, 8, 8, 7, 7, 6, 6, 5, 5, 5, 5, 4, 4, 3, 2, 1, 1 };
  926. #else NeXT    /* added relational ops, changed precedence to be same as C */
  927. op_rank [] = { 0, 3, 3, 3, 3, 3, 2, 2, 2, 2, 1, 1 };
  928. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  929.  
  930. segT                /* Return resultP -> X_seg. */
  931. expr (rank, resultP)
  932.      register operator_rankT    rank; /* Larger # is higher rank. */
  933.      register expressionS *    resultP; /* Deliver result here. */
  934. {
  935.   expressionS        right;
  936.   register operatorT    op_left;
  937.   register char        c_left;    /* 1st operator character. */
  938.   register operatorT    op_right;
  939.   register char        c_right;
  940. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  941.   operatorT two_char_op_encoding ();
  942. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  943.  
  944.   know( rank >= 0 );
  945.   (void)operand (resultP);
  946.   know( * input_line_pointer != ' ' ); /* Operand() gobbles spaces. */
  947.   c_left = * input_line_pointer; /* Potential operator character. */
  948.   op_left = (operatorT) op_encoding [c_left];
  949. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  950.   if (op_left == two_char_operator)
  951.     op_left = two_char_op_encoding (c_left);
  952.   while (op_left && op_rank [(int) op_left] > rank)
  953. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  954.   while (op_left != O_illegal && op_rank [(int) op_left] > rank)
  955.     {
  956. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  957.       input_line_pointer += op_size[ op_left ];
  958.       /* -> after 1st character of operator. */
  959. #else NeXT    /* added relational ops, changed precedence to be same as C */
  960.       input_line_pointer ++;    /* -> after 1st character of operator. */
  961.                 /* Operators "<<" and ">>" have 2 characters. */
  962.       if (* input_line_pointer == c_left && (c_left == '<' || c_left == '>') )
  963.     {
  964.       input_line_pointer ++;
  965.     }            /* -> after operator. */
  966. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  967.       if (SEG_NONE == expr (op_rank[(int) op_left], &right))
  968.     {
  969.       as_warn("Missing operand value assumed absolute 0.");
  970.       resultP -> X_add_number    = 0;
  971.       resultP -> X_subtract_symbol    = NULL;
  972.       resultP -> X_add_symbol    = NULL;
  973.       resultP -> X_seg = SEG_ABSOLUTE;
  974.     }
  975.       know( * input_line_pointer != ' ' );
  976.       c_right = * input_line_pointer;
  977.       op_right = (operatorT) op_encoding [c_right];
  978. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  979.       if (op_right == two_char_operator)
  980.     op_right = two_char_op_encoding (c_right);
  981.       /* -> after 1st character of operator. */
  982. #else NeXT    /* added relational ops, changed precedence to be same as C */
  983.       if (* input_line_pointer == c_right && (c_right == '<' || c_right == '>') )
  984.     {
  985.       input_line_pointer ++;
  986.     }            /* -> after operator. */
  987. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  988.       know(   (int) op_right == 0
  989.        || op_rank [(int) op_right] <= op_rank[(int) op_left] );
  990.       /* input_line_pointer -> after right-hand quantity. */
  991.       /* left-hand quantity in resultP */
  992.       /* right-hand quantity in right. */
  993.       /* operator in op_left. */
  994.       if ( resultP -> X_seg == SEG_PASS1 || right . X_seg == SEG_PASS1 )
  995.     {
  996.       resultP -> X_seg = SEG_PASS1;
  997.     }
  998.       else
  999.     {
  1000.       if ( resultP -> X_seg == SEG_BIG )
  1001.         {
  1002.           as_warn( "Left operand of %c is a %s.  Integer 0 assumed.",
  1003.               c_left, resultP -> X_add_number > 0 ? "bignum" : "float");
  1004.           resultP -> X_seg = SEG_ABSOLUTE;
  1005.           resultP -> X_add_symbol = 0;
  1006.           resultP -> X_subtract_symbol = 0;
  1007.           resultP -> X_add_number = 0;
  1008.         }
  1009.       if ( right . X_seg == SEG_BIG )
  1010.         {
  1011.           as_warn( "Right operand of %c is a %s.  Integer 0 assumed.",
  1012.               c_left, right . X_add_number > 0 ? "bignum" : "float");
  1013.           right . X_seg = SEG_ABSOLUTE;
  1014.           right . X_add_symbol = 0;
  1015.           right . X_subtract_symbol = 0;
  1016.           right . X_add_number = 0;
  1017.         }
  1018.       if ( op_left == O_subtract )
  1019.         {
  1020.           /*
  1021.            * Convert - into + by exchanging symbols and negating number.
  1022.            * I know -infinity can't be negated in 2's complement:
  1023.            * but then it can't be subtracted either. This trick
  1024.            * does not cause any further inaccuracy.
  1025.            */
  1026.  
  1027.           register struct symbol *    symbolP;
  1028.  
  1029.           right . X_add_number      = - right . X_add_number;
  1030.           symbolP                   = right . X_add_symbol;
  1031.           right . X_add_symbol    = right . X_subtract_symbol;
  1032.           right . X_subtract_symbol = symbolP;
  1033.           if (symbolP)
  1034.         {
  1035.           right . X_seg        = SEG_DIFFERENCE;
  1036.         }
  1037.           op_left = O_add;
  1038.         }
  1039.  
  1040.       if ( op_left == O_add )
  1041.         {
  1042.           segT    seg1;
  1043.           segT    seg2;
  1044.           
  1045.           know(   resultP -> X_seg == SEG_DATA        
  1046.            || resultP -> X_seg == SEG_TEXT        
  1047.            || resultP -> X_seg == SEG_BSS        
  1048.            || resultP -> X_seg == SEG_UNKNOWN        
  1049.            || resultP -> X_seg == SEG_DIFFERENCE    
  1050.            || resultP -> X_seg == SEG_ABSOLUTE        
  1051.            || resultP -> X_seg == SEG_PASS1        
  1052.            );
  1053.           know(     right .  X_seg == SEG_DATA        
  1054.            ||   right .  X_seg == SEG_TEXT        
  1055.            ||   right .  X_seg == SEG_BSS        
  1056.            ||   right .  X_seg == SEG_UNKNOWN        
  1057.            ||   right .  X_seg == SEG_DIFFERENCE    
  1058.            ||   right .  X_seg == SEG_ABSOLUTE        
  1059.            ||   right .  X_seg == SEG_PASS1        
  1060.            );
  1061.           
  1062.           clean_up_expression (& right);
  1063.           clean_up_expression (resultP);
  1064.  
  1065.           seg1 = expr_part (& resultP -> X_add_symbol, right . X_add_symbol);
  1066.           seg2 = expr_part (& resultP -> X_subtract_symbol, right . X_subtract_symbol);
  1067.           if (   seg1 == SEG_PASS1
  1068.           || seg2 == SEG_PASS1)
  1069.         {
  1070. #ifdef NeXT
  1071.           as_warn( "Can't relocate expression. Absolute 0 assumed.");
  1072.           resultP -> X_seg        = SEG_ABSOLUTE;
  1073.           resultP -> X_add_number = 0;
  1074. #else !defined(NeXT)
  1075.           need_pass_2 = TRUE;
  1076.           resultP -> X_seg = SEG_PASS1;
  1077. #endif NeXT
  1078.         }
  1079.           else
  1080.         {
  1081.           if (seg2 == SEG_ABSOLUTE)
  1082.             {
  1083.               resultP -> X_seg = seg1;
  1084.             }
  1085.           else
  1086.             {
  1087.               know( seg2 != SEG_ABSOLUTE );
  1088.               know( resultP -> X_subtract_symbol );
  1089.               if (   seg1 != SEG_UNKNOWN
  1090.               && seg1 != SEG_ABSOLUTE
  1091.               && seg2 != SEG_UNKNOWN
  1092.               && seg1 != seg2)
  1093.             {
  1094.               know( seg1 == SEG_TEXT || seg1 == SEG_DATA || seg1== SEG_BSS );
  1095.               know( seg2 == SEG_TEXT || seg2 == SEG_DATA || seg2== SEG_BSS );
  1096.               know( resultP -> X_add_symbol      );
  1097.               know( resultP -> X_subtract_symbol );
  1098.               as_warn("Expression too complex: forgetting %s - %s",
  1099.                   resultP -> X_add_symbol      -> sy_name,
  1100.                   resultP -> X_subtract_symbol -> sy_name);
  1101.               resultP -> X_seg = SEG_ABSOLUTE;
  1102.               /* Clean_up_expression() will do the rest. */
  1103.             }
  1104.               else
  1105.             {
  1106.               resultP -> X_seg = SEG_DIFFERENCE;
  1107.             }    /* If relocation too complex. */
  1108.             }        /* If seg2 == SEG_ABSOLUTE. */
  1109.         }        /* If need pass 2. */
  1110.           resultP -> X_add_number += right . X_add_number;
  1111.           clean_up_expression (resultP);
  1112.         }
  1113.       else
  1114.         {            /* Not +. */
  1115.           if ( resultP -> X_seg == SEG_UNKNOWN || right . X_seg == SEG_UNKNOWN )
  1116.         {
  1117. #ifdef NeXT
  1118.           as_warn( "Can't relocate expression. Absolute 0 assumed.");
  1119.           resultP -> X_seg        = SEG_ABSOLUTE;
  1120.           resultP -> X_add_number = 0;
  1121. #else !defined(NeXT)
  1122.           resultP -> X_seg = SEG_PASS1;
  1123.           need_pass_2 = TRUE;
  1124. #endif NeXT
  1125.  
  1126.         }
  1127.           else
  1128.         {
  1129. #ifdef NeXT    /* feature to try to make expressions absolute */
  1130.           /* DJA -- we make an attempt to make expressions absolute */
  1131.           try_to_make_absolute (resultP);
  1132.           try_to_make_absolute (&right);
  1133. #endif NeXT    /* feature to try to make expressions absolute */
  1134.           resultP -> X_subtract_symbol = NULL;
  1135.           resultP -> X_add_symbol = NULL;
  1136.           /* Will be SEG_ABSOLUTE. */
  1137.           if ( resultP -> X_seg != SEG_ABSOLUTE || right . X_seg != SEG_ABSOLUTE )
  1138.             {
  1139.               as_warn( "Relocation error. Absolute 0 assumed.");
  1140.               resultP -> X_seg        = SEG_ABSOLUTE;
  1141.               resultP -> X_add_number = 0;
  1142.             }
  1143.           else
  1144.             {
  1145.               switch ( op_left )
  1146.             {
  1147.             case O_bit_inclusive_or:
  1148.               resultP -> X_add_number |= right . X_add_number;
  1149.               break;
  1150.               
  1151.             case O_modulus:
  1152.               if (right . X_add_number)
  1153.                 {
  1154.                   resultP -> X_add_number %= right . X_add_number;
  1155.                 }
  1156.               else
  1157.                 {
  1158.                   as_warn( "Division by 0. 0 assumed." );
  1159.                   resultP -> X_add_number = 0;
  1160.                 }
  1161.               break;
  1162.               
  1163.             case O_bit_and:
  1164.               resultP -> X_add_number &= right . X_add_number;
  1165.               break;
  1166.               
  1167.             case O_multiply:
  1168.               resultP -> X_add_number *= right . X_add_number;
  1169.               break;
  1170.               
  1171.             case O_divide:
  1172.               if (right . X_add_number)
  1173.                 {
  1174.                   resultP -> X_add_number /= right . X_add_number;
  1175.                 }
  1176.               else
  1177.                 {
  1178.                   as_warn( "Division by 0. 0 assumed." );
  1179.                   resultP -> X_add_number = 0;
  1180.                 }
  1181.               break;
  1182.               
  1183.             case O_left_shift:
  1184.               resultP -> X_add_number <<= right . X_add_number;
  1185.               break;
  1186.               
  1187.             case O_right_shift:
  1188.               resultP -> X_add_number >>= right . X_add_number;
  1189.               break;
  1190.               
  1191.             case O_bit_exclusive_or:
  1192.               resultP -> X_add_number ^= right . X_add_number;
  1193.               break;
  1194.               
  1195.             case O_bit_or_not:
  1196.               resultP -> X_add_number |= ~ right . X_add_number;
  1197.               break;
  1198.  
  1199. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  1200.             case O_less_than:
  1201.               resultP -> X_add_number =
  1202.                (resultP -> X_add_number < right . X_add_number);
  1203.               break;
  1204.               
  1205.             case O_greater_than:
  1206.               resultP -> X_add_number =
  1207.                (resultP -> X_add_number > right . X_add_number);
  1208.               break;
  1209.               
  1210.             case O_less_than_or_equal:
  1211.               resultP -> X_add_number =
  1212.                (resultP -> X_add_number <= right . X_add_number);
  1213.               break;
  1214.               
  1215.             case O_greater_than_or_equal:
  1216.               resultP -> X_add_number =
  1217.                (resultP -> X_add_number >= right . X_add_number);
  1218.               break;
  1219.               
  1220.             case O_equal:
  1221.               resultP -> X_add_number =
  1222.                (resultP -> X_add_number == right . X_add_number);
  1223.               break;
  1224.               
  1225.             case O_not_equal:
  1226.               resultP -> X_add_number =
  1227.                (resultP -> X_add_number != right . X_add_number);
  1228.               break;
  1229. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  1230.               
  1231.             default:
  1232.               BAD_CASE( op_left );
  1233.               break;
  1234.             } /* switch(operator) */
  1235.             }
  1236.         }        /* If we have to force need_pass_2. */
  1237.         }            /* If operator was +. */
  1238.     }            /* If we didn't set need_pass_2. */
  1239.       op_left = op_right;
  1240.     }                /* While next operator is >= this rank. */
  1241.   return (resultP -> X_seg);
  1242. }
  1243.  
  1244. #ifdef NeXT    /* added relational ops, changed precedence to be same as C */
  1245. /*
  1246.  * two_char_op_encoding()    DJA -- added for relation ops
  1247.  *
  1248.  * Deal with the operators that are two characters long.
  1249.  *
  1250.  */
  1251. operatorT
  1252. two_char_op_encoding (first_op_char)
  1253.               register char first_op_char;
  1254. {
  1255.   register char second_op_char;
  1256.  
  1257.   second_op_char = input_line_pointer[1];
  1258.   switch (first_op_char)
  1259.     {
  1260.     case '<':
  1261.       if (second_op_char == '<')
  1262.     return O_left_shift;
  1263.       if (second_op_char == '=')
  1264.         return O_less_than_or_equal;
  1265.       if (second_op_char == '>')
  1266.     return O_not_equal;
  1267.       return O_less_than;
  1268.     case '>':
  1269.       if (second_op_char == '>')
  1270.     return O_right_shift;
  1271.       if (second_op_char == '=')
  1272.         return O_greater_than_or_equal;
  1273.       return O_greater_than;
  1274.     case '=':
  1275.       if (second_op_char == '=')
  1276.         return O_equal;
  1277.       return O_illegal;
  1278.     case '!':
  1279.       if (second_op_char == '=')
  1280.         return O_not_equal;
  1281.       return O_not_equal;
  1282.     default:
  1283.       BAD_CASE( first_op_char );
  1284.       return O_illegal;
  1285.     } /* switch (first_op_char) */
  1286. } /* two_char_op_encoding */
  1287. #endif NeXT    /* added relational ops, changed precedence to be same as C */
  1288.  
  1289. /*
  1290.  *            get_symbol_end()
  1291.  *
  1292.  * This lives here because it belongs equally in expr.c & read.c.
  1293.  * Expr.c is just a branch office read.c anyway, and putting it
  1294.  * here lessens the crowd at read.c.
  1295.  *
  1296.  * Assume input_line_pointer is at start of symbol name.
  1297.  * Advance input_line_pointer past symbol name.
  1298.  * Turn that character into a '\0', returning its former value.
  1299.  * This allows a string compare (RMS wants symbol names to be strings)
  1300.  * of the symbol name.
  1301.  * There will always be a char following symbol name, because all good
  1302.  * lines end in end-of-line.
  1303.  */
  1304. char
  1305. get_symbol_end()
  1306. {
  1307.   register char c;
  1308. #ifdef NeXT
  1309.   if ( * input_line_pointer == '"' )
  1310.     {
  1311.       input_line_pointer ++ ;
  1312.       do
  1313.     {
  1314.       c = * input_line_pointer ++ ;
  1315.     }
  1316.       while ( c != '"' && c != '\0' && c != '\n' ) ;
  1317.       if ( c == '"' )
  1318.     {
  1319.       * (input_line_pointer - 1) = 0;
  1320.       c = * input_line_pointer ++ ;
  1321.     }
  1322.     }
  1323.   else
  1324.     {
  1325.       while ( is_part_of_name( c = * input_line_pointer ++ ) )
  1326.     {
  1327.     }
  1328.     }
  1329. #else !defined(NeXT)
  1330.  
  1331.   while ( is_part_of_name( c = * input_line_pointer ++ ) )
  1332.     ;
  1333. #endif NeXT
  1334.   * -- input_line_pointer = 0;
  1335.   return (c);
  1336. }
  1337.  
  1338. /* end: expr.c */
  1339.