63 lines
2.2 KiB
JavaScript
63 lines
2.2 KiB
JavaScript
|
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
||
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
||
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
||
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
||
|
};
|
||
|
var _Visitor_instances, _Visitor_getNode;
|
||
|
import * as Nodes from './nodes/index.js';
|
||
|
export default class Visitor {
|
||
|
constructor() {
|
||
|
_Visitor_instances.add(this);
|
||
|
this.scope = new Map();
|
||
|
this.listeners = {};
|
||
|
this.ast = [];
|
||
|
}
|
||
|
setAST(ast) {
|
||
|
this.ast = ast;
|
||
|
}
|
||
|
run() {
|
||
|
let result;
|
||
|
for (const node of this.ast) {
|
||
|
result = this.visitNode(node);
|
||
|
}
|
||
|
return result;
|
||
|
}
|
||
|
/**
|
||
|
* Visits a given node and executes it.
|
||
|
*/
|
||
|
visitNode(node) {
|
||
|
if (!node)
|
||
|
return null;
|
||
|
const target_node = __classPrivateFieldGet(this, _Visitor_instances, "m", _Visitor_getNode).call(this, node.type);
|
||
|
if (target_node) {
|
||
|
const instance = new target_node(node, this);
|
||
|
return instance.run();
|
||
|
}
|
||
|
}
|
||
|
/**
|
||
|
* Gets the name of a node.
|
||
|
* @param node - The target node.
|
||
|
*/
|
||
|
getName(node) {
|
||
|
if (node.type === 'Identifier')
|
||
|
return node.name;
|
||
|
else if (node.type === 'Literal')
|
||
|
return node.value;
|
||
|
}
|
||
|
/**
|
||
|
* Listens for node calls. Can be used to override default behavior or add new functionality.
|
||
|
* @param node_name - The node to listen for.
|
||
|
* @param listener - The callback function.
|
||
|
*/
|
||
|
on(node_name, listener) {
|
||
|
this.listeners[node_name] = listener;
|
||
|
}
|
||
|
}
|
||
|
_Visitor_instances = new WeakSet(), _Visitor_getNode = function _Visitor_getNode(type) {
|
||
|
const node = Nodes[type];
|
||
|
if (!node) {
|
||
|
console.warn('[JINTER]:', `JavaScript node "${type}" not implemented!\nIf this is causing unexpected behavior, please report it at https://github.com/LuanRT/Jinter/issues/new`);
|
||
|
}
|
||
|
return node;
|
||
|
};
|