Refactoring

step 1
This commit is contained in:
Onoshko Dan 2014-04-16 23:43:40 +07:00
parent ba3a59843a
commit 10db7a5ef4
12 changed files with 1758 additions and 1680 deletions

32
demo.cola Normal file
View File

@ -0,0 +1,32 @@
function main(){
console.log(`
Hello!
My name is ColaScript, and i know who you are }:->
@{navigator.userAgent}
`);
console.log("pow:", 5 ** 2, "; modulo:", 5 %% 3, ";");
var a = 3.14, b = 584;
a ?= b; console.log(a);
a = undefined;
a ?= b; console.log(a);
console.log(`is:`, location.href is String, `; isnt:`, 123 isnt Number, ";");
if(yes === true && on === true && no === false && off === false) console.log('Boolean alternatives');
console.log('Raw string:', r`@test \n \t \r`);
var isEmail = /
([\w-\.]+)
@
((?:[\w]+\.)+)
([a-zA-Z]{2,4})
/, email = r'danon0404@gmail.com';
console.log("@email is email:", isEmail.test(email));
}
main();

View File

@ -45,9 +45,10 @@
***********************************************************************/ ***********************************************************************/
"use strict"; "use strict";
!window.Cola && (window.Cola = {});
function DEFNODE(type, props, methods, base) { Cola.DEFNODE = function (type, props, methods, base) {
if (arguments.length < 4) base = AST_Node; if (arguments.length < 4) base = Cola.AST_Node;
if (!props) props = []; if (!props) props = [];
else props = props.split(/\s+/); else props = props.split(/\s+/);
var self_props = props; var self_props = props;
@ -87,10 +88,10 @@ function DEFNODE(type, props, methods, base) {
return ctor; return ctor;
}; };
var AST_Token = DEFNODE("Token", "type value line col pos endpos nlb comments_before file" /* ColaScropt + " endcol endline"*/, { Cola.AST_Token = Cola.DEFNODE("Token", "type value line col pos endpos nlb comments_before file", {
}, null); }, null);
var AST_Node = DEFNODE("Node", "start end", { Cola.AST_Node = Cola.DEFNODE("Node", "start end", {
clone: function() { clone: function() {
return new this.CTOR(this); return new this.CTOR(this);
}, },
@ -107,44 +108,44 @@ var AST_Node = DEFNODE("Node", "start end", {
} }
}, null); }, null);
AST_Node.warn_function = null; Cola.AST_Node.warn_function = null;
AST_Node.warn = function(txt, props) { Cola.AST_Node.warn = function(txt, props) {
if (AST_Node.warn_function) if (Cola.AST_Node.warn_function)
AST_Node.warn_function(string_template(txt, props)); Cola.AST_Node.warn_function(Cola.string_template(txt, props));
}; };
/* -----[ statements ]----- */ /* -----[ statements ]----- */
var AST_Statement = DEFNODE("Statement", null, { Cola.AST_Statement = Cola.DEFNODE("Statement", null, {
$documentation: "Base class of all statements", $documentation: "Base class of all statements",
}); });
var AST_Debugger = DEFNODE("Debugger", null, { Cola.AST_Debugger = Cola.DEFNODE("Debugger", null, {
$documentation: "Represents a debugger statement", $documentation: "Represents a debugger statement",
}, AST_Statement); }, Cola.AST_Statement);
var AST_Directive = DEFNODE("Directive", "value scope", { Cola.AST_Directive = Cola.DEFNODE("Directive", "value scope", {
$documentation: "Represents a directive, like \"use strict\";", $documentation: "Represents a directive, like \"use strict\";",
$propdoc: { $propdoc: {
value: "[string] The value of this directive as a plain string (it's not an AST_String!)", value: "[string] The value of this directive as a plain string (it's not an AST_String!)",
scope: "[AST_Scope/S] The scope that this directive affects" scope: "[AST_Scope/S] The scope that this directive affects"
}, },
}, AST_Statement); }, Cola.AST_Statement);
var AST_SimpleStatement = DEFNODE("SimpleStatement", "body", { Cola.AST_SimpleStatement = Cola.DEFNODE("SimpleStatement", "body", {
$documentation: "A statement consisting of an expression, i.e. a = 1 + 2", $documentation: "A statement consisting of an expression, i.e. a = 1 + 2",
$propdoc: { $propdoc: {
body: "[AST_Node] an expression node (should not be instanceof AST_Statement)" body: "[AST_Node] an expression node (should not be instanceof Cola.AST_Statement)"
}, },
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_Statement); }, Cola.AST_Statement);
function walk_body(node, visitor) { Cola.walk_body = function (node, visitor) {
if (node.body instanceof AST_Statement) { if (node.body instanceof Cola.AST_Statement) {
node.body._walk(visitor); node.body._walk(visitor);
} }
else node.body.forEach(function(stat){ else node.body.forEach(function(stat){
@ -152,30 +153,30 @@ function walk_body(node, visitor) {
}); });
}; };
var AST_Block = DEFNODE("Block", "body", { Cola.AST_Block = Cola.DEFNODE("Block", "body", {
$documentation: "A body of statements (usually bracketed)", $documentation: "A body of statements (usually bracketed)",
$propdoc: { $propdoc: {
body: "[AST_Statement*] an array of statements" body: "[AST_Statement*] an array of statements"
}, },
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
walk_body(this, visitor); Cola.walk_body(this, visitor);
}); });
} }
}, AST_Statement); }, Cola.AST_Statement);
var AST_BlockStatement = DEFNODE("BlockStatement", null, { Cola.AST_BlockStatement = Cola.DEFNODE("BlockStatement", null, {
$documentation: "A block statement", $documentation: "A block statement",
}, AST_Block); }, Cola.AST_Block);
var AST_EmptyStatement = DEFNODE("EmptyStatement", null, { Cola.AST_EmptyStatement = Cola.DEFNODE("EmptyStatement", null, {
$documentation: "The empty statement (empty block or simply a semicolon)", $documentation: "The empty statement (empty block or simply a semicolon)",
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this); return visitor._visit(this);
} }
}, AST_Statement); }, Cola.AST_Statement);
var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", { Cola.AST_StatementWithBody = Cola.DEFNODE("StatementWithBody", "body", {
$documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`", $documentation: "Base class for all statements that contain one nested body: `For`, `ForIn`, `Do`, `While`, `With`",
$propdoc: { $propdoc: {
body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement" body: "[AST_Statement] the body; this should always be present, even if it's an AST_EmptyStatement"
@ -185,9 +186,9 @@ var AST_StatementWithBody = DEFNODE("StatementWithBody", "body", {
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_Statement); }, Cola.AST_Statement);
var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", { Cola.AST_LabeledStatement = Cola.DEFNODE("LabeledStatement", "label", {
$documentation: "Statement with a label", $documentation: "Statement with a label",
$propdoc: { $propdoc: {
label: "[AST_Label] a label definition" label: "[AST_Label] a label definition"
@ -198,16 +199,16 @@ var AST_LabeledStatement = DEFNODE("LabeledStatement", "label", {
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_StatementWithBody); }, Cola.AST_StatementWithBody);
var AST_IterationStatement = DEFNODE("IterationStatement", null, { Cola.AST_IterationStatement = Cola.DEFNODE("IterationStatement", null, {
$documentation: "Internal class. All loops inherit from it." $documentation: "Internal class. All loops inherit from it."
}, AST_StatementWithBody); }, Cola.AST_StatementWithBody);
var AST_DWLoop = DEFNODE("DWLoop", "condition", { Cola.AST_DWLoop = Cola.DEFNODE("DWLoop", "condition", {
$documentation: "Base class for do/while statements", $documentation: "Base class for do/while statements",
$propdoc: { $propdoc: {
condition: "[AST_Node] the loop condition. Should not be instanceof AST_Statement" condition: "[AST_Node] the loop condition. Should not be instanceof Cola.AST_Statement"
}, },
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
@ -215,17 +216,17 @@ var AST_DWLoop = DEFNODE("DWLoop", "condition", {
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_IterationStatement); }, Cola.AST_IterationStatement);
var AST_Do = DEFNODE("Do", null, { Cola.AST_Do = Cola.DEFNODE("Do", null, {
$documentation: "A `do` statement", $documentation: "A `do` statement",
}, AST_DWLoop); }, Cola.AST_DWLoop);
var AST_While = DEFNODE("While", null, { Cola.AST_While = Cola.DEFNODE("While", null, {
$documentation: "A `while` statement", $documentation: "A `while` statement",
}, AST_DWLoop); }, Cola.AST_DWLoop);
var AST_For = DEFNODE("For", "init condition step", { Cola.AST_For = Cola.DEFNODE("For", "init condition step", {
$documentation: "A `for` statement", $documentation: "A `for` statement",
$propdoc: { $propdoc: {
init: "[AST_Node?] the `for` initialization code, or null if empty", init: "[AST_Node?] the `for` initialization code, or null if empty",
@ -240,9 +241,9 @@ var AST_For = DEFNODE("For", "init condition step", {
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_IterationStatement); }, Cola.AST_IterationStatement);
var AST_ForIn = DEFNODE("ForIn", "init name object", { Cola.AST_ForIn = Cola.DEFNODE("ForIn", "init name object", {
$documentation: "A `for ... in` statement", $documentation: "A `for ... in` statement",
$propdoc: { $propdoc: {
init: "[AST_Node] the `for/in` initialization code", init: "[AST_Node] the `for/in` initialization code",
@ -256,9 +257,9 @@ var AST_ForIn = DEFNODE("ForIn", "init name object", {
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_IterationStatement); }, Cola.AST_IterationStatement);
var AST_With = DEFNODE("With", "expression", { Cola.AST_With = Cola.DEFNODE("With", "expression", {
$documentation: "A `with` statement", $documentation: "A `with` statement",
$propdoc: { $propdoc: {
expression: "[AST_Node] the `with` expression" expression: "[AST_Node] the `with` expression"
@ -269,11 +270,11 @@ var AST_With = DEFNODE("With", "expression", {
this.body._walk(visitor); this.body._walk(visitor);
}); });
} }
}, AST_StatementWithBody); }, Cola.AST_StatementWithBody);
/* -----[ scope and functions ]----- */ /* -----[ scope and functions ]----- */
var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", { Cola.AST_Scope = Cola.DEFNODE("Scope", "directives variables functions uses_with uses_eval parent_scope enclosed cname", {
$documentation: "Base class for all statements introducing a lexical scope", $documentation: "Base class for all statements introducing a lexical scope",
$propdoc: { $propdoc: {
directives: "[string*/S] an array of directives declared in this scope", directives: "[string*/S] an array of directives declared in this scope",
@ -285,9 +286,9 @@ var AST_Scope = DEFNODE("Scope", "directives variables functions uses_with uses_
enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes", enclosed: "[SymbolDef*/S] a list of all symbol definitions that are accessed from this scope or any subscopes",
cname: "[integer/S] current index for mangling variables (used internally by the mangler)", cname: "[integer/S] current index for mangling variables (used internally by the mangler)",
}, },
}, AST_Block); }, Cola.AST_Block);
var AST_Toplevel = DEFNODE("Toplevel", "globals", { Cola.AST_Toplevel = Cola.DEFNODE("Toplevel", "globals", {
$documentation: "The toplevel scope", $documentation: "The toplevel scope",
$propdoc: { $propdoc: {
globals: "[Object/S] a map of name -> SymbolDef for all undeclared names", globals: "[Object/S] a map of name -> SymbolDef for all undeclared names",
@ -305,10 +306,10 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
}); });
var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")"; var wrapped_tl = "(function(" + parameters.join(",") + "){ '$ORIG'; })(" + args.join(",") + ")";
wrapped_tl = parse(wrapped_tl); wrapped_tl = Cola.parse(wrapped_tl);
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
if (node instanceof AST_Directive && node.value == "$ORIG") { if (node instanceof Cola.AST_Directive && node.value == "$ORIG") {
return MAP.splice(self.body); return Cola.MAP.splice(self.body);
} }
})); }));
return wrapped_tl; return wrapped_tl;
@ -319,43 +320,43 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", {
if (export_all) { if (export_all) {
self.figure_out_scope(); self.figure_out_scope();
self.walk(new TreeWalker(function(node){ self.walk(new TreeWalker(function(node){
if (node instanceof AST_SymbolDeclaration && node.definition().global) { if (node instanceof Cola.AST_SymbolDeclaration && node.definition().global) {
if (!find_if(function(n){ return n.name == node.name }, to_export)) if (!Cola.find_if(function(n){ return n.name == node.name }, to_export))
to_export.push(node); to_export.push(node);
} }
})); }));
} }
var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))"; var wrapped_tl = "(function(exports, global){ global['" + name + "'] = exports; '$ORIG'; '$EXPORTS'; }({}, (function(){return this}())))";
wrapped_tl = parse(wrapped_tl); wrapped_tl = Cola.parse(wrapped_tl);
wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){ wrapped_tl = wrapped_tl.transform(new TreeTransformer(function before(node){
if (node instanceof AST_SimpleStatement) { if (node instanceof Cola.AST_SimpleStatement) {
node = node.body; node = node.body;
if (node instanceof AST_String) switch (node.getValue()) { if (node instanceof Cola.AST_String) switch (node.getValue()) {
case "$ORIG": case "$ORIG":
return MAP.splice(self.body); return Cola.MAP.splice(self.body);
case "$EXPORTS": case "$EXPORTS":
var body = []; var body = [];
to_export.forEach(function(sym){ to_export.forEach(function(sym){
body.push(new AST_SimpleStatement({ body.push(new Cola.AST_SimpleStatement({
body: new AST_Assign({ body: new Cola.AST_Assign({
left: new AST_Sub({ left: new Cola.AST_Sub({
expression: new AST_SymbolRef({ name: "exports" }), expression: new Cola.AST_SymbolRef({ name: "exports" }),
property: new AST_String({ value: sym.name }), property: new Cola.AST_String({ value: sym.name }),
}), }),
operator: "=", operator: "=",
right: new AST_SymbolRef(sym), right: new Cola.AST_SymbolRef(sym),
}), }),
})); }));
}); });
return MAP.splice(body); return Cola.MAP.splice(body);
} }
} }
})); }));
return wrapped_tl; return wrapped_tl;
} }
}, AST_Scope); }, Cola.AST_Scope);
var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", { Cola.AST_Lambda = Cola.DEFNODE("Lambda", "name argnames uses_arguments", {
$documentation: "Base class for functions", $documentation: "Base class for functions",
$propdoc: { $propdoc: {
name: "[AST_SymbolDeclaration?] the name of this function", name: "[AST_SymbolDeclaration?] the name of this function",
@ -368,30 +369,30 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments", {
this.argnames.forEach(function(arg){ this.argnames.forEach(function(arg){
arg._walk(visitor); arg._walk(visitor);
}); });
walk_body(this, visitor); Cola.walk_body(this, visitor);
}); });
} }
}, AST_Scope); }, Cola.AST_Scope);
var AST_Accessor = DEFNODE("Accessor", null, { Cola.AST_Accessor = Cola.DEFNODE("Accessor", null, {
$documentation: "A setter/getter function. The `name` property is always null." $documentation: "A setter/getter function. The `name` property is always null."
}, AST_Lambda); }, Cola.AST_Lambda);
var AST_Function = DEFNODE("Function", null, { Cola.AST_Function = Cola.DEFNODE("Function", null, {
$documentation: "A function expression" $documentation: "A function expression"
}, AST_Lambda); }, Cola.AST_Lambda);
var AST_Defun = DEFNODE("Defun", null, { Cola.AST_Defun = Cola.DEFNODE("Defun", null, {
$documentation: "A function definition" $documentation: "A function definition"
}, AST_Lambda); }, Cola.AST_Lambda);
/* -----[ JUMPS ]----- */ /* -----[ JUMPS ]----- */
var AST_Jump = DEFNODE("Jump", null, { Cola.AST_Jump = Cola.DEFNODE("Jump", null, {
$documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)" $documentation: "Base class for “jumps” (for now that's `return`, `throw`, `break` and `continue`)"
}, AST_Statement); }, Cola.AST_Statement);
var AST_Exit = DEFNODE("Exit", "value", { Cola.AST_Exit = Cola.DEFNODE("Exit", "value", {
$documentation: "Base class for “exits” (`return` and `throw`)", $documentation: "Base class for “exits” (`return` and `throw`)",
$propdoc: { $propdoc: {
value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return" value: "[AST_Node?] the value returned or thrown by this statement; could be null for AST_Return"
@ -401,17 +402,17 @@ var AST_Exit = DEFNODE("Exit", "value", {
this.value._walk(visitor); this.value._walk(visitor);
}); });
} }
}, AST_Jump); }, Cola.AST_Jump);
var AST_Return = DEFNODE("Return", null, { Cola.AST_Return = Cola.DEFNODE("Return", null, {
$documentation: "A `return` statement" $documentation: "A `return` statement"
}, AST_Exit); }, Cola.AST_Exit);
var AST_Throw = DEFNODE("Throw", null, { Cola.AST_Throw = Cola.DEFNODE("Throw", null, {
$documentation: "A `throw` statement" $documentation: "A `throw` statement"
}, AST_Exit); }, Cola.AST_Exit);
var AST_LoopControl = DEFNODE("LoopControl", "label", { Cola.AST_LoopControl = Cola.DEFNODE("LoopControl", "label", {
$documentation: "Base class for loop control statements (`break` and `continue`)", $documentation: "Base class for loop control statements (`break` and `continue`)",
$propdoc: { $propdoc: {
label: "[AST_LabelRef?] the label, or null if none", label: "[AST_LabelRef?] the label, or null if none",
@ -421,19 +422,19 @@ var AST_LoopControl = DEFNODE("LoopControl", "label", {
this.label._walk(visitor); this.label._walk(visitor);
}); });
} }
}, AST_Jump); }, Cola.AST_Jump);
var AST_Break = DEFNODE("Break", null, { Cola.AST_Break = Cola.DEFNODE("Break", null, {
$documentation: "A `break` statement" $documentation: "A `break` statement"
}, AST_LoopControl); }, Cola.AST_LoopControl);
var AST_Continue = DEFNODE("Continue", null, { Cola.AST_Continue = Cola.DEFNODE("Continue", null, {
$documentation: "A `continue` statement" $documentation: "A `continue` statement"
}, AST_LoopControl); }, Cola.AST_LoopControl);
/* -----[ IF ]----- */ /* -----[ IF ]----- */
var AST_If = DEFNODE("If", "condition alternative", { Cola.AST_If = Cola.DEFNODE("If", "condition alternative", {
$documentation: "A `if` statement", $documentation: "A `if` statement",
$propdoc: { $propdoc: {
condition: "[AST_Node] the `if` condition", condition: "[AST_Node] the `if` condition",
@ -446,11 +447,11 @@ var AST_If = DEFNODE("If", "condition alternative", {
if (this.alternative) this.alternative._walk(visitor); if (this.alternative) this.alternative._walk(visitor);
}); });
} }
}, AST_StatementWithBody); }, Cola.AST_StatementWithBody);
/* -----[ SWITCH ]----- */ /* -----[ SWITCH ]----- */
var AST_Switch = DEFNODE("Switch", "expression", { Cola.AST_Switch = Cola.DEFNODE("Switch", "expression", {
$documentation: "A `switch` statement", $documentation: "A `switch` statement",
$propdoc: { $propdoc: {
expression: "[AST_Node] the `switch` “discriminant”" expression: "[AST_Node] the `switch` “discriminant”"
@ -458,20 +459,20 @@ var AST_Switch = DEFNODE("Switch", "expression", {
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
this.expression._walk(visitor); this.expression._walk(visitor);
walk_body(this, visitor); Cola.walk_body(this, visitor);
}); });
} }
}, AST_Block); }, Cola.AST_Block);
var AST_SwitchBranch = DEFNODE("SwitchBranch", null, { Cola.AST_SwitchBranch = Cola.DEFNODE("SwitchBranch", null, {
$documentation: "Base class for `switch` branches", $documentation: "Base class for `switch` branches",
}, AST_Block); }, Cola.AST_Block);
var AST_Default = DEFNODE("Default", null, { Cola.AST_Default = Cola.DEFNODE("Default", null, {
$documentation: "A `default` switch branch", $documentation: "A `default` switch branch",
}, AST_SwitchBranch); }, Cola.AST_SwitchBranch);
var AST_Case = DEFNODE("Case", "expression", { Cola.AST_Case = Cola.DEFNODE("Case", "expression", {
$documentation: "A `case` switch branch", $documentation: "A `case` switch branch",
$propdoc: { $propdoc: {
expression: "[AST_Node] the `case` expression" expression: "[AST_Node] the `case` expression"
@ -479,14 +480,14 @@ var AST_Case = DEFNODE("Case", "expression", {
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
this.expression._walk(visitor); this.expression._walk(visitor);
walk_body(this, visitor); Cola.walk_body(this, visitor);
}); });
} }
}, AST_SwitchBranch); }, Cola.AST_SwitchBranch);
/* -----[ EXCEPTIONS ]----- */ /* -----[ EXCEPTIONS ]----- */
var AST_Try = DEFNODE("Try", "bcatch bfinally", { Cola.AST_Try = Cola.DEFNODE("Try", "bcatch bfinally", {
$documentation: "A `try` statement", $documentation: "A `try` statement",
$propdoc: { $propdoc: {
bcatch: "[AST_Catch?] the catch block, or null if not present", bcatch: "[AST_Catch?] the catch block, or null if not present",
@ -494,14 +495,14 @@ var AST_Try = DEFNODE("Try", "bcatch bfinally", {
}, },
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
walk_body(this, visitor); Cola.walk_body(this, visitor);
if (this.bcatch) this.bcatch._walk(visitor); if (this.bcatch) this.bcatch._walk(visitor);
if (this.bfinally) this.bfinally._walk(visitor); if (this.bfinally) this.bfinally._walk(visitor);
}); });
} }
}, AST_Block); }, Cola.AST_Block);
var AST_Catch = DEFNODE("Catch", "argname", { Cola.AST_Catch = Cola.DEFNODE("Catch", "argname", {
$documentation: "A `catch` node; only makes sense as part of a `try` statement", $documentation: "A `catch` node; only makes sense as part of a `try` statement",
$propdoc: { $propdoc: {
argname: "[AST_SymbolCatch] symbol for the exception" argname: "[AST_SymbolCatch] symbol for the exception"
@ -509,18 +510,18 @@ var AST_Catch = DEFNODE("Catch", "argname", {
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
this.argname._walk(visitor); this.argname._walk(visitor);
walk_body(this, visitor); Cola.walk_body(this, visitor);
}); });
} }
}, AST_Block); }, Cola.AST_Block);
var AST_Finally = DEFNODE("Finally", null, { Cola.AST_Finally = Cola.DEFNODE("Finally", null, {
$documentation: "A `finally` node; only makes sense as part of a `try` statement" $documentation: "A `finally` node; only makes sense as part of a `try` statement"
}, AST_Block); }, Cola.AST_Block);
/* -----[ VAR/CONST ]----- */ /* -----[ VAR/CONST ]----- */
var AST_Definitions = DEFNODE("Definitions", "definitions", { Cola.AST_Definitions = Cola.DEFNODE("Definitions", "definitions", {
$documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)", $documentation: "Base class for `var` or `const` nodes (variable declarations/initializations)",
$propdoc: { $propdoc: {
definitions: "[AST_VarDef*] array of variable definitions" definitions: "[AST_VarDef*] array of variable definitions"
@ -532,17 +533,17 @@ var AST_Definitions = DEFNODE("Definitions", "definitions", {
}); });
}); });
} }
}, AST_Statement); }, Cola.AST_Statement);
var AST_Var = DEFNODE("Var", null, { Cola.AST_Var = Cola.DEFNODE("Var", null, {
$documentation: "A `var` statement" $documentation: "A `var` statement"
}, AST_Definitions); }, Cola.AST_Definitions);
var AST_Const = DEFNODE("Const", null, { Cola.AST_Const = Cola.DEFNODE("Const", null, {
$documentation: "A `const` statement" $documentation: "A `const` statement"
}, AST_Definitions); }, Cola.AST_Definitions);
var AST_VarDef = DEFNODE("VarDef", "name value", { Cola.AST_VarDef = Cola.DEFNODE("VarDef", "name value", {
$documentation: "A variable declaration; only appears in a AST_Definitions node", $documentation: "A variable declaration; only appears in a AST_Definitions node",
$propdoc: { $propdoc: {
name: "[AST_SymbolVar|AST_SymbolConst] name of the variable", name: "[AST_SymbolVar|AST_SymbolConst] name of the variable",
@ -558,7 +559,7 @@ var AST_VarDef = DEFNODE("VarDef", "name value", {
/* -----[ OTHER ]----- */ /* -----[ OTHER ]----- */
var AST_Call = DEFNODE("Call", "expression args", { Cola.AST_Call = Cola.DEFNODE("Call", "expression args", {
$documentation: "A function call expression", $documentation: "A function call expression",
$propdoc: { $propdoc: {
expression: "[AST_Node] expression to invoke as function", expression: "[AST_Node] expression to invoke as function",
@ -574,18 +575,18 @@ var AST_Call = DEFNODE("Call", "expression args", {
} }
}); });
var AST_New = DEFNODE("New", null, { Cola.AST_New = Cola.DEFNODE("New", null, {
$documentation: "An object instantiation. Derives from a function call since it has exactly the same properties" $documentation: "An object instantiation. Derives from a function call since it has exactly the same properties"
}, AST_Call); }, Cola.AST_Call);
var AST_Seq = DEFNODE("Seq", "car cdr", { Cola.AST_Seq = Cola.DEFNODE("Seq", "car cdr", {
$documentation: "A sequence expression (two comma-separated expressions)", $documentation: "A sequence expression (two comma-separated expressions)",
$propdoc: { $propdoc: {
car: "[AST_Node] first element in sequence", car: "[AST_Node] first element in sequence",
cdr: "[AST_Node] second element in sequence" cdr: "[AST_Node] second element in sequence"
}, },
$cons: function(x, y) { $cons: function(x, y) {
var seq = new AST_Seq(x); var seq = new Cola.AST_Seq(x);
seq.car = x; seq.car = x;
seq.cdr = y; seq.cdr = y;
return seq; return seq;
@ -595,7 +596,7 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
if (array.length == 1) return array[0].clone(); if (array.length == 1) return array[0].clone();
var list = null; var list = null;
for (var i = array.length; --i >= 0;) { for (var i = array.length; --i >= 0;) {
list = AST_Seq.cons(array[i], list); list = Cola.AST_Seq.cons(array[i], list);
} }
var p = list; var p = list;
while (p) { while (p) {
@ -611,7 +612,7 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
var p = this, a = []; var p = this, a = [];
while (p) { while (p) {
a.push(p.car); a.push(p.car);
if (p.cdr && !(p.cdr instanceof AST_Seq)) { if (p.cdr && !(p.cdr instanceof Cola.AST_Seq)) {
a.push(p.cdr); a.push(p.cdr);
break; break;
} }
@ -622,8 +623,8 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
add: function(node) { add: function(node) {
var p = this; var p = this;
while (p) { while (p) {
if (!(p.cdr instanceof AST_Seq)) { if (!(p.cdr instanceof Cola.AST_Seq)) {
var cell = AST_Seq.cons(p.cdr, node); var cell = Cola.AST_Seq.cons(p.cdr, node);
return p.cdr = cell; return p.cdr = cell;
} }
p = p.cdr; p = p.cdr;
@ -637,7 +638,7 @@ var AST_Seq = DEFNODE("Seq", "car cdr", {
} }
}); });
var AST_PropAccess = DEFNODE("PropAccess", "expression property", { Cola.AST_PropAccess = Cola.DEFNODE("PropAccess", "expression property", {
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`", $documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
$propdoc: { $propdoc: {
expression: "[AST_Node] the “container” expression", expression: "[AST_Node] the “container” expression",
@ -645,16 +646,16 @@ var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
} }
}); });
var AST_Dot = DEFNODE("Dot", null, { Cola.AST_Dot = Cola.DEFNODE("Dot", null, {
$documentation: "A dotted property access expression", $documentation: "A dotted property access expression",
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
this.expression._walk(visitor); this.expression._walk(visitor);
}); });
} }
}, AST_PropAccess); }, Cola.AST_PropAccess);
var AST_Sub = DEFNODE("Sub", null, { Cola.AST_Sub = Cola.DEFNODE("Sub", null, {
$documentation: "Index-style property access, i.e. `a[\"foo\"]`", $documentation: "Index-style property access, i.e. `a[\"foo\"]`",
_walk: function(visitor) { _walk: function(visitor) {
return visitor._visit(this, function(){ return visitor._visit(this, function(){
@ -662,9 +663,9 @@ var AST_Sub = DEFNODE("Sub", null, {
this.property._walk(visitor); this.property._walk(visitor);
}); });
} }
}, AST_PropAccess); }, Cola.AST_PropAccess);
var AST_Unary = DEFNODE("Unary", "operator expression", { Cola.AST_Unary = Cola.DEFNODE("Unary", "operator expression", {
$documentation: "Base class for unary expressions", $documentation: "Base class for unary expressions",
$propdoc: { $propdoc: {
operator: "[string] the operator", operator: "[string] the operator",
@ -677,15 +678,15 @@ var AST_Unary = DEFNODE("Unary", "operator expression", {
} }
}); });
var AST_UnaryPrefix = DEFNODE("UnaryPrefix", null, { Cola.AST_UnaryPrefix = Cola.DEFNODE("UnaryPrefix", null, {
$documentation: "Unary prefix expression, i.e. `typeof i` or `++i`" $documentation: "Unary prefix expression, i.e. `typeof i` or `++i`"
}, AST_Unary); }, Cola.AST_Unary);
var AST_UnaryPostfix = DEFNODE("UnaryPostfix", null, { Cola.AST_UnaryPostfix = Cola.DEFNODE("UnaryPostfix", null, {
$documentation: "Unary postfix expression, i.e. `i++`" $documentation: "Unary postfix expression, i.e. `i++`"
}, AST_Unary); }, Cola.AST_Unary);
var AST_Binary = DEFNODE("Binary", "left operator right", { Cola.AST_Binary = Cola.DEFNODE("Binary", "left operator right", {
$documentation: "Binary expression, i.e. `a + b`", $documentation: "Binary expression, i.e. `a + b`",
$propdoc: { $propdoc: {
left: "[AST_Node] left-hand side expression", left: "[AST_Node] left-hand side expression",
@ -700,7 +701,7 @@ var AST_Binary = DEFNODE("Binary", "left operator right", {
} }
}); });
var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative", { Cola.AST_Conditional = Cola.DEFNODE("Conditional", "condition consequent alternative", {
$documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`", $documentation: "Conditional expression using the ternary operator, i.e. `a ? b : c`",
$propdoc: { $propdoc: {
condition: "[AST_Node]", condition: "[AST_Node]",
@ -716,13 +717,13 @@ var AST_Conditional = DEFNODE("Conditional", "condition consequent alternative",
} }
}); });
var AST_Assign = DEFNODE("Assign", null, { Cola.AST_Assign = Cola.DEFNODE("Assign", null, {
$documentation: "An assignment expression — `a = b + 5`", $documentation: "An assignment expression — `a = b + 5`",
}, AST_Binary); }, Cola.AST_Binary);
/* -----[ LITERALS ]----- */ /* -----[ LITERALS ]----- */
var AST_Array = DEFNODE("Array", "elements", { Cola.AST_Array = Cola.DEFNODE("Array", "elements", {
$documentation: "An array literal", $documentation: "An array literal",
$propdoc: { $propdoc: {
elements: "[AST_Node*] array of elements" elements: "[AST_Node*] array of elements"
@ -736,7 +737,7 @@ var AST_Array = DEFNODE("Array", "elements", {
} }
}); });
var AST_Object = DEFNODE("Object", "properties", { Cola.AST_Object = Cola.DEFNODE("Object", "properties", {
$documentation: "An object literal", $documentation: "An object literal",
$propdoc: { $propdoc: {
properties: "[AST_ObjectProperty*] array of properties" properties: "[AST_ObjectProperty*] array of properties"
@ -750,7 +751,7 @@ var AST_Object = DEFNODE("Object", "properties", {
} }
}); });
var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", { Cola.AST_ObjectProperty = Cola.DEFNODE("ObjectProperty", "key value", {
$documentation: "Base class for literal object properties", $documentation: "Base class for literal object properties",
$propdoc: { $propdoc: {
key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.", key: "[string] the property name converted to a string for ObjectKeyVal. For setters and getters this is an arbitrary AST_Node.",
@ -763,19 +764,19 @@ var AST_ObjectProperty = DEFNODE("ObjectProperty", "key value", {
} }
}); });
var AST_ObjectKeyVal = DEFNODE("ObjectKeyVal", null, { Cola.AST_ObjectKeyVal = Cola.DEFNODE("ObjectKeyVal", null, {
$documentation: "A key: value object property", $documentation: "A key: value object property",
}, AST_ObjectProperty); }, Cola.AST_ObjectProperty);
var AST_ObjectSetter = DEFNODE("ObjectSetter", null, { Cola.AST_ObjectSetter = Cola.DEFNODE("ObjectSetter", null, {
$documentation: "An object setter property", $documentation: "An object setter property",
}, AST_ObjectProperty); }, Cola.AST_ObjectProperty);
var AST_ObjectGetter = DEFNODE("ObjectGetter", null, { Cola.AST_ObjectGetter = Cola.DEFNODE("ObjectGetter", null, {
$documentation: "An object getter property", $documentation: "An object getter property",
}, AST_ObjectProperty); }, Cola.AST_ObjectProperty);
var AST_Symbol = DEFNODE("Symbol", "scope name thedef", { Cola.AST_Symbol = Cola.DEFNODE("Symbol", "scope name thedef", {
$propdoc: { $propdoc: {
name: "[string] name of this symbol", name: "[string] name of this symbol",
scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)", scope: "[AST_Scope/S] the current scope (not necessarily the definition scope)",
@ -784,42 +785,42 @@ var AST_Symbol = DEFNODE("Symbol", "scope name thedef", {
$documentation: "Base class for all symbols", $documentation: "Base class for all symbols",
}); });
var AST_SymbolAccessor = DEFNODE("SymbolAccessor", null, { Cola.AST_SymbolAccessor = Cola.DEFNODE("SymbolAccessor", null, {
$documentation: "The name of a property accessor (setter/getter function)" $documentation: "The name of a property accessor (setter/getter function)"
}, AST_Symbol); }, Cola.AST_Symbol);
var AST_SymbolDeclaration = DEFNODE("SymbolDeclaration", "init", { Cola.AST_SymbolDeclaration = Cola.DEFNODE("SymbolDeclaration", "init", {
$documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)", $documentation: "A declaration symbol (symbol in var/const, function name or argument, symbol in catch)",
$propdoc: { $propdoc: {
init: "[AST_Node*/S] array of initializers for this declaration." init: "[AST_Node*/S] array of initializers for this declaration."
} }
}, AST_Symbol); }, Cola.AST_Symbol);
var AST_SymbolVar = DEFNODE("SymbolVar", null, { Cola.AST_SymbolVar = Cola.DEFNODE("SymbolVar", null, {
$documentation: "Symbol defining a variable", $documentation: "Symbol defining a variable",
}, AST_SymbolDeclaration); }, Cola.AST_SymbolDeclaration);
var AST_SymbolConst = DEFNODE("SymbolConst", null, { Cola.AST_SymbolConst = Cola.DEFNODE("SymbolConst", null, {
$documentation: "A constant declaration" $documentation: "A constant declaration"
}, AST_SymbolDeclaration); }, Cola.AST_SymbolDeclaration);
var AST_SymbolFunarg = DEFNODE("SymbolFunarg", null, { Cola.AST_SymbolFunarg = Cola.DEFNODE("SymbolFunarg", null, {
$documentation: "Symbol naming a function argument", $documentation: "Symbol naming a function argument",
}, AST_SymbolVar); }, Cola.AST_SymbolVar);
var AST_SymbolDefun = DEFNODE("SymbolDefun", null, { Cola.AST_SymbolDefun = Cola.DEFNODE("SymbolDefun", null, {
$documentation: "Symbol defining a function", $documentation: "Symbol defining a function",
}, AST_SymbolDeclaration); }, Cola.AST_SymbolDeclaration);
var AST_SymbolLambda = DEFNODE("SymbolLambda", null, { Cola.AST_SymbolLambda = Cola.DEFNODE("SymbolLambda", null, {
$documentation: "Symbol naming a function expression", $documentation: "Symbol naming a function expression",
}, AST_SymbolDeclaration); }, Cola.AST_SymbolDeclaration);
var AST_SymbolCatch = DEFNODE("SymbolCatch", null, { Cola.AST_SymbolCatch = Cola.DEFNODE("SymbolCatch", null, {
$documentation: "Symbol naming the exception in catch", $documentation: "Symbol naming the exception in catch",
}, AST_SymbolDeclaration); }, Cola.AST_SymbolDeclaration);
var AST_Label = DEFNODE("Label", "references", { Cola.AST_Label = Cola.DEFNODE("Label", "references", {
$documentation: "Symbol naming a label (declaration)", $documentation: "Symbol naming a label (declaration)",
$propdoc: { $propdoc: {
references: "[AST_LoopControl*] a list of nodes referring to this label" references: "[AST_LoopControl*] a list of nodes referring to this label"
@ -828,110 +829,110 @@ var AST_Label = DEFNODE("Label", "references", {
this.references = []; this.references = [];
this.thedef = this; this.thedef = this;
} }
}, AST_Symbol); }, Cola.AST_Symbol);
var AST_SymbolRef = DEFNODE("SymbolRef", null, { Cola.AST_SymbolRef = Cola.DEFNODE("SymbolRef", null, {
$documentation: "Reference to some symbol (not definition/declaration)", $documentation: "Reference to some symbol (not definition/declaration)",
}, AST_Symbol); }, Cola.AST_Symbol);
var AST_LabelRef = DEFNODE("LabelRef", null, { Cola.AST_LabelRef = Cola.DEFNODE("LabelRef", null, {
$documentation: "Reference to a label symbol", $documentation: "Reference to a label symbol",
}, AST_Symbol); }, Cola.AST_Symbol);
var AST_This = DEFNODE("This", null, { Cola.AST_This = Cola.DEFNODE("This", null, {
$documentation: "The `this` symbol", $documentation: "The `this` symbol",
}, AST_Symbol); }, Cola.AST_Symbol);
var AST_Constant = DEFNODE("Constant", null, { Cola.AST_Constant = Cola.DEFNODE("Constant", null, {
$documentation: "Base class for all constants", $documentation: "Base class for all constants",
getValue: function() { getValue: function() {
return this.value; return this.value;
} }
}); });
var AST_String = DEFNODE("String", "value", { Cola.AST_String = Cola.DEFNODE("String", "value", {
$documentation: "A string literal", $documentation: "A string literal",
$propdoc: { $propdoc: {
value: "[string] the contents of this string" value: "[string] the contents of this string"
} }
}, AST_Constant); }, Cola.AST_Constant);
var AST_StringTemplate = DEFNODE("StringTemplate", null, { Cola.AST_StringTemplate = Cola.DEFNODE("StringTemplate", null, {
$documentation: "A string template", $documentation: "A string template",
$propdoc: { $propdoc: {
body: "[AST_Statement*] the contents of this string template" body: "[AST_Statement*] the contents of this string template"
} }
}, AST_Block); }, Cola.AST_Block);
var AST_Number = DEFNODE("Number", "value", { Cola.AST_Number = Cola.DEFNODE("Number", "value", {
$documentation: "A number literal", $documentation: "A number literal",
$propdoc: { $propdoc: {
value: "[number] the numeric value" value: "[number] the numeric value"
} }
}, AST_Constant); }, Cola.AST_Constant);
var AST_RegExp = DEFNODE("RegExp", "value", { Cola.AST_RegExp = Cola.DEFNODE("RegExp", "value", {
$documentation: "A regexp literal", $documentation: "A regexp literal",
$propdoc: { $propdoc: {
value: "[RegExp] the actual regexp" value: "[RegExp] the actual regexp"
} }
}, AST_Constant); }, Cola.AST_Constant);
var AST_Atom = DEFNODE("Atom", null, { Cola.AST_Atom = Cola.DEFNODE("Atom", null, {
$documentation: "Base class for atoms", $documentation: "Base class for atoms",
}, AST_Constant); }, Cola.AST_Constant);
var AST_Null = DEFNODE("Null", null, { Cola.AST_Null = Cola.DEFNODE("Null", null, {
$documentation: "The `null` atom", $documentation: "The `null` atom",
value: null value: null
}, AST_Atom); }, Cola.AST_Atom);
var AST_NaN = DEFNODE("NaN", null, { Cola.AST_NaN = Cola.DEFNODE("NaN", null, {
$documentation: "The impossible value", $documentation: "The impossible value",
value: 0/0 value: 0/0
}, AST_Atom); }, Cola.AST_Atom);
var AST_Undefined = DEFNODE("Undefined", null, { Cola.AST_Undefined = Cola.DEFNODE("Undefined", null, {
$documentation: "The `undefined` value", $documentation: "The `undefined` value",
value: (function(){}()) value: (function(){}())
}, AST_Atom); }, Cola.AST_Atom);
var AST_Hole = DEFNODE("Hole", null, { Cola.AST_Hole = Cola.DEFNODE("Hole", null, {
$documentation: "A hole in an array", $documentation: "A hole in an array",
value: (function(){}()) value: (function(){}())
}, AST_Atom); }, Cola.AST_Atom);
var AST_Infinity = DEFNODE("Infinity", null, { Cola.AST_Infinity = Cola.DEFNODE("Infinity", null, {
$documentation: "The `Infinity` value", $documentation: "The `Infinity` value",
value: 1/0 value: 1/0
}, AST_Atom); }, Cola.AST_Atom);
var AST_Boolean = DEFNODE("Boolean", null, { Cola.AST_Boolean = Cola.DEFNODE("Boolean", null, {
$documentation: "Base class for booleans", $documentation: "Base class for booleans",
}, AST_Atom); }, Cola.AST_Atom);
var AST_False = DEFNODE("False", null, { Cola.AST_False = Cola.DEFNODE("False", null, {
$documentation: "The `false` atom", $documentation: "The `false` atom",
value: false value: false
}, AST_Boolean); }, Cola.AST_Boolean);
var AST_True = DEFNODE("True", null, { Cola.AST_True = Cola.DEFNODE("True", null, {
$documentation: "The `true` atom", $documentation: "The `true` atom",
value: true value: true
}, AST_Boolean); }, Cola.AST_Boolean);
/* -----[ TreeWalker ]----- */ /* -----[ TreeWalker ]----- */
function TreeWalker(callback) { Cola.TreeWalker = function (callback) {
this.visit = callback; this.visit = callback;
this.stack = []; this.stack = [];
}; };
TreeWalker.prototype = { Cola.TreeWalker.prototype = {
_visit: function(node, descend) { _visit: function(node, descend) {
this.stack.push(node); this.stack.push(node);
var ret = this.visit(node, descend ? function(){ var ret = this.visit(node, descend ? function(){
descend.call(node); descend.call(node);
} : noop); } : Cola.noop);
if (!ret && descend) { if (!ret && descend) {
descend.call(node); descend.call(node);
} }
@ -958,22 +959,22 @@ TreeWalker.prototype = {
} }
}, },
has_directive: function(type) { has_directive: function(type) {
return this.find_parent(AST_Scope).has_directive(type); return this.find_parent(Cola.AST_Scope).has_directive(type);
}, },
in_boolean_context: function() { in_boolean_context: function() {
var stack = this.stack; var stack = this.stack;
var i = stack.length, self = stack[--i]; var i = stack.length, self = stack[--i];
while (i > 0) { while (i > 0) {
var p = stack[--i]; var p = stack[--i];
if ((p instanceof AST_If && p.condition === self) || if ((p instanceof Cola.AST_If && p.condition === self) ||
(p instanceof AST_Conditional && p.condition === self) || (p instanceof Cola.AST_Conditional && p.condition === self) ||
(p instanceof AST_DWLoop && p.condition === self) || (p instanceof Cola.AST_DWLoop && p.condition === self) ||
(p instanceof AST_For && p.condition === self) || (p instanceof Cola.AST_For && p.condition === self) ||
(p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self)) (p instanceof Cola.AST_UnaryPrefix && p.operator == "!" && p.expression === self))
{ {
return true; return true;
} }
if (!(p instanceof AST_Binary && (p.operator == "&&" || p.operator == "||"))) if (!(p instanceof Cola.AST_Binary && (p.operator == "&&" || p.operator == "||")))
return false; return false;
self = p; self = p;
} }
@ -982,12 +983,12 @@ TreeWalker.prototype = {
var stack = this.stack; var stack = this.stack;
if (label) for (var i = stack.length; --i >= 0;) { if (label) for (var i = stack.length; --i >= 0;) {
var x = stack[i]; var x = stack[i];
if (x instanceof AST_LabeledStatement && x.label.name == label.name) { if (x instanceof Cola.AST_LabeledStatement && x.label.name == label.name) {
return x.body; return x.body;
} }
} else for (var i = stack.length; --i >= 0;) { } else for (var i = stack.length; --i >= 0;) {
var x = stack[i]; var x = stack[i];
if (x instanceof AST_Switch || x instanceof AST_IterationStatement) if (x instanceof Cola.AST_Switch || x instanceof Cola.AST_IterationStatement)
return x; return x;
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -65,7 +65,7 @@
try { try {
// 1. compile // 1. compile
ast = parse(source); ast = Cola.parse(source);
ast = translate(ast); ast = translate(ast);
ast.print(stream); ast.print(stream);
translationArea.value = stream.toString(); translationArea.value = stream.toString();
@ -85,6 +85,8 @@
} catch(e){ } catch(e){
translationArea.value = ''; translationArea.value = '';
resultArea.value = ''; resultArea.value = '';
throw e;
} }
} }
@ -94,7 +96,7 @@
function Translate(){ function Translate(){
stream = OutputStream({ beautify : true }); stream = OutputStream({ beautify : true });
translate(parse(source)).print(stream); translate(Cola.parse(source)).print(stream);
return stream.toString(); return stream.toString();
} }

View File

@ -47,16 +47,16 @@
var MOZ_TO_ME = { var MOZ_TO_ME = {
TryStatement : function(M) { TryStatement : function(M) {
return new AST_Try({ return new Cola.AST_Try({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
body : from_moz(M.block).body, body : from_moz(M.block).body,
bcatch : from_moz(M.handlers[0]), bcatch : from_moz(M.handlers[0]),
bfinally : M.finalizer ? new AST_Finally(from_moz(M.finalizer)) : null bfinally : M.finalizer ? new Cola.AST_Finally(from_moz(M.finalizer)) : null
}); });
}, },
CatchClause : function(M) { CatchClause : function(M) {
return new AST_Catch({ return new Cola.AST_Catch({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
argname : from_moz(M.param), argname : from_moz(M.param),
@ -64,7 +64,7 @@
}); });
}, },
ObjectExpression : function(M) { ObjectExpression : function(M) {
return new AST_Object({ return new Cola.AST_Object({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
properties : M.properties.map(function(prop){ properties : M.properties.map(function(prop){
@ -78,22 +78,22 @@
}; };
switch (prop.kind) { switch (prop.kind) {
case "init": case "init":
return new AST_ObjectKeyVal(args); return new Cola.AST_ObjectKeyVal(args);
case "set": case "set":
args.value.name = from_moz(key); args.value.name = from_moz(key);
return new AST_ObjectSetter(args); return new Cola.AST_ObjectSetter(args);
case "get": case "get":
args.value.name = from_moz(key); args.value.name = from_moz(key);
return new AST_ObjectGetter(args); return new Cola.AST_ObjectGetter(args);
} }
}) })
}); });
}, },
SequenceExpression : function(M) { SequenceExpression : function(M) {
return AST_Seq.from_array(M.expressions.map(from_moz)); return Cola.AST_Seq.from_array(M.expressions.map(from_moz));
}, },
MemberExpression : function(M) { MemberExpression : function(M) {
return new (M.computed ? AST_Sub : AST_Dot)({ return new (M.computed ? Cola.AST_Sub : Cola.AST_Dot)({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
property : M.computed ? from_moz(M.property) : M.property.name, property : M.computed ? from_moz(M.property) : M.property.name,
@ -101,7 +101,7 @@
}); });
}, },
SwitchCase : function(M) { SwitchCase : function(M) {
return new (M.test ? AST_Case : AST_Default)({ return new (M.test ? Cola.AST_Case : Cola.AST_Default)({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
expression : from_moz(M.test), expression : from_moz(M.test),
@ -113,33 +113,33 @@
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M) end : my_end_token(M)
}; };
if (val === null) return new AST_Null(args); if (val === null) return new Cola.AST_Null(args);
switch (typeof val) { switch (typeof val) {
case "string": case "string":
args.value = val; args.value = val;
return new AST_String(args); return new Cola.AST_String(args);
case "number": case "number":
args.value = val; args.value = val;
return new AST_Number(args); return new Cola.AST_Number(args);
case "boolean": case "boolean":
return new (val ? AST_True : AST_False)(args); return new (val ? Cola.AST_True : Cola.AST_False)(args);
default: default:
args.value = val; args.value = val;
return new AST_RegExp(args); return new Cola.AST_RegExp(args);
} }
}, },
UnaryExpression: From_Moz_Unary, UnaryExpression: From_Moz_Unary,
UpdateExpression: From_Moz_Unary, UpdateExpression: From_Moz_Unary,
Identifier: function(M) { Identifier: function(M) {
var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2]; var p = FROM_MOZ_STACK[FROM_MOZ_STACK.length - 2];
return new (M.name == "this" ? AST_This return new (M.name == "this" ? Cola.AST_This
: p.type == "LabeledStatement" ? AST_Label : p.type == "LabeledStatement" ? Cola.AST_Label
: p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? AST_SymbolConst : AST_SymbolVar) : p.type == "VariableDeclarator" && p.id === M ? (p.kind == "const" ? Cola.AST_SymbolConst : Cola.AST_SymbolVar)
: p.type == "FunctionExpression" ? (p.id === M ? AST_SymbolLambda : AST_SymbolFunarg) : p.type == "FunctionExpression" ? (p.id === M ? Cola.AST_SymbolLambda : Cola.AST_SymbolFunarg)
: p.type == "FunctionDeclaration" ? (p.id === M ? AST_SymbolDefun : AST_SymbolFunarg) : p.type == "FunctionDeclaration" ? (p.id === M ? Cola.AST_SymbolDefun : Cola.AST_SymbolFunarg)
: p.type == "CatchClause" ? AST_SymbolCatch : p.type == "CatchClause" ? Cola.AST_SymbolCatch
: p.type == "BreakStatement" || p.type == "ContinueStatement" ? AST_LabelRef : p.type == "BreakStatement" || p.type == "ContinueStatement" ? Cola.AST_LabelRef
: AST_SymbolRef)({ : Cola.AST_SymbolRef)({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
name : M.name name : M.name
@ -150,7 +150,7 @@
function From_Moz_Unary(M) { function From_Moz_Unary(M) {
var prefix = "prefix" in M ? M.prefix var prefix = "prefix" in M ? M.prefix
: M.type == "UnaryExpression" ? true : false; : M.type == "UnaryExpression" ? true : false;
return new (prefix ? AST_UnaryPrefix : AST_UnaryPostfix)({ return new (prefix ? Cola.AST_UnaryPrefix : Cola.AST_UnaryPostfix)({
start : my_start_token(M), start : my_start_token(M),
end : my_end_token(M), end : my_end_token(M),
operator : M.operator, operator : M.operator,
@ -160,43 +160,43 @@
var ME_TO_MOZ = {}; var ME_TO_MOZ = {};
map("Node", AST_Node); map("Node", Cola.AST_Node);
map("Program", AST_Toplevel, "body@body"); map("Program", Cola.AST_Toplevel, "body@body");
map("Function", AST_Function, "id>name, params@argnames, body%body"); map("Function", Cola.AST_Function, "id>name, params@argnames, body%body");
map("EmptyStatement", AST_EmptyStatement); map("EmptyStatement", Cola.AST_EmptyStatement);
map("BlockStatement", AST_BlockStatement, "body@body"); map("BlockStatement", Cola.AST_BlockStatement, "body@body");
map("ExpressionStatement", AST_SimpleStatement, "expression>body"); map("ExpressionStatement", Cola.AST_SimpleStatement, "expression>body");
map("IfStatement", AST_If, "test>condition, consequent>body, alternate>alternative"); map("IfStatement", Cola.AST_If, "test>condition, consequent>body, alternate>alternative");
map("LabeledStatement", AST_LabeledStatement, "label>label, body>body"); map("LabeledStatement", Cola.AST_LabeledStatement, "label>label, body>body");
map("BreakStatement", AST_Break, "label>label"); map("BreakStatement", Cola.AST_Break, "label>label");
map("ContinueStatement", AST_Continue, "label>label"); map("ContinueStatement", Cola.AST_Continue, "label>label");
map("WithStatement", AST_With, "object>expression, body>body"); map("WithStatement", Cola.AST_With, "object>expression, body>body");
map("SwitchStatement", AST_Switch, "discriminant>expression, cases@body"); map("SwitchStatement", Cola.AST_Switch, "discriminant>expression, cases@body");
map("ReturnStatement", AST_Return, "argument>value"); map("ReturnStatement", Cola.AST_Return, "argument>value");
map("ThrowStatement", AST_Throw, "argument>value"); map("ThrowStatement", Cola.AST_Throw, "argument>value");
map("WhileStatement", AST_While, "test>condition, body>body"); map("WhileStatement", Cola.AST_While, "test>condition, body>body");
map("DoWhileStatement", AST_Do, "test>condition, body>body"); map("DoWhileStatement", Cola.AST_Do, "test>condition, body>body");
map("ForStatement", AST_For, "init>init, test>condition, update>step, body>body"); map("ForStatement", Cola.AST_For, "init>init, test>condition, update>step, body>body");
map("ForInStatement", AST_ForIn, "left>init, right>object, body>body"); map("ForInStatement", Cola.AST_ForIn, "left>init, right>object, body>body");
map("DebuggerStatement", AST_Debugger); map("DebuggerStatement", Cola.AST_Debugger);
map("FunctionDeclaration", AST_Defun, "id>name, params@argnames, body%body"); map("FunctionDeclaration", Cola.AST_Defun, "id>name, params@argnames, body%body");
map("VariableDeclaration", AST_Var, "declarations@definitions"); map("VariableDeclaration", Cola.AST_Var, "declarations@definitions");
map("VariableDeclarator", AST_VarDef, "id>name, init>value"); map("VariableDeclarator", Cola.AST_VarDef, "id>name, init>value");
map("ThisExpression", AST_This); map("ThisExpression", Cola.AST_This);
map("ArrayExpression", AST_Array, "elements@elements"); map("ArrayExpression", Cola.AST_Array, "elements@elements");
map("FunctionExpression", AST_Function, "id>name, params@argnames, body%body"); map("FunctionExpression", Cola.AST_Function, "id>name, params@argnames, body%body");
map("BinaryExpression", AST_Binary, "operator=operator, left>left, right>right"); map("BinaryExpression", Cola.AST_Binary, "operator=operator, left>left, right>right");
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right"); map("AssignmentExpression", Cola.AST_Assign, "operator=operator, left>left, right>right");
map("LogicalExpression", AST_Binary, "operator=operator, left>left, right>right"); map("LogicalExpression", Cola.AST_Binary, "operator=operator, left>left, right>right");
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative"); map("ConditionalExpression", Cola.AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
map("NewExpression", AST_New, "callee>expression, arguments@args"); map("NewExpression", Cola.AST_New, "callee>expression, arguments@args");
map("CallExpression", AST_Call, "callee>expression, arguments@args"); map("CallExpression", Cola.AST_Call, "callee>expression, arguments@args");
/* -----[ tools ]----- */ /* -----[ tools ]----- */
function my_start_token(moznode) { function my_start_token(moznode) {
return new AST_Token({ return new Cola.AST_Token({
file : moznode.loc && moznode.loc.source, file : moznode.loc && moznode.loc.source,
line : moznode.loc && moznode.loc.start.line, line : moznode.loc && moznode.loc.start.line,
col : moznode.loc && moznode.loc.start.column, col : moznode.loc && moznode.loc.start.column,
@ -206,7 +206,7 @@
}; };
function my_end_token(moznode) { function my_end_token(moznode) {
return new AST_Token({ return new Cola.AST_Token({
file : moznode.loc && moznode.loc.source, file : moznode.loc && moznode.loc.source,
line : moznode.loc && moznode.loc.end.line, line : moznode.loc && moznode.loc.end.line,
col : moznode.loc && moznode.loc.end.column, col : moznode.loc && moznode.loc.end.column,
@ -256,7 +256,7 @@
return ret; return ret;
}; };
AST_Node.from_mozilla_ast = function(node){ Cola.AST_Node.from_mozilla_ast = function(node){
var save_stack = FROM_MOZ_STACK; var save_stack = FROM_MOZ_STACK;
FROM_MOZ_STACK = []; FROM_MOZ_STACK = [];
var ast = from_moz(node); var ast = from_moz(node);

View File

@ -45,7 +45,7 @@
function OutputStream(options) { function OutputStream(options) {
options = defaults(options, { options = Cola.defaults(options, {
indent_start : 0, indent_start : 0,
indent_level : 4, indent_level : 4,
quote_keys : false, quote_keys : false,
@ -121,7 +121,7 @@ function OutputStream(options) {
}; };
function make_indent(back) { function make_indent(back) {
return repeat_string(" ", options.indent_start + indentation - back * options.indent_level); return Cola.repeat_string(" ", options.indent_start + indentation - back * options.indent_level);
}; };
/* -----[ beautification/minification ]----- */ /* -----[ beautification/minification ]----- */
@ -139,7 +139,7 @@ function OutputStream(options) {
print("\n"); print("\n");
}; };
var requireSemicolonChars = makePredicate("( [ + * / - , ."); var requireSemicolonChars = Cola.makePredicate("( [ + * / - , .");
function print(str) { function print(str) {
str = String(str); str = String(str);
@ -176,8 +176,8 @@ function OutputStream(options) {
if (might_need_space) { if (might_need_space) {
var prev = last_char(); var prev = last_char();
if ((is_identifier_char(prev) if ((Cola.is_identifier_char(prev)
&& (is_identifier_char(ch) || ch == "\\")) && (Cola.is_identifier_char(ch) || ch == "\\"))
|| (/^[\+\-\/]$/.test(ch) && ch == prev)) || (/^[\+\-\/]$/.test(ch) && ch == prev))
{ {
OUTPUT += " "; OUTPUT += " ";
@ -208,7 +208,7 @@ function OutputStream(options) {
if (options.beautify) { if (options.beautify) {
print(make_indent(half ? 0.5 : 0)); print(make_indent(half ? 0.5 : 0));
} }
} : noop; } : Cola.noop;
var with_indent = options.beautify ? function(col, cont) { var with_indent = options.beautify ? function(col, cont) {
if (col === true) col = next_indent(); if (col === true) col = next_indent();
@ -221,7 +221,7 @@ function OutputStream(options) {
var newline = options.beautify ? function() { var newline = options.beautify ? function() {
print("\n"); print("\n");
} : noop; } : Cola.noop;
var semicolon = options.beautify ? function() { var semicolon = options.beautify ? function() {
print(";"); print(";");
@ -286,7 +286,7 @@ function OutputStream(options) {
(!name && token.type == "name") ? token.value : name (!name && token.type == "name") ? token.value : name
); );
} catch(ex) { } catch(ex) {
AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", { Cola.AST_Node.warn("Couldn't figure out mapping for {file}:{line},{col} → {cline},{ccol} [{name}]", {
file: token.file, file: token.file,
line: token.line, line: token.line,
col: token.col, col: token.col,
@ -295,7 +295,7 @@ function OutputStream(options) {
name: name || "" name: name || ""
}) })
} }
} : noop; } : Cola.noop;
function get() { function get() {
return OUTPUT; return OUTPUT;
@ -354,7 +354,7 @@ function OutputStream(options) {
nodetype.DEFMETHOD("_codegen", generator); nodetype.DEFMETHOD("_codegen", generator);
}; };
AST_Node.DEFMETHOD("print", function(stream, force_parens){ Cola.AST_Node.DEFMETHOD("print", function(stream, force_parens){
var self = this, generator = self._codegen; var self = this, generator = self._codegen;
function doit() { function doit() {
self.add_comments(stream); self.add_comments(stream);
@ -370,7 +370,7 @@ function OutputStream(options) {
stream.pop_node(); stream.pop_node();
}); });
AST_Node.DEFMETHOD("print_to_string", function(options){ Cola.AST_Node.DEFMETHOD("print_to_string", function(options){
var s = OutputStream(options); var s = OutputStream(options);
this.print(s); this.print(s);
return s.get(); return s.get();
@ -378,7 +378,7 @@ function OutputStream(options) {
/* -----[ comments ]----- */ /* -----[ comments ]----- */
AST_Node.DEFMETHOD("add_comments", function(output){ Cola.AST_Node.DEFMETHOD("add_comments", function(output){
var c = output.option("comments"), self = this; var c = output.option("comments"), self = this;
if (c) { if (c) {
var start = self.start; var start = self.start;
@ -388,15 +388,15 @@ function OutputStream(options) {
// XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112 // XXX: ugly fix for https://github.com/mishoo/UglifyJS2/issues/112
// and https://github.com/mishoo/UglifyJS2/issues/372 // and https://github.com/mishoo/UglifyJS2/issues/372
if (self instanceof AST_Exit && self.value) { if (self instanceof Cola.AST_Exit && self.value) {
self.value.walk(new TreeWalker(function(node){ self.value.walk(new Cola.TreeWalker(function(node){
if (node.start && node.start.comments_before) { if (node.start && node.start.comments_before) {
comments = comments.concat(node.start.comments_before); comments = comments.concat(node.start.comments_before);
node.start.comments_before = []; node.start.comments_before = [];
} }
if (node instanceof AST_Function || if (node instanceof Cola.AST_Function ||
node instanceof AST_Array || node instanceof Cola.AST_Array ||
node instanceof AST_Object) node instanceof Cola.AST_Object)
{ {
return true; // don't go inside. return true; // don't go inside.
} }
@ -437,56 +437,56 @@ function OutputStream(options) {
nodetype.DEFMETHOD("needs_parens", func); nodetype.DEFMETHOD("needs_parens", func);
}; };
PARENS(AST_Node, function(){ PARENS(Cola.AST_Node, function(){
return false; return false;
}); });
// a function expression needs parens around it when it's provably // a function expression needs parens around it when it's provably
// the first token to appear in a statement. // the first token to appear in a statement.
PARENS(AST_Function, function(output){ PARENS(Cola.AST_Function, function(output){
return first_in_statement(output); return first_in_statement(output);
}); });
// same goes for an object literal, because otherwise it would be // same goes for an object literal, because otherwise it would be
// interpreted as a block of code. // interpreted as a block of code.
PARENS(AST_Object, function(output){ PARENS(Cola.AST_Object, function(output){
return first_in_statement(output); return first_in_statement(output);
}); });
PARENS(AST_Unary, function(output){ PARENS(Cola.AST_Unary, function(output){
var p = output.parent(); var p = output.parent();
return p instanceof AST_PropAccess && p.expression === this; return p instanceof Cola.AST_PropAccess && p.expression === this;
}); });
PARENS(AST_Seq, function(output){ PARENS(Cola.AST_Seq, function(output){
var p = output.parent(); var p = output.parent();
return p instanceof AST_Call // (foo, bar)() or foo(1, (2, 3), 4) return p instanceof Cola.AST_Call // (foo, bar)() or foo(1, (2, 3), 4)
|| p instanceof AST_Unary // !(foo, bar, baz) || p instanceof Cola.AST_Unary // !(foo, bar, baz)
|| p instanceof AST_Binary // 1 + (2, 3) + 4 ==> 8 || p instanceof Cola.AST_Binary // 1 + (2, 3) + 4 ==> 8
|| p instanceof AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4 || p instanceof Cola.AST_VarDef // var a = (1, 2), b = a + a; ==> b == 4
|| p instanceof AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2 || p instanceof Cola.AST_PropAccess // (1, {foo:2}).foo or (1, {foo:2})["foo"] ==> 2
|| p instanceof AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ] || p instanceof Cola.AST_Array // [ 1, (2, 3), 4 ] ==> [ 1, 3, 4 ]
|| p instanceof AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2 || p instanceof Cola.AST_ObjectProperty // { foo: (1, 2) }.foo ==> 2
|| p instanceof AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30) || p instanceof Cola.AST_Conditional /* (false, true) ? (a = 10, b = 20) : (c = 30)
* ==> 20 (side effect, set a := 10 and b := 20) */ * ==> 20 (side effect, set a := 10 and b := 20) */
; ;
}); });
PARENS(AST_Binary, function(output){ PARENS(Cola.AST_Binary, function(output){
var p = output.parent(); var p = output.parent();
// (foo && bar)() // (foo && bar)()
if (p instanceof AST_Call && p.expression === this) if (p instanceof Cola.AST_Call && p.expression === this)
return true; return true;
// typeof (foo && bar) // typeof (foo && bar)
if (p instanceof AST_Unary) if (p instanceof Cola.AST_Unary)
return true; return true;
// (foo && bar)["prop"], (foo && bar).prop // (foo && bar)["prop"], (foo && bar).prop
if (p instanceof AST_PropAccess && p.expression === this) if (p instanceof Cola.AST_PropAccess && p.expression === this)
return true; return true;
// this deals with precedence: 3 * (2 + 1) // this deals with precedence: 3 * (2 + 1)
if (p instanceof AST_Binary) { if (p instanceof Cola.AST_Binary) {
var po = p.operator, pp = PRECEDENCE[po]; var po = p.operator, pp = Cola.PRECEDENCE[po];
var so = this.operator, sp = PRECEDENCE[so]; var so = this.operator, sp = Cola.PRECEDENCE[so];
if (pp > sp if (pp > sp
|| (pp == sp || (pp == sp
&& this === p.right)) { && this === p.right)) {
@ -495,9 +495,9 @@ function OutputStream(options) {
} }
}); });
PARENS(AST_PropAccess, function(output){ PARENS(Cola.AST_PropAccess, function(output){
var p = output.parent(); var p = output.parent();
if (p instanceof AST_New && p.expression === this) { if (p instanceof Cola.AST_New && p.expression === this) {
// i.e. new (foo.bar().baz) // i.e. new (foo.bar().baz)
// //
// if there's one call into this subtree, then we need // if there's one call into this subtree, then we need
@ -505,8 +505,8 @@ function OutputStream(options) {
// interpreted as passing the arguments to the upper New // interpreted as passing the arguments to the upper New
// expression. // expression.
try { try {
this.walk(new TreeWalker(function(node){ this.walk(new Cola.TreeWalker(function(node){
if (node instanceof AST_Call) throw p; if (node instanceof Cola.AST_Call) throw p;
})); }));
} catch(ex) { } catch(ex) {
if (ex !== p) throw ex; if (ex !== p) throw ex;
@ -515,69 +515,69 @@ function OutputStream(options) {
} }
}); });
PARENS(AST_Call, function(output){ PARENS(Cola.AST_Call, function(output){
var p = output.parent(), p1; var p = output.parent(), p1;
if (p instanceof AST_New && p.expression === this) if (p instanceof Cola.AST_New && p.expression === this)
return true; return true;
// workaround for Safari bug. // workaround for Safari bug.
// https://bugs.webkit.org/show_bug.cgi?id=123506 // https://bugs.webkit.org/show_bug.cgi?id=123506
return this.expression instanceof AST_Function return this.expression instanceof Cola.AST_Function
&& p instanceof AST_PropAccess && p instanceof Cola.AST_PropAccess
&& p.expression === this && p.expression === this
&& (p1 = output.parent(1)) instanceof AST_Assign && (p1 = output.parent(1)) instanceof Cola.AST_Assign
&& p1.left === p; && p1.left === p;
}); });
PARENS(AST_New, function(output){ PARENS(Cola.AST_New, function(output){
var p = output.parent(); var p = output.parent();
if (no_constructor_parens(this, output) if (no_constructor_parens(this, output)
&& (p instanceof AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]() && (p instanceof Cola.AST_PropAccess // (new Date).getTime(), (new Date)["getTime"]()
|| p instanceof AST_Call && p.expression === this)) // (new foo)(bar) || p instanceof Cola.AST_Call && p.expression === this)) // (new foo)(bar)
return true; return true;
}); });
PARENS(AST_Number, function(output){ PARENS(Cola.AST_Number, function(output){
var p = output.parent(); var p = output.parent();
if (this.getValue() < 0 && p instanceof AST_PropAccess && p.expression === this) if (this.getValue() < 0 && p instanceof Cola.AST_PropAccess && p.expression === this)
return true; return true;
}); });
PARENS(AST_NaN, function(output){ PARENS(Cola.AST_NaN, function(output){
var p = output.parent(); var p = output.parent();
if (p instanceof AST_PropAccess && p.expression === this) if (p instanceof Cola.AST_PropAccess && p.expression === this)
return true; return true;
}); });
function assign_and_conditional_paren_rules(output) { function assign_and_conditional_paren_rules(output) {
var p = output.parent(); var p = output.parent();
// !(a = false) → true // !(a = false) → true
if (p instanceof AST_Unary) if (p instanceof Cola.AST_Unary)
return true; return true;
// 1 + (a = 2) + 3 → 6, side effect setting a = 2 // 1 + (a = 2) + 3 → 6, side effect setting a = 2
if (p instanceof AST_Binary && !(p instanceof AST_Assign)) if (p instanceof Cola.AST_Binary && !(p instanceof Cola.AST_Assign))
return true; return true;
// (a = func)() —or— new (a = Object)() // (a = func)() —or— new (a = Object)()
if (p instanceof AST_Call && p.expression === this) if (p instanceof Cola.AST_Call && p.expression === this)
return true; return true;
// (a = foo) ? bar : baz // (a = foo) ? bar : baz
if (p instanceof AST_Conditional && p.condition === this) if (p instanceof Cola.AST_Conditional && p.condition === this)
return true; return true;
// (a = foo)["prop"] —or— (a = foo).prop // (a = foo)["prop"] —or— (a = foo).prop
if (p instanceof AST_PropAccess && p.expression === this) if (p instanceof Cola.AST_PropAccess && p.expression === this)
return true; return true;
}; };
PARENS(AST_Assign, assign_and_conditional_paren_rules); PARENS(Cola.AST_Assign, assign_and_conditional_paren_rules);
PARENS(AST_Conditional, assign_and_conditional_paren_rules); PARENS(Cola.AST_Conditional, assign_and_conditional_paren_rules);
/* -----[ PRINTERS ]----- */ /* -----[ PRINTERS ]----- */
DEFPRINT(AST_Directive, function(self, output){ DEFPRINT(Cola.AST_Directive, function(self, output){
output.print_string(self.value); output.print_string(self.value);
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_Debugger, function(self, output){ DEFPRINT(Cola.AST_Debugger, function(self, output){
output.print("debugger"); output.print("debugger");
output.semicolon(); output.semicolon();
}); });
@ -587,7 +587,7 @@ function OutputStream(options) {
function display_body(body, is_toplevel, output) { function display_body(body, is_toplevel, output) {
var last = body.length - 1; var last = body.length - 1;
body.forEach(function(stmt, i){ body.forEach(function(stmt, i){
if (!(stmt instanceof AST_EmptyStatement)) { if (!(stmt instanceof Cola.AST_EmptyStatement)) {
output.indent(); output.indent();
stmt.print(output); stmt.print(output);
if (!(i == last && is_toplevel)) { if (!(i == last && is_toplevel)) {
@ -598,24 +598,24 @@ function OutputStream(options) {
}); });
}; };
AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){ Cola.AST_StatementWithBody.DEFMETHOD("_do_print_body", function(output){
force_statement(this.body, output); force_statement(this.body, output);
}); });
DEFPRINT(AST_Statement, function(self, output){ DEFPRINT(Cola.AST_Statement, function(self, output){
self.body.print(output); self.body.print(output);
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_Toplevel, function(self, output){ DEFPRINT(Cola.AST_Toplevel, function(self, output){
display_body(self.body, true, output); display_body(self.body, true, output);
output.print(""); output.print("");
}); });
DEFPRINT(AST_LabeledStatement, function(self, output){ DEFPRINT(Cola.AST_LabeledStatement, function(self, output){
self.label.print(output); self.label.print(output);
output.colon(); output.colon();
self.body.print(output); self.body.print(output);
}); });
DEFPRINT(AST_SimpleStatement, function(self, output){ DEFPRINT(Cola.AST_SimpleStatement, function(self, output){
self.body.print(output); self.body.print(output);
output.semicolon(); output.semicolon();
}); });
@ -625,13 +625,13 @@ function OutputStream(options) {
}); });
else output.print("{}"); else output.print("{}");
}; };
DEFPRINT(AST_BlockStatement, function(self, output){ DEFPRINT(Cola.AST_BlockStatement, function(self, output){
print_bracketed(self.body, output); print_bracketed(self.body, output);
}); });
DEFPRINT(AST_EmptyStatement, function(self, output){ DEFPRINT(Cola.AST_EmptyStatement, function(self, output){
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_Do, function(self, output){ DEFPRINT(Cola.AST_Do, function(self, output){
output.print("do"); output.print("do");
output.space(); output.space();
self._do_print_body(output); self._do_print_body(output);
@ -643,7 +643,7 @@ function OutputStream(options) {
}); });
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_While, function(self, output){ DEFPRINT(Cola.AST_While, function(self, output){
output.print("while"); output.print("while");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
@ -652,12 +652,12 @@ function OutputStream(options) {
output.space(); output.space();
self._do_print_body(output); self._do_print_body(output);
}); });
DEFPRINT(AST_For, function(self, output){ DEFPRINT(Cola.AST_For, function(self, output){
output.print("for"); output.print("for");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
if (self.init) { if (self.init) {
if (self.init instanceof AST_Definitions) { if (self.init instanceof Cola.AST_Definitions) {
self.init.print(output); self.init.print(output);
} else { } else {
parenthesize_for_noin(self.init, output, true); parenthesize_for_noin(self.init, output, true);
@ -681,7 +681,7 @@ function OutputStream(options) {
output.space(); output.space();
self._do_print_body(output); self._do_print_body(output);
}); });
DEFPRINT(AST_ForIn, function(self, output){ DEFPRINT(Cola.AST_ForIn, function(self, output){
output.print("for"); output.print("for");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
@ -694,7 +694,7 @@ function OutputStream(options) {
output.space(); output.space();
self._do_print_body(output); self._do_print_body(output);
}); });
DEFPRINT(AST_With, function(self, output){ DEFPRINT(Cola.AST_With, function(self, output){
output.print("with"); output.print("with");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
@ -705,7 +705,7 @@ function OutputStream(options) {
}); });
/* -----[ functions ]----- */ /* -----[ functions ]----- */
AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){ Cola.AST_Lambda.DEFMETHOD("_do_print", function(output, nokeyword){
var self = this; var self = this;
if (!nokeyword) { if (!nokeyword) {
output.print("function"); output.print("function");
@ -723,12 +723,12 @@ function OutputStream(options) {
output.space(); output.space();
print_bracketed(self.body, output); print_bracketed(self.body, output);
}); });
DEFPRINT(AST_Lambda, function(self, output){ DEFPRINT(Cola.AST_Lambda, function(self, output){
self._do_print(output); self._do_print(output);
}); });
/* -----[ exits ]----- */ /* -----[ exits ]----- */
AST_Exit.DEFMETHOD("_do_print", function(output, kind){ Cola.AST_Exit.DEFMETHOD("_do_print", function(output, kind){
output.print(kind); output.print(kind);
if (this.value) { if (this.value) {
output.space(); output.space();
@ -736,15 +736,15 @@ function OutputStream(options) {
} }
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_Return, function(self, output){ DEFPRINT(Cola.AST_Return, function(self, output){
self._do_print(output, "return"); self._do_print(output, "return");
}); });
DEFPRINT(AST_Throw, function(self, output){ DEFPRINT(Cola.AST_Throw, function(self, output){
self._do_print(output, "throw"); self._do_print(output, "throw");
}); });
/* -----[ loop control ]----- */ /* -----[ loop control ]----- */
AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){ Cola.AST_LoopControl.DEFMETHOD("_do_print", function(output, kind){
output.print(kind); output.print(kind);
if (this.label) { if (this.label) {
output.space(); output.space();
@ -752,10 +752,10 @@ function OutputStream(options) {
} }
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_Break, function(self, output){ DEFPRINT(Cola.AST_Break, function(self, output){
self._do_print(output, "break"); self._do_print(output, "break");
}); });
DEFPRINT(AST_Continue, function(self, output){ DEFPRINT(Cola.AST_Continue, function(self, output){
self._do_print(output, "continue"); self._do_print(output, "continue");
}); });
@ -774,7 +774,7 @@ function OutputStream(options) {
// adds the block brackets if needed. // adds the block brackets if needed.
if (!self.body) if (!self.body)
return output.force_semicolon(); return output.force_semicolon();
if (self.body instanceof AST_Do if (self.body instanceof Cola.AST_Do
&& !output.option("screw_ie8")) { && !output.option("screw_ie8")) {
// https://github.com/mishoo/UglifyJS/issues/#issue/57 IE // https://github.com/mishoo/UglifyJS/issues/#issue/57 IE
// croaks with "syntax error" on code like this: if (foo) // croaks with "syntax error" on code like this: if (foo)
@ -785,21 +785,21 @@ function OutputStream(options) {
} }
var b = self.body; var b = self.body;
while (true) { while (true) {
if (b instanceof AST_If) { if (b instanceof Cola.AST_If) {
if (!b.alternative) { if (!b.alternative) {
make_block(self.body, output); make_block(self.body, output);
return; return;
} }
b = b.alternative; b = b.alternative;
} }
else if (b instanceof AST_StatementWithBody) { else if (b instanceof Cola.AST_StatementWithBody) {
b = b.body; b = b.body;
} }
else break; else break;
} }
force_statement(self.body, output); force_statement(self.body, output);
}; };
DEFPRINT(AST_If, function(self, output){ DEFPRINT(Cola.AST_If, function(self, output){
output.print("if"); output.print("if");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
@ -818,7 +818,7 @@ function OutputStream(options) {
}); });
/* -----[ switch ]----- */ /* -----[ switch ]----- */
DEFPRINT(AST_Switch, function(self, output){ DEFPRINT(Cola.AST_Switch, function(self, output){
output.print("switch"); output.print("switch");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
@ -834,7 +834,7 @@ function OutputStream(options) {
}); });
else output.print("{}"); else output.print("{}");
}); });
AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){ Cola.AST_SwitchBranch.DEFMETHOD("_do_print_body", function(output){
if (this.body.length > 0) { if (this.body.length > 0) {
output.newline(); output.newline();
this.body.forEach(function(stmt){ this.body.forEach(function(stmt){
@ -844,11 +844,11 @@ function OutputStream(options) {
}); });
} }
}); });
DEFPRINT(AST_Default, function(self, output){ DEFPRINT(Cola.AST_Default, function(self, output){
output.print("default:"); output.print("default:");
self._do_print_body(output); self._do_print_body(output);
}); });
DEFPRINT(AST_Case, function(self, output){ DEFPRINT(Cola.AST_Case, function(self, output){
output.print("case"); output.print("case");
output.space(); output.space();
self.expression.print(output); self.expression.print(output);
@ -857,7 +857,7 @@ function OutputStream(options) {
}); });
/* -----[ exceptions ]----- */ /* -----[ exceptions ]----- */
DEFPRINT(AST_Try, function(self, output){ DEFPRINT(Cola.AST_Try, function(self, output){
output.print("try"); output.print("try");
output.space(); output.space();
print_bracketed(self.body, output); print_bracketed(self.body, output);
@ -870,7 +870,7 @@ function OutputStream(options) {
self.bfinally.print(output); self.bfinally.print(output);
} }
}); });
DEFPRINT(AST_Catch, function(self, output){ DEFPRINT(Cola.AST_Catch, function(self, output){
output.print("catch"); output.print("catch");
output.space(); output.space();
output.with_parens(function(){ output.with_parens(function(){
@ -879,14 +879,14 @@ function OutputStream(options) {
output.space(); output.space();
print_bracketed(self.body, output); print_bracketed(self.body, output);
}); });
DEFPRINT(AST_Finally, function(self, output){ DEFPRINT(Cola.AST_Finally, function(self, output){
output.print("finally"); output.print("finally");
output.space(); output.space();
print_bracketed(self.body, output); print_bracketed(self.body, output);
}); });
/* -----[ var/const ]----- */ /* -----[ var/const ]----- */
AST_Definitions.DEFMETHOD("_do_print", function(output, kind){ Cola.AST_Definitions.DEFMETHOD("_do_print", function(output, kind){
output.print(kind); output.print(kind);
output.space(); output.space();
this.definitions.forEach(function(def, i){ this.definitions.forEach(function(def, i){
@ -894,15 +894,15 @@ function OutputStream(options) {
def.print(output); def.print(output);
}); });
var p = output.parent(); var p = output.parent();
var in_for = p instanceof AST_For || p instanceof AST_ForIn; var in_for = p instanceof Cola.AST_For || p instanceof Cola.AST_ForIn;
var avoid_semicolon = in_for && p.init === this; var avoid_semicolon = in_for && p.init === this;
if (!avoid_semicolon) if (!avoid_semicolon)
output.semicolon(); output.semicolon();
}); });
DEFPRINT(AST_Var, function(self, output){ DEFPRINT(Cola.AST_Var, function(self, output){
self._do_print(output, "var"); self._do_print(output, "var");
}); });
DEFPRINT(AST_Const, function(self, output){ DEFPRINT(Cola.AST_Const, function(self, output){
self._do_print(output, "const"); self._do_print(output, "const");
}); });
@ -911,8 +911,8 @@ function OutputStream(options) {
else try { else try {
// need to take some precautions here: // need to take some precautions here:
// https://github.com/mishoo/UglifyJS2/issues/60 // https://github.com/mishoo/UglifyJS2/issues/60
node.walk(new TreeWalker(function(node){ node.walk(new Cola.TreeWalker(function(node){
if (node instanceof AST_Binary && node.operator == "in") if (node instanceof Cola.AST_Binary && node.operator == "in")
throw output; throw output;
})); }));
node.print(output); node.print(output);
@ -922,22 +922,22 @@ function OutputStream(options) {
} }
}; };
DEFPRINT(AST_VarDef, function(self, output){ DEFPRINT(Cola.AST_VarDef, function(self, output){
self.name.print(output); self.name.print(output);
if (self.value) { if (self.value) {
output.space(); output.space();
output.print("="); output.print("=");
output.space(); output.space();
var p = output.parent(1); var p = output.parent(1);
var noin = p instanceof AST_For || p instanceof AST_ForIn; var noin = p instanceof Cola.AST_For || p instanceof Cola.AST_ForIn;
parenthesize_for_noin(self.value, output, noin); parenthesize_for_noin(self.value, output, noin);
} }
}); });
/* -----[ other expressions ]----- */ /* -----[ other expressions ]----- */
DEFPRINT(AST_Call, function(self, output){ DEFPRINT(Cola.AST_Call, function(self, output){
self.expression.print(output); self.expression.print(output);
if (self instanceof AST_New && no_constructor_parens(self, output)) if (self instanceof Cola.AST_New && no_constructor_parens(self, output))
return; return;
output.with_parens(function(){ output.with_parens(function(){
self.args.forEach(function(expr, i){ self.args.forEach(function(expr, i){
@ -946,13 +946,13 @@ function OutputStream(options) {
}); });
}); });
}); });
DEFPRINT(AST_New, function(self, output){ DEFPRINT(Cola.AST_New, function(self, output){
output.print("new"); output.print("new");
output.space(); output.space();
AST_Call.prototype._codegen(self, output); Cola.AST_Call.prototype._codegen(self, output);
}); });
AST_Seq.DEFMETHOD("_do_print", function(output){ Cola.AST_Seq.DEFMETHOD("_do_print", function(output){
this.car.print(output); this.car.print(output);
if (this.cdr) { if (this.cdr) {
output.comma(); output.comma();
@ -963,10 +963,10 @@ function OutputStream(options) {
this.cdr.print(output); this.cdr.print(output);
} }
}); });
DEFPRINT(AST_Seq, function(self, output){ DEFPRINT(Cola.AST_Seq, function(self, output){
self._do_print(output); self._do_print(output);
// var p = output.parent(); // var p = output.parent();
// if (p instanceof AST_Statement) { // if (p instanceof Cola.AST_Statement) {
// output.with_indent(output.next_indent(), function(){ // output.with_indent(output.next_indent(), function(){
// self._do_print(output); // self._do_print(output);
// }); // });
@ -974,10 +974,10 @@ function OutputStream(options) {
// self._do_print(output); // self._do_print(output);
// } // }
}); });
DEFPRINT(AST_Dot, function(self, output){ DEFPRINT(Cola.AST_Dot, function(self, output){
var expr = self.expression; var expr = self.expression;
expr.print(output); expr.print(output);
if (expr instanceof AST_Number && expr.getValue() >= 0) { if (expr instanceof Cola.AST_Number && expr.getValue() >= 0) {
if (!/[xa-f.]/i.test(output.last())) { if (!/[xa-f.]/i.test(output.last())) {
output.print("."); output.print(".");
} }
@ -987,31 +987,31 @@ function OutputStream(options) {
output.add_mapping(self.end); output.add_mapping(self.end);
output.print_name(self.property); output.print_name(self.property);
}); });
DEFPRINT(AST_Sub, function(self, output){ DEFPRINT(Cola.AST_Sub, function(self, output){
self.expression.print(output); self.expression.print(output);
output.print("["); output.print("[");
self.property.print(output); self.property.print(output);
output.print("]"); output.print("]");
}); });
DEFPRINT(AST_UnaryPrefix, function(self, output){ DEFPRINT(Cola.AST_UnaryPrefix, function(self, output){
var op = self.operator; var op = self.operator;
output.print(op); output.print(op);
if (/^[a-z]/i.test(op)) if (/^[a-z]/i.test(op))
output.space(); output.space();
self.expression.print(output); self.expression.print(output);
}); });
DEFPRINT(AST_UnaryPostfix, function(self, output){ DEFPRINT(Cola.AST_UnaryPostfix, function(self, output){
self.expression.print(output); self.expression.print(output);
output.print(self.operator); output.print(self.operator);
}); });
DEFPRINT(AST_Binary, function(self, output){ DEFPRINT(Cola.AST_Binary, function(self, output){
self.left.print(output); self.left.print(output);
output.space(); output.space();
output.print(self.operator); output.print(self.operator);
if (self.operator == "<" if (self.operator == "<"
&& self.right instanceof AST_UnaryPrefix && self.right instanceof Cola.AST_UnaryPrefix
&& self.right.operator == "!" && self.right.operator == "!"
&& self.right.expression instanceof AST_UnaryPrefix && self.right.expression instanceof Cola.AST_UnaryPrefix
&& self.right.expression.operator == "--") { && self.right.expression.operator == "--") {
// space is mandatory to avoid outputting <!-- // space is mandatory to avoid outputting <!--
// http://javascript.spec.whatwg.org/#comment-syntax // http://javascript.spec.whatwg.org/#comment-syntax
@ -1022,7 +1022,7 @@ function OutputStream(options) {
} }
self.right.print(output); self.right.print(output);
}); });
DEFPRINT(AST_Conditional, function(self, output){ DEFPRINT(Cola.AST_Conditional, function(self, output){
self.condition.print(output); self.condition.print(output);
output.space(); output.space();
output.print("?"); output.print("?");
@ -1034,7 +1034,7 @@ function OutputStream(options) {
}); });
/* -----[ literals ]----- */ /* -----[ literals ]----- */
DEFPRINT(AST_Array, function(self, output){ DEFPRINT(Cola.AST_Array, function(self, output){
output.with_square(function(){ output.with_square(function(){
var a = self.elements, len = a.length; var a = self.elements, len = a.length;
if (len > 0) output.space(); if (len > 0) output.space();
@ -1044,13 +1044,13 @@ function OutputStream(options) {
// If the final element is a hole, we need to make sure it // If the final element is a hole, we need to make sure it
// doesn't look like a trailing comma, by inserting an actual // doesn't look like a trailing comma, by inserting an actual
// trailing comma. // trailing comma.
if (i === len - 1 && exp instanceof AST_Hole) if (i === len - 1 && exp instanceof Cola.AST_Hole)
output.comma(); output.comma();
}); });
if (len > 0) output.space(); if (len > 0) output.space();
}); });
}); });
DEFPRINT(AST_Object, function(self, output){ DEFPRINT(Cola.AST_Object, function(self, output){
if (self.properties.length > 0) output.with_block(function(){ if (self.properties.length > 0) output.with_block(function(){
self.properties.forEach(function(prop, i){ self.properties.forEach(function(prop, i){
if (i) { if (i) {
@ -1064,7 +1064,7 @@ function OutputStream(options) {
}); });
else output.print("{}"); else output.print("{}");
}); });
DEFPRINT(AST_ObjectKeyVal, function(self, output){ DEFPRINT(Cola.AST_ObjectKeyVal, function(self, output){
var key = self.key; var key = self.key;
if (output.option("quote_keys")) { if (output.option("quote_keys")) {
output.print_string(key + ""); output.print_string(key + "");
@ -1073,7 +1073,7 @@ function OutputStream(options) {
&& +key + "" == key) && +key + "" == key)
&& parseFloat(key) >= 0) { && parseFloat(key) >= 0) {
output.print(make_num(key)); output.print(make_num(key));
} else if (RESERVED_WORDS(key) ? output.option("screw_ie8") : is_identifier_string(key)) { } else if (Cola.RESERVED_WORDS(key) ? output.option("screw_ie8") : Cola.is_identifier_string(key)) {
output.print_name(key); output.print_name(key);
} else { } else {
output.print_string(key); output.print_string(key);
@ -1081,42 +1081,42 @@ function OutputStream(options) {
output.colon(); output.colon();
self.value.print(output); self.value.print(output);
}); });
DEFPRINT(AST_ObjectSetter, function(self, output){ DEFPRINT(Cola.AST_ObjectSetter, function(self, output){
output.print("set"); output.print("set");
output.space(); output.space();
self.key.print(output); self.key.print(output);
self.value._do_print(output, true); self.value._do_print(output, true);
}); });
DEFPRINT(AST_ObjectGetter, function(self, output){ DEFPRINT(Cola.AST_ObjectGetter, function(self, output){
output.print("get"); output.print("get");
output.space(); output.space();
self.key.print(output); self.key.print(output);
self.value._do_print(output, true); self.value._do_print(output, true);
}); });
DEFPRINT(AST_Symbol, function(self, output){ DEFPRINT(Cola.AST_Symbol, function(self, output){
var def = self.definition(); var def = self.definition();
output.print_name(def ? def.mangled_name || def.name : self.name); output.print_name(def ? def.mangled_name || def.name : self.name);
}); });
DEFPRINT(AST_Undefined, function(self, output){ DEFPRINT(Cola.AST_Undefined, function(self, output){
output.print("void 0"); output.print("void 0");
}); });
DEFPRINT(AST_Hole, noop); DEFPRINT(Cola.AST_Hole, Cola.noop);
DEFPRINT(AST_Infinity, function(self, output){ DEFPRINT(Cola.AST_Infinity, function(self, output){
output.print("1/0"); output.print("1/0");
}); });
DEFPRINT(AST_NaN, function(self, output){ DEFPRINT(Cola.AST_NaN, function(self, output){
output.print("0/0"); output.print("0/0");
}); });
DEFPRINT(AST_This, function(self, output){ DEFPRINT(Cola.AST_This, function(self, output){
output.print("this"); output.print("this");
}); });
DEFPRINT(AST_Constant, function(self, output){ DEFPRINT(Cola.AST_Constant, function(self, output){
output.print(self.getValue()); output.print(self.getValue());
}); });
DEFPRINT(AST_String, function(self, output){ DEFPRINT(Cola.AST_String, function(self, output){
output.print_string(self.getValue()); output.print_string(self.getValue());
}); });
DEFPRINT(AST_Number, function(self, output){ DEFPRINT(Cola.AST_Number, function(self, output){
output.print(make_num(self.getValue())); output.print(make_num(self.getValue()));
}); });
@ -1148,7 +1148,7 @@ function OutputStream(options) {
].indexOf(code) < 0; ].indexOf(code) < 0;
}; };
DEFPRINT(AST_RegExp, function(self, output){ DEFPRINT(Cola.AST_RegExp, function(self, output){
var str = self.getValue().toString(); var str = self.getValue().toString();
if (output.option("ascii_only")) { if (output.option("ascii_only")) {
str = output.to_ascii(str); str = output.to_ascii(str);
@ -1162,15 +1162,15 @@ function OutputStream(options) {
} }
output.print(str); output.print(str);
var p = output.parent(); var p = output.parent();
if (p instanceof AST_Binary && /^in/.test(p.operator) && p.left === self) if (p instanceof Cola.AST_Binary && /^in/.test(p.operator) && p.left === self)
output.print(" "); output.print(" ");
}); });
function force_statement(stat, output) { function force_statement(stat, output) {
if (output.option("bracketize")) { if (output.option("bracketize")) {
if (!stat || stat instanceof AST_EmptyStatement) if (!stat || stat instanceof Cola.AST_EmptyStatement)
output.print("{}"); output.print("{}");
else if (stat instanceof AST_BlockStatement) else if (stat instanceof Cola.AST_BlockStatement)
stat.print(output); stat.print(output);
else output.with_block(function(){ else output.with_block(function(){
output.indent(); output.indent();
@ -1178,7 +1178,7 @@ function OutputStream(options) {
output.newline(); output.newline();
}); });
} else { } else {
if (!stat || stat instanceof AST_EmptyStatement) if (!stat || stat instanceof Cola.AST_EmptyStatement)
output.force_semicolon(); output.force_semicolon();
else else
stat.print(output); stat.print(output);
@ -1191,15 +1191,15 @@ function OutputStream(options) {
function first_in_statement(output) { function first_in_statement(output) {
var a = output.stack(), i = a.length, node = a[--i], p = a[--i]; var a = output.stack(), i = a.length, node = a[--i], p = a[--i];
while (i > 0) { while (i > 0) {
if (p instanceof AST_Statement && p.body === node) if (p instanceof Cola.AST_Statement && p.body === node)
return true; return true;
if ((p instanceof AST_Seq && p.car === node ) || if ((p instanceof Cola.AST_Seq && p.car === node ) ||
(p instanceof AST_Call && p.expression === node && !(p instanceof AST_New) ) || (p instanceof Cola.AST_Call && p.expression === node && !(p instanceof Cola.AST_New) ) ||
(p instanceof AST_Dot && p.expression === node ) || (p instanceof Cola.AST_Dot && p.expression === node ) ||
(p instanceof AST_Sub && p.expression === node ) || (p instanceof Cola.AST_Sub && p.expression === node ) ||
(p instanceof AST_Conditional && p.condition === node ) || (p instanceof Cola.AST_Conditional && p.condition === node ) ||
(p instanceof AST_Binary && p.left === node ) || (p instanceof Cola.AST_Binary && p.left === node ) ||
(p instanceof AST_UnaryPostfix && p.expression === node )) (p instanceof Cola.AST_UnaryPostfix && p.expression === node ))
{ {
node = p; node = p;
p = a[--i]; p = a[--i];
@ -1209,7 +1209,7 @@ function OutputStream(options) {
} }
}; };
// self should be AST_New. decide if we want to show parens or not. // self should be Cola.AST_New. decide if we want to show parens or not.
function no_constructor_parens(self, output) { function no_constructor_parens(self, output) {
return self.args.length == 0 && !output.option("beautify"); return self.args.length == 0 && !output.option("beautify");
}; };
@ -1246,7 +1246,7 @@ function OutputStream(options) {
}; };
function make_block(stmt, output) { function make_block(stmt, output) {
if (stmt instanceof AST_BlockStatement) { if (stmt instanceof Cola.AST_BlockStatement) {
stmt.print(output); stmt.print(output);
return; return;
} }
@ -1266,8 +1266,8 @@ function OutputStream(options) {
}; };
// We could easily add info for ALL nodes, but it seems to me that // We could easily add info for ALL nodes, but it seems to me that
// would be quite wasteful, hence this noop in the base class. // would be quite wasteful, hence this Cola.noop in the base class.
DEFMAP(AST_Node, noop); DEFMAP(Cola.AST_Node, Cola.noop);
function basic_sourcemap_gen(self, output) { function basic_sourcemap_gen(self, output) {
output.add_mapping(self.start); output.add_mapping(self.start);
@ -1276,24 +1276,24 @@ function OutputStream(options) {
// XXX: I'm not exactly sure if we need it for all of these nodes, // XXX: I'm not exactly sure if we need it for all of these nodes,
// or if we should add even more. // or if we should add even more.
DEFMAP(AST_Directive, basic_sourcemap_gen); DEFMAP(Cola.AST_Directive, basic_sourcemap_gen);
DEFMAP(AST_Debugger, basic_sourcemap_gen); DEFMAP(Cola.AST_Debugger, basic_sourcemap_gen);
DEFMAP(AST_Symbol, basic_sourcemap_gen); DEFMAP(Cola.AST_Symbol, basic_sourcemap_gen);
DEFMAP(AST_Jump, basic_sourcemap_gen); DEFMAP(Cola.AST_Jump, basic_sourcemap_gen);
DEFMAP(AST_StatementWithBody, basic_sourcemap_gen); DEFMAP(Cola.AST_StatementWithBody, basic_sourcemap_gen);
DEFMAP(AST_LabeledStatement, noop); // since the label symbol will mark it DEFMAP(Cola.AST_LabeledStatement, Cola.noop); // since the label symbol will mark it
DEFMAP(AST_Lambda, basic_sourcemap_gen); DEFMAP(Cola.AST_Lambda, basic_sourcemap_gen);
DEFMAP(AST_Switch, basic_sourcemap_gen); DEFMAP(Cola.AST_Switch, basic_sourcemap_gen);
DEFMAP(AST_SwitchBranch, basic_sourcemap_gen); DEFMAP(Cola.AST_SwitchBranch, basic_sourcemap_gen);
DEFMAP(AST_BlockStatement, basic_sourcemap_gen); DEFMAP(Cola.AST_BlockStatement, basic_sourcemap_gen);
DEFMAP(AST_Toplevel, noop); DEFMAP(Cola.AST_Toplevel, Cola.noop);
DEFMAP(AST_New, basic_sourcemap_gen); DEFMAP(Cola.AST_New, basic_sourcemap_gen);
DEFMAP(AST_Try, basic_sourcemap_gen); DEFMAP(Cola.AST_Try, basic_sourcemap_gen);
DEFMAP(AST_Catch, basic_sourcemap_gen); DEFMAP(Cola.AST_Catch, basic_sourcemap_gen);
DEFMAP(AST_Finally, basic_sourcemap_gen); DEFMAP(Cola.AST_Finally, basic_sourcemap_gen);
DEFMAP(AST_Definitions, basic_sourcemap_gen); DEFMAP(Cola.AST_Definitions, basic_sourcemap_gen);
DEFMAP(AST_Constant, basic_sourcemap_gen); DEFMAP(Cola.AST_Constant, basic_sourcemap_gen);
DEFMAP(AST_ObjectProperty, function(self, output){ DEFMAP(Cola.AST_ObjectProperty, function(self, output){
output.add_mapping(self.start, self.key); output.add_mapping(self.start, self.key);
}); });

File diff suppressed because it is too large Load Diff

View File

@ -64,15 +64,15 @@ SymbolDef.prototype = {
mangle: function(options) { mangle: function(options) {
if (!this.mangled_name && !this.unmangleable(options)) { if (!this.mangled_name && !this.unmangleable(options)) {
var s = this.scope; var s = this.scope;
if (!options.screw_ie8 && this.orig[0] instanceof AST_SymbolLambda) if (!options.screw_ie8 && this.orig[0] instanceof Cola.AST_SymbolLambda)
s = s.parent_scope; s = s.parent_scope;
this.mangled_name = s.next_mangled(options, this); this.mangled_name = s.next_mangled(options, this);
} }
} }
}; };
AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){ Cola.AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
options = defaults(options, { options = Cola.defaults(options, {
screw_ie8: false screw_ie8: false
}); });
@ -81,17 +81,17 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
var scope = self.parent_scope = null; var scope = self.parent_scope = null;
var defun = null; var defun = null;
var nesting = 0; var nesting = 0;
var tw = new TreeWalker(function(node, descend){ var tw = new Cola.TreeWalker(function(node, descend){
if (options.screw_ie8 && node instanceof AST_Catch) { if (options.screw_ie8 && node instanceof Cola.AST_Catch) {
var save_scope = scope; var save_scope = scope;
scope = new AST_Scope(node); scope = new Cola.AST_Scope(node);
scope.init_scope_vars(nesting); scope.init_scope_vars(nesting);
scope.parent_scope = save_scope; scope.parent_scope = save_scope;
descend(); descend();
scope = save_scope; scope = save_scope;
return true; return true;
} }
if (node instanceof AST_Scope) { if (node instanceof Cola.AST_Scope) {
node.init_scope_vars(nesting); node.init_scope_vars(nesting);
var save_scope = node.parent_scope = scope; var save_scope = node.parent_scope = scope;
var save_defun = defun; var save_defun = defun;
@ -99,39 +99,39 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
++nesting; descend(); --nesting; ++nesting; descend(); --nesting;
scope = save_scope; scope = save_scope;
defun = save_defun; defun = save_defun;
return true; // don't descend again in TreeWalker return true; // don't descend again in Cola.TreeWalker
} }
if (node instanceof AST_Directive) { if (node instanceof Cola.AST_Directive) {
node.scope = scope; node.scope = scope;
push_uniq(scope.directives, node.value); Cola.push_uniq(scope.directives, node.value);
return true; return true;
} }
if (node instanceof AST_With) { if (node instanceof Cola.AST_With) {
for (var s = scope; s; s = s.parent_scope) for (var s = scope; s; s = s.parent_scope)
s.uses_with = true; s.uses_with = true;
return; return;
} }
if (node instanceof AST_Symbol) { if (node instanceof Cola.AST_Symbol) {
node.scope = scope; node.scope = scope;
} }
if (node instanceof AST_SymbolLambda) { if (node instanceof Cola.AST_SymbolLambda) {
defun.def_function(node); defun.def_function(node);
} }
else if (node instanceof AST_SymbolDefun) { else if (node instanceof Cola.AST_SymbolDefun) {
// Careful here, the scope where this should be defined is // Careful here, the scope where this should be defined is
// the parent scope. The reason is that we enter a new // the parent scope. The reason is that we enter a new
// scope when we encounter the AST_Defun node (which is // scope when we encounter the Cola.AST_Defun node (which is
// instanceof AST_Scope) but we get to the symbol a bit // instanceof Cola.AST_Scope) but we get to the symbol a bit
// later. // later.
(node.scope = defun.parent_scope).def_function(node); (node.scope = defun.parent_scope).def_function(node);
} }
else if (node instanceof AST_SymbolVar else if (node instanceof Cola.AST_SymbolVar
|| node instanceof AST_SymbolConst) { || node instanceof Cola.AST_SymbolConst) {
var def = defun.def_variable(node); var def = defun.def_variable(node);
def.constant = node instanceof AST_SymbolConst; def.constant = node instanceof Cola.AST_SymbolConst;
def.init = tw.parent().value; def.init = tw.parent().value;
} }
else if (node instanceof AST_SymbolCatch) { else if (node instanceof Cola.AST_SymbolCatch) {
(options.screw_ie8 ? scope : defun) (options.screw_ie8 ? scope : defun)
.def_variable(node); .def_variable(node);
} }
@ -140,16 +140,16 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
// pass 2: find back references and eval // pass 2: find back references and eval
var func = null; var func = null;
var globals = self.globals = new Dictionary(); var globals = self.globals = new Cola.Dictionary();
var tw = new TreeWalker(function(node, descend){ var tw = new Cola.TreeWalker(function(node, descend){
if (node instanceof AST_Lambda) { if (node instanceof Cola.AST_Lambda) {
var prev_func = func; var prev_func = func;
func = node; func = node;
descend(); descend();
func = prev_func; func = prev_func;
return true; return true;
} }
if (node instanceof AST_SymbolRef) { if (node instanceof Cola.AST_SymbolRef) {
var name = node.name; var name = node.name;
var sym = node.scope.find_variable(name); var sym = node.scope.find_variable(name);
if (!sym) { if (!sym) {
@ -163,7 +163,7 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
globals.set(name, g); globals.set(name, g);
} }
node.thedef = g; node.thedef = g;
if (name == "eval" && tw.parent() instanceof AST_Call) { if (name == "eval" && tw.parent() instanceof Cola.AST_Call) {
for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope) for (var s = node.scope; s && !s.uses_eval; s = s.parent_scope)
s.uses_eval = true; s.uses_eval = true;
} }
@ -180,10 +180,10 @@ AST_Toplevel.DEFMETHOD("figure_out_scope", function(options){
self.walk(tw); self.walk(tw);
}); });
AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){ Cola.AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
this.directives = []; // contains the directives defined in this scope, i.e. "use strict" this.directives = []; // contains the directives defined in this scope, i.e. "use strict"
this.variables = new Dictionary(); // map name to AST_SymbolVar (variables defined in this scope; includes functions) this.variables = new Cola.Dictionary(); // map name to Cola.AST_SymbolVar (variables defined in this scope; includes functions)
this.functions = new Dictionary(); // map name to AST_SymbolDefun (functions defined in this scope) this.functions = new Cola.Dictionary(); // map name to Cola.AST_SymbolDefun (functions defined in this scope)
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval` this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
this.parent_scope = null; // the parent scope this.parent_scope = null; // the parent scope
@ -192,43 +192,43 @@ AST_Scope.DEFMETHOD("init_scope_vars", function(nesting){
this.nesting = nesting; // the nesting level of this scope (0 means toplevel) this.nesting = nesting; // the nesting level of this scope (0 means toplevel)
}); });
AST_Scope.DEFMETHOD("strict", function(){ Cola.AST_Scope.DEFMETHOD("strict", function(){
return this.has_directive("use strict"); return this.has_directive("use strict");
}); });
AST_Lambda.DEFMETHOD("init_scope_vars", function(){ Cola.AST_Lambda.DEFMETHOD("init_scope_vars", function(){
AST_Scope.prototype.init_scope_vars.apply(this, arguments); Cola.AST_Scope.prototype.init_scope_vars.apply(this, arguments);
this.uses_arguments = false; this.uses_arguments = false;
}); });
AST_SymbolRef.DEFMETHOD("reference", function() { Cola.AST_SymbolRef.DEFMETHOD("reference", function() {
var def = this.definition(); var def = this.definition();
def.references.push(this); def.references.push(this);
var s = this.scope; var s = this.scope;
while (s) { while (s) {
push_uniq(s.enclosed, def); Cola.push_uniq(s.enclosed, def);
if (s === def.scope) break; if (s === def.scope) break;
s = s.parent_scope; s = s.parent_scope;
} }
this.frame = this.scope.nesting - def.scope.nesting; this.frame = this.scope.nesting - def.scope.nesting;
}); });
AST_Scope.DEFMETHOD("find_variable", function(name){ Cola.AST_Scope.DEFMETHOD("find_variable", function(name){
if (name instanceof AST_Symbol) name = name.name; if (name instanceof Cola.AST_Symbol) name = name.name;
return this.variables.get(name) return this.variables.get(name)
|| (this.parent_scope && this.parent_scope.find_variable(name)); || (this.parent_scope && this.parent_scope.find_variable(name));
}); });
AST_Scope.DEFMETHOD("has_directive", function(value){ Cola.AST_Scope.DEFMETHOD("has_directive", function(value){
return this.parent_scope && this.parent_scope.has_directive(value) return this.parent_scope && this.parent_scope.has_directive(value)
|| (this.directives.indexOf(value) >= 0 ? this : null); || (this.directives.indexOf(value) >= 0 ? this : null);
}); });
AST_Scope.DEFMETHOD("def_function", function(symbol){ Cola.AST_Scope.DEFMETHOD("def_function", function(symbol){
this.functions.set(symbol.name, this.def_variable(symbol)); this.functions.set(symbol.name, this.def_variable(symbol));
}); });
AST_Scope.DEFMETHOD("def_variable", function(symbol){ Cola.AST_Scope.DEFMETHOD("def_variable", function(symbol){
var def; var def;
if (!this.variables.has(symbol.name)) { if (!this.variables.has(symbol.name)) {
def = new SymbolDef(this, this.variables.size(), symbol); def = new SymbolDef(this, this.variables.size(), symbol);
@ -241,11 +241,11 @@ AST_Scope.DEFMETHOD("def_variable", function(symbol){
return symbol.thedef = def; return symbol.thedef = def;
}); });
AST_Scope.DEFMETHOD("next_mangled", function(options){ Cola.AST_Scope.DEFMETHOD("next_mangled", function(options){
var ext = this.enclosed; var ext = this.enclosed;
out: while (true) { out: while (true) {
var m = base54(++this.cname); var m = base54(++this.cname);
if (!is_identifier(m)) continue; // skip over "do" if (!Cola.is_identifier(m)) continue; // skip over "do"
// https://github.com/mishoo/UglifyJS2/issues/242 -- do not // https://github.com/mishoo/UglifyJS2/issues/242 -- do not
// shadow a name excepted from mangling. // shadow a name excepted from mangling.
@ -263,65 +263,65 @@ AST_Scope.DEFMETHOD("next_mangled", function(options){
} }
}); });
AST_Function.DEFMETHOD("next_mangled", function(options, def){ Cola.AST_Function.DEFMETHOD("next_mangled", function(options, def){
// #179, #326 // #179, #326
// in Safari strict mode, something like (function x(x){...}) is a syntax error; // in Safari strict mode, something like (function x(x){...}) is a syntax error;
// a function expression's argument cannot shadow the function expression's name // a function expression's argument cannot shadow the function expression's name
var tricky_def = def.orig[0] instanceof AST_SymbolFunarg && this.name && this.name.definition(); var tricky_def = def.orig[0] instanceof Cola.AST_SymbolFunarg && this.name && this.name.definition();
while (true) { while (true) {
var name = AST_Lambda.prototype.next_mangled.call(this, options, def); var name = Cola.AST_Lambda.prototype.next_mangled.call(this, options, def);
if (!(tricky_def && tricky_def.mangled_name == name)) if (!(tricky_def && tricky_def.mangled_name == name))
return name; return name;
} }
}); });
AST_Scope.DEFMETHOD("references", function(sym){ Cola.AST_Scope.DEFMETHOD("references", function(sym){
if (sym instanceof AST_Symbol) sym = sym.definition(); if (sym instanceof Cola.AST_Symbol) sym = sym.definition();
return this.enclosed.indexOf(sym) < 0 ? null : sym; return this.enclosed.indexOf(sym) < 0 ? null : sym;
}); });
AST_Symbol.DEFMETHOD("unmangleable", function(options){ Cola.AST_Symbol.DEFMETHOD("unmangleable", function(options){
return this.definition().unmangleable(options); return this.definition().unmangleable(options);
}); });
// property accessors are not mangleable // property accessors are not mangleable
AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){ Cola.AST_SymbolAccessor.DEFMETHOD("unmangleable", function(){
return true; return true;
}); });
// labels are always mangleable // labels are always mangleable
AST_Label.DEFMETHOD("unmangleable", function(){ Cola.AST_Label.DEFMETHOD("unmangleable", function(){
return false; return false;
}); });
AST_Symbol.DEFMETHOD("unreferenced", function(){ Cola.AST_Symbol.DEFMETHOD("unreferenced", function(){
return this.definition().references.length == 0 return this.definition().references.length == 0
&& !(this.scope.uses_eval || this.scope.uses_with); && !(this.scope.uses_eval || this.scope.uses_with);
}); });
AST_Symbol.DEFMETHOD("undeclared", function(){ Cola.AST_Symbol.DEFMETHOD("undeclared", function(){
return this.definition().undeclared; return this.definition().undeclared;
}); });
AST_LabelRef.DEFMETHOD("undeclared", function(){ Cola.AST_LabelRef.DEFMETHOD("undeclared", function(){
return false; return false;
}); });
AST_Label.DEFMETHOD("undeclared", function(){ Cola.AST_Label.DEFMETHOD("undeclared", function(){
return false; return false;
}); });
AST_Symbol.DEFMETHOD("definition", function(){ Cola.AST_Symbol.DEFMETHOD("definition", function(){
return this.thedef; return this.thedef;
}); });
AST_Symbol.DEFMETHOD("global", function(){ Cola.AST_Symbol.DEFMETHOD("global", function(){
return this.definition().global; return this.definition().global;
}); });
AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){ Cola.AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
return defaults(options, { return Cola.defaults(options, {
except : [], except : [],
eval : false, eval : false,
sort : false, sort : false,
@ -330,23 +330,23 @@ AST_Toplevel.DEFMETHOD("_default_mangler_options", function(options){
}); });
}); });
AST_Toplevel.DEFMETHOD("mangle_names", function(options){ Cola.AST_Toplevel.DEFMETHOD("mangle_names", function(options){
options = this._default_mangler_options(options); options = this._default_mangler_options(options);
// We only need to mangle declaration nodes. Special logic wired // We only need to mangle declaration nodes. Special logic wired
// into the code generator will display the mangled name if it's // into the code generator will display the mangled name if it's
// present (and for AST_SymbolRef-s it'll use the mangled name of // present (and for Cola.AST_SymbolRef-s it'll use the mangled name of
// the AST_SymbolDeclaration that it points to). // the Cola.AST_SymbolDeclaration that it points to).
var lname = -1; var lname = -1;
var to_mangle = []; var to_mangle = [];
var tw = new TreeWalker(function(node, descend){ var tw = new Cola.TreeWalker(function(node, descend){
if (node instanceof AST_LabeledStatement) { if (node instanceof Cola.AST_LabeledStatement) {
// lname is incremented when we get to the AST_Label // lname is incremented when we get to the Cola.AST_Label
var save_nesting = lname; var save_nesting = lname;
descend(); descend();
lname = save_nesting; lname = save_nesting;
return true; // don't descend again in TreeWalker return true; // don't descend again in Cola.TreeWalker
} }
if (node instanceof AST_Scope) { if (node instanceof Cola.AST_Scope) {
var p = tw.parent(), a = []; var p = tw.parent(), a = [];
node.variables.each(function(symbol){ node.variables.each(function(symbol){
if (options.except.indexOf(symbol.name) < 0) { if (options.except.indexOf(symbol.name) < 0) {
@ -359,13 +359,13 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
to_mangle.push.apply(to_mangle, a); to_mangle.push.apply(to_mangle, a);
return; return;
} }
if (node instanceof AST_Label) { if (node instanceof Cola.AST_Label) {
var name; var name;
do name = base54(++lname); while (!is_identifier(name)); do name = base54(++lname); while (!Cola.is_identifier(name));
node.mangled_name = name; node.mangled_name = name;
return true; return true;
} }
if (options.screw_ie8 && node instanceof AST_SymbolCatch) { if (options.screw_ie8 && node instanceof Cola.AST_SymbolCatch) {
to_mangle.push(node.definition()); to_mangle.push(node.definition());
return; return;
} }
@ -374,70 +374,70 @@ AST_Toplevel.DEFMETHOD("mangle_names", function(options){
to_mangle.forEach(function(def){ def.mangle(options) }); to_mangle.forEach(function(def){ def.mangle(options) });
}); });
AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){ Cola.AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options){
options = this._default_mangler_options(options); options = this._default_mangler_options(options);
var tw = new TreeWalker(function(node){ var tw = new Cola.TreeWalker(function(node){
if (node instanceof AST_Constant) if (node instanceof Cola.AST_Constant)
base54.consider(node.print_to_string()); base54.consider(node.print_to_string());
else if (node instanceof AST_Return) else if (node instanceof Cola.AST_Return)
base54.consider("return"); base54.consider("return");
else if (node instanceof AST_Throw) else if (node instanceof Cola.AST_Throw)
base54.consider("throw"); base54.consider("throw");
else if (node instanceof AST_Continue) else if (node instanceof Cola.AST_Continue)
base54.consider("continue"); base54.consider("continue");
else if (node instanceof AST_Break) else if (node instanceof Cola.AST_Break)
base54.consider("break"); base54.consider("break");
else if (node instanceof AST_Debugger) else if (node instanceof Cola.AST_Debugger)
base54.consider("debugger"); base54.consider("debugger");
else if (node instanceof AST_Directive) else if (node instanceof Cola.AST_Directive)
base54.consider(node.value); base54.consider(node.value);
else if (node instanceof AST_While) else if (node instanceof Cola.AST_While)
base54.consider("while"); base54.consider("while");
else if (node instanceof AST_Do) else if (node instanceof Cola.AST_Do)
base54.consider("do while"); base54.consider("do while");
else if (node instanceof AST_If) { else if (node instanceof Cola.AST_If) {
base54.consider("if"); base54.consider("if");
if (node.alternative) base54.consider("else"); if (node.alternative) base54.consider("else");
} }
else if (node instanceof AST_Var) else if (node instanceof Cola.AST_Var)
base54.consider("var"); base54.consider("var");
else if (node instanceof AST_Const) else if (node instanceof Cola.AST_Const)
base54.consider("const"); base54.consider("const");
else if (node instanceof AST_Lambda) else if (node instanceof Cola.AST_Lambda)
base54.consider("function"); base54.consider("function");
else if (node instanceof AST_For) else if (node instanceof Cola.AST_For)
base54.consider("for"); base54.consider("for");
else if (node instanceof AST_ForIn) else if (node instanceof Cola.AST_ForIn)
base54.consider("for in"); base54.consider("for in");
else if (node instanceof AST_Switch) else if (node instanceof Cola.AST_Switch)
base54.consider("switch"); base54.consider("switch");
else if (node instanceof AST_Case) else if (node instanceof Cola.AST_Case)
base54.consider("case"); base54.consider("case");
else if (node instanceof AST_Default) else if (node instanceof Cola.AST_Default)
base54.consider("default"); base54.consider("default");
else if (node instanceof AST_With) else if (node instanceof Cola.AST_With)
base54.consider("with"); base54.consider("with");
else if (node instanceof AST_ObjectSetter) else if (node instanceof Cola.AST_ObjectSetter)
base54.consider("set" + node.key); base54.consider("set" + node.key);
else if (node instanceof AST_ObjectGetter) else if (node instanceof Cola.AST_ObjectGetter)
base54.consider("get" + node.key); base54.consider("get" + node.key);
else if (node instanceof AST_ObjectKeyVal) else if (node instanceof Cola.AST_ObjectKeyVal)
base54.consider(node.key); base54.consider(node.key);
else if (node instanceof AST_New) else if (node instanceof Cola.AST_New)
base54.consider("new"); base54.consider("new");
else if (node instanceof AST_This) else if (node instanceof Cola.AST_This)
base54.consider("this"); base54.consider("this");
else if (node instanceof AST_Try) else if (node instanceof Cola.AST_Try)
base54.consider("try"); base54.consider("try");
else if (node instanceof AST_Catch) else if (node instanceof Cola.AST_Catch)
base54.consider("catch"); base54.consider("catch");
else if (node instanceof AST_Finally) else if (node instanceof Cola.AST_Finally)
base54.consider("finally"); base54.consider("finally");
else if (node instanceof AST_Symbol && node.unmangleable(options)) else if (node instanceof Cola.AST_Symbol && node.unmangleable(options))
base54.consider(node.name); base54.consider(node.name);
else if (node instanceof AST_Unary || node instanceof AST_Binary) else if (node instanceof Cola.AST_Unary || node instanceof Cola.AST_Binary)
base54.consider(node.operator); base54.consider(node.operator);
else if (node instanceof AST_Dot) else if (node instanceof Cola.AST_Dot)
base54.consider(node.property); base54.consider(node.property);
}); });
this.walk(tw); this.walk(tw);
@ -459,9 +459,9 @@ var base54 = (function() {
} }
}; };
base54.sort = function() { base54.sort = function() {
chars = mergeSort(chars, function(a, b){ chars = Cola.mergeSort(chars, function(a, b){
if (is_digit(a) && !is_digit(b)) return 1; if (Cola.is_digit(a) && !Cola.is_digit(b)) return 1;
if (is_digit(b) && !is_digit(a)) return -1; if (Cola.is_digit(b) && !Cola.is_digit(a)) return -1;
return frequency[b] - frequency[a]; return frequency[b] - frequency[a];
}); });
}; };
@ -481,8 +481,8 @@ var base54 = (function() {
return base54; return base54;
})(); })();
AST_Toplevel.DEFMETHOD("scope_warnings", function(options){ Cola.AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
options = defaults(options, { options = Cola.defaults(options, {
undeclared : false, // this makes a lot of noise undeclared : false, // this makes a lot of noise
unreferenced : true, unreferenced : true,
assign_to_global : true, assign_to_global : true,
@ -490,15 +490,15 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
nested_defuns : true, nested_defuns : true,
eval : true eval : true
}); });
var tw = new TreeWalker(function(node){ var tw = new Cola.TreeWalker(function(node){
if (options.undeclared if (options.undeclared
&& node instanceof AST_SymbolRef && node instanceof Cola.AST_SymbolRef
&& node.undeclared()) && node.undeclared())
{ {
// XXX: this also warns about JS standard names, // XXX: this also warns about JS standard names,
// i.e. Object, Array, parseInt etc. Should add a list of // i.e. Object, Array, parseInt etc. Should add a list of
// exceptions. // exceptions.
AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", { Cola.AST_Node.warn("Undeclared symbol: {name} [{file}:{line},{col}]", {
name: node.name, name: node.name,
file: node.start.file, file: node.start.file,
line: node.start.line, line: node.start.line,
@ -508,14 +508,14 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
if (options.assign_to_global) if (options.assign_to_global)
{ {
var sym = null; var sym = null;
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) if (node instanceof Cola.AST_Assign && node.left instanceof Cola.AST_SymbolRef)
sym = node.left; sym = node.left;
else if (node instanceof AST_ForIn && node.init instanceof AST_SymbolRef) else if (node instanceof Cola.AST_ForIn && node.init instanceof Cola.AST_SymbolRef)
sym = node.init; sym = node.init;
if (sym if (sym
&& (sym.undeclared() && (sym.undeclared()
|| (sym.global() && sym.scope !== sym.definition().scope))) { || (sym.global() && sym.scope !== sym.definition().scope))) {
AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", { Cola.AST_Node.warn("{msg}: {name} [{file}:{line},{col}]", {
msg: sym.undeclared() ? "Accidental global?" : "Assignment to global", msg: sym.undeclared() ? "Accidental global?" : "Assignment to global",
name: sym.name, name: sym.name,
file: sym.start.file, file: sym.start.file,
@ -525,16 +525,16 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
} }
} }
if (options.eval if (options.eval
&& node instanceof AST_SymbolRef && node instanceof Cola.AST_SymbolRef
&& node.undeclared() && node.undeclared()
&& node.name == "eval") { && node.name == "eval") {
AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start); Cola.AST_Node.warn("Eval is used [{file}:{line},{col}]", node.start);
} }
if (options.unreferenced if (options.unreferenced
&& (node instanceof AST_SymbolDeclaration || node instanceof AST_Label) && (node instanceof Cola.AST_SymbolDeclaration || node instanceof Cola.AST_Label)
&& node.unreferenced()) { && node.unreferenced()) {
AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", { Cola.AST_Node.warn("{type} {name} is declared but not referenced [{file}:{line},{col}]", {
type: node instanceof AST_Label ? "Label" : "Symbol", type: node instanceof Cola.AST_Label ? "Label" : "Symbol",
name: node.name, name: node.name,
file: node.start.file, file: node.start.file,
line: node.start.line, line: node.start.line,
@ -542,9 +542,9 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
}); });
} }
if (options.func_arguments if (options.func_arguments
&& node instanceof AST_Lambda && node instanceof Cola.AST_Lambda
&& node.uses_arguments) { && node.uses_arguments) {
AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", { Cola.AST_Node.warn("arguments used in function {name} [{file}:{line},{col}]", {
name: node.name ? node.name.name : "anonymous", name: node.name ? node.name.name : "anonymous",
file: node.start.file, file: node.start.file,
line: node.start.line, line: node.start.line,
@ -552,9 +552,9 @@ AST_Toplevel.DEFMETHOD("scope_warnings", function(options){
}); });
} }
if (options.nested_defuns if (options.nested_defuns
&& node instanceof AST_Defun && node instanceof Cola.AST_Defun
&& !(tw.parent() instanceof AST_Scope)) { && !(tw.parent() instanceof Cola.AST_Scope)) {
AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", { Cola.AST_Node.warn("Function {name} declared in nested statement \"{type}\" [{file}:{line},{col}]", {
name: node.name.name, name: node.name.name,
type: tw.parent().TYPE, type: tw.parent().TYPE,
file: node.start.file, file: node.start.file,

View File

@ -45,7 +45,7 @@
// a small wrapper around fitzgen's source-map library // a small wrapper around fitzgen's source-map library
function SourceMap(options) { function SourceMap(options) {
options = defaults(options, { options = Cola.defaults(options, {
file : null, file : null,
root : null, root : null,
orig : null, orig : null,

View File

@ -46,11 +46,11 @@
// Tree transformer helpers. // Tree transformer helpers.
function TreeTransformer(before, after) { function TreeTransformer(before, after) {
TreeWalker.call(this); Cola.TreeWalker.call(this);
this.before = before; this.before = before;
this.after = after; this.after = after;
} }
TreeTransformer.prototype = new TreeWalker; TreeTransformer.prototype = new Cola.TreeWalker;
(function(undefined){ (function(undefined){
@ -76,142 +76,142 @@ TreeTransformer.prototype = new TreeWalker;
}; };
function do_list(list, tw) { function do_list(list, tw) {
return MAP(list, function(node){ return Cola.MAP(list, function(node){
return node.transform(tw, true); return node.transform(tw, true);
}); });
}; };
_(AST_Node, noop); _(Cola.AST_Node, Cola.noop);
_(AST_LabeledStatement, function(self, tw){ _(Cola.AST_LabeledStatement, function(self, tw){
self.label = self.label.transform(tw); self.label = self.label.transform(tw);
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
}); });
_(AST_SimpleStatement, function(self, tw){ _(Cola.AST_SimpleStatement, function(self, tw){
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
}); });
_(AST_Block, function(self, tw){ _(Cola.AST_Block, function(self, tw){
self.body = do_list(self.body, tw); self.body = do_list(self.body, tw);
}); });
_(AST_DWLoop, function(self, tw){ _(Cola.AST_DWLoop, function(self, tw){
self.condition = self.condition.transform(tw); self.condition = self.condition.transform(tw);
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
}); });
_(AST_For, function(self, tw){ _(Cola.AST_For, function(self, tw){
if (self.init) self.init = self.init.transform(tw); if (self.init) self.init = self.init.transform(tw);
if (self.condition) self.condition = self.condition.transform(tw); if (self.condition) self.condition = self.condition.transform(tw);
if (self.step) self.step = self.step.transform(tw); if (self.step) self.step = self.step.transform(tw);
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
}); });
_(AST_ForIn, function(self, tw){ _(Cola.AST_ForIn, function(self, tw){
self.init = self.init.transform(tw); self.init = self.init.transform(tw);
self.object = self.object.transform(tw); self.object = self.object.transform(tw);
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
}); });
_(AST_With, function(self, tw){ _(Cola.AST_With, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
}); });
_(AST_Exit, function(self, tw){ _(Cola.AST_Exit, function(self, tw){
if (self.value) self.value = self.value.transform(tw); if (self.value) self.value = self.value.transform(tw);
}); });
_(AST_LoopControl, function(self, tw){ _(Cola.AST_LoopControl, function(self, tw){
if (self.label) self.label = self.label.transform(tw); if (self.label) self.label = self.label.transform(tw);
}); });
_(AST_If, function(self, tw){ _(Cola.AST_If, function(self, tw){
self.condition = self.condition.transform(tw); self.condition = self.condition.transform(tw);
self.body = self.body.transform(tw); self.body = self.body.transform(tw);
if (self.alternative) self.alternative = self.alternative.transform(tw); if (self.alternative) self.alternative = self.alternative.transform(tw);
}); });
_(AST_Switch, function(self, tw){ _(Cola.AST_Switch, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
self.body = do_list(self.body, tw); self.body = do_list(self.body, tw);
}); });
_(AST_Case, function(self, tw){ _(Cola.AST_Case, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
self.body = do_list(self.body, tw); self.body = do_list(self.body, tw);
}); });
_(AST_Try, function(self, tw){ _(Cola.AST_Try, function(self, tw){
self.body = do_list(self.body, tw); self.body = do_list(self.body, tw);
if (self.bcatch) self.bcatch = self.bcatch.transform(tw); if (self.bcatch) self.bcatch = self.bcatch.transform(tw);
if (self.bfinally) self.bfinally = self.bfinally.transform(tw); if (self.bfinally) self.bfinally = self.bfinally.transform(tw);
}); });
_(AST_Catch, function(self, tw){ _(Cola.AST_Catch, function(self, tw){
self.argname = self.argname.transform(tw); self.argname = self.argname.transform(tw);
self.body = do_list(self.body, tw); self.body = do_list(self.body, tw);
}); });
_(AST_Definitions, function(self, tw){ _(Cola.AST_Definitions, function(self, tw){
self.definitions = do_list(self.definitions, tw); self.definitions = do_list(self.definitions, tw);
}); });
_(AST_VarDef, function(self, tw){ _(Cola.AST_VarDef, function(self, tw){
self.name = self.name.transform(tw); self.name = self.name.transform(tw);
if (self.value) self.value = self.value.transform(tw); if (self.value) self.value = self.value.transform(tw);
}); });
_(AST_Lambda, function(self, tw){ _(Cola.AST_Lambda, function(self, tw){
if (self.name) self.name = self.name.transform(tw); if (self.name) self.name = self.name.transform(tw);
self.argnames = do_list(self.argnames, tw); self.argnames = do_list(self.argnames, tw);
self.body = do_list(self.body, tw); self.body = do_list(self.body, tw);
}); });
_(AST_Call, function(self, tw){ _(Cola.AST_Call, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
self.args = do_list(self.args, tw); self.args = do_list(self.args, tw);
}); });
_(AST_Seq, function(self, tw){ _(Cola.AST_Seq, function(self, tw){
self.car = self.car.transform(tw); self.car = self.car.transform(tw);
self.cdr = self.cdr.transform(tw); self.cdr = self.cdr.transform(tw);
}); });
_(AST_Dot, function(self, tw){ _(Cola.AST_Dot, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
}); });
_(AST_Sub, function(self, tw){ _(Cola.AST_Sub, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
self.property = self.property.transform(tw); self.property = self.property.transform(tw);
}); });
_(AST_Unary, function(self, tw){ _(Cola.AST_Unary, function(self, tw){
self.expression = self.expression.transform(tw); self.expression = self.expression.transform(tw);
}); });
_(AST_Binary, function(self, tw){ _(Cola.AST_Binary, function(self, tw){
self.left = self.left.transform(tw); self.left = self.left.transform(tw);
self.right = self.right.transform(tw); self.right = self.right.transform(tw);
}); });
_(AST_Conditional, function(self, tw){ _(Cola.AST_Conditional, function(self, tw){
self.condition = self.condition.transform(tw); self.condition = self.condition.transform(tw);
self.consequent = self.consequent.transform(tw); self.consequent = self.consequent.transform(tw);
self.alternative = self.alternative.transform(tw); self.alternative = self.alternative.transform(tw);
}); });
_(AST_Array, function(self, tw){ _(Cola.AST_Array, function(self, tw){
self.elements = do_list(self.elements, tw); self.elements = do_list(self.elements, tw);
}); });
_(AST_Object, function(self, tw){ _(Cola.AST_Object, function(self, tw){
self.properties = do_list(self.properties, tw); self.properties = do_list(self.properties, tw);
}); });
_(AST_ObjectProperty, function(self, tw){ _(Cola.AST_ObjectProperty, function(self, tw){
self.value = self.value.transform(tw); self.value = self.value.transform(tw);
}); });

View File

@ -41,114 +41,114 @@ function translate(tree){
var tt = new TreeTransformer(null, function(node){ var tt = new TreeTransformer(null, function(node){
var newNode, props; var newNode, props;
if(node instanceof AST_Binary && node.operator == '**'){ if(node instanceof Cola.AST_Binary && node.operator == '**'){
props = { props = {
args : [node.left, node.right], args : [node.left, node.right],
start : new AST_Token({ nlb : false, type : 'name', value : 'Math' }), start : new Cola.AST_Token({ nlb : false, type : 'name', value : 'Math' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }) end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
}; };
props.expression = new AST_Dot({ props.expression = new Cola.AST_Dot({
property : 'pow', property : 'pow',
start : props.start, start : props.start,
end : new AST_Token({ nlb : false, type : 'name', value : 'pow' }), end : new Cola.AST_Token({ nlb : false, type : 'name', value : 'pow' }),
expression : new AST_SymbolRef({ name : 'Math', start : props.start, end : props.start }) expression : new Cola.AST_SymbolRef({ name : 'Math', start : props.start, end : props.start })
}); });
node = new AST_Call(props); node = new Cola.AST_Call(props);
} else } else
if(node instanceof AST_Binary && node.operator == '%%'){ if(node instanceof Cola.AST_Binary && node.operator == '%%'){
props = { props = {
args : [node.left, node.right], args : [node.left, node.right],
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_modulo' }), start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_modulo' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }) end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
}; };
props.expression = new AST_SymbolRef({ props.expression = new Cola.AST_SymbolRef({
name : '$_cola_modulo', name : '$_cola_modulo',
start : props.start, start : props.start,
end : props.start end : props.start
}); });
node = new AST_Call(props); node = new Cola.AST_Call(props);
} else } else
if(node instanceof AST_SimpleStatement && node.body instanceof AST_Assign && node.body.operator == '?='){ if(node instanceof Cola.AST_SimpleStatement && node.body instanceof Cola.AST_Assign && node.body.operator == '?='){
node.body.operator = '='; node.body.operator = '=';
props = { props = {
args : [node.body.left], args : [node.body.left],
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }), start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }) end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
}; };
props.expression = new AST_SymbolRef({ props.expression = new Cola.AST_SymbolRef({
name : '$_cola_isntset', name : '$_cola_isntset',
start : props.start, start : props.start,
end : props.start end : props.start
}); });
node = new AST_If({ node = new Cola.AST_If({
body : node.clone(), body : node.clone(),
start : new AST_Token({ nlb : false, type : 'keyword', value : 'if' }), start : new Cola.AST_Token({ nlb : false, type : 'keyword', value : 'if' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ';' }), end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ';' }),
condition : new AST_Call(props) condition : new Cola.AST_Call(props)
}); });
} else } else
if(node instanceof AST_Assign && node.operator == '?='){ if(node instanceof Cola.AST_Assign && node.operator == '?='){
node.operator = '='; node.operator = '=';
props = { props = {
args : [node.left], args : [node.left],
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }), start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isntset' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }) end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
}; };
props.expression = new AST_SymbolRef({ props.expression = new Cola.AST_SymbolRef({
name : '$_cola_isntset', name : '$_cola_isntset',
start : props.start, start : props.start,
end : props.start end : props.start
}); });
node = new AST_Conditional({ node = new Cola.AST_Conditional({
start : new AST_Token({ nlb : false, type : 'punc', value : '(' }), start : new Cola.AST_Token({ nlb : false, type : 'punc', value : '(' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }), end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' }),
condition : new AST_Call(props), condition : new Cola.AST_Call(props),
consequent : node.clone(), consequent : node.clone(),
alternative : node.left alternative : node.left
}); });
} else } else
if(node instanceof AST_Binary && node.operator == 'is'){ if(node instanceof Cola.AST_Binary && node.operator == 'is'){
props = { props = {
args : [node.left, node.right], args : [node.left, node.right],
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_is' }), start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_is' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }) end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
}; };
props.expression = new AST_SymbolRef({ props.expression = new Cola.AST_SymbolRef({
name : '$_cola_is', name : '$_cola_is',
start : props.start, start : props.start,
end : props.start end : props.start
}); });
node = new AST_Call(props); node = new Cola.AST_Call(props);
} else } else
if(node instanceof AST_Binary && node.operator == 'isnt'){ if(node instanceof Cola.AST_Binary && node.operator == 'isnt'){
props = { props = {
args : [node.left, node.right], args : [node.left, node.right],
start : new AST_Token({ nlb : false, type : 'name', value : '$_cola_isnt' }), start : new Cola.AST_Token({ nlb : false, type : 'name', value : '$_cola_isnt' }),
end : new AST_Token({ nlb : false, type : 'punc', value : ')' }) end : new Cola.AST_Token({ nlb : false, type : 'punc', value : ')' })
}; };
props.expression = new AST_SymbolRef({ props.expression = new Cola.AST_SymbolRef({
name : '$_cola_isnt', name : '$_cola_isnt',
start : props.start, start : props.start,
end : props.start end : props.start
}); });
node = new AST_Call(props); node = new Cola.AST_Call(props);
} else } else
if(node instanceof AST_StringTemplate){ if(node instanceof Cola.AST_StringTemplate){
newNode = new AST_Binary({ newNode = new Cola.AST_Binary({
operator : '+', operator : '+',
left : node.body[0], left : node.body[0],
right : node.body[1], right : node.body[1],
@ -156,7 +156,7 @@ function translate(tree){
end : node.body[1].end end : node.body[1].end
}); });
for(var i = 2; i < node.body.length; i++) for(var i = 2; i < node.body.length; i++)
newNode = new AST_Binary({ newNode = new Cola.AST_Binary({
operator : '+', operator : '+',
left : newNode, left : newNode,
right : node.body[i], right : node.body[i],
@ -167,7 +167,7 @@ function translate(tree){
node = newNode; node = newNode;
} else } else
if(node instanceof AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){ if(node instanceof Cola.AST_RegExp && (node.value.indexOf('\n') != -1 || /\/[\w]*x[\w]*$/.test(node.value))){
node.value = node.value.replace(/[\r\n\s]/g,'').replace(/(\/[\w]*)x([\w]*$)/, '$1$2'); node.value = node.value.replace(/[\r\n\s]/g,'').replace(/(\/[\w]*)x([\w]*$)/, '$1$2');
} }

View File

@ -42,79 +42,80 @@
***********************************************************************/ ***********************************************************************/
"use strict"; "use strict";
!window.Cola && (window.Cola = {});
function array_to_hash(a) { Cola.array_to_hash = function (a) {
var ret = Object.create(null); var ret = Object.create(null);
for (var i = 0; i < a.length; ++i) for (var i = 0; i < a.length; ++i)
ret[a[i]] = true; ret[a[i]] = true;
return ret; return ret;
}; };
function slice(a, start) { Cola.slice = function (a, start) {
return Array.prototype.slice.call(a, start || 0); return Array.prototype.slice.call(a, start || 0);
}; };
function characters(str) { Cola.characters = function (str) {
return str.split(""); return str.split("");
}; };
function member(name, array) { Cola.member = function (name, array) {
for (var i = array.length; --i >= 0;) for (var i = array.length; --i >= 0;)
if (array[i] == name) if (array[i] == name)
return true; return true;
return false; return false;
}; };
function find_if(func, array) { Cola.find_if = function (func, array) {
for (var i = 0, n = array.length; i < n; ++i) { for (var i = 0, n = array.length; i < n; ++i) {
if (func(array[i])) if (func(array[i]))
return array[i]; return array[i];
} }
}; };
function repeat_string(str, i) { Cola.repeat_string = function (str, i) {
if (i <= 0) return ""; if (i <= 0) return "";
if (i == 1) return str; if (i == 1) return str;
var d = repeat_string(str, i >> 1); var d = Cola.repeat_string(str, i >> 1);
d += d; d += d;
if (i & 1) d += str; if (i & 1) d += str;
return d; return d;
}; };
function DefaultsError(msg, defs) { Cola.DefaultsError = function (msg, defs) {
Error.call(this, msg); Error.call(this, msg);
this.msg = msg; this.msg = msg;
this.defs = defs; this.defs = defs;
}; };
DefaultsError.prototype = Object.create(Error.prototype); Cola.DefaultsError.prototype = Object.create(Error.prototype);
DefaultsError.prototype.constructor = DefaultsError; Cola.DefaultsError.prototype.constructor = Cola.DefaultsError;
DefaultsError.croak = function(msg, defs) { Cola.DefaultsError.croak = function(msg, defs) {
throw new DefaultsError(msg, defs); throw new Cola.DefaultsError(msg, defs);
}; };
function defaults(args, defs, croak) { Cola.defaults = function (args, defs, croak) {
if (args === true) if (args === true)
args = {}; args = {};
var ret = args || {}; var ret = args || {};
if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i)) if (croak) for (var i in ret) if (ret.hasOwnProperty(i) && !defs.hasOwnProperty(i))
DefaultsError.croak("`" + i + "` is not a supported option", defs); Cola.DefaultsError.croak("`" + i + "` is not a supported option", defs);
for (var i in defs) if (defs.hasOwnProperty(i)) { for (var i in defs) if (defs.hasOwnProperty(i)) {
ret[i] = (args && args.hasOwnProperty(i)) ? args[i] : defs[i]; ret[i] = (args && args.hasOwnProperty(i)) ? args[i] : defs[i];
} }
return ret; return ret;
}; };
function merge(obj, ext) { Cola.merge = function (obj, ext) {
for (var i in ext) if (ext.hasOwnProperty(i)) { for (var i in ext) if (ext.hasOwnProperty(i)) {
obj[i] = ext[i]; obj[i] = ext[i];
} }
return obj; return obj;
}; };
function noop() {}; Cola.noop = function () {};
var MAP = (function(){ Cola.MAP = (function(){
function MAP(a, f, backwards) { function MAP(a, f, backwards) {
var ret = [], top = [], i; var ret = [], top = [], i;
function doit() { function doit() {
@ -162,24 +163,24 @@ var MAP = (function(){
return MAP; return MAP;
})(); })();
function push_uniq(array, el) { Cola.push_uniq = function (array, el) {
if (array.indexOf(el) < 0) if (array.indexOf(el) < 0)
array.push(el); array.push(el);
}; };
function string_template(text, props) { Cola.string_template = function (text, props) {
return text.replace(/\{(.+?)\}/g, function(str, p){ return text.replace(/\{(.+?)\}/g, function(str, p){
return props[p]; return props[p];
}); });
}; };
function remove(array, el) { Cola.remove = function (array, el) {
for (var i = array.length; --i >= 0;) { for (var i = array.length; --i >= 0;) {
if (array[i] === el) array.splice(i, 1); if (array[i] === el) array.splice(i, 1);
} }
}; };
function mergeSort(array, cmp) { Cola.mergeSort = function (array, cmp) {
if (array.length < 2) return array.slice(); if (array.length < 2) return array.slice();
function merge(a, b) { function merge(a, b) {
var r = [], ai = 0, bi = 0, i = 0; var r = [], ai = 0, bi = 0, i = 0;
@ -203,13 +204,13 @@ function mergeSort(array, cmp) {
return _ms(array); return _ms(array);
}; };
function set_difference(a, b) { Cola.set_difference = function (a, b) {
return a.filter(function(el){ return a.filter(function(el){
return b.indexOf(el) < 0; return b.indexOf(el) < 0;
}); });
}; };
function set_intersection(a, b) { Cola.set_intersection = function (a, b) {
return a.filter(function(el){ return a.filter(function(el){
return b.indexOf(el) >= 0; return b.indexOf(el) >= 0;
}); });
@ -217,7 +218,7 @@ function set_intersection(a, b) {
// this function is taken from Acorn [1], written by Marijn Haverbeke // this function is taken from Acorn [1], written by Marijn Haverbeke
// [1] https://github.com/marijnh/acorn // [1] https://github.com/marijnh/acorn
function makePredicate(words) { Cola.makePredicate = function (words) {
if (!(words instanceof Array)) words = words.split(" "); if (!(words instanceof Array)) words = words.split(" ");
var f = "", cats = []; var f = "", cats = [];
out: for (var i = 0; i < words.length; ++i) { out: for (var i = 0; i < words.length; ++i) {
@ -252,18 +253,18 @@ function makePredicate(words) {
return new Function("str", f); return new Function("str", f);
}; };
function all(array, predicate) { Cola.all = function (array, predicate) {
for (var i = array.length; --i >= 0;) for (var i = array.length; --i >= 0;)
if (!predicate(array[i])) if (!predicate(array[i]))
return false; return false;
return true; return true;
}; };
function Dictionary() { Cola.Dictionary = function () {
this._values = Object.create(null); this._values = Object.create(null);
this._size = 0; this._size = 0;
}; };
Dictionary.prototype = { Cola.Dictionary.prototype = {
set: function(key, val) { set: function(key, val) {
if (!this.has(key)) ++this._size; if (!this.has(key)) ++this._size;
this._values["$" + key] = val; this._values["$" + key] = val;