_start = 0;
_topOperator = 0;
- _ops[_topOperator++] = new OperatorInfo(Nodes.Noop, Operators.Noop, Operators.priStart);
+ _ops[_topOperator++] = new OperatorInfo(Nodes.Noop, Operators.Noop, Operators.PriStart);
}
// CONSIDER: configure the scanner : local info
throw ExprException.MissingOperand(opInfo);
}
// collect all nodes
- BuildExpression(Operators.priLow);
+ BuildExpression(Operators.PriLow);
if (_topOperator != 1)
{
throw ExprException.MissingRightParen();
node = new FunctionNode(_table, "In");
NodePush(node);
/* Push operator decriptor */
- _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.priParen);
+ _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.PriParen);
}
else
{ /* Normal ( */
/* Push operator decriptor */
- _ops[_topOperator++] = new OperatorInfo(Nodes.Paren, Operators.Noop, Operators.priParen);
+ _ops[_topOperator++] = new OperatorInfo(Nodes.Paren, Operators.Noop, Operators.PriParen);
}
}
else
// This is a procedure call or () qualification
// Force out any dot qualifiers; check for bomb
- BuildExpression(Operators.priProc);
+ BuildExpression(Operators.PriProc);
_prevOperand = Empty;
ExpressionNode? nodebefore = NodePeek();
}
NodePush(node);
- _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.priParen);
+ _ops[_topOperator++] = new OperatorInfo(Nodes.Call, Operators.Noop, Operators.PriParen);
}
goto loop;
/* Right parentheses: Build expression if we have an operand. */
if (_prevOperand != Empty)
{
- BuildExpression(Operators.priLow);
+ BuildExpression(Operators.PriLow);
}
/* We must have Tokens.LeftParen on stack. If no operand, must be procedure call. */
throw ExprException.MissingOperand(opInfo);
}
- Debug.Assert(opInfo._priority == Operators.priParen, "melformed operator stack.");
+ Debug.Assert(opInfo._priority == Operators.PriParen, "melformed operator stack.");
if (opInfo._type == Nodes.Call)
{
/* We are be in a procedure call */
/* build next argument */
- BuildExpression(Operators.priLow);
+ BuildExpression(Operators.PriLow);
opInfo = _ops[_topOperator - 1];
}
// PushOperator descriptor
- _ops[_topOperator++] = new OperatorInfo(Nodes.Zop, _op, Operators.priMax);
+ _ops[_topOperator++] = new OperatorInfo(Nodes.Zop, _op, Operators.PriMax);
_prevOperand = Expr;
goto loop;
{
ExpressionNode? expr;
- Debug.Assert(pri > Operators.priStart && pri <= Operators.priMax, "Invalid priority value");
+ Debug.Assert(pri > Operators.PriStart && pri <= Operators.PriMax, "Invalid priority value");
/* For all operators of higher or same precedence (we are always
left-associative) */
/// <summary>
/// Operator priorities
/// </summary>
- internal const int priStart = 0;
- internal const int priSubstr = 1;
- internal const int priParen = 2;
- internal const int priLow = 3;
- internal const int priImp = 4;
- internal const int priEqv = 5;
- internal const int priXor = 6;
- internal const int priOr = 7;
- internal const int priAnd = 8;
- internal const int priNot = 9;
- internal const int priIs = 10;
- internal const int priBetweenInLike = 11;
- internal const int priBetweenAnd = 12;
- internal const int priRelOp = 13;
- internal const int priConcat = 14;
- internal const int priContains = 15;
- internal const int priPlusMinus = 16;
- internal const int priMod = 17;
- internal const int priIDiv = 18;
- internal const int priMulDiv = 19;
- internal const int priNeg = 20;
- internal const int priExp = 21;
- internal const int priProc = 22;
- internal const int priDot = 23;
- internal const int priMax = 24;
-
- /// <summary>
- /// Mapping from Operator to priorities
- /// CONSIDER: fast, but hard to maintain
- /// </summary>
-
- private static readonly int[] s_priority = new int[] {
- priStart, // Noop
- priNeg, priNeg, priNot, // Unary -, +, Not
- priBetweenAnd, priBetweenInLike, priBetweenInLike,
- priRelOp, priRelOp, priRelOp, priRelOp, priRelOp, priRelOp,
- priIs,
- priBetweenInLike, // Like
+ internal const byte PriStart = 0;
+ internal const byte PriSubstr = 1;
+ internal const byte PriParen = 2;
+ internal const byte PriLow = 3;
+ internal const byte PriImp = 4;
+ internal const byte PriEqv = 5;
+ internal const byte PriXor = 6;
+ internal const byte PriOr = 7;
+ internal const byte PriAnd = 8;
+ internal const byte PriNot = 9;
+ internal const byte PriIs = 10;
+ internal const byte PriBetweenInLike = 11;
+ internal const byte PriBetweenAnd = 12;
+ internal const byte PriRelOp = 13;
+ internal const byte PriConcat = 14;
+ internal const byte PriContains = 15;
+ internal const byte PriPlusMinus = 16;
+ internal const byte PriMod = 17;
+ internal const byte PriIDiv = 18;
+ internal const byte PriMulDiv = 19;
+ internal const byte PriNeg = 20;
+ internal const byte PriExp = 21;
+ internal const byte PriProc = 22;
+ internal const byte PriDot = 23;
+ internal const byte PriMax = 24;
+
+ /// <summary>Mapping from Operator to priorities.</summary>
+ internal static int Priority(int op)
+ {
+ ReadOnlySpan<byte> priorities = new byte[]
+ {
+ PriStart, // Noop
+ PriNeg, PriNeg, PriNot, // Unary -, +, Not
+ PriBetweenAnd, PriBetweenInLike, PriBetweenInLike,
+ PriRelOp, PriRelOp, PriRelOp, PriRelOp, PriRelOp, PriRelOp,
+ PriIs,
+ PriBetweenInLike, // Like
- priPlusMinus, priPlusMinus, // +, -
- priMulDiv, priMulDiv, priIDiv, priMod, // *, /, \, Mod
- priExp, // **
+ PriPlusMinus, PriPlusMinus, // +, -
+ PriMulDiv, PriMulDiv, PriIDiv, PriMod, // *, /, \, Mod
+ PriExp, // **
- priAnd, priOr, priXor, priNot,
- priAnd, priOr,
+ PriAnd, PriOr, PriXor, PriNot,
+ PriAnd, PriOr,
- priParen, priProc, priDot, priDot, // Proc, Iff, Qula, Dot..
+ PriParen, PriProc, PriDot, PriDot, // Proc, Iff, Qula, Dot..
- priMax, priMax, priMax, priMax, priMax, priMax, priMax,
- priMax, priMax, priMax, priMax,
- priMax,
- };
+ // anything beyond is PriMax
+ };
- internal static int Priority(int op)
- {
- if ((uint)op >= (uint)s_priority.Length)
- return priMax;
- return s_priority[op];
+ return (uint)op < (uint)priorities.Length ? priorities[op] : PriMax;
}
/// <summary>