shared/schema.js
function findOuterChar(str, char){
	
	
	var square=0, curly=0, round=0, angle=0;
	for(var i=0;i<str.length;++i){
		var c = str.charAt(i);

		if(c === char && square === 0 && curly === 0 && round === 0 && angle === 0){
			return i;
		}
		
		if(c === '[') ++square;
		else if(c === ']') --square;
		else if(c === '{') ++curly;
		else if(c === '}') --curly;
		else if(c === '(') ++round;
		else if(c === ')') --round;
		else if(c === '<') ++angle;
		else if(c === '>') --angle;

		if(c === char && square === 0 && curly === 0 && round === 0 && angle === 0){
			return i;
		}
	}
	
	if(square !== 0) _.errout('mismatched [] brackets: ' + str);
	if(curly !== 0) _.errout('mismatched {} brackets: ' + str);
	if(round !== 0) _.errout('mismatched () brackets: ' + str);
	
	return -1;
}
function findOuterChar(str, char){
	
	
	var square=0, curly=0, round=0, angle=0;
	for(var i=0;i<str.length;++i){
		var c = str.charAt(i);

		if(c === char && square === 0 && curly === 0 && round === 0 && angle === 0){
			return i;
		}
		
		if(c === '[') ++square;
		else if(c === ']') --square;
		else if(c === '{') ++curly;
		else if(c === '}') --curly;
		else if(c === '(') ++round;
		else if(c === ')') --round;
		else if(c === '<') ++angle;
		else if(c === '>') --angle;

		if(c === char && square === 0 && curly === 0 && round === 0 && angle === 0){
			return i;
		}
	}
	
	if(square !== 0) _.errout('mismatched [] brackets: ' + str);
	if(curly !== 0) _.errout('mismatched {} brackets: ' + str);
	if(round !== 0) _.errout('mismatched () brackets: ' + str);
	
	return -1;
}
var ampersandParam = {type: 'param', name: '~'}