Last active
August 29, 2015 13:58
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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