// Various tools for parsing LLVM. Utilities of various sorts, that are
// specific to Emscripten (and hence not in utility.js).
// Does simple 'macro' substitution, using Django-like syntax,
// {{{ code }}} will be replaced with |eval(code)|.
function processMacros(text) {
return text.replace(/{{{[^}]+}}}/g, function(str) {
str = str.substr(3, str.length-6);
return eval(str).toString();
});
}
// Simple #if/else/endif preprocessing for a file. Checks if the
// ident checked is true in our global. Also replaces some constants.
function preprocess(text, constants) {
for (constant in constants) {
text = text.replace(eval('/' + constant + '/g'), constants[constant]);
}
var lines = text.split('\n');
var ret = '';
var showStack = [];
for (var i = 0; i < lines.length; i++) {
var line = lines[i];
if (!line[0] || line[0] != '#') {
if (showStack.indexOf(false) == -1) {
ret += line + '\n';
}
} else {
if (line[1] && line[1] == 'i') { // if
var ident = line.substr(4);
showStack.push(!!this[ident] && this[ident] > 0);
} else if (line[2] && line[2] == 'l') { // else
showStack.push(!showStack.pop());
} else if (line[2] && line[2] == 'n') { // endif
showStack.pop();
} else {
throw "Unclear preprocessor command: " + line;
}
}
}
assert(showStack.length == 0);
return ret;
}
function addPointing(type) { return type + '*' }
function removePointing(type, num) {
if (num === 0) return type;
return type.substr(0, type.length-(num ? num : 1));
}
function pointingLevels(type) {
if (!type) return 0;
var ret = 0;
var len1 = type.length - 1;
while (type[len1-ret] && type[len1-ret] === '*') {
ret ++;
}
return ret;
}
function removeAllPointing(type) {
return removePointing(type, pointingLevels(type));
}
function toNiceIdent(ident) {
assert(ident);
if (parseFloat(ident) == ident) return ident;
if (ident == 'null') return '0'; // see parseNumerical
return ident.replace('%', '$').replace(/["&\\ \.@:<>,\*\[\]-]/g, '_');
}
// Kind of a hack. In some cases we have strings that we do not want
// to |toNiceIdent|, as they are the output of previous processing. We
// should refactor everything into an object, with an explicit flag
// saying what has been |toNiceIdent|ed. Until then, this will detect
// simple idents that are in need of |toNiceIdent|ation. Or, we should
// ensure that processed strings never start with %,@, e.g. by always
// enclosing them in ().
function toNiceIdentCarefully(ident) {
if (ident[0] == '%' || ident[0] == '@') ident = toNiceIdent(ident);
return ident;
}
// Returns true if ident is a niceIdent (see toNiceIdent). If loose
// is true, then also allow () and spaces.
function isNiceIdent(ident, loose) {
if (loose) {
return /^[\w$_ ()]+$/.test(ident);
} else {
re