1
0
mirror of https://github.com/Jermolene/TiddlyWiki5 synced 2024-12-24 17:10:29 +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
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.
The pegjs parser uses "StringLiteral" nodes to represent individual string literals. TiddlyWiki adds
@ -25,30 +25,50 @@ var JavaScriptParseTree = function(tree) {
this.tree = tree;
};
// Render the entire JavaScript tree object to JavaScript source code
JavaScriptParseTree.prototype.render = function() {
var output = [];
if(this.tree instanceof Array) {
this.renderSubTree(output,this.tree);
JavaScriptParseTree.prototype.compile = function(targetType) {
if(targetType === "application/javascript") {
return this.compileJS();
} else if(targetType === "text/html") {
return {render: this.toString};
} 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.renderSubTree = function(output,tree) {
JavaScriptParseTree.prototype.toString = function() {
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++) {
if(t) {
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;
switch(node.type) {
case "StringLiteral":
@ -59,23 +79,23 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
break;
case "FunctionCall":
output.push("(");
this.renderNode(output,node.name);
this.compileNode(output,node.name);
output.push(")(");
for(p=0; p<node["arguments"].length; p++) {
if(p) {
output.push(",");
}
this.renderNode(output,node["arguments"][p]);
this.compileNode(output,node["arguments"][p]);
}
output.push(")");
break;
case "PropertyAccess":
this.renderNode(output,node.base);
this.compileNode(output,node.base);
if(typeof node.name === "string") {
output.push("." + node.name);
} else {
output.push("[");
this.renderNode(output,node.name);
this.compileNode(output,node.name);
output.push("]");
}
break;
@ -85,7 +105,7 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
if(p) {
output.push(",");
}
this.renderNode(output,node.elements[p]);
this.compileNode(output,node.elements[p]);
}
output.push("]");
break;
@ -98,7 +118,7 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
if(p) {
output.push(",");
}
this.renderNode(output,node.properties[p]);
this.compileNode(output,node.properties[p]);
}
output.push("}");
break;
@ -106,15 +126,15 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
output.push("'");
output.push(node.name);
output.push("':");
this.renderNode(output,node.value);
this.compileNode(output,node.value);
break;
case "BinaryExpression":
output.push("(");
this.renderNode(output,node.left);
this.compileNode(output,node.left);
output.push(")");
output.push(node.operator);
output.push("(");
this.renderNode(output,node.right);
this.compileNode(output,node.right);
output.push(")");
break;
case "NumericLiteral":
@ -128,12 +148,12 @@ JavaScriptParseTree.prototype.renderNode = function(output,node) {
output.push("(");
output.push(node.params.join(","));
output.push("){");
this.renderSubTree(output,node.elements);
this.compileSubTree(output,node.elements);
output.push("})");
break;
case "ReturnStatement":
output.push("return ");
this.renderNode(output,node.value);
this.compileNode(output,node.value);
break;
case "This":
output.push("this");

View File

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