mirror of
https://github.com/bendtherules/completion-viz.git
synced 2026-08-18 13:42:51 +00:00
Clone engine262 in /engine262
This commit is contained in:
@@ -0,0 +1,163 @@
|
||||
# engine262
|
||||
|
||||
An implementation of ECMA-262 in JavaScript
|
||||
|
||||
Goals
|
||||
- 100% Spec Compliance
|
||||
- Introspection
|
||||
- Ease of modification
|
||||
|
||||
Non-Goals
|
||||
- Speed at the expense of any of the goals
|
||||
|
||||
This project is bound by a [Code of Conduct][COC].
|
||||
|
||||
Join us on [#engine262 on freenode][irc] ([web][irc-webchat]).
|
||||
|
||||
## Why this exists
|
||||
|
||||
While helping develop new features for JavaScript, I've found that one of the
|
||||
most useful methods of finding what works and what doesn't is being able to
|
||||
actually run code using the new feature. [Babel][] is fantastic for this, but
|
||||
sometimes features just can't be nicely represented with it. Similarly,
|
||||
implementing a feature in one of the engines is a large undertaking, involving
|
||||
long compile times and annoying bugs with the optimizing compilers.
|
||||
|
||||
engine262 is a tool to allow JavaScript developers to have a sandbox where new
|
||||
features can be quickly prototyped and explored. As an example, adding
|
||||
[do expressions][] to this engine is as simple as the following diff:
|
||||
|
||||
```diff
|
||||
--- a/src/evaluator.mjs
|
||||
+++ b/src/evaluator.mjs
|
||||
@@ -232,6 +232,8 @@ export function* Evaluate(node) {
|
||||
case 'GeneratorBody':
|
||||
case 'AsyncGeneratorBody':
|
||||
return yield* Evaluate_AnyFunctionBody(node);
|
||||
+ case 'DoExpression':
|
||||
+ return yield* Evaluate_Block(node.Block);
|
||||
default:
|
||||
throw new OutOfRange('Evaluate', node);
|
||||
}
|
||||
--- a/src/parser/ExpressionParser.mjs
|
||||
+++ b/src/parser/ExpressionParser.mjs
|
||||
@@ -579,6 +579,12 @@ export class ExpressionParser extends FunctionParser {
|
||||
return this.parseRegularExpressionLiteral();
|
||||
case Token.LPAREN:
|
||||
return this.parseParenthesizedExpression();
|
||||
+ case Token.DO: {
|
||||
+ const node = this.startNode();
|
||||
+ this.next();
|
||||
+ node.Block = this.parseBlock();
|
||||
+ return this.finishNode(node, 'DoExpression');
|
||||
+ }
|
||||
default:
|
||||
return this.unexpected();
|
||||
}
|
||||
```
|
||||
|
||||
This simplicity applies to many other proposals, such as [optional chaining][],
|
||||
[pattern matching][], [the pipeline operator][], and more. This engine has also
|
||||
been used to find bugs in ECMA-262 and test262, the test suite for
|
||||
conforming JavaScript implementations.
|
||||
|
||||
## Requirements
|
||||
|
||||
To run engine262 itself, a engine with support for recent ECMAScript features
|
||||
is needed. Additionally, the CLI (`bin/engine262.js`) and test262 runner
|
||||
(`test/test262.js`) require a recent version of Node.js.
|
||||
|
||||
## Using engine262
|
||||
|
||||
Use it online: https://engine262.js.org
|
||||
|
||||
You can install the latest engine262 build from [GitHub Packages][].
|
||||
|
||||
If you install it globally, you can use the CLI like so:
|
||||
|
||||
`$ engine262`
|
||||
|
||||
Or, you can install it locally and use the API:
|
||||
|
||||
```js
|
||||
'use strict';
|
||||
|
||||
const {
|
||||
Agent,
|
||||
setSurroundingAgent,
|
||||
ManagedRealm,
|
||||
Value,
|
||||
|
||||
CreateDataProperty,
|
||||
|
||||
inspect,
|
||||
} = require('engine262');
|
||||
|
||||
const agent = new Agent({
|
||||
// onDebugger() {},
|
||||
// ensureCanCompileStrings() {},
|
||||
// hasSourceTextAvailable() {},
|
||||
// onNodeEvaluation() {},
|
||||
// features: [],
|
||||
});
|
||||
setSurroundingAgent(agent);
|
||||
|
||||
const realm = new ManagedRealm({
|
||||
// promiseRejectionTracker() {},
|
||||
// resolveImportedModule() {},
|
||||
// getImportMetaProperties() {},
|
||||
// finalizeImportMeta() {},
|
||||
// randomSeed() {},
|
||||
});
|
||||
|
||||
realm.scope(() => {
|
||||
// Add print function from host
|
||||
const print = new Value((args) => {
|
||||
console.log(...args.map((tmp) => inspect(tmp)));
|
||||
return Value.undefined;
|
||||
});
|
||||
CreateDataProperty(realm.GlobalObject, new Value('print'), print);
|
||||
});
|
||||
|
||||
realm.evaluateScript(`
|
||||
'use strict';
|
||||
|
||||
async function* numbers() {
|
||||
let i = 0;
|
||||
while (true) {
|
||||
const n = await Promise.resolve(i++);
|
||||
yield n;
|
||||
}
|
||||
}
|
||||
|
||||
(async () => {
|
||||
for await (const item of numbers()) {
|
||||
print(item);
|
||||
}
|
||||
})();
|
||||
`);
|
||||
|
||||
// a stream of numbers fills your console. it fills you with determination.
|
||||
```
|
||||
|
||||
## Related Projects
|
||||
|
||||
Many people and organizations have attempted to write a JavaScript interpreter
|
||||
in JavaScript much like engine262, with different goals. Some of them are
|
||||
included here for reference, though engine262 is not based on any of them.
|
||||
|
||||
- https://github.com/facebook/prepack
|
||||
- https://github.com/mozilla/narcissus
|
||||
- https://github.com/NeilFraser/JS-Interpreter
|
||||
- https://github.com/metaes/metaes
|
||||
- https://github.com/Siubaak/sval
|
||||
|
||||
[Babel]: https://babeljs.io/
|
||||
[COC]: https://github.com/engine262/engine262/blob/master/CODE_OF_CONDUCT.md
|
||||
[do expressions]: https://github.com/tc39/proposal-do-expressions
|
||||
[irc]: ircs://chat.freenode.net:6697/engine262
|
||||
[irc-webchat]: https://webchat.freenode.net/?channels=engine262
|
||||
[optional chaining]: https://github.com/tc39/proposal-optional-chaining
|
||||
[pattern matching]: https://github.com/tc39/proposal-pattern-matching
|
||||
[the pipeline operator]: https://github.com/tc39/proposal-pipeline-operator
|
||||
[GitHub Packages]: https://github.com/engine262/engine262/packages
|
||||
Reference in New Issue
Block a user