# Expressions
## Literal Expression
Literal expressions are as the name suggests expressions consisting of solely of literal types `number`, `bigint` and `String`.
## Identifier Expression
Identifiers start with ASCII underscore or alphabetic character and are followed by ASCII underscore or alphanumeric characters. Except any of the keywords.
```
Alpha ::= [A-Za-Z]
AlphaNum ::= [A-Za-Z0-9]
## Precedence and Associativity of Expressions
| 18 | ✅ | Grouping | N/A | `(x + y)` |
| 17 | ❌ | Member Access | Left-to-right | `object.property` |
| 16 | ❌ | Namespace Access | Left-to-right | `module::property` |
| | ❌ | Computed Member Access | Left-to-right | `object["property"]` |
| | ❌ | Function Call | Left-to-right | `myFunction(arg1, arg2)` |
| 15 | ✅ | Try Operator | Left-to-right | `object?` |
| 14 | ✅ | Logical NOT | Right-to-left | `!x` |
| | ✅ | Bitwise NOT | Right-to-left | `~x` |
| | ✅ | Unary Plus/Minus | Right-to-left | `+x`, `-x` |
| 13 | ✅ | Exponentiation | Right-to-left | `x ** y` |
| 12 | ✅ | Multiplication/Division/Modulo | Left-to-right | `x * y`, `x / y`, `x % y` |
| 11 | ✅ | Addition/Subtraction | Left-to-right | `x + y`, `x - y` |
| 10 | ✅ | Bitwise Shift | Left-to-right | `x << y`, `x >> y` |
| 9 | ✅ | Relational | Left-to-right | `x < y`, `x > y`, `x <= y`, `x >= y` |
| 8 | ✅ | Equality | Left-to-right | `x == y`, `x != y` |
| 7 | ✅ | Bitwise AND | Left-to-right | `x & y` |
| 6 | ✅ | Bitwise XOR | Left-to-right | `x ^ y` |
| 5 | ✅ | Bitwise OR | Left-to-right | `x \| y` |
| 4 | ✅ | Logical AND | Left-to-right | `x && y` |
| 3 | ✅ | Logical OR | Left-to-right | `x \|\| y` |
| 2 | ✅ | Pipe | Left-to-Right | `x \|> f \|> g ` |
| 1 | ❌ | Conditional (Ternary) | Right-to-left | `condition ? expr1 : expr2` |
### Notes
- BlanketScript equality operators `==` and `!=` map to `===` and `!==` respectively. Coalescing equality operators in ECMAScript are not supported.
- Comma operator is removed, `let a = (1, 2, 3);` creates a tuple and compiles down to `[1, 2, 3]`, instead of returning `3`.
- Assignment isn't an expression in BlanketScript, `let b = (a = 5);` is a syntax error.
- `instanceof` and `typeof` are replaced by function `instanceOf` and `typeOf` functions.
- Example `typeOf(42)` evaluates to `Builtins::Number`
- `in` is replaced with `Object::hasProperty`, for example `"a" in obj` is equivalent to `Object::hasProperty(obj, "a")`
- `delete` and `void` expressions are removed.
- Pipe operator `|>` passes left side of the expression to last argument of function expression.
- Example: `x |> (n) => n ** 2` is equal to `let anon = n => n ** 2; anon(x)`
- Example: `x |> map((n) => n ** 2)` is equal to `map(n => n ** 2, x)`
- Example: `[1, 2, 3] |> filter(n => n % 2 == 0) |> map(n => n ** 2)` is equal to `map((n) => n ** 2, filter(n => n % 2 == 0, [1, 2, 3]))`
- Nullish coalescing operator is removed as BlanketScript doesn't have nullable types. Instead it has postfix `?` operator for early returns for `Result` and `Option` types.