Created
September 14, 2010 03:33
-
-
Save bmeck/578481 to your computer and use it in GitHub Desktop.
This file contains 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
(function(){ | |
//pistachio | |
//fear the stachio | |
function compile(source,opts) { | |
source = String(source) | |
opts = opts || {} | |
var template_source = "" | |
var matcher = /[{][{]([@])?([#])?([/])?([a-zA-Z_$]\w*|[.])([\[](-?\d+)?(..(-?\d+)?)?[\]])?[}][}]/g | |
var index = 0 | |
var match; | |
var need_context = false | |
var need_template = false | |
var need_iteration = false | |
var need_locals = false | |
var context_depth = 0 | |
var context_allocated_depth = 0 | |
var iteration_depth = 0 | |
var iteration_allocated_depth = 0 | |
var ender_stack=[] | |
var defaulted_value = opts.default_value ? "||"+JSON.stringify(opts.default_value) : "" | |
while(match = matcher.exec(source)) { | |
if(index !== match.index) | |
template_source += "stream.write("+JSON.stringify(source.slice(index,match.index))+");" | |
var target = "" | |
var obj = match[4] | |
index = matcher.lastIndex | |
//template | |
if(match[1]) { | |
need_template = true | |
target = "template_table."+obj | |
template_source += "tmp="+target+";" | |
template_source += | |
"typeof tmp ==='function'?tmp(c0,template_table,stream):("+target+"=compile("+target+",opts))(c0,template_table,stream);" | |
continue; | |
} | |
//with | |
else if (match[2]) { | |
need_context = true | |
context_depth++ | |
if(context_depth > context_allocated_depth) context_allocated_depth = context_depth | |
template_source += "c"+context_depth+"=c"+(context_depth-1)+"."+obj+";" | |
ender_stack.push(false) | |
continue | |
} | |
//close | |
else if (match[3]) { | |
var alter = ender_stack.pop() | |
if(alter) { | |
template_source += alter[0] | |
context_depth -= alter[1] | |
} | |
else { | |
context_depth--; | |
} | |
continue | |
} | |
//iteration | |
else if (match[5]) { | |
//start | |
need_context = true | |
need_iteration = true | |
var start = Number(match[6]||0) | |
var end = match[7] ? match[8] ? Number(match[8]) : null : start | |
if(start == end) { | |
context_depth++ | |
if(context_depth > context_allocated_depth) context_allocated_depth = context_depth | |
var cindex | |
if(start < 0) cindex = "c"+(context_depth-1)+"."+obj+".length"+start | |
else cindex = start | |
template_source += "c"+context_depth+"=c"+(context_depth-1)+"."+obj+"["+cindex+"];" | |
ender_stack.push(false) | |
console.log(match) | |
} | |
else { | |
var l = "l"+iteration_depth | |
var i = "i"+iteration_depth | |
context_depth++ | |
iteration_depth++ | |
if(iteration_depth > iteration_allocated_depth) iteration_allocated_depth = context_depth | |
if(end) { | |
if(end < 0) end = "c"+context_depth+".length"+(end===null||end==0?"":end) | |
} | |
else { | |
end = "c"+context_depth+".length" | |
} | |
template_source += "c"+context_depth+"=c"+(context_depth-1)+"."+obj+";"; | |
template_source += l+"="+end+";" | |
if(start < 0) start = l+start | |
context_depth++ | |
if(context_depth > context_allocated_depth) context_allocated_depth = context_depth | |
template_source += "for("+i+"="+start+";"+i+"<"+l+";++"+i+"){" | |
template_source += "c"+context_depth+"=c"+(context_depth-1)+"["+i+"];"; | |
ender_stack.push(["}",2]) | |
} | |
continue | |
//end | |
} | |
else if (obj === ".") { | |
template_source+="stream.write(c"+context_depth+defaulted_value+");" | |
continue | |
} | |
else { | |
need_locals = true | |
for(var i=context_depth;i>0;i--) { | |
var context_var = "c"+i | |
target+="\""+obj +"\" in "+context_var+"?"+context_var+"."+obj+":"; | |
} | |
target += "c0."+obj+"" | |
} | |
template_source += "stream.write("+target+defaulted_value+");" | |
} | |
if(index !== source.length) | |
template_source += "stream.write("+JSON.stringify(source.slice(index))+");" | |
var pre = "" | |
//if(need_locals) pre+="c0=c0||{};" | |
//if(need_template) pre+="template_table=template_table||{};var tmp;" | |
if(need_context) while(context_allocated_depth > 0) pre+="var c"+(context_allocated_depth--)+";" | |
if(need_iteration) while(iteration_allocated_depth > 0) pre+="var i"+(iteration_allocated_depth)+";"+"var l"+(iteration_allocated_depth--)+";" | |
console.log(pre+template_source) | |
var render = Function("compile","opts","return function(c0,template_table,stream){"+pre+template_source+"}")(compile,opts) | |
render.source = template_source | |
return render | |
} | |
if(typeof module !== "undefined") module.exports = compile | |
if(window) window.pistachio = {compile : compile} | |
})() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment