Last active
August 29, 2015 14:02
-
-
Save kl0tl/3b9a283a4d18753604d3 to your computer and use it in GitHub Desktop.
Existential operator `?`
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| `a?()` | |
| Call its operand only if it is defined and a `function`, returns `undefined` otherwise | |
| `a?.b` or `a?['b']` | |
| Access a property on its operand only if it is defined and not `null` nor `undefined`, returns `undefined` otherwise | |
| `a ?= b` | |
| Assign its right operand to its left operand only if the later is defined, not `null` nor `undefined` and returns the value, or `undefined` otherwise | |
| `a ?? b` | |
| Returns its left operand only if it is defined and not `null` nor `undefined`, or its right operand otherwise | |
| `a?` | |
| Returns `true` only if its operand is defined and not `null` nor `undefined` | |
| Besides `?=` all existential operators can safely be used with undeclared variables | |
| */ | |
| macro function_arguments { | |
| rule { ($argument:expr (,) ...) } | |
| } | |
| macro property_accessor { | |
| rule { . $property:ident } | |
| rule { [ $property:expr ] } | |
| } | |
| macro guard { | |
| rule { $symbol:ident } => { | |
| typeof $symbol === 'undefined' ? null : $symbol | |
| } | |
| } | |
| let ? = macro { | |
| /* TODO | |
| rule infix { $symbol | $arguments:function_arguments $(? $next_arguments:function_arguments) ... } => { | |
| (typeof $symbol === 'function' ? function (ref) { | |
| return $((typeof ref) !== 'function' ? undefined : | |
| ref = ref $next_arguments) (,) ... | |
| }($symbol $arguments) : undefined) | |
| }//*/ | |
| rule infix { $symbol:ident | $arguments:function_arguments } => { | |
| (typeof $symbol === 'function' ? $symbol $arguments : undefined) | |
| } | |
| rule infix { $expression:expr | $arguments:function_arguments } => { | |
| (function (ref) { | |
| if (typeof ref === 'function') { | |
| return ref $arguments | |
| } | |
| }($expression)) | |
| } | |
| rule infix { $symbol:ident | . $head:ident ?. $($($next:ident ?) (.) ...) $tail:ident } => { | |
| (function (ref) { | |
| return (ref === null ? undefined : | |
| (ref = ref.$head) == null ? undefined : | |
| $((ref = ref.$next) == null ? undefined :) ... | |
| ref) === undefined ? undefined : ref.$tail | |
| }(guard $symbol)) | |
| } | |
| rule infix { $expression:expr | . $head:ident ?. $($($next:ident ?) (.) ...) $tail:ident } => { | |
| (function (ref) { | |
| return (ref == null ? undefined : | |
| (ref = ref.$head) == null ? undefined : | |
| $((ref = ref.$next) == null ? undefined :) ... | |
| ref) === undefined ? undefined : ref.$tail | |
| }($expression)) | |
| } | |
| rule infix { $symbol:ident | $property:property_accessor } => { | |
| (function (ref) { | |
| return ref == null ? undefined : ref $property | |
| }(guard $symbol)) | |
| } | |
| rule infix { $expression:expr | $property:property_accessor } => { | |
| (function (ref) { | |
| return ref == null ? undefined : ref $property | |
| }($expression)) | |
| } | |
| rule infix { $symbol:ident | = $value:expr } => { | |
| ($symbol == null ? $symbol = $value : $symbol) | |
| } | |
| rule infix { $left:ident | ? $right:expr } => { | |
| (function (left, right) { | |
| return left === null ? right : left; | |
| }(guard $left, $right)) | |
| } | |
| rule infix { $left:expr | ? $right:expr } => { | |
| (function (left, right) { | |
| return left == null ? right : left; | |
| }($left, $right)) | |
| } | |
| rule infix { $cond:expr | $then:expr : $else:expr } => { | |
| ($cond ? $then : $else) | |
| } | |
| rule infix { $operand:ident | } => { | |
| (guard $operand) | |
| } | |
| rule infix { $operand:expr | } => { | |
| ($operand != null) | |
| } | |
| } | |
| export ?; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment