|
Enhanced C#
Loyc library documentation
|
Contains Precedence objects that represent the precedence rules of EC#. More...
Contains Precedence objects that represent the precedence rules of EC#.
This precedence table uses the immiscibility concept represented by the Precedence.Lo and Precedence.Hi properties. When printing an expression, we avoid emitting x | y == z because the ranges of == and | overlap. Instead EcsNodePrinter prints @`'|`(x, y == z). Admittedly this is rather ugly, but you can enable the ILNodePrinterOptions.AllowChangeParentheses option, which allows parenthesis to be added so that a Loyc tree with the structure @`'|`(x, y == z) is emitted as x | (y == z), even though the latter is a slightly different tree.
Most of the operators use a range of two adjacent numbers, e.g. 10..11. This represents a couple of ideas for future use in a compiler that allows you to define new operators; one idea is, you could give new operators the "same" precedence as existing operators, but make them immiscible with those operators... yet still make them miscible with another new operator. For instance, suppose you define two new operators glob and fup with PrecedenceRange 41..41 and 40..40 respectively. Then neither can be mixed with + and -, but they can be mixed with each other and fup has higher precedence. Maybe this is not very useful, but hey, why not? If simply incrementing a number opens up new extensibility features, I'm happy to do it. (I could have used a non-numeric partial ordering system to do the same thing, but it would have been more complex, and of questionable value.)
Public static fields | |
| static readonly Precedence | Substitute = new Precedence(106, 105, 105, 106) |
| static readonly Precedence | Of = new Precedence(102) |
| List<T> | |
| static readonly Precedence | Primary = new Precedence(100) |
| static readonly Precedence | NullDot = new Precedence(99) |
Officially the ?. operator (and its weird ternary cousin ?[...]) does not have its own precedence level, but we can infer it exists: plain C# returns null for the expression ((string)null)?.Trim().Length, and throws an exception for (((string)null)?.Trim()).Length. Its cousin ?[...] behaves similarly: ((string)null)?[5].ToString() is null, while (((string)null)?[5]).ToString() is "" (because ((char?)null).ToString() returns ""). More... | |
| static readonly Precedence | Prefix = new Precedence(91, 90, 90, 91) |
| static readonly Precedence | Power = new Precedence(85) |
| ** (tentatively left-associative) | |
| static readonly Precedence | Range = new Precedence(80) |
| .. | |
| static readonly Precedence | Forward = new Precedence(78) |
| ==> x | |
| static readonly Precedence | Switch = new Precedence(75) |
| with, switch | |
| static readonly Precedence | Multiply = new Precedence(70) |
| *, /, % | |
| static readonly Precedence | Add = new Precedence(60) |
| +, -, ~ | |
| static readonly Precedence | Shift = new Precedence(56, 56, 56, 70) |
| |
| static readonly Precedence | Backtick = new Precedence(46, 72, 45, 73) |
custom operator (immiscible with * / + - << >> ..) | |
| static readonly Precedence | Compare3Way = new Precedence(42) |
| <=> | |
| static readonly Precedence | Compare = new Precedence(40) |
| < > <= >= | |
| static readonly Precedence | Is = new Precedence(40, 42, 40, 40) |
| is | |
| static readonly Precedence | AsUsing = new Precedence(40, 99, 40, 40) |
| as using (casts) | |
| static readonly new Precedence | Equals = new Precedence(38) |
| == != in | |
| static readonly Precedence | AndBits = new Precedence(32, 32, 32, 45) |
| & (^ and | should not be mixed with Compare/Equals | |
| static readonly Precedence | XorBits = new Precedence(30, 30, 32, 45) |
| ^ either, but the low-high system cannot express this | |
| static readonly Precedence | OrBits = new Precedence(28, 28, 32, 45) |
| | while allowing & ^ | to be mixed with each other.) | |
| static readonly Precedence | And = new Precedence(22) |
| && | |
| static readonly Precedence | Or = new Precedence(20) |
| || ^^ | |
| static readonly Precedence | OrIfNull = new Precedence(17) |
| ?? | |
| static readonly Precedence | PipeArrow = new Precedence(15) |
| |> ?|> |=> ?|=> | |
| static readonly Precedence | PatternNot = new Precedence(13) |
| not (right-hand side of is/switch only) | |
| static readonly Precedence | PatternAnd = new Precedence(12) |
| and (right-hand side of is/switch only) | |
| static readonly Precedence | PatternOr = new Precedence(11) |
| or (right-hand side of is/switch only) | |
| static readonly Precedence | IfElse = new Precedence(11, 10, 10, 11) |
| x ? y : z | |
| static readonly Precedence | WhenWhere = new Precedence(5) |
| when, where | |
| static readonly Precedence | Assign = new Precedence(26, 0, 0, 1) |
| = *= /= %= += -= <<= >>= &= ^= |= ??= ~= | |
| static readonly Precedence | Lambda = new Precedence(85, -1, -2, -1) |
| => | |
|
static |
Officially the ?. operator (and its weird ternary cousin ?[...]) does not have its own precedence level, but we can infer it exists: plain C# returns null for the expression ((string)null)?.Trim().Length, and throws an exception for (((string)null)?.Trim()).Length. Its cousin ?[...] behaves similarly: ((string)null)?[5].ToString() is null, while (((string)null)?[5]).ToString() is "" (because ((char?)null).ToString() returns "").
|
static |
|
static |
x.y x::y x=:y x->y f(x) x(->y) a[x] x++ x– typeof() checked() unchecked() new
1.8.7