Skip to content

Instantly share code, notes, and snippets.

@srikumarks
Last active August 29, 2015 13:58
Show Gist options
  • Save srikumarks/9941056 to your computer and use it in GitHub Desktop.
Save srikumarks/9941056 to your computer and use it in GitHub Desktop.
A conservative algorithm to minimally rename the sweetjs hygienified variables at file scope.
// Takes a file produced by sweet.js and minimally renames
// all the identifiers that have been hygienified by the macro
// expansion. Run using -
// node /path/to/rename_sweet.js file1.js > fileout.js
var fs = require('fs');
var code = fs.readFileSync(process.argv[2], 'utf8');
var idRE = /[A-Za-z_][A-Za-z0-9_\$]*/g;
function findIDs(code, ids) {
var id;
while (id = idRE.exec(code)) {
ids.push({index: id.index, match: id[0]});
}
return ids;
}
function rename(code) {
var ids = findIDs(code, []);
var uniqs = {};
// Find the unique set of ids.
ids.forEach(function (id) {
uniqs['$'+id.match] = true;
});
// Get the unique list, strip out the leading '$' character.
var uniqids = Object.keys(uniqs).map(function (s) { return s.substring(1); });
//console.log(ids);
//console.log(ids.length);
var idmap = {};
// idmap['*'+id] keeps track of a count of the number of times
// that id occurs so that we can add an appropriate suffix to
// unique ids.
uniqids.forEach(function (id) {
idmap['$'+id] = id;
idmap['*'+id] = 1;
});
var sweetidRE = /^([A-Za-z_][A-Za-z0-9_\$]*)\$([0-9]+)$/;
// Prepare a rename map that is minimal.
uniqids.forEach(function (id) {
var x = sweetidRE.exec(id);
if (x) {
var root = x[1];
var suffix = x[2];
if (idmap['*'+root]) {
// The root is already used. Increment the number and use it.
idmap['*'+root] += 1;
idmap['$'+id] = root + '_' + idmap['*'+root];
} else {
// The root is unused. Use it for the first time.
idmap['*'+root] = 1;
idmap['$'+id] = root;
}
}
});
// Assemble the result.
var result = [], pos = 0;
ids.forEach(function (id, i) {
result.push(code.substring(pos, id.index));
result.push(idmap['$'+id.match]);
pos = id.index + id.match.length;
if (i === ids.length - 1) {
result.push(code.substring(pos));
}
});
return result.join('');
}
process.stdout.write(rename(code));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment