1. package Expressions.Operators is 
  2.  
  3.     -- A Binary_Operator has two operands upon which it operates. Evaluating it 
  4.     -- produces a single resultant value. 
  5.     -- 
  6.     -- Relative order of operations (highest priority first) 
  7.     -- * / %           | Multiplication, division, modulo 
  8.     -- + -             | Addition, subtraction 
  9.     -- = != < <= > >=  | Comparators 
  10.     -- && ||           | Logical operators 
  11.     type Binary_Operator is abstract new Expression with private; 
  12.     type A_Binary_Operator is access all Binary_Operator'Class; 
  13.  
  14.     -- Creates a new Binary_Operator of a concrete type depending on 'token'. 
  15.     function Create_Binary_Operator( token : not null A_Token ) return A_Binary_Operator; 
  16.  
  17.     function Get_Precedence( this : not null access Binary_Operator'Class ) return Positive; 
  18.  
  19.     -- Sets the 'left' and 'right' operands of the operator. 
  20.     procedure Set_Operands( this        : not null access Binary_Operator'Class; 
  21.                             left, right : in out A_Expression ); 
  22.     pragma Precondition( left /= null ); 
  23.     pragma Precondition( right /= null ); 
  24.     pragma Postcondition( left = null ); 
  25.     pragma Postcondition( right = null ); 
  26.  
  27.     -- Returns True if the token type represents a binary operator. 
  28.     function Is_Binary( tokenType : Token_Type ) return Boolean; 
  29.  
  30.     ---------------------------------------------------------------------------- 
  31.  
  32.     -- A Unary_Operator has only one operand upon which it operates. Evaluating 
  33.     -- it produces a single resultant value. 
  34.     type Unary_Operator is abstract new Expression with private; 
  35.     type A_Unary_Operator is access all Unary_Operator'Class; 
  36.  
  37.     -- Creates a new Unary_Operator of a concrete type depending on 'token'. 
  38.     function Create_Unary_Operator( token : not null A_Token ) return A_Unary_Operator; 
  39.  
  40.     -- Sets the 'right' (and only) operand of the operator. 
  41.     procedure Set_Operand( this  : not null access Unary_Operator'Class; 
  42.                            right : in out A_Expression ); 
  43.     pragma Precondition( right /= null ); 
  44.     pragma Postcondition( right = null ); 
  45.  
  46.     -- Returns True if the token type represents a unary operator. 
  47.     function Is_Unary( tokenType : Token_Type ) return Boolean; 
  48.  
  49. private 
  50.  
  51.     type Binary_Operator is abstract new Expression with 
  52.         record 
  53.             precedence : Positive; 
  54.             left       : A_Expression; 
  55.             right      : A_Expression; 
  56.         end record; 
  57.  
  58.     procedure Construct( this       : access Binary_Operator; 
  59.                          loc        : Token_Location; 
  60.                          precedence : Positive ); 
  61.  
  62.     procedure Delete( this : in out Binary_Operator ); 
  63.  
  64.     ---------------------------------------------------------------------------- 
  65.  
  66.     -- Add_Op performs addition and string concatenation. 
  67.     type Add_Op is new Binary_Operator with null record; 
  68.  
  69.     function Evaluate( this    : access Add_Op; 
  70.                        context : not null A_Eval_Context ) return A_Value; 
  71.  
  72.     ---------------------------------------------------------------------------- 
  73.  
  74.     -- And_Op performs a logical AND operation. 
  75.     type And_Op is new Binary_Operator with null record; 
  76.  
  77.     function Evaluate( this    : access And_Op; 
  78.                        context : not null A_Eval_Context ) return A_Value; 
  79.  
  80.     ---------------------------------------------------------------------------- 
  81.  
  82.     -- Divide_Op performs division. 
  83.     type Divide_Op is new Binary_Operator with null record; 
  84.  
  85.     function Evaluate( this    : access Divide_Op; 
  86.                        context : not null A_Eval_Context ) return A_Value; 
  87.  
  88.     ---------------------------------------------------------------------------- 
  89.  
  90.     -- Equals_Op tests value equality. 
  91.     type Equals_Op is new Binary_Operator with null record; 
  92.  
  93.     function Evaluate( this    : access Equals_Op; 
  94.                        context : not null A_Eval_Context ) return A_Value; 
  95.  
  96.     ---------------------------------------------------------------------------- 
  97.  
  98.     -- Greater_Op performs numeric and string comparison (case sensitive). 
  99.     type Greater_Op is new Binary_Operator with null record; 
  100.  
  101.     function Evaluate( this    : access Greater_Op; 
  102.                        context : not null A_Eval_Context ) return A_Value; 
  103.  
  104.     ---------------------------------------------------------------------------- 
  105.  
  106.     -- Greater_Equals_Op performs numeric and string comparison (case sensitive). 
  107.     type Greater_Equals_Op is new Binary_Operator with null record; 
  108.  
  109.     function Evaluate( this    : access Greater_Equals_Op; 
  110.                        context : not null A_Eval_Context ) return A_Value; 
  111.  
  112.     ---------------------------------------------------------------------------- 
  113.  
  114.     -- Less_Op performs numeric and string comparison (case sensitive). 
  115.     type Less_Op is new Binary_Operator with null record; 
  116.  
  117.     function Evaluate( this    : access Less_Op; 
  118.                        context : not null A_Eval_Context ) return A_Value; 
  119.  
  120.     ---------------------------------------------------------------------------- 
  121.  
  122.     -- Less_Equals_Op performs numeric and string comparison (case sensitive). 
  123.     type Less_Equals_Op is new Binary_Operator with null record; 
  124.  
  125.     function Evaluate( this    : access Less_Equals_Op; 
  126.                        context : not null A_Eval_Context ) return A_Value; 
  127.  
  128.     ---------------------------------------------------------------------------- 
  129.  
  130.     -- Mod_Op performs a numeric modulus/remainder operation. 
  131.     type Mod_Op is new Binary_Operator with null record; 
  132.  
  133.     function Evaluate( this    : access Mod_Op; 
  134.                        context : not null A_Eval_Context ) return A_Value; 
  135.  
  136.     ---------------------------------------------------------------------------- 
  137.  
  138.     -- Multiply_Op performs a multiplication operation. 
  139.     type Multiply_Op is new Binary_Operator with null record; 
  140.  
  141.     function Evaluate( this    : access Multiply_Op; 
  142.                        context : not null A_Eval_Context ) return A_Value; 
  143.  
  144.     ---------------------------------------------------------------------------- 
  145.  
  146.     -- Not_Equals_Op performs numeric and string comparison (case sensitive). 
  147.     type Not_Equals_Op is new Binary_Operator with null record; 
  148.  
  149.     function Evaluate( this    : access Not_Equals_Op; 
  150.                        context : not null A_Eval_Context ) return A_Value; 
  151.  
  152.     ---------------------------------------------------------------------------- 
  153.  
  154.     -- Or_Op performs a logical OR operation. 
  155.     type Or_Op is new Binary_Operator with null record; 
  156.  
  157.     function Evaluate( this    : access Or_Op; 
  158.                        context : not null A_Eval_Context ) return A_Value; 
  159.  
  160.     ---------------------------------------------------------------------------- 
  161.  
  162.     -- Subtract_Op performs substraction. 
  163.     type Subtract_Op is new Binary_Operator with null record; 
  164.  
  165.     function Evaluate( this    : access Subtract_Op; 
  166.                        context : not null A_Eval_Context ) return A_Value; 
  167.  
  168.     ---------------------------------------------------------------------------- 
  169.  
  170.     type Unary_Operator is abstract new Expression with 
  171.         record 
  172.             right : A_Expression; 
  173.         end record; 
  174.  
  175.     procedure Delete( this : in out Unary_Operator ); 
  176.  
  177.     ---------------------------------------------------------------------------- 
  178.  
  179.     -- Negate_Op performs numeric negation. 
  180.     type Negate_Op is new Unary_Operator with null record; 
  181.  
  182.     function Evaluate( this    : access Negate_Op; 
  183.                        context : not null A_Eval_Context ) return A_Value; 
  184.  
  185.     ---------------------------------------------------------------------------- 
  186.  
  187.     -- Not_Op performs a logical NOT operation. 
  188.     type Not_Op is new Unary_Operator with null record; 
  189.  
  190.     function Evaluate( this    : access Not_Op; 
  191.                        context : not null A_Eval_Context ) return A_Value; 
  192.  
  193. end Expressions.Operators;