jintr
Version:
A tiny JavaScript interpreter written in TypeScript.
49 lines (48 loc) • 1.99 kB
JavaScript
import BaseJSNode from './BaseJSNode.js';
export default class AssignmentExpression extends BaseJSNode {
handleMemberExpression(leftNode, rightValue, operation) {
const obj = this.visitor.visitNode(leftNode.object);
const prop = this.visitor.visitNode(leftNode.property);
const currentValue = obj[prop];
const newValue = operation(currentValue, rightValue);
return (obj[prop] = newValue);
}
handleIdentifier(leftNode, rightValue, operation) {
const currentValue = this.visitor.visitNode(leftNode);
const newValue = operation(currentValue, rightValue);
this.visitor.scope.set(leftNode.name, newValue);
return this.visitor.scope.get(leftNode.name);
}
run() {
const { operator, left, right } = this.node;
const rightValue = this.visitor.visitNode(right);
const operation = AssignmentExpression.operatorMap[operator];
if (!operation) {
console.warn('Unhandled operator:', operator);
return undefined;
}
if (left.type === 'MemberExpression') {
return this.handleMemberExpression(left, rightValue, operation);
}
else if (left.type === 'Identifier') {
return this.handleIdentifier(left, rightValue, operation);
}
console.warn('Unhandled left node type:', left.type);
return undefined;
}
}
AssignmentExpression.operatorMap = {
'=': (_, right) => right,
'+=': (left, right) => left + right,
'-=': (left, right) => left - right,
'*=': (left, right) => left * right,
'/=': (left, right) => left / right,
'%=': (left, right) => left % right,
'**=': (left, right) => left ** right,
'<<=': (left, right) => left << right,
'>>=': (left, right) => left >> right,
'>>>=': (left, right) => left >>> right,
'&=': (left, right) => left & right,
'^=': (left, right) => left ^ right,
'|=': (left, right) => left | right
};