Skip to content

Commit

Permalink
refactor!: overhaul interpreter (#3)
Browse files Browse the repository at this point in the history
* feat: use ESTree for the AST types

* feat: implement all update, unary, logical and assignment operators

* chore: update remaining nodes

* chore: update examples and tests

* chore: remove trailing spaces

* feat: add support for arrow functions

* chore: update readme and bump deps
  • Loading branch information
LuanRT authored Feb 10, 2023
1 parent 49e3d0c commit 3b5e56e
Show file tree
Hide file tree
Showing 47 changed files with 2,086 additions and 1,327 deletions.
35 changes: 16 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
[actions]: https://github.com/LuanRT/Jinter/actions
[say-thanks]: https://saythanks.io/to/LuanRT

<h1 align=center>
Jinter
</h1>
<h1 align=center>Jinter</h1>

<p align=center>
<i>A tiny JavaScript interpreter written in TypeScript</i>
</p>
<p align=center>A tiny JavaScript interpreter written in TypeScript

<div align="center">

Expand All @@ -16,7 +12,7 @@

</div>

> **Note**: This project is experimental and not all JavaScript features are implemented! [^1]
> **Note**: This project was originally developed for use in [YouTube.js](https://github.com/LuanRT/YouTube.js).
### Usage

Expand All @@ -37,38 +33,39 @@ const jinter = new Jinter(code);
jinter.interpret();
```
---
Inject your own functions and variables into the interpreter;
Inject your own functions and variables into the interpreter:
```ts
// ...

jinter.visitor.on('println', (node: any, visitor: Visitor) => {
const args = node.arguments.map((arg: any) => visitor.visitNode(arg));
return console.log(...args);
jinter.visitor.on('println', (node, visitor) => {
if (node.type === 'CallExpression' && node.callee.type === 'MemberExpression') {
const args = node.arguments.map((arg) => visitor.visitNode(arg));
return console.log(...args);
}
});

// Ex: str.toArray();
jinter.visitor.on('toArray', (node: any, visitor: Visitor) => {
const obj = visitor.visitNode(node.callee.object);
return obj.split('');
jinter.visitor.on('toArray', (node, visitor) => {
if (node.type === 'CallExpression' && node.callee.type === 'MemberExpression') {
const obj = visitor.visitNode(node.callee.object);
return obj.split('');
}
});

// Or you can just intercept access to specific nodes;
jinter.visitor.on('myFn', (node: any, visitor: Visitor) => {
jinter.visitor.on('myFn', (node, visitor) => {
console.info('MyFn node just got accessed:', node);
return 'proceed'; // tells the interpreter to continue execution
});

jinter.interpret();
```

More examples are available in the [`test`](/test) & [`examples`](/examples) folders.
For more examples see [`/test`](https://github.com/LuanRT/Jinter/tree/main/test) and [`/examples`](https://github.com/LuanRT/Jinter/tree/main/examples).

## License
Distributed under the [MIT](https://choosealicense.com/licenses/mit/) License.

<!-- Footnotes -->
[^1]: This project was originally developed for use in [YouTube.js](https://github.com/LuanRT/YouTube.js).

<p align="right">
(<a href="#top">back to top</a>)
</p>
21 changes: 9 additions & 12 deletions acorn.d.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import * as ESTree from 'estree';

declare module 'acorn' {
export function parse(s: string, o: Options): ESTree.Program;
type ExtendNode<T> = {
[K in keyof T]: T[K] extends object ? ExtendNode<T[K]> : T[K];
} & (T extends ESTree.Node
? {
start: number;
end: number;
}
: unknown);

// fix type of Comment property 'type'
export type AcornComment = Omit<Comment, 'type'> & {
type: 'Line' | 'Block';
};
}

declare module 'estree' {
interface BaseNodeWithoutComments {
start: number;
end: number;
}
export function parse(s: string, o: Options): ExtendNode<ESTree.Program>;
}
10 changes: 10 additions & 0 deletions examples/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import fs from 'fs';
import Jinter from '../dist';

const code = fs.readFileSync('./test-code.js').toString();

const jinter = new Jinter(code);
jinter.scope.set('ntoken', 'vPIcacaohWtfY_');
const result = jinter.interpret();

console.info('Transformed sig:', result);
179 changes: 0 additions & 179 deletions examples/ncode.js

This file was deleted.

Loading

0 comments on commit 3b5e56e

Please sign in to comment.