1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2025-06-22 16:34:06 +00:00

Refactored the naming of the JavaScript parser methods

This commit is contained in:
Jeremy Ruston 2012-02-09 13:15:37 +00:00
parent 66bcef51b3
commit 6166ca3d36
2 changed files with 50 additions and 30 deletions

View File

@ -5,7 +5,7 @@ This object stores a JavaScript parse tree in the format produced by the pegjs J
The parse tree represents the syntactical structure of a JavaScript program, represented as a tree The parse tree represents the syntactical structure of a JavaScript program, represented as a tree
structure built from JavaScript arrays and objects. The nodes of the tree are objects with a "type" structure built from JavaScript arrays and objects. The nodes of the tree are objects with a "type"
field that indicates the type of the node (see the function renderNode() for a list of the types). field that indicates the type of the node (see the function compileNode() for a list of the types).
Depending on the type, other fields provide further details about the node. Depending on the type, other fields provide further details about the node.
The pegjs parser uses "StringLiteral" nodes to represent individual string literals. TiddlyWiki adds The pegjs parser uses "StringLiteral" nodes to represent individual string literals. TiddlyWiki adds
@ -25,30 +25,50 @@ var JavaScriptParseTree = function(tree) {
this.tree = tree; this.tree = tree;
}; };
// Render the entire JavaScript tree object to JavaScript source code JavaScriptParseTree.prototype.compile = function(targetType) {
JavaScriptParseTree.prototype.render = function() { if(targetType === "application/javascript") {
var output = []; return this.compileJS();
if(this.tree instanceof Array) { } else if(targetType === "text/html") {
this.renderSubTree(output,this.tree); return {render: this.toString};
} else { } else {
this.renderNode(output,this.tree); return null;
} }
var r = output.join("");
return r;
}; };
// Render a subtree of the parse tree to an array of fragments of JavaScript source code JavaScriptParseTree.prototype.toString = function() {
JavaScriptParseTree.prototype.renderSubTree = function(output,tree) { return JSON.stringify(this.tree);
};
// Compile the entire JavaScript tree object to a renderer object
JavaScriptParseTree.prototype.compileJS = function() {
/*jslint evil: true */
var output = [];
if(this.tree instanceof Array) {
this.compileSubTree(output,this.tree);
} else {
this.compileNode(output,this.tree);
}
var r = output.join("");
return {render: eval(r)};
};
// Compile a subtree of the parse tree to an array of fragments of JavaScript source code
JavaScriptParseTree.prototype.compileSubTree = function(output,tree) {
for(var t=0; t<tree.length; t++) { for(var t=0; t<tree.length; t++) {
if(t) { if(t) {
this.output.push(";\n"); this.output.push(";\n");
} }
this.renderNode(output,tree[t]); this.compileNode(output,tree[t]);
} }
}; };
// Compile a JavaScript node to an array of fragments of JavaScript source code /*
JavaScriptParseTree.prototype.renderNode = function(output,node) { Compile a JavaScript node to an array of fragments of JavaScript source code
The code currently inserts some unneeded parenthesis because it doesn't look
at the binding order of operators to determine if they are needed.
*/
JavaScriptParseTree.prototype.compileNode = function(output,node) {
var p; var p;
switch(node.type) { switch(node.type) {
case "StringLiteral": case "StringLiteral":
@ -59,23 +79,23 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
break; break;
case "FunctionCall": case "FunctionCall":
output.push("("); output.push("(");
this.renderNode(output,node.name); this.compileNode(output,node.name);
output.push(")("); output.push(")(");
for(p=0; p<node["arguments"].length; p++) { for(p=0; p<node["arguments"].length; p++) {
if(p) { if(p) {
output.push(","); output.push(",");
} }
this.renderNode(output,node["arguments"][p]); this.compileNode(output,node["arguments"][p]);
} }
output.push(")"); output.push(")");
break; break;
case "PropertyAccess": case "PropertyAccess":
this.renderNode(output,node.base); this.compileNode(output,node.base);
if(typeof node.name === "string") { if(typeof node.name === "string") {
output.push("." + node.name); output.push("." + node.name);
} else { } else {
output.push("["); output.push("[");
this.renderNode(output,node.name); this.compileNode(output,node.name);
output.push("]"); output.push("]");
} }
break; break;
@ -85,7 +105,7 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
if(p) { if(p) {
output.push(","); output.push(",");
} }
this.renderNode(output,node.elements[p]); this.compileNode(output,node.elements[p]);
} }
output.push("]"); output.push("]");
break; break;
@ -98,7 +118,7 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
if(p) { if(p) {
output.push(","); output.push(",");
} }
this.renderNode(output,node.properties[p]); this.compileNode(output,node.properties[p]);
} }
output.push("}"); output.push("}");
break; break;
@ -106,15 +126,15 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
output.push("'"); output.push("'");
output.push(node.name); output.push(node.name);
output.push("':"); output.push("':");
this.renderNode(output,node.value); this.compileNode(output,node.value);
break; break;
case "BinaryExpression": case "BinaryExpression":
output.push("("); output.push("(");
this.renderNode(output,node.left); this.compileNode(output,node.left);
output.push(")"); output.push(")");
output.push(node.operator); output.push(node.operator);
output.push("("); output.push("(");
this.renderNode(output,node.right); this.compileNode(output,node.right);
output.push(")"); output.push(")");
break; break;
case "NumericLiteral": case "NumericLiteral":
@ -128,12 +148,12 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
output.push("("); output.push("(");
output.push(node.params.join(",")); output.push(node.params.join(","));
output.push("){"); output.push("){");
this.renderSubTree(output,node.elements); this.compileSubTree(output,node.elements);
output.push("})"); output.push("})");
break; break;
case "ReturnStatement": case "ReturnStatement":
output.push("return "); output.push("return ");
this.renderNode(output,node.value); this.compileNode(output,node.value);
break; break;
case "This": case "This":
output.push("this"); output.push("this");

