home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / Programming / ace_gpl_release / src_ansi / ace / c / expr.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-05  |  25.5 KB  |  1,171 lines

  1. /* << ACE >>
  2.  
  3.    -- Amiga BASIC Compiler --
  4.  
  5.    ** Parser: Expression code **
  6.    ** Copyright (C) 1998 David Benn
  7.    ** 
  8.    ** This program is free software; you can redistribute it and/or
  9.    ** modify it under the terms of the GNU General Public License
  10.    ** as published by the Free Software Foundation; either version 2
  11.    ** of the License, or (at your option) any later version.
  12.    **
  13.    ** This program is distributed in the hope that it will be useful,
  14.    ** but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    ** GNU General Public License for more details.
  17.    **
  18.    ** You should have received a copy of the GNU General Public License
  19.    ** along with this program; if not, write to the Free Software
  20.    ** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    Author: David J Benn
  23.    Date: 26th October-30th November, 1st-13th December 1991,
  24.    14th,20th-27th January 1992, 
  25.    2nd-17th, 21st-29th February 1992, 
  26.    1st,13th,14th,22nd,23rd March 1992,
  27.    21st,22nd April 1992,
  28.    2nd,3rd,11th,15th,16th May 1992,
  29.    7th,8th,9th,11th,13th,14th,28th,29th,30th June 1992,
  30.    2nd-8th,14th-19th,26th-29th July 1992,
  31.    1st-3rd,7th,8th,9th August 1992,
  32.    6th,7th,21st December 1992,
  33.    28th February 1993,
  34.    12th June 1993,
  35.    12th,29th July 1994,
  36.    5th,6th November 1995
  37.  */
  38.  
  39. #include "acedef.h"
  40. #include <string.h>
  41.  
  42. /* externals */
  43. extern int sym;
  44. extern int factype;
  45. extern int negtype;
  46. extern int prodtype;
  47. extern int idivtype;
  48. extern int modtype;
  49. extern int simptype;
  50. extern int nottype;
  51. extern int andtype;
  52. extern int ortype;
  53. extern int eqvtype;
  54. extern CODE *curr_code;
  55. extern long labelcount;
  56. extern char tempstrname[80];
  57.  
  58. /* functions */
  59. BOOL coerce (int *typ1, int *typ2, CODE * cx[])
  60. {
  61.   if ((*typ1 == stringtype) && (*typ2 != stringtype))
  62.     return (FALSE);
  63.   else if ((*typ2 == stringtype) && (*typ1 != stringtype))
  64.     return (FALSE);
  65.   else if (((*typ1 == shorttype) || (*typ1 == longtype)) && (*typ2 == singletype))
  66.     {
  67.       change_Flt (*typ1, cx);
  68.       *typ1 = singletype;
  69.       return (TRUE);
  70.     }
  71.   else if (((*typ2 == shorttype) || (*typ2 == longtype)) && (*typ1 == singletype))
  72.     {
  73.       gen_Flt (*typ2);
  74.       *typ2 = singletype;
  75.       return (TRUE);
  76.     }
  77.   else if ((*typ1 == shorttype) && (*typ2 == longtype))
  78.     {
  79.       change (cx[0], "move.w", "(sp)+", "d0");
  80.       change (cx[1], "ext.l", "d0", "  ");
  81.       change (cx[2], "move.l", "d0", "-(sp)");
  82.       *typ1 = longtype;
  83.       return (TRUE);
  84.     }
  85.   else if ((*typ2 == shorttype) && (*typ1 == longtype))
  86.     {
  87.       gen ("move.w", "(sp)+", "d0");
  88.       gen ("ext.l", "d0", "  ");
  89.       gen ("move.l", "d0", "-(sp)");
  90.       *typ2 = longtype;
  91.       return (TRUE);
  92.     }
  93.   else
  94.     return (TRUE);        /* both shorttype, longtype or singletype OR notype! */
  95. }
  96.  
  97. void make_short (void)
  98. {
  99.   gen ("move.l", "(sp)+", "d0");
  100.   gen ("move.w", "d0", "-(sp)");
  101. }
  102.  
  103. void make_long (void)
  104. {
  105.   gen ("move.w", "(sp)+", "d0");
  106.   gen ("ext.l", "d0", "  ");
  107.   gen ("move.l", "d0", "-(sp)");
  108. }
  109.  
  110. int ptr_term (void)
  111. {
  112. /* pointer operators -- higher precedence
  113.    than unary negation and exponentiation. */
  114.  
  115.   int localtype, op;
  116.   BOOL dereference = FALSE;
  117.  
  118.   if (sym == shortpointer || sym == longpointer || sym == singlepointer)
  119.     {
  120.       op = sym;
  121.       dereference = TRUE;
  122.       insymbol ();
  123.     }
  124.  
  125.   localtype = factor ();
  126.  
  127.   if (dereference)
  128.     {
  129.       if (localtype != longtype)
  130.     {
  131.       _error (4);
  132.       localtype = undefined;
  133.     }
  134.       else
  135.     {
  136.       /* store address into a0 */
  137.       gen ("move.l", "(sp)+", "a0");
  138.  
  139.       /* get value at address in a0 */
  140.       switch (op)
  141.         {
  142.           /* *%<address> */
  143.         case shortpointer:
  144.           gen ("move.w", "(a0)", "-(sp)");
  145.           localtype = shorttype;
  146.           break;
  147.  
  148.           /* *&<address> */
  149.         case longpointer:
  150.           gen ("move.l", "(a0)", "-(sp)");
  151.           localtype = longtype;
  152.           break;
  153.  
  154.           /* *!<address> */
  155.         case singlepointer:
  156.           gen ("move.l", "(a0)", "-(sp)");
  157.           localtype = singletype;
  158.           break;
  159.         }
  160.     }
  161.     }
  162.  
  163.   return (localtype);
  164. }
  165.  
  166. int expterm (void)
  167. {
  168. /* exponentiation -> ALWAYS returns single */
  169.   int i;
  170.   int firsttype, original_firsttype, localtype, coercedtype;
  171.   BOOL coercion;
  172.   CODE *cx[5];
  173.  
  174.   firsttype = ptr_term ();
  175.   localtype = firsttype;
  176.  
  177.   while (sym == raiseto)
  178.     {
  179.       if ((firsttype == shorttype) || (firsttype == longtype))
  180.     {
  181.       /* may need to coerce to singletype */
  182.       for (i = 0; i <= 4; i++)
  183.         {
  184.           gen ("nop", "  ", "  ");
  185.           cx[i] = curr_code;
  186.         }
  187.     }
  188.  
  189.       insymbol ();
  190.       factype = ptr_term ();
  191.       if (factype == undefined)
  192.     return (factype);
  193.       original_firsttype = firsttype;    /* in case of SHORT->single coerce later */
  194.       coercion = coerce (&firsttype, &factype, cx);
  195.  
  196.       if (coercion)
  197.     {
  198.       coercedtype = factype;
  199.  
  200.       /* already singletype? */
  201.       if (coercedtype != singletype)
  202.         {
  203.           /* neither operands are singletype */
  204.           change_Flt (original_firsttype, cx);    /* handles SHORT->single coerce */
  205.           gen_Flt (factype);
  206.         }
  207.  
  208.       gen ("jsr", "_power", "  ");    /* - Call exponentiation function. */
  209.       gen ("addq", "#8", "sp");    /* - Remove parameters from stack. */
  210.       gen ("move.l", "d0", "-(sp)");    /* - Push the result. */
  211.  
  212.       enter_XREF ("_power");
  213.       enter_XREF ("_MathTransBase");    /* opens FFP+IEEE SP transcendental libraries */
  214.  
  215.       localtype = singletype;    /* MUST always return a single-precision value
  216.                        because exponent might be -ve! */
  217.     }
  218.       else
  219.     _error (4);        /* type mismatch */
  220.  
  221.       firsttype = localtype;    /* moving record of last sub-expression type */
  222.     }
  223.   return (localtype);
  224. }
  225.  
  226. int negterm (void)
  227. {
  228.   int localtype;
  229.   BOOL negate = FALSE;
  230.  
  231.   /* unary negation? */
  232.   if (sym == minus)
  233.     negate = TRUE;
  234.   if ((sym == minus) || (sym == plus))
  235.     insymbol ();
  236.  
  237.   localtype = expterm ();
  238.   if (localtype == undefined)
  239.     return (localtype);
  240.  
  241.   if (negate)
  242.     {
  243.       switch (localtype)
  244.     {
  245.     case shorttype:
  246.       gen ("neg.w", "(sp)", "  ");
  247.       break;
  248.  
  249.     case longtype:
  250.       gen ("neg.l", "(sp)", "  ");
  251.       break;
  252.  
  253.     case singletype:
  254.       gen ("move.l", "(sp)+", "d0");
  255.       gen ("move.l", "_MathBase", "a6");
  256.       gen ("jsr", "_LVOSPNeg(a6)", "  ");
  257.       gen ("move.l", "d0", "-(sp)");
  258.       enter_XREF ("_MathBase");
  259.       enter_XREF ("_LVOSPNeg");
  260.       break;
  261.     case stringtype:
  262.       _error (4);
  263.       break;
  264.     }
  265.     }
  266.   return (localtype);
  267. }
  268.  
  269. int prodterm (void)
  270. {
  271. /*
  272.    multiplication           -> returns long or single
  273.    floating-point division  -> returns single
  274.  */
  275.   int op, i;
  276.   int firsttype, original_firsttype, localtype, coercedtype;
  277.   BOOL coercion;
  278.   CODE *cx[5];
  279.  
  280.   firsttype = negterm ();
  281.   localtype = firsttype;
  282.  
  283.   while ((sym == multiply) || (sym == fdiv))
  284.     {
  285.       if ((firsttype == shorttype) || (firsttype == longtype))
  286.     {
  287.       /* may need to coerce to singletype or longtype */
  288.       for (i = 0; i <= 4; i++)
  289.         {
  290.           gen ("nop", "  ", "  ");
  291.           cx[i] = curr_code;
  292.         }
  293.     }
  294.  
  295.       op = sym;            /* multiply or fdiv ? */
  296.  
  297.       insymbol ();
  298.       negtype = negterm ();
  299.  
  300.       if (negtype == undefined)
  301.     return (negtype);
  302.  
  303.       /* save firsttype in case of a SHORT->single coercion 
  304.          later because coercion will need to start over again 
  305.          to avoid short->single code overwriting short->long code */
  306.  
  307.       original_firsttype = firsttype;
  308.       coercion = coerce (&firsttype, &negtype, cx);
  309.  
  310.       /* if not stringtype, perform operation */
  311.       if (coercion)
  312.     {
  313.       coercedtype = negtype;
  314.  
  315.       /* make sure operands are singletype if FFP division */
  316.       if ((op == fdiv) && (coercedtype != singletype))
  317.         {
  318.           /* neither operands are singletype 
  319.              -> both short or long */
  320.           change_Flt (original_firsttype, cx);    /* handles SHORT->single correctly */
  321.           gen_Flt (negtype);
  322.           coercedtype = singletype;
  323.         }
  324.  
  325.       if ((op == multiply) && (coercedtype != longtype))
  326.         pop_operands (coercedtype);
  327.  
  328.       switch (op)
  329.         {
  330.         case multiply:
  331.           switch (coercedtype)
  332.         {
  333.         case shorttype:
  334.           gen ("muls", "d1", "d0");
  335.           localtype = longtype;
  336.           break;
  337.  
  338.         case longtype:    /* args on stack */
  339.           gen ("jsr", "lmul", "  ");
  340.           gen ("add.l", "#8", "sp");
  341.           enter_XREF ("lmul");
  342.           localtype = longtype;
  343.           break;
  344.  
  345.         case singletype:
  346.           gen ("movea.l", "_MathBase", "a6");
  347.           gen ("jsr", "_LVOSPMul(a6)", "  ");
  348.           enter_XREF ("_MathBase");
  349.           enter_XREF ("_LVOSPMul");
  350.           localtype = singletype;
  351.           break;
  352.         }
  353.           break;
  354.  
  355.         case fdiv:
  356.           gen ("move.l", "(sp)+", "d1");    /* 2nd operand */
  357.           gen ("move.l", "(sp)+", "d0");    /* 1st operand */
  358.           gen ("movea.l", "_MathBase", "a6");
  359.           gen ("jsr", "_LVOSPDiv(a6)", "  ");
  360.           enter_XREF ("_MathBase");
  361.           enter_XREF ("_LVOSPDiv");
  362.           localtype = singletype;
  363.           break;
  364.         }
  365.  
  366.       push_result (localtype);    /* result */
  367.  
  368.     }
  369.       else
  370.     _error (4);        /* notype -> type mismatch */
  371.  
  372.       firsttype = localtype;    /* moving record of last sub-expression type */
  373.     }
  374.   return (localtype);
  375. }
  376.  
  377. int idivterm (void)
  378. {
  379. /* integer division -- LONG = LONG \ LONG */
  380.   int i;
  381.   int firsttype, localtype;
  382.   int targettype = longtype;
  383.   CODE *cx[5];
  384.  
  385.   firsttype = prodterm ();
  386.   localtype = firsttype;
  387.  
  388.   while (sym == idiv)
  389.     {
  390.       firsttype = make_integer (firsttype);    /* short or long -> 1st approximation */
  391.  
  392.       /* may need to coerce to long */
  393.       for (i = 0; i <= 2; i++)
  394.     {
  395.       gen ("nop", "  ", "  ");
  396.       cx[i] = curr_code;
  397.     }
  398.  
  399.       if (firsttype == undefined)
  400.     return (firsttype);
  401.  
  402.       coerce (&firsttype, &targettype, cx);    /* make sure it's a long dividend */
  403.       localtype = firsttype;
  404.  
  405.       insymbol ();
  406.       prodtype = prodterm ();
  407.       if (prodtype == undefined)
  408.     return (prodtype);
  409.       prodtype = make_integer (prodtype);    /* short or long at first */
  410.  
  411.       if ((firsttype != notype) && (prodtype != notype) &&
  412.       (firsttype != stringtype) && (prodtype != stringtype))
  413.     {
  414.       if (prodtype == shorttype)
  415.         make_long ();    /* ensure that divisor is LONG! */
  416.       prodtype = longtype;
  417.       localtype = prodtype;
  418.  
  419.       /* integer division - args on stack */
  420.       gen ("jsr", "ace_ldiv", "  ");
  421.       gen ("add.l", "#8", "sp");
  422.       gen ("move.l", "d0", "-(sp)");
  423.       enter_XREF ("ace_ldiv");
  424.     }
  425.       else
  426.     _error (4);        /* notype -> type mismatch */
  427.       firsttype = localtype;    /* moving record of last sub-expression type */
  428.     }
  429.   return (localtype);
  430. }
  431.  
  432. int modterm (void)
  433. {
  434. /* modulo arithmetic -> returns remainder of long integer or FFP division */
  435.   int i;
  436.   int firsttype, localtype;
  437.   int targettype = longtype;
  438.   CODE *cx[5];
  439.  
  440.   firsttype = idivterm ();
  441.   localtype = firsttype;
  442.  
  443.   while (sym == modsym)
  444.     {
  445.       /* may need to coerce to single */
  446.       for (i = 0; i <= 4; i++)
  447.     {
  448.       gen ("nop", "  ", "  ");
  449.       cx[i] = curr_code;
  450.     }
  451.  
  452.       if (firsttype == undefined)
  453.     return (firsttype);
  454.  
  455.       insymbol ();
  456.       idivtype = idivterm ();
  457.  
  458.       if (idivtype == undefined)
  459.     return (idivtype);
  460.  
  461.       /* perform integer or FFP modulo operation */
  462.       if ((firsttype != notype) && (idivtype != notype) &&
  463.       (firsttype != stringtype) && (idivtype != stringtype))
  464.     {
  465.       /* dividend (firsttype) is either short, long or single */
  466.  
  467.       if ((firsttype == singletype) || (idivtype == singletype))
  468.         {
  469.           /* single MOD */
  470.           coerce (&firsttype, &idivtype, cx);
  471. /***************/
  472.         }
  473.       else
  474.         {
  475.           /* integer MOD */
  476.           if (idivtype == shorttype)
  477.         {
  478.           make_long ();    /* ensure that divisor is LONG! */
  479.           idivtype = longtype;
  480.         }
  481.  
  482.           if (firsttype == shorttype)
  483.         coerce (&firsttype, &targettype, cx);
  484. /***************/
  485.         }
  486.  
  487.       localtype = idivtype;    /* short or single */
  488.  
  489.       if (localtype == longtype)
  490.         {
  491.           /* integer MOD - args on stack */
  492.           gen ("jsr", "ace_lrem", "  ");
  493.           gen ("add.l", "#8", "sp");
  494.           gen ("move.l", "d0", "-(sp)");
  495.           enter_XREF ("ace_lrem");
  496.         }
  497.       else
  498.         {
  499.           /* single MOD */
  500.           gen ("move.l", "(sp)+", "d1");    /* divisor */
  501.           gen ("move.l", "(sp)+", "d0");    /* dividend */
  502.           gen ("jsr", "_modffp", "  ");
  503.           gen ("move.l", "d0", "-(sp)");
  504.           enter_XREF ("_modffp");
  505.           enter_XREF ("_MathBase");
  506.           localtype = singletype;
  507.         }
  508.     }
  509.       else
  510.     _error (4);        /* notype -> type mismatch */
  511.       firsttype = localtype;    /* moving record of last sub-expression type */
  512.     }
  513.   return (localtype);
  514. }
  515.  
  516. int simple_expr (void)
  517. {
  518.   int op, i;
  519.   int firsttype, localtype;
  520.   BOOL coercion;
  521.   CODE *cx[5];
  522.  
  523.   firsttype = modterm ();
  524.   localtype = firsttype;
  525.  
  526.   while ((sym == plus) || (sym == minus))
  527.     {
  528.       if ((firsttype == shorttype) || (firsttype == longtype))
  529.     {
  530.       /* may need to coerce */
  531.       for (i = 0; i <= 4; i++)
  532.         {
  533.           gen ("nop", "  ", "  ");
  534.           cx[i] = curr_code;
  535.         }
  536.     }
  537.       op = sym;
  538.       insymbol ();
  539.       modtype = modterm ();
  540.       if (modtype == undefined)
  541.     return (modtype);
  542.       coercion = coerce (&firsttype, &modtype, cx);
  543.       localtype = modtype;
  544.       if (coercion)
  545.     {
  546.       switch (op)
  547.         {
  548.         case plus:
  549.           if ((modtype != stringtype) && (modtype != shorttype))
  550.         {
  551.           gen ("move.l", "(sp)+", "d1");
  552.           gen ("move.l", "(sp)+", "d0");
  553.         }
  554.  
  555.           switch (modtype)
  556.         {
  557.         case shorttype:
  558.           gen ("move.w", "(sp)+", "d1");
  559.           gen ("move.w", "(sp)+", "d0");
  560.           gen ("add.w", "d1", "d0");
  561.           break;
  562.  
  563.         case longtype:
  564.           gen ("add.l", "d1", "d0");
  565.           break;
  566.  
  567.         case singletype:
  568.           gen ("move.l", "_MathBase", "a6");
  569.           gen ("jsr", "_LVOSPAdd(a6)", "  ");
  570.           enter_XREF ("_LVOSPAdd");
  571.           enter_XREF ("_MathBase");
  572.           break;
  573.  
  574.         case stringtype:    /* copy source to temp string */
  575.           gen ("move.l", "(sp)+", "a2");    /* 2nd */
  576.           gen ("move.l", "(sp)+", "a1");    /* 1st */
  577.           make_temp_string ();
  578.           gen ("lea", tempstrname, "a0");
  579.           gen ("jsr", "_strcpy", "  ");
  580.           /* prepare for strcat */
  581.           gen ("lea", tempstrname, "a0");
  582.           gen ("move.l", "a2", "a1");
  583.           gen ("jsr", "_strcat", "  ");
  584.           gen ("pea", tempstrname, "  ");
  585.           enter_XREF ("_strcpy");
  586.           enter_XREF ("_strcat");
  587.           break;
  588.         }
  589.  
  590.           if (modtype == shorttype)
  591.         gen ("move.w", "d0", "-(sp)");
  592.           else if (modtype != stringtype)
  593.         gen ("move.l", "d0", "-(sp)");
  594.           break;
  595.  
  596.         case minus:
  597.           if ((modtype != stringtype) && (modtype != shorttype))
  598.         {
  599.           gen ("move.l", "(sp)+", "d1");
  600.           gen ("move.l", "(sp)+", "d0");
  601.         }
  602.  
  603.           switch (modtype)
  604.         {
  605.         case shorttype:
  606.           gen ("move.w", "(sp)+", "d1");
  607.           gen ("move.w", "(sp)+", "d0");
  608.           gen ("sub.w", "d1", "d0");
  609.           break;
  610.  
  611.         case longtype:
  612.           gen ("sub.l", "d1", "d0");
  613.           break;
  614.  
  615.         case singletype:
  616.           gen ("move.l", "_MathBase", "a6");
  617.           gen ("jsr", "_LVOSPSub(a6)", "  ");
  618.           enter_XREF ("_LVOSPSub");
  619.           enter_XREF ("_MathBase");
  620.           break;
  621.  
  622.         case stringtype:
  623.           _error (4);
  624.           break;
  625.         }
  626.  
  627.           if (modtype == shorttype)
  628.         gen ("move.w", "d0", "-(sp)");
  629.           else if (modtype != stringtype)
  630.         gen ("move.l", "d0", "-(sp)");
  631.         }
  632.     }
  633.       else
  634.     _error (4);        /* notype -> type mismatch */
  635.       firsttype = localtype;    /* moving record of last sub-expression type */
  636.     }
  637.   return (localtype);
  638. }
  639.  
  640. BOOL relop (int op)
  641. {
  642.   if ((op == equal) || (op == notequal) || (op == gtrthan) ||
  643.       (op == lessthan) || (op == gtorequal) || (op == ltorequal))
  644.     return (TRUE);
  645.   else
  646.     return (FALSE);
  647. }
  648.  
  649. char *cond_branch_op (int op)
  650. {
  651.   switch (op)
  652.     {
  653.     case equal:
  654.       return ("beq.s");
  655.     case notequal:
  656.       return ("bne.s");
  657.     case lessthan:
  658.       return ("blt.s");
  659.     case gtrthan:
  660.       return ("bgt.s");
  661.     case ltorequal:
  662.       return ("ble.s");
  663.     case gtorequal:
  664.       return ("bge.s");
  665.     }
  666. }
  667.  
  668. void make_label (char *name, char *lab)
  669. {
  670.   char num[40];
  671.  
  672.   strcpy (name, "_lab");
  673.   itoa (labelcount++, num, 10);
  674.   strcat (name, num);
  675.   strcpy (lab, name);
  676.   strcat (lab, ":\0");
  677. }
  678.  
  679. int relexpr (void)
  680. {
  681. /* relational expression -> pass through this only ONCE */
  682.   int i, op = undefined;
  683.   int firsttype, localtype;
  684.   char labname[80], lablabel[80], branch[6];
  685.   BOOL coercion;
  686.   CODE *cx[5];
  687.  
  688.   firsttype = simple_expr ();
  689.   localtype = firsttype;
  690.  
  691.   if (relop (sym))
  692.     {
  693.       if ((firsttype == shorttype) || (firsttype == longtype))
  694.     {
  695.       /* may need to coerce */
  696.       for (i = 0; i <= 4; i++)
  697.         {
  698.           gen ("nop", "  ", "  ");
  699.           cx[i] = curr_code;
  700.         }
  701.     }
  702.       op = sym;
  703.       insymbol ();
  704.       simptype = simple_expr ();
  705.       if (simptype == undefined)
  706.     return (simptype);
  707.       coercion = coerce (&firsttype, &simptype, cx);
  708.       localtype = simptype;
  709.       if (coercion)
  710.     {
  711.  
  712.       /* compare on basis of type -> d5 = d0 op d1 */
  713.       switch (simptype)
  714.         {
  715.         case shorttype:
  716.           gen ("move.w", "(sp)+", "d1");    /* 2nd */
  717.           gen ("move.w", "(sp)+", "d0");    /* 1st */
  718.           gen ("moveq", "#-1", "d5");    /* assume true */
  719.           gen ("cmp.w", "d1", "d0");
  720.           break;
  721.  
  722.         case longtype:
  723.           gen ("move.l", "(sp)+", "d1");    /* 2nd */
  724.           gen ("move.l", "(sp)+", "d0");    /* 1st */
  725.           gen ("moveq", "#-1", "d5");    /* assume true */
  726.           gen ("cmp.l", "d1", "d0");
  727.           break;
  728.  
  729.         case singletype:
  730.           gen ("move.l", "(sp)+", "d1");    /* 2nd */
  731.           gen ("move.l", "(sp)+", "d0");    /* 1st */
  732.           gen ("moveq", "#-1", "d5");    /* assume true */
  733.           gen ("move.l", "_MathBase", "a6");
  734.           gen ("jsr", "_LVOSPCmp(a6)", "  ");
  735.           enter_XREF ("_LVOSPCmp");
  736.           enter_XREF ("_MathBase");
  737.           break;
  738.  
  739.         case stringtype:
  740.           gen ("move.l", "(sp)+", "a1");    /* addr of 2nd string */
  741.           gen ("move.l", "(sp)+", "a0");    /* addr of 1st string */
  742.           switch (op)
  743.         {
  744.         case equal:
  745.           gen ("jsr", "_streq", "  ");
  746.           enter_XREF ("_streq");
  747.           break;
  748.         case notequal:
  749.           gen ("jsr", "_strne", "  ");
  750.           enter_XREF ("_strne");
  751.           break;
  752.         case lessthan:
  753.           gen ("jsr", "_strlt", "  ");
  754.           enter_XREF ("_strlt");
  755.           break;
  756.         case gtrthan:
  757.           gen ("jsr", "_strgt", "  ");
  758.           enter_XREF ("_strgt");
  759.           break;
  760.         case ltorequal:
  761.           gen ("jsr", "_strle", "  ");
  762.           enter_XREF ("_strle");
  763.           break;
  764.         case gtorequal:
  765.           gen ("jsr", "_strge", "  ");
  766.           enter_XREF ("_strge");
  767.           break;
  768.         }
  769.           gen ("move.l", "d0", "-(sp)");    /* push boolean result */
  770.           break;
  771.         }
  772.  
  773.       /* leave result on stack according to operator (-1 = true, 0 = false) */
  774.       /* (this code for short,long & single comparisons only) */
  775.       if (simptype != stringtype)
  776.         {
  777.           make_label (labname, lablabel);
  778.           strcpy (branch, cond_branch_op (op));
  779.           gen (branch, labname, "  ");
  780.           gen ("moveq", "#0", "d5");    /* not true */
  781.           gen (lablabel, "  ", "  ");
  782.           gen ("move.l", "d5", "-(sp)");    /* boolean result on stack */
  783.         }
  784.     }
  785.       else
  786.     _error (4);
  787.     }
  788.  
  789.   if (op == undefined)
  790.     return (localtype);
  791.   else
  792.     return (longtype);        /* BOOLEAN! */
  793. }
  794.  
  795. int notexpr (void)
  796. {
  797.   int localtype, op;
  798.  
  799.   op = sym;
  800.   if (sym == notsym)
  801.     insymbol ();
  802.  
  803.   localtype = relexpr ();
  804.  
  805.   if (op == notsym)
  806.     {
  807.       localtype = make_integer (localtype);
  808.       if (localtype == notype)
  809.     return (localtype);
  810.       if (localtype == shorttype)
  811.     gen ("not.w", "(sp)", "  ");
  812.       else
  813.     gen ("not.l", "(sp)", "  ");
  814.     }
  815.   return (localtype);
  816. }
  817.  
  818. int andexpr (void)
  819. {
  820.   int i;
  821.   int firsttype, localtype;
  822.   CODE *cx[5];
  823.  
  824.   firsttype = notexpr ();
  825.   localtype = firsttype;
  826.  
  827.   if (sym == andsym)
  828.     {
  829.       firsttype = make_integer (firsttype);
  830.       if (firsttype != notype)
  831.     {
  832.       while (sym == andsym)
  833.         {
  834.           if ((firsttype == shorttype) || (firsttype == longtype))
  835.         {
  836.           /* may need to coerce */
  837.           for (i = 0; i <= 4; i++)
  838.             {
  839.               gen ("nop", "  ", "  ");
  840.               cx[i] = curr_code;
  841.             }
  842.         }
  843.           insymbol ();
  844.           nottype = notexpr ();
  845.           if (nottype == undefined)
  846.         return (nottype);
  847.           nottype = make_integer (nottype);
  848.           coerce (&firsttype, ¬type, cx);
  849.           localtype = nottype;
  850.           if (nottype != notype)
  851.         {
  852.           pop_operands (nottype);
  853.           if (nottype == shorttype)
  854.             gen ("and.w", "d1", "d0");
  855.           else
  856.             gen ("and.l", "d1", "d0");
  857.           push_result (nottype);
  858.         }
  859.           else
  860.         _error (4);
  861.         }
  862.     }
  863.       else
  864.     _error (4);
  865.       firsttype = localtype;
  866.     }
  867.   return (localtype);
  868. }
  869.  
  870. int orexpr (void)
  871. {
  872.   int op, i;
  873.   int firsttype, localtype;
  874.   CODE *cx[5];
  875.  
  876.   firsttype = andexpr ();
  877.   localtype = firsttype;
  878.  
  879.   if ((sym == orsym) || (sym == xorsym))
  880.     {
  881.       firsttype = make_integer (firsttype);
  882.       if (firsttype != notype)
  883.     {
  884.       while ((sym == orsym) || (sym == xorsym))
  885.         {
  886.           if ((firsttype == shorttype) || (firsttype == longtype))
  887.         {
  888.           /* may need to coerce */
  889.           for (i = 0; i <= 4; i++)
  890.             {
  891.               gen ("nop", "  ", "  ");
  892.               cx[i] = curr_code;
  893.             }
  894.         }
  895.           op = sym;
  896.           insymbol ();
  897.           andtype = andexpr ();
  898.           if (andtype == undefined)
  899.         return (andtype);
  900.           andtype = make_integer (andtype);
  901.           coerce (&firsttype, &andtype, cx);
  902.           localtype = andtype;
  903.           if (andtype != notype)
  904.         {
  905.           pop_operands (andtype);
  906.           switch (op)
  907.             {
  908.             case orsym:
  909.               if (andtype == shorttype)
  910.             gen ("or.w", "d1", "d0");
  911.               else
  912.             gen ("or.l", "d1", "d0");
  913.               break;
  914.  
  915.             case xorsym:
  916.               if (andtype == shorttype)
  917.             gen ("eor.w", "d1", "d0");
  918.               else
  919.             gen ("eor.l", "d1", "d0");
  920.               break;
  921.             }
  922.           push_result (andtype);
  923.         }
  924.           else
  925.         _error (4);
  926.         }
  927.     }
  928.       else
  929.     _error (4);
  930.       firsttype = localtype;
  931.     }
  932.   return (localtype);
  933. }
  934.  
  935. int eqvexpr (void)
  936. {
  937.   int i;
  938.   int firsttype, localtype;
  939.   CODE *cx[5];
  940.  
  941.   firsttype = orexpr ();
  942.   localtype = firsttype;
  943.  
  944.   if (sym == eqvsym)
  945.     {
  946.       firsttype = make_integer (firsttype);
  947.       if (firsttype != notype)
  948.     {
  949.       while (sym == eqvsym)
  950.         {
  951.           if ((firsttype == shorttype) || (firsttype == longtype))
  952.         {
  953.           /* may need to coerce */
  954.           for (i = 0; i <= 4; i++)
  955.             {
  956.               gen ("nop", "  ", "  ");
  957.               cx[i] = curr_code;
  958.             }
  959.         }
  960.           insymbol ();
  961.           ortype = orexpr ();
  962.           if (ortype == undefined)
  963.         return (ortype);
  964.           ortype = make_integer (ortype);
  965.           coerce (&firsttype, &ortype, cx);
  966.           localtype = ortype;
  967.           if (ortype != notype)
  968.         {
  969.           pop_operands (ortype);
  970.           if (ortype == shorttype)
  971.             {
  972.               gen ("jsr", "_eqvw", "  ");
  973.               enter_XREF ("_eqvw");
  974.             }
  975.           else
  976.             {
  977.               gen ("jsr", "_eqvl", "  ");
  978.               enter_XREF ("_eqvl");
  979.             }
  980.           push_result (ortype);
  981.         }
  982.           else
  983.         _error (4);
  984.         }
  985.     }
  986.       else
  987.     _error (4);
  988.       firsttype = localtype;
  989.     }
  990.   return (localtype);
  991. }
  992.  
  993. int expr (void)
  994. {
  995.   int i;
  996.   int firsttype, localtype;
  997.   CODE *cx[5];
  998.  
  999.   firsttype = eqvexpr ();
  1000.   localtype = firsttype;
  1001.  
  1002.   if (sym == impsym)
  1003.     {
  1004.       firsttype = make_integer (firsttype);
  1005.       if (firsttype != notype)
  1006.     {
  1007.       while (sym == impsym)
  1008.         {
  1009.           if ((firsttype == shorttype) || (firsttype == longtype))
  1010.         {
  1011.           /* may need to coerce */
  1012.           for (i = 0; i <= 4; i++)
  1013.             {
  1014.               gen ("nop", "  ", "  ");
  1015.               cx[i] = curr_code;
  1016.             }
  1017.         }
  1018.           insymbol ();
  1019.           eqvtype = eqvexpr ();
  1020.           if (eqvtype == undefined)
  1021.         return (eqvtype);
  1022.           eqvtype = make_integer (eqvtype);
  1023.           coerce (&firsttype, &eqvtype, cx);
  1024.           localtype = eqvtype;
  1025.           if (eqvtype != notype)
  1026.         {
  1027.           pop_operands (eqvtype);
  1028.           if (eqvtype == shorttype)
  1029.             {
  1030.               gen ("jsr", "_impw", "  ");
  1031.               enter_XREF ("_impw");
  1032.             }
  1033.           else
  1034.             {
  1035.               gen ("jsr", "_impl", "  ");
  1036.               enter_XREF ("_impl");
  1037.             }
  1038.           push_result (eqvtype);
  1039.         }
  1040.           else
  1041.         _error (4);
  1042.         }
  1043.     }
  1044.       else
  1045.     _error (4);
  1046.       firsttype = localtype;
  1047.     }
  1048.   return (localtype);
  1049. }
  1050.  
  1051. void pop_operands (int typ)
  1052. {
  1053.   if (typ == shorttype)
  1054.     {
  1055.       gen ("move.w", "(sp)+", "d0");    /* 2nd operand */
  1056.       gen ("move.w", "(sp)+", "d1");    /* 1st operand -> d0 = d1 op d0 */
  1057.     }
  1058.   else
  1059.     {
  1060.       gen ("move.l", "(sp)+", "d0");    /* 2nd operand */
  1061.       gen ("move.l", "(sp)+", "d1");    /* 1st operand -> d0 = d1 op d0 */
  1062.     }
  1063. }
  1064.  
  1065. void push_result (int typ)
  1066. {
  1067.   if (typ == shorttype)
  1068.     gen ("move.w", "d0", "-(sp)");
  1069.   else
  1070.     gen ("move.l", "d0", "-(sp)");
  1071. }
  1072.  
  1073. void gen_round (int type)
  1074. {
  1075. /*
  1076.    ** Convert float to integer
  1077.    ** with rounding.
  1078.  */
  1079.   gen ("move.l", "(sp)+", "d0");
  1080.   gen ("jsr", "_round", "  ");
  1081.   gen ("move.l", "d0", "-(sp)");
  1082.   enter_XREF ("_round");
  1083.   enter_XREF ("_MathBase");
  1084.  
  1085.   /*
  1086.      ** Only relevant when called from
  1087.      ** assign_coerce() and STOREType=shorttype.
  1088.    */
  1089.   if (type == shorttype)
  1090.     {
  1091.       gen ("move.l", "(sp)+", "d0");
  1092.       gen ("move.w", "d0", "-(sp)");
  1093.     }
  1094. }
  1095.  
  1096. void gen_Flt (int typ)
  1097. {
  1098. /* convert an integer to a single-precision float */
  1099.   if (typ == singletype)
  1100.     return;            /* already a float! */
  1101.  
  1102.   if (typ == stringtype)
  1103.     _error (4);            /* can't do it */
  1104.  
  1105.   if (typ == shorttype)
  1106.     gen ("move.w", "(sp)+", "d0");
  1107.   else
  1108.     gen ("move.l", "(sp)+", "d0");
  1109.  
  1110.   if (typ == shorttype)
  1111.     gen ("ext.l", "d0", "  ");    /* extend sign */
  1112.  
  1113.   gen ("move.l", "_MathBase", "a6");
  1114.   gen ("jsr", "_LVOSPFlt(a6)", "  ");
  1115.   gen ("move.l", "d0", "-(sp)");
  1116.   enter_XREF ("_LVOSPFlt");
  1117.   enter_XREF ("_MathBase");
  1118. }
  1119.  
  1120. void change_Flt (int exptyp, CODE * cx[])
  1121. {
  1122. /* convert an integer to a float */
  1123.   if (exptyp == shorttype)
  1124.     change (cx[0], "move.w", "(sp)+", "d0");
  1125.   else
  1126.     change (cx[0], "move.l", "(sp)+", "d0");
  1127.   if (exptyp == shorttype)
  1128.     change (cx[1], "ext.l", "d0", "  ");
  1129.   change (cx[2], "move.l", "_MathBase", "a6");
  1130.   change (cx[3], "jsr", "_LVOSPFlt(a6)", "  ");
  1131.   change (cx[4], "move.l", "d0", "-(sp)");
  1132.   enter_XREF ("_LVOSPFlt");
  1133.   enter_XREF ("_MathBase");
  1134. }
  1135.  
  1136. int make_integer (int oldtyp)
  1137. {
  1138.   if (oldtyp == stringtype)
  1139.     return (notype);        /* can't do it! */
  1140.   else if (oldtyp == singletype)
  1141.     {
  1142.       gen_round (oldtyp);
  1143.       return (longtype);
  1144.     }
  1145.   else
  1146.     return (oldtyp);        /* already an integer */
  1147. }
  1148.  
  1149. void make_sure_short (int type)
  1150. {
  1151.   if (type == longtype)
  1152.     make_short ();
  1153.   else if (type == singletype)
  1154.     {
  1155.       make_integer (type);
  1156.       make_short ();
  1157.     }
  1158.   else if (type == stringtype)
  1159.     _error (4);
  1160. }
  1161.  
  1162. void make_sure_long (int type)
  1163. {
  1164.   if (type == shorttype)
  1165.     make_long ();
  1166.   else if (type == singletype)
  1167.     make_integer (type);
  1168.   else if (type == stringtype)
  1169.     _error (4);
  1170. }
  1171.