forked from tc39/proposal-pipeline-operator
-
Notifications
You must be signed in to change notification settings - Fork 0
/
spec.html
81 lines (76 loc) · 4.49 KB
/
spec.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<!doctype html>
<meta charset="utf8">
<pre class=metadata>
title: Pipeline operator
stage: 0
contributors: Daniel Ehrenberg
</pre>
<emu-intro id=sec-intro>
<h1>Introduction</h1>
<p>This document specifies the pipeline operator `|>`. See <a href="https://github.com/tc39/proposal-pipeline-operator/">the explainer</a> for an introduction.</p>
<p>The main design decisions made in this specification are:
<ol>
<li>The right argument of `|>` is treated directly as a function; even if it is a |CallExpression|, the result of evaluating that |CallExpression| is treated as the function, rather than slotting the left argument into the arguments list. That is `x |> y(z)` is similar in semantics to `y(z)(x)`. <a href="https://github.com/tc39/proposal-pipeline-operator/issues/4">bug</a></li>
<li>The precedence of `|>` sits between the ternary operator and `||`. It is left-associative. <a href="https://github.com/tc39/proposal-pipeline-operator/issues/23">bug</a></li>
<li>All calls to `eval` are indirect eval.</li>
<li>The pipeline operator is eligible for proper tail calls, when appropriate.</li>
<li>The left argument to `|>` is evaluated before the right one.</li>
<li>If the right argument to `|>` has a receiver, it is used for the call, with rules similar to a method call. That is `x |> y.z` gets `y` as a receiver, just as if it were written `y.z(x)`.</li>
</ol>
</p>
</emu-intro>
<emu-clause id=sec-pipeline-syntax>
<h1>Syntax</h1>
<emu-grammar>
ConditionalExpression[In, Yield, Await] :
<del>LogicalORExpression[?In, ?Yield, ?Await]</del>
<del>LogicalORExpression[?In, ?Yield, ?Await] `?` AssignmentExpression[+In, ?Yield, ?Await] `:` AssignmentExpression[?In, ?Yield, ?Await]</del>
<ins>PipelineExpression[?In, ?Yield, ?Await]</ins>
<ins>PipelineExpression[?In, ?Yield, ?Await] `?` AssignmentExpression[+In, ?Yield, ?Await] `:` AssignmentExpression[?In, ?Yield, ?Await]</ins>
<ins>
PipelineExpression[In, Yield, Await] :
LogicalORExpression[?In, ?Yield, ?Await]
PipelineExpression[?In, ?Yield, ?Await] `|>` LogicalORExpression[?In, ?Yield, ?Await]
</ins>
</emu-grammar>
</emu-clause>
<emu-clause id=sec-pipeline-semantics>
<h1>Semantics</h1>
<emu-clause id=sec-pipeline-evaluation>
<h1>Runtime Semantics: Evaluation</h1>
<emu-grammar>PipelineExpression : PipelineExpression '|>` LogicalORExpression</emu-grammar>
<emu-alg>
1. Let _argRef_ be the result of evaluating |PipelineExpression|.
1. Let _arg_ be ? GetValue(_argRef_).
1. Let _funcRef_ be the result of evaluating |LogicalORExpression|.
1. Let _func_ be ? GetValue(_funcRef_).
1. If Type(_funcRef_) is Reference, then
1. If IsPropertyReference(_funcRef_) is *true*, then
1. Let _thisValue_ be GetThisValue(_funcRef_).
1. Else the base of _funcRef_ is an Environment Record,
1. Let _refEnv_ be GetBase(_funcRef_).
1. Let _thisValue_ be _refEnv_.WithBaseObject().
1. Else Type(_funcRef_) is not Reference,
1. Let _thisValue_ be *undefined*.
1. If Type(_func_) is not Object, throw a *TypeError* exception.
1. If IsCallable(_func_) is *false*, throw a *TypeError* exception.
1. Let _thisCall_ be this outer |PipelineExpression|.
1. Let _tailPosition_ be IsInTailPosition(_thisCall_).
1. If _tailPosition_ is *true*, perform PrepareForTailCall().
1. Let _result_ be Call(_func_, _thisValue_, « _arg_ »).
1. Assert: If _tailPosition_ is *true*, the above call will not return here, but instead evaluation will continue as if the following return has already occurred.
1. Assert: If _result_ is not an abrupt completion, then Type(_result_) is an ECMAScript language type.
1. Return _result_.
</emu-alg>
<emu-note>All calls to eval from a pipeline operator are indirect eval calls.</emu-note>
<emu-note type="editor">This definition is somewhat duplicated from the definition of evaluating CallExpression; when merging with the main specification, a refactoring will be done to de-duplicate it.</emu-note>
</emu-clause>
<emu-clause id=sec-pipeline-has-call-in-tail-position>
<h1>Static Semantics: HasCallInTailPosition</h1>
<emu-grammar>PipelineExpression : PipelineExpression '|>` LogicalORExpression</emu-grammar>
<emu-alg>
1. If this outer |PipelineExpression| is _call_, return *true*.
1. Return *false*.
</emu-alg>
</emu-clause>
</emu-clause>