View File

@ -70,7 +70,7 @@ WikiTextParseTree.prototype.compile = function(type,treenode) {
renderStep.type = "main"; renderStep.type = "main";
renderStep.step = renderStepIndex; renderStep.step = renderStepIndex;
renderStep.dependencies = {}; renderStep.dependencies = {};
renderStep.handler = eval(parseTree.render()); renderStep.handler = parseTree.compile("application/javascript").render;
return renderer; return renderer;
}; };
@ -123,7 +123,7 @@ WikiTextParseTree.prototype.compileMacroCall = function(output,renderer,type,nod
value: n value: n
}); });
} }
renderStep.params = eval(this.store.jsParser.createTree([ renderStep.params = this.store.jsParser.createTree([
{ {
type: "Function", type: "Function",
name: null, name: null,
@ -136,13 +136,13 @@ WikiTextParseTree.prototype.compileMacroCall = function(output,renderer,type,nod
} }
} ] } ]
} }
]).render()); ]).compile("application/javascript").render;
// Compile any child nodes // Compile any child nodes
var subOutput = []; var subOutput = [];
if(node.children) { if(node.children) {
this.compileSubTreeHtml(subOutput,renderer,node.children); this.compileSubTreeHtml(subOutput,renderer,node.children);
} }
renderStep.content = eval(this.store.jsParser.createTree([ renderStep.content = this.store.jsParser.createTree([
{ {
type: "Function", type: "Function",
name: null, name: null,
@ -169,7 +169,7 @@ WikiTextParseTree.prototype.compileMacroCall = function(output,renderer,type,nod
} }
] ]
} }
]).render()); ]).compile("application/javascript").render;
// Add the wrapper node // Add the wrapper node
var wrapperTag = macro.wrapperTag || "div"; var wrapperTag = macro.wrapperTag || "div";
if(type === "text/html" && !this.store.disableHtmlWrapperNodes) { if(type === "text/html" && !this.store.disableHtmlWrapperNodes) {