I'm an IDIOT!! June 11, 2013
                                    
                                    
									    I spent a ton of time trying to write a syntax parser for a meta-language which would be parsed by Javascript.  I just replaced a lot of confusing logic with about 40 lines of code.
                                
                            First, Javascript is dynamic and has stuff built in that can evaluate arbitrary code passed in via a string.
I'm not talking about eval().
Function!
However, my syntax looks like this:  Hello {{page.user == null ? 'Anonymous' : page.user.firstName }}
So, we need to know what "page" is in the context of the function.  I still have to parse out top level variables.  In the code above, it will get "page" as a top level variable.
Then, I build up the function:
var f = new Function(vars[0], body);
"body" is actually modified, I set it to "return " + body;  So that I can do {{ page.user == null ? 'Anonymous' : page.user.firstName }} and it will return the display name instead of undefined, the default behavior of a void function.
I have to count up the number of variables used, and build the function accordingly.  Currently, this is a switch statement.
switch (vars.length){
     case 0: f = new Function(body); break;
     case 1: f = new Function(vars[0], body); break;
     case 2: f = new Function(vars[0], vars[1], body); break;
}
Luckily in my code, there aren't more than 3-4 "top level" variables, including globals like "Array" and "String".
Here's the variable parsing part:
var shared = require("./shared");
require("strings");
var constants = { "true": true, "false": true, "null": true };
var lookup = {};
this.getVariables = function(body){
	if (body in lookup)
		return lookup[body];
	var vars = [];
	var instr = false;
	var instrch = null;
	var buf = "";
	var toplevel = false;
	var result = null;
	for (var i = 0; i < body.length; i++){
		var ch = body.charAt(i);
		switch (ch){
			case "'": case "\"":
				instr = ch != instrch;
				instrch = instrch == null ? ch : (instr ? instrch : null);
				break;
		}
		if ((!instr && shared.tokenSeparator.test(ch)) || i == body.length-1){
			if (i == body.length-1) buf+= ch;
			if (!toplevel && (result = shared.variable.exec(buf)) != null && !(result[1] in constants)){
				if (!vars.some(function(d){ return d == result[1]})){
					vars.push(result[1]);
					toplevel = true;
				}
			}
			buf = "";
		}
		else if (instr) buf = "";
		else buf += ch;
		if (toplevel && (instr || (shared.tokenSeparator.test(ch) && ch != "." && ch != "]"))) toplevel = false;
	}
	lookup[body] = vars;
	return vars;
}
And here's the evaluation part:
var syntax = require("./syntax");
var shared = require("./shared");
var lookup = {};
var Evaluator = function(globals){
	this.globals = globals;
}
Evaluator.prototype.evaluate = function(body, context){
	body = shared.replaceComps(body);
	var vars = syntax.getVariables(body);
	var args = [];
	body = "return " + body;
	for (var i = 0; i < vars.length; i++){
		if (context && vars[i] in context)
			args.push(context[vars[i]]);
		else if (this.globals && vars[i] in this.globals)
			args.push(this.globals[vars[i]]);
	}
	if (body in lookup){
		return lookup[body].apply(null, args);
	}
	var f = null;
	switch (vars.length){
		case 0: f = new Function(body); break;
		case 1: f = new Function(vars[0], body); break;
		case 2: f = new Function(vars[0], vars[1], body); break;
		case 3: f = new Function(vars[0], vars[1], vars[2], body); break;
		case 4: f = new Function(vars[0], vars[1], vars[2], vars[3], body); break;
	}
	var result = null;
	if (f != null){
		result = f.apply(null, args);
		lookup[body] = f;
	} 
	return result;
}
this.Evaluator = Evaluator;
shared.js has a regular expression, a map (for old syntax considerations), and a function to replace some old ways of doing things with the new, pure Javascript way of doing it.
this.replCompRegex = / (eq|ne|gt|lt|gte|lte) /;
this.replCompMap = { eq: "==", ne: "!=", gt: ">", lt: "<", gte: ">=", lte: "<=" };
this.replaceComps = function(body){
	var res = null;
	while ((res = this.replCompRegex.exec(body)) != null){
		body = body.replace(res[1], this.replCompMap[res[1]]);
	}
	return body;
}