Skip to content

Instantly share code, notes, and snippets.

@nasser
Created November 15, 2020 21:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nasser/0f05df7106ff90019dcbe086399960ba to your computer and use it in GitHub Desktop.
Save nasser/0f05df7106ff90019dcbe086399960ba to your computer and use it in GitHub Desktop.
sketch of limited operator overloading in javascript
const esprima = require("esprima")
const escodegen = require("escodegen")
const THREE = require("three")
/// implementation
let opMap = {
"+=": "add",
"/": "divideScalar",
// ... more operators here ...
}
function replaceOperators(source) {
let ast = esprima.parseScript(source, {}, node => {
if ((node.type == "BinaryExpression" || node.type == "AssignmentExpression") && opMap[node.operator]) {
node.type = "CallExpression"
node.callee = {
type: "MemberExpression",
object: node.left,
property: {
type: "Identifier",
name: opMap[node.operator]
}
}
node.arguments = [
node.right
]
}
})
return escodegen.generate(ast);
}
/// api
function kernel(f) {
return eval(replaceOperators(f.toString()))
}
/// usage
const centroid = kernel(vs => {
let x = new THREE.Vector3()
for (const v of vs)
x += v
return x / vs.length
})
console.log(centroid([new THREE.Vector3(3, 4, 5),
new THREE.Vector3(4, 18, 21),
new THREE.Vector3(68, 2, 82),
new THREE.Vector3(5, 6, 3)]));
// => Vector3 { x: 20, y: 7.5, z: 27.75 }
@nasser
Copy link
Author

nasser commented Nov 15, 2020

needs more work to be fully functional (support for different types, needs to generate a dispatching function, etc) but the basic principle works ✌️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment