Created
June 30, 2020 21:42
-
-
Save devsnek/45cfb143ecca5861c210de2338444642 to your computer and use it in GitHub Desktop.
This file contains 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
diff --git a/src/intrinsics/ArrayPrototype.mjs b/src/intrinsics/ArrayPrototype.mjs | |
index f6be4d6..c0f658f 100644 | |
--- a/src/intrinsics/ArrayPrototype.mjs | |
+++ b/src/intrinsics/ArrayPrototype.mjs | |
@@ -563,6 +563,7 @@ export function BootstrapArrayPrototype(realmRec) { | |
); | |
proto.DefineOwnProperty(wellKnownSymbols.iterator, proto.GetOwnProperty(new Value('values'))); | |
+ proto.DefineOwnProperty(wellKnownSymbols.slice, proto.GetOwnProperty(new Value('slice'))); | |
{ | |
const unscopableList = OrdinaryObjectCreate(Value.null); | |
diff --git a/src/intrinsics/StringPrototype.mjs b/src/intrinsics/StringPrototype.mjs | |
index 1d43716..cf3afb7 100644 | |
--- a/src/intrinsics/StringPrototype.mjs | |
+++ b/src/intrinsics/StringPrototype.mjs | |
@@ -718,5 +718,7 @@ export function BootstrapStringPrototype(realmRec) { | |
[wellKnownSymbols.iterator, StringProto_iterator, 0], | |
]); | |
+ X(proto.DefineOwnProperty(wellKnownSymbols.slice, proto.GetOwnProperty(new Value('slice')))); | |
+ | |
realmRec.Intrinsics['%String.prototype%'] = proto; | |
} | |
diff --git a/src/parser/ExpressionParser.mjs b/src/parser/ExpressionParser.mjs | |
index 176289b..4a1b7fe 100644 | |
--- a/src/parser/ExpressionParser.mjs | |
+++ b/src/parser/ExpressionParser.mjs | |
@@ -436,9 +436,21 @@ export class ExpressionParser extends FunctionParser { | |
this.next(); | |
node.MemberExpression = result; | |
node.IdentifierName = null; | |
- node.Expression = this.parseExpression(); | |
- result = this.finishNode(node, 'MemberExpression'); | |
+ if (this.eat(Token.COLON)) { | |
+ node.Expression_b = this.parseAssignmentExpression(); | |
+ } else { | |
+ const expression = this.parseExpression(); | |
+ if (expression.type !== 'CommaOperator' && this.eat(Token.COLON)) { | |
+ node.Expression_a = expression; | |
+ if (!this.test(Token.RBRACK)) { | |
+ node.Expression_b = this.parseAssignmentExpression(); | |
+ } | |
+ } else { | |
+ node.Expression = expression; | |
+ } | |
+ } | |
this.expect(Token.RBRACK); | |
+ result = this.finishNode(node, 'MemberExpression'); | |
break; | |
} | |
case Token.PERIOD: | |
diff --git a/src/runtime-semantics/MemberExpression.mjs b/src/runtime-semantics/MemberExpression.mjs | |
index 26c1c1b..857508f 100644 | |
--- a/src/runtime-semantics/MemberExpression.mjs | |
+++ b/src/runtime-semantics/MemberExpression.mjs | |
@@ -1,4 +1,10 @@ | |
-import { GetValue } from '../abstract-ops/all.mjs'; | |
+import { Value, wellKnownSymbols } from '../value.mjs'; | |
+import { | |
+ GetValue, | |
+ Call, | |
+ GetMethod, | |
+ ToObject, | |
+} from '../abstract-ops/all.mjs'; | |
import { Evaluate } from '../evaluator.mjs'; | |
import { Q } from '../completion.mjs'; | |
import { OutOfRange } from '../helpers.mjs'; | |
@@ -40,12 +46,33 @@ function* Evaluate_MemberExpression_IdentifierName({ strict, MemberExpression, I | |
// CallExpression : | |
// CallExpression `[` Expression `]` | |
// CallExpression `.` IdentifierName | |
-export function Evaluate_MemberExpression(MemberExpression) { | |
+export function* Evaluate_MemberExpression(MemberExpression) { | |
switch (true) { | |
+ case !!MemberExpression.Expression_a || !!MemberExpression.Expression_b: { | |
+ const baseReference = yield* Evaluate(MemberExpression.MemberExpression); | |
+ const baseValue = Q(GetValue(baseReference)); | |
+ let start; | |
+ if (MemberExpression.Expression_a) { | |
+ const startRef = yield* Evaluate(MemberExpression.Expression_a); | |
+ start = Q(GetValue(startRef)); | |
+ } else { | |
+ start = new Value(0); | |
+ } | |
+ let end; | |
+ if (MemberExpression.Expression_b) { | |
+ const endRef = yield* Evaluate(MemberExpression.Expression_b); | |
+ end = Q(GetValue(endRef)); | |
+ } else { | |
+ end = Value.undefined; | |
+ } | |
+ const base = Q(ToObject(baseValue)); | |
+ const method = Q(GetMethod(base, wellKnownSymbols.slice)); | |
+ return Q(Call(method, base, [start, end])); | |
+ } | |
case !!MemberExpression.Expression: | |
- return Evaluate_MemberExpression_Expression(MemberExpression); | |
+ return yield* Evaluate_MemberExpression_Expression(MemberExpression); | |
case !!MemberExpression.IdentifierName: | |
- return Evaluate_MemberExpression_IdentifierName(MemberExpression); | |
+ return yield* Evaluate_MemberExpression_IdentifierName(MemberExpression); | |
default: | |
throw new OutOfRange('Evaluate_MemberExpression', MemberExpression); | |
} | |
diff --git a/src/value.mjs b/src/value.mjs | |
index e06cb63..6d1fffc 100644 | |
--- a/src/value.mjs | |
+++ b/src/value.mjs | |
@@ -628,6 +628,7 @@ for (const name of [ | |
'matchAll', | |
'replace', | |
'search', | |
+ 'slice', | |
'species', | |
'split', | |
'toPrimitive', |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment