/*CLI Binary Operator Node:
   List of (CLI operator, Actor operator) pairs:
   (*, *), (/, /), (% mod), (+, +), (-, -), (<, <), (>, >), (<=, <=), (>=, >=),
   (==, =), (!=, <>), (&, bitAnd), (^, bitXor), (|, bitOr), (&&, and), (||, or).
   Note that shift operations are constructed by multiply/divide operation,    followed by masking. */!!

inherit(Object, #CLIBinaryOpNode, #(left right
operator  /* negate, not, or bitwise negate */), 2, nil)!!

now(class(CLIBinaryOpNode))!!

now(CLIBinaryOpNode)!!

/* Compile the node into Actor source. */
Def CLICodeCompile(self | errorMessage)
{
  select
   /* simple 1-1 CLI->Actor operator mapping */
    case operator = TSTAR is
      CLIInfixCodeCompile(self, left, right, " * ");
      endCase
    case operator = TSLASH is
      CLIInfixCodeCompile(self, left, right, " / ");
      endCase
    case operator = TPERCENT is
      CLIInfixCodeCompile(self, left, right, " mod ");
      endCase
    case operator = TPLUS is
      CLIInfixCodeCompile(self, left, right, " + ");
      endCase
    case operator = TMINUS is
      CLIInfixCodeCompile(self, left, right, " - ");
      endCase
    case operator = TAMPER is
      CLIInfixCodeCompile(self, left, right, " bitAnd ");
      endCase
    case operator = TUPARROW is
      CLIInfixCodeCompile(self, left, right, " bitXor ");
      endCase
    case operator = TBAR is
      CLIInfixCodeCompile(self, left, right, " bitOr ");
      endCase
   /* logical operations must be mapped onto C-sensitive methods */
    case operator = TEQUAL_TO is
      CLIPostfixCodeCompile(self, left, right, "logicalEqual");
      endCase
    case operator = TNOT_EQUAL is
      CLIPostfixCodeCompile(self, left, right, "logicalNotEqual");
      endCase
    case operator = TL_ANGLE is
      CLIPostfixCodeCompile(self, left, right, "logicalLess");
      endCase
    case operator = TR_ANGLE is
      CLIPostfixCodeCompile(self, left, right, "logicalGreater");
      endCase
    case operator = TLESS_EQ is
      CLIPostfixCodeCompile(self, left, right, "logicalLessEq");
      endCase
    case operator = TGREATER_EQ is
      CLIPostfixCodeCompile(self, left, right, "logicalGreaterEq");
      endCase
    case operator = TLOG_AND is
      CLIPostfixCodeCompile(self, left, right, "logicalAnd");
      endCase
    case operator = TLOG_OR is
      CLIPostfixCodeCompile(self, left, right, "logicalOr");
      endCase
   /* no straight operator mapping */
    case operator = TLSHIFT is
      CLIPostfixCodeCompile(self, left, right, "primLeftShift");
      endCase;
    case operator = TRSHIFT is
      CLIPostfixCodeCompile(self, left, right, "primRightShift");
      endCase;
    default
      errorMessage := getFormattedError(ErrorTextLibClass$Inst, 
         ER_CLI_INTERNAL_ERROR, "CLIBinaryNode:CLICodeCompile", nil, nil);
      syntaxError(self, nil, errorMessage);
      /* syntaxError unravels call stack, and does not return */
  endSelect;
}!!

/* Compile the infix-style node into Actor source. */
Def CLIInfixCodeCompile(self, left, right, op)
{
  CLICodeCompile(left);
  CLICodeCompile(op);
  CLICodeCompile(right);
}!!

/* Compile the postfix-style node into Actor source. */
Def CLIPostfixCodeCompile(self, left, right, op)
{
  CLICodeCompile(op);
  CLICodeCompile("(self,");
  CLICodeCompile(left);
  CLICodeCompile(",");
  CLICodeCompile(right);
  CLICodeCompile(")");
}!!

Def init(self, l, r, o)
{
  left := l;
  right := r;
  operator := o;
}!!
