private void BuildExpression(int pri)
{
ExpressionNode expr = null;
Debug.Assert(pri > Operators.priStart && pri <= Operators.priMax, "Invalid priority value");
/* For all operators of higher or same precedence (we are always
left-associative) */
while (true)
{
Debug.Assert(_topOperator > 0, "Empty operator stack!!");
OperatorInfo opInfo = _ops[_topOperator - 1];
if (opInfo._priority < pri)
goto end_loop;
Debug.Assert(opInfo._priority >= pri, "Invalid prioriry value");
_topOperator--;
ExpressionNode nodeLeft;
ExpressionNode nodeRight;
switch (opInfo._type)
{
case Nodes.Binop:
{
// get right, left operands. Bind them.
nodeRight = NodePop();
nodeLeft = NodePop();
/* This is the place to do type and other checks */
switch (opInfo._op)
{
case Operators.Between:
case Operators.BetweenAnd:
case Operators.BitwiseAnd:
case Operators.BitwiseOr:
case Operators.BitwiseXor:
case Operators.BitwiseNot:
throw ExprException.UnsupportedOperator(opInfo._op);
case Operators.Is:
case Operators.Or:
case Operators.And:
case Operators.EqualTo:
case Operators.NotEqual:
case Operators.Like:
case Operators.LessThen:
case Operators.LessOrEqual:
case Operators.GreaterThen:
case Operators.GreaterOrEqual:
case Operators.In:
break;
default:
Debug.Assert(opInfo._op == Operators.Plus ||
opInfo._op == Operators.Minus ||
opInfo._op == Operators.Multiply ||
opInfo._op == Operators.Divide ||
opInfo._op == Operators.Modulo,
"Invalud Binary operation");
break;
}
Debug.Assert(nodeLeft != null, "Invalid left operand");
Debug.Assert(nodeRight != null, "Invalid right operand");
if (opInfo._op == Operators.Like)
{
expr = new LikeNode(_table, opInfo._op, nodeLeft, nodeRight);
}
else
{
expr = new BinaryNode(_table, opInfo._op, nodeLeft, nodeRight);
}
break;
}
case Nodes.Unop:
/* Unary operator: Pop and bind right op. */
nodeLeft = null;
nodeRight = NodePop();
/* Check for special cases */
switch (opInfo._op)
{
case Operators.Not:
break;
case Operators.BitwiseNot:
throw ExprException.UnsupportedOperator(opInfo._op);
case Operators.Negative:
break;
}
Debug.Assert(nodeLeft == null, "Invalid left operand");
Debug.Assert(nodeRight != null, "Invalid right operand");
expr = new UnaryNode(_table, opInfo._op, nodeRight);
break;
case Nodes.Zop:
/* Intrinsic constant: just create node. */
expr = new ZeroOpNode(opInfo._op);
break;
default:
Debug.Assert(false, "Unhandled operator type");
goto end_loop;
}
Debug.Assert(expr != null, "Failed to create expression");
NodePush(expr);
// countinue while loop;
}
end_loop:
;
}