( expr: Expression | undefined )
| 109 | * to a `["Function"]` expression with anonymous parameters |
| 110 | * 2/ A `Block` scope is created |
| 111 | * 3/ The function parameters are declared in the Block's scope |
| 112 | * 4/ The function body is canonicalized in the context of the scope. |
| 113 | * The Block's localScope captures the defining scope as its parent. |
| 114 | * |
| 115 | * |
| 116 | * #### DURING EVALUATION (executing the result of makeLambda()) |
| 117 | * |
| 118 | * 1/ The arguments are evaluated in the **calling** scope |
| 119 | * 2/ A fresh scope is created per call, with parent = the **defining** |
| 120 | * scope (body.localScope.parent), giving true lexical scoping |
| 121 | * 3/ The function parameters are declared in the fresh scope |
| 122 | * 4/ body.localScope is temporarily re-parented to chain through the |
| 123 | * fresh scope: bigOpScope → bodyScope → freshScope → capturedScope. |
| 124 | * Param bindings in bodyScope (stale, from canonicalization) are |
| 125 | * temporarily hidden so they don't shadow freshScope's values. |
| 126 | * This lets nested scoped expressions (Sum, Product) find params |
| 127 | * by walking up their static scope chain. |
| 128 | * 5/ The function body is evaluated in the context of the fresh scope |
| 129 | * 6/ If the result contains Function literals, they are rebound to |
| 130 | * close over the fresh scope (closure capture) |
| 131 | * 7/ The fresh scope is discarded; body.localScope.parent is restored |
| 132 | * 8/ The result is returned |
| 133 | * |
| 134 | */ |
| 135 | |
| 136 | /** |
| 137 | * From an expression, return a predicate function, which can be used to filter. |
| 138 | */ |
| 139 | export function predicate( |
| 140 | _expr: Expression |
| 141 | ): (...args: Expression[]) => boolean { |
| 142 | // @todo |
| 143 | return () => false; |
| 144 | } |
| 145 | |
| 146 | /** |
| 147 | * From an expression, create an ordering function, which can be used to sort. |
| 148 | */ |
| 149 | export function order( |
| 150 | _expr: Expression |
| 151 | ): (a: Expression, b: Expression) => -1 | 0 | 1 { |
| 152 | // @todo |
| 153 | // |
| 154 | // Default comparator |
| 155 | // |
| 156 | return (a: Expression, b: Expression) => { |
| 157 | const c = cmp(a, b); |
| 158 | if (c === '=') return 0; |
| 159 | if (c === '<' || c === '<=') return -1; |
| 160 | return 1; |
| 161 | }; |
| 162 | } |
| 163 | |
| 164 | /** |
| 165 | * Given an expression, rewrite it to a symbol or canonical Function form. |
| 166 | * |
| 167 | * - symbol (no change): |
| 168 | * "Sin" |
no test coverage detected