home *** CD-ROM | disk | FTP | other *** search
/ Software 2000 / Software 2000 Volume 1 (Disc 1 of 2).iso / utilities / u287.dms / in.adf / Source / Optimize.p < prev    next >
Encoding:
Text File  |  1991-06-08  |  9.7 KB  |  345 lines

  1. External;
  2.  
  3. {$I "Pascal.i"}
  4.  
  5.  
  6.     Procedure Error(msg : String);
  7.     External;
  8.  
  9.  
  10. Procedure Optimize(Expr : ExprPtr);
  11. var
  12.     Param : ExprPtr;
  13.  
  14.     Function BinaryOptimize : Boolean;
  15.     begin
  16.     with Expr^ do begin
  17.         Optimize(Left);
  18.         Optimize(Right);
  19.         if (Left^.Kind = Const1) and (Right^.Kind = Const1) then begin
  20.         Kind := Const1;
  21.         BinaryOptimize := True;
  22.         end else
  23.         BinaryOptimize := False;
  24.     end;
  25.     end;
  26.  
  27. begin
  28.     with Expr^ do begin
  29.     if Kind <= xor1 then begin
  30.         if Kind <= or1 then begin
  31.         case Kind of              { From and1 to or1 } 
  32.           and1 : if BinaryOptimize then
  33.                  Value := Left^.Value and Right^.Value
  34.                          else if (Left^.Kind = Const1) and
  35.                                  (Left^.Value = 0) and
  36.                                  ShortCircuit then begin
  37.                              Kind := Const1;
  38.                              Value := 0;
  39.                          end else if (Right^.Kind = Const1) and
  40.                                      (Right^.Value = 0) and
  41.                                      ShortCircuit then begin
  42.                              Kind := Const1;
  43.                              Value := 0;
  44.                          end;
  45.           const1 : ;
  46.           div1 : if BinaryOptimize then begin
  47.                  if Left^.Value <> 0 then
  48.                  Value := Right^.Value div Left^.Value
  49.                  else begin
  50.                  Error("Division by zero in DIV expression");
  51.                  Value := 1;
  52.                  EType := BadType;
  53.                  end;
  54.              end else if (Left^.Kind = Const1) and
  55.                     (Left^.Value = 0) then
  56.                  Error("Division by zero in DIV expression");
  57.           func1: begin
  58.                  Param := Expr^.Left;    
  59.                  while Param <> Nil do begin
  60.                  Optimize(Param);
  61.                  Param := Param^.Next;
  62.                  end;
  63.              end;
  64.           mod1 : if BinaryOptimize then begin
  65.                  if Left^.Value <> 0 then
  66.                  Value := Right^.Value mod Left^.Value
  67.                  else begin
  68.                  Error("Division by zero in MOD expression");
  69.                  Value := 1;
  70.                  EType := BadType;
  71.                  end;
  72.              end else if (Left^.Kind = Const1) and
  73.                     (Left^.Value = 0) then
  74.                 Error("Division by zero in MOD expression");
  75.           not1 : begin
  76.                  Optimize(Left);
  77.                  if Left^.Kind = Const1 then begin
  78.                  Value := not Left^.Value;
  79.                  Kind := Const1;
  80.                  end;
  81.              end;
  82.           or1  : if BinaryOptimize then
  83.                  Value := Left^.Value or Right^.Value
  84.                          else if (Left^.Kind = Const1) and
  85.                                  (Left^.Value = -1) and
  86.                                  ShortCircuit then begin
  87.                              Value := -1;
  88.                              Kind := Const1;
  89.                          end else if (Right^.Kind = Const1) and
  90.                                      (Right^.Value = -1) and
  91.                                      ShortCircuit then begin
  92.                              Value := -1;
  93.                              Kind := Const1;
  94.                          end;
  95.         end;
  96.         end else begin
  97.         case Kind of        { from shl1 to xor1 }
  98.           shl1 : if BinaryOptimize then
  99.                  Value := Left^.Value shl Right^.Value
  100.              else if Right^.Kind = Const1 then begin
  101.                  if (Right^.Value) and 31 = 0 then
  102.                  Expr^ := Left^;
  103.              end;
  104.           shr1 : if BinaryOptimize then
  105.                  Value := Left^.Value shr Right^.Value
  106.              else if Right^.Kind = Const1 then begin
  107.                  if (Right^.Value) and 31 = 0 then
  108.                  Expr^ := Left^;
  109.              end;
  110.           type1: Optimize(Left);
  111.           var1 : ;
  112.           xor1 : if BinaryOptimize then
  113.                  Value := Left^.Value xor Right^.Value;
  114.         end;
  115.         end;
  116.     end else begin
  117.         if Kind <= minus1 then begin
  118.         case Kind of
  119.           numeral1 : ;
  120.           asterisk1 :
  121.             if BinaryOptimize then begin
  122.                 if EType = RealType then
  123.                 Value := Integer(Real(Left^.Value) *
  124.                         Real(Right^.Value))
  125.                 else
  126.                 Value := Left^.Value * Right^.Value;
  127.             end else if Left^.Kind = Const1 then begin
  128.                 if Left^.Value = 0 then begin { zero for anything }
  129.                 Value := 0;
  130.                 Kind := Const1;
  131.                 end else if (EType^.Object = ob_ordinal) and
  132.                     (Left^.Value = 1) then begin
  133.                 if Right^.EType^.Size < 4 then begin
  134.                     Kind := Short2Long;
  135.                     Left := Right;
  136.                     Right := Nil;
  137.                 end else
  138.                     Expr^ := Right^;
  139.                 end;
  140.             end;
  141.           equal1 :
  142.             if BinaryOptimize then begin
  143.                 if Left^.EType = RealType then
  144.                 Value := Ord(Real(Left^.Value) =
  145.                         Real(Right^.Value))
  146.                 else
  147.                 Value := Ord(Left^.Value = Right^.Value);
  148.             end;
  149.           greater1 :
  150.             if BinaryOptimize then begin
  151.                 if Left^.EType = RealType then
  152.                 Value := Ord(Real(Left^.Value) >
  153.                         Real(Right^.Value))
  154.                 else
  155.                 Value := Ord(Left^.Value > Right^.Value);
  156.             end;
  157.           leftbrack1 :
  158.             begin
  159.                 Optimize(Right);
  160.                 if (Right^.Kind = Const1) and
  161.                 (Left^.EType^.Object = ob_array) then begin
  162.                 if RangeCheck then begin
  163.                     if (Right^.Value < Left^.EType^.Lower) or
  164.                        (Right^.Value > Left^.EType^.Upper) then
  165.                     Error("Index out of range");
  166.                 end;
  167.                 Kind := Period1;
  168.                 Value := Right^.Value;
  169.                 end;
  170.             end;
  171.           less1 :
  172.             if BinaryOptimize then begin
  173.                 if Left^.EType = RealType then
  174.                 Value := Ord(Real(Left^.Value) <
  175.                         Real(Right^.Value))
  176.                 else
  177.                 Value := Ord(Left^.Value < Right^.Value);
  178.             end;
  179.           minus1 :
  180.             if Right = Nil then begin { Unary minus }
  181.                 Optimize(Left);
  182.                 if Left^.Kind = Const1 then begin
  183.                 if EType = RealType then
  184.                     Value := Integer(-Real(Left^.Value))
  185.                 else
  186.                     Value := -Left^.Value;
  187.                 Kind := Const1;
  188.                 if EType = ByteType then
  189.                     EType := ShortType;
  190.                 end;
  191.             end else if BinaryOptimize then begin
  192.                 if EType = RealType then
  193.                 Value := Integer(Real(Right^.Value) -
  194.                         Real(Left^.Value))
  195.                 else
  196.                 Value := Right^.Value - Left^.Value;
  197.             end else if Left^.Kind = Const1 then begin
  198.                 if Left^.Value = 0 then
  199.                 Expr^ := Right^;
  200.             end;
  201.         end;
  202.         end else if Kind <= realnumeral1 then begin
  203.         case Kind of { notequal1 through realnumeral1 }
  204.           notequal1 :
  205.             if BinaryOptimize then begin
  206.                 if Left^.EType = RealType then
  207.                 Value := Ord(Real(Left^.Value) <>
  208.                         Real(Right^.Value))
  209.                 else
  210.                 Value := Ord(Left^.Value <> Right^.Value);
  211.             end;
  212.           notgreater1 :
  213.             if BinaryOptimize then begin
  214.                 if Left^.EType = RealType then
  215.                 Value := Ord(Real(Left^.Value) <=
  216.                         Real(Right^.Value))
  217.                 else
  218.                 Value := Ord(Left^.Value <= Right^.Value);
  219.             end;
  220.           notless1 :
  221.             if BinaryOptimize then begin
  222.                 if Left^.EType = RealType then
  223.                 Value := Ord(Real(Left^.Value) >=
  224.                         Real(Right^.Value))
  225.                 else
  226.                 Value := Ord(Left^.Value >= Right^.Value);
  227.             end;
  228.           period1 : Optimize(Left);
  229.           plus1 :
  230.             if BinaryOptimize then begin
  231.                 if EType = RealType then
  232.                 Value := Integer(Real(Left^.Value) +
  233.                         Real(Right^.Value))
  234.                 else
  235.                 Value := Left^.Value + Right^.Value;
  236.             end else if Left^.Kind = Const1 then begin
  237.                 if Left^.Value = 0 then
  238.                 Expr^ := Right^;
  239.             end;
  240.           quote1 : ;
  241.           carat1 : begin
  242.                 Optimize(Left);
  243.                 if Right <> Nil then
  244.                     Optimize(Right);
  245.                end;
  246.           at1 : Optimize(Left);
  247.           realdiv1 :
  248.             if BinaryOptimize then begin
  249.                 if Left^.Value <> 0 then
  250.                 Value := Integer(Real(Right^.Value) /
  251.                         Real(Left^.Value))
  252.                 else begin
  253.                 Error("Division by zero in '/' expression");
  254.                 Value := 1;
  255.                 EType := BadType;
  256.                 end;
  257.             end;
  258.           realnumeral1 : ;
  259.         end;
  260.         end else begin
  261.         case Kind of        { int2real1 through field1 }
  262.           int2real :
  263.             begin
  264.                 Optimize(Left);
  265.                 if Left^.Kind = Const1 then begin
  266.                 Value := Integer(Float(Left^.Value));
  267.                 Kind := Const1;
  268.                 end;
  269.             end;
  270.           real2int :
  271.             begin
  272.                 Optimize(Left);
  273.                 if Left^.Kind = Const1 then begin
  274.                 Value := Trunc(Real(Left^.Value));
  275.                 Kind := Const1;
  276.                 end;
  277.             end;
  278.           short2long :
  279.             begin
  280.                 Optimize(Left);
  281.                 if Left^.Kind = Const1 then begin
  282.                 Value := Left^.Value;
  283.                 Kind := Const1;
  284.                 end else if Left^.Kind = byte2short then begin
  285.                 Kind := byte2long;
  286.                 Left := Left^.Left;
  287.                 end;
  288.             end;
  289.           byte2short :
  290.             begin
  291.                 Optimize(Left);
  292.                 if Left^.EType^.Size > 1 then
  293.                 Expr^ := Left^
  294.                 else if Left^.Kind = Const1 then begin
  295.                 Kind := Const1;
  296.                 Value := Left^.Value and 255;
  297.                 end;
  298.             end;
  299.           byte2long : ;
  300.           stanfunc1 :
  301.             if (Value < 7) or (Value > 9) then begin
  302.                 Optimize(Left);
  303.                 if Left^.Kind = Const1 then begin
  304.                 if (Value < 15) or (Value > 16) then begin
  305.                     case Value of
  306.                       1,2 : Value := Left^.Value;
  307.                       3 : Value := Ord(Odd(Left^.Value));
  308.                       4 : if EType = RealType then
  309.                           Value := Integer(Abs(Real(Left^.Value)))
  310.                       else
  311.                           Value := Abs(Left^.Value);
  312.                       5 : Value := Succ(Left^.Value);
  313.                       6 : Value := Pred(Left^.Value);
  314.                       10: Value := Trunc(Real(Left^.Value));
  315.                       11: Value := Round(Real(Left^.Value));
  316.                       12: Value := Integer(Float(Left^.Value));
  317.                       13: Value := Integer(Floor(Real(Left^.Value)));
  318.                       14: Value := Integer(Ceil(Real(Left^.Value)));
  319.                       17: Value := Bit(Left^.Value);
  320.                       18: Value := Integer(Sqr(Real(Left^.Value)));
  321.                       19: Value := Integer(Sin(Real(Left^.Value)));
  322.                       20: Value := Integer(Cos(Real(Left^.Value)));
  323.                       21: Value := Integer(Sqrt(Real(Left^.Value)));
  324.                       22: Value := Integer(Tan(Real(Left^.Value)));
  325.                       23: Value := Integer(ArcTan(Real(Left^.Value)));
  326.                       24: Value := Integer(Ln(Real(Left^.Value)));
  327.                       25: Value := Integer(Exp(Real(Left^.Value)));
  328.                     end;
  329.                     Kind := Const1;
  330.                 end;
  331.                 end;
  332.             end else if (Value = 7) or (Value = 8) then begin
  333.                 Optimize(Left^.Next);    { Record size }
  334.                 Optimize(Left);        { File expression }
  335.                 Optimize(Right);        { Filename }
  336.             end;
  337.           field1 : ;
  338.         end;
  339.         end;
  340.     end; { else }
  341.     if (Kind = Const1) and (EType = ByteType) and (Value < 0) then
  342.         EType := ShortType;
  343.     end; { with }
  344. end; { Optimize }
  345.