Comparing version 0.0.9 to 0.1.0
1020
index.js
@@ -1,529 +0,627 @@ | ||
// Export reader | ||
exports.read = function(opts, input){ | ||
return compile(opts, parse(input)); | ||
exports.read = function(opts, input) { | ||
return compile(opts, parse(input)) | ||
}; | ||
// Export parser | ||
var parse = exports.parse = require('./parser').parse; | ||
// Export compiler | ||
var compile = exports.compile = function(opts, ast){ | ||
var compile = exports.compile = function(opts, ast) { | ||
opts = opts || {}; | ||
opts.tab = opts.tab || -1; | ||
var tab = (new Array(parseInt(opts.tab === -1 ? 0 : opts.tab, 10)+1)).join(' '); | ||
var ind = function(il){ | ||
var tab = new Array(parseInt((opts.tab === -1 ? | ||
0 | ||
: opts.tab | ||
), 10) + 1).join(' '); | ||
var ind = function(il) { | ||
if (!opts.tab) return ''; | ||
else return (new Array(il+1)).join(tab); | ||
else return new Array(il + 1).join(tab); | ||
}; | ||
var nli = function(il){ | ||
var nli = function(il) { | ||
if (opts.tab === -1) return ''; | ||
else return '\n' +ind(il); | ||
else return '\n' + ind(il); | ||
}; | ||
var inl = function(il){ | ||
var inl = function(il) { | ||
if (!il) return nli(il); | ||
else return ''; | ||
}; | ||
var sp = function(){ | ||
var sp = function() { | ||
if (opts.compress) return ''; | ||
else return ' '; | ||
}; | ||
var noop = function(){ return '' }; | ||
var Element = function(type, code){ | ||
}; | ||
var noop = function() { | ||
return '' | ||
}; | ||
var Element = function(type, code) { | ||
this.type = type; | ||
this.code = code; | ||
this.code = code | ||
}; | ||
Element.prototype.toString = | ||
Element.prototype.valueOf = function(){ | ||
return this.code; | ||
}; | ||
Element.prototype.toString = Element.prototype.valueOf = function() { | ||
return this.code | ||
}; | ||
var inlineElements = { | ||
AssignmentExpression:0, | ||
FunctionCall:0, | ||
VariableDeclaration:0, | ||
PropertyAccess:0, | ||
PropertyAssignment:0 | ||
"AssignmentExpression": 0, | ||
"FunctionCall": 0, | ||
"VariableDeclaration": 0, | ||
"PropertyAccess": 0, | ||
"PropertyAssignment": 0 | ||
}; | ||
//console.log(JSON.stringify(ast, null, 4)); | ||
return (function compile(il, par){ | ||
il = il || 0; | ||
return function(node){ | ||
var rules = { | ||
'Function': function(){ | ||
var name = node.name ? ' ' +node.name : '', | ||
elements = node.elements ? | ||
node.elements.length ? | ||
node.elements.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, | ||
(!(par in inlineElements) ? inl(il) : '') | ||
+'function' +name | ||
+'(' +(node.params && node.params.length ? | ||
node.params.join(','+sp()) | ||
: '') +'){' | ||
+nli(il+1) | ||
+elements.join(';'+nli(il+1)) | ||
+nli(il) | ||
+'}'); | ||
var notTerminatedElements = { | ||
"IfStatement": 0, | ||
"ForStatement": 0, | ||
"ForInStatement": 0, | ||
"Function": 0, | ||
"WhileStatement": 0, | ||
"DoWhileStatement": 0, | ||
"WithStatement": 0, | ||
"SwitchStatement": 0 | ||
}; | ||
return function compile(il, par) { | ||
il = il || 0; | ||
return function(node) { | ||
var rules = { | ||
"Function": function() { | ||
var name = (node.name ? | ||
' ' + node.name | ||
: '' | ||
); | ||
var elements = (node.elements ? | ||
(node.elements.length ? | ||
node.elements.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, (!par in inlineElements ? | ||
inl(il) | ||
: '' | ||
) + 'function' + name + '(' + (node.params && node.params.length ? | ||
node.params.join(',' + sp()) | ||
: '' | ||
) + ')' + sp() + '{' + nli(il + 1) + elements.reduce(function(code, element, index) { | ||
var lastElement = index === elements.length - 1; | ||
var notTerminatedElement = element.type in notTerminatedElements; | ||
return code += element + (lastElement ? | ||
nli(il) | ||
: (notTerminatedElement ? | ||
'' | ||
: ';' | ||
) + nli(il + 1) | ||
) | ||
}, '') + '}') | ||
}, | ||
'FunctionCall': function(){ | ||
var name = node.name ? | ||
node.name.type ? | ||
"FunctionCall": function() { | ||
var name = (node.name ? | ||
(node.name.type ? | ||
compile(il, node.type)(node.name) | ||
: node.name | ||
: '', | ||
args = node.arguments ? | ||
node.arguments.length ? | ||
) | ||
: '' | ||
); | ||
var args = (node.arguments ? | ||
(node.arguments.length ? | ||
node.arguments.map(compile(il, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, | ||
(!(par in inlineElements) ? inl(il) : '') +name | ||
+'(' +args.join(',' +sp()) + ')'); | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, (!par in inlineElements ? | ||
inl(il) | ||
: '' | ||
) + name + '(' + args.join(',' + sp()) + ')') | ||
}, | ||
'PropertyAccess': function(){ | ||
var base = node.base ? | ||
compile(il, node.type)(node.base) | ||
: '', | ||
name = node.name ? | ||
node.name.type ? | ||
compile(il, node.type)(node.name) | ||
: node.name | ||
: ''; | ||
if (String(name.toString()) | ||
.match(/\d+|[^\w$_]+[\w\d$_]*/)) | ||
return new Element(node.type, base +'[' +name +']'); | ||
else return new Element(node.type, base +'.' +name); | ||
"PropertyAccess": function() { | ||
var base = (node.base ? | ||
compile(il, node.type)(node.base) | ||
: '' | ||
); | ||
var name = (node.name ? | ||
(node.name.type ? | ||
compile(il, node.type)(node.name) | ||
: node.name | ||
) | ||
: '' | ||
); | ||
if (name.type === 'Expression' || String(name).match(/\d+|[^\w$_]+[\w\d$_]*/)) { | ||
return new Element(node.type, base + '[' + name + ']') | ||
} | ||
else return new Element(node.type, base + '.' + name); | ||
}, | ||
'Variable': function(){ | ||
return new Element(node.type, node.name); | ||
"Variable": function() { | ||
return new Element(node.type, node.name) | ||
}, | ||
'NumericLiteral': function(){ | ||
return new Element(node.type, node.value); | ||
"NumericLiteral": function() { | ||
return new Element(node.type, node.value) | ||
}, | ||
'StringLiteral': function(){ | ||
var replaces = [ | ||
["\\\\", "\\\\"], | ||
["\\n","\\n"], | ||
["\\r","\\r"] | ||
"StringLiteral": function() { | ||
var replaces = [ | ||
[ | ||
'\\\\', | ||
'\\\\' | ||
], | ||
[ | ||
'\\n', | ||
'\\n' | ||
], | ||
[ | ||
'\\r', | ||
'\\r' | ||
] | ||
]; | ||
var replaced = replaces.reduce(function(str, rep){ | ||
return str.replace(new RegExp(rep[0],'g'),rep[1]); | ||
}, node.value || ""); | ||
return new Element(node.type, (replaced.indexOf("'")>-1?'"':"'") +replaced +(replaced.indexOf("'")>-1?'"':"'")); | ||
var replaced = replaces.reduce(function(str, rep) { | ||
return str.replace(new RegExp(rep[0], 'g'), rep[1]) | ||
}, node.value || ''); | ||
return new Element(node.type, (replaced.indexOf("'") > -1 ? | ||
'"' | ||
: "'" | ||
) + replaced + (replaced.indexOf("'") > -1 ? | ||
'"' | ||
: "'" | ||
)) | ||
}, | ||
'NullLiteral': function(){ | ||
return new Element(node.type, 'null'); | ||
"NullLiteral": function() { | ||
return new Element(node.type, 'null') | ||
}, | ||
'BooleanLiteral': function(){ | ||
return new Element(node.type, node.value); | ||
"BooleanLiteral": function() { | ||
return new Element(node.type, node.value) | ||
}, | ||
'RegularExpressionLiteral': function(){ | ||
return new Element(node.type, '/' +node.body +'/' +node.opts); | ||
"RegularExpressionLiteral": function() { | ||
return new Element(node.type, '/' + node.body + '/' + (node.opts ? | ||
node.opts | ||
: '' | ||
)) | ||
}, | ||
'This': function(){ | ||
return new Element(node.type, 'this'); | ||
"This": function() { | ||
return new Element(node.type, 'this') | ||
}, | ||
'ArrayLiteral': function(){ | ||
var elements = node.elements ? | ||
node.elements.length ? | ||
node.elements.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, '[' | ||
+(elements.length ? | ||
nli(il+1) | ||
+elements.join(','+nli(il+1)) | ||
+nli(il) : '') | ||
+']'); | ||
"ArrayLiteral": function() { | ||
var elements = (node.elements ? | ||
(node.elements.length ? | ||
node.elements.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, '[' + (elements.length ? | ||
nli(il + 1) + elements.join(',' + nli(il + 1)) + nli(il) | ||
: '' | ||
) + ']') | ||
}, | ||
'ObjectLiteral': function(){ | ||
var properties = node.properties ? | ||
node.properties.length ? | ||
node.properties.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, '{' | ||
+(properties.length ? | ||
nli(il+1) | ||
+properties.join(','+nli(il+1)) | ||
+nli(il) : '') | ||
+'}'); | ||
"ObjectLiteral": function() { | ||
var properties = (node.properties ? | ||
(node.properties.length ? | ||
node.properties.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, '{' + (properties.length ? | ||
nli(il + 1) + properties.join(',' + nli(il + 1)) + nli(il) | ||
: '' | ||
) + '}') | ||
}, | ||
'PropertyAssignment': function(){ | ||
var value = node.value ? | ||
compile(il, node.type)(node.value) | ||
: 'undefined'; | ||
return new Element(node.type, '\"' +node.name +'\":' +sp() +value); | ||
"PropertyAssignment": function() { | ||
var value = (node.value ? | ||
compile(il, node.type)(node.value) | ||
: 'undefined' | ||
); | ||
return new Element(node.type, '"' + node.name + '":' + sp() + value) | ||
}, | ||
'GetterDefinition': function(){ | ||
var body = node.body ? | ||
node.body.length ? | ||
node.body.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, 'get ' +node.name +'(){' | ||
+nli(il+1) | ||
+body.join(';'+nli(il+1)) | ||
+nli(il) | ||
+'}'); | ||
"GetterDefinition": function() { | ||
var body = (node.body ? | ||
(node.body.length ? | ||
node.body.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, 'get' + node.name + ' ()' + sp() + '{' + nli(il + 1) + body.join(';' + nli(il + 1)) + nli(il) + '}') | ||
}, | ||
'SetterDefinition': function(){ | ||
var body = node.body ? | ||
node.body.length ? | ||
node.body.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, 'set ' +node.name +'(' | ||
+node.param | ||
+'){' | ||
+nli(il+1) | ||
+body.join(';'+nli(il+1)) | ||
+nli(il) | ||
+'}'); | ||
"SetterDefinition": function() { | ||
var body = (node.body ? | ||
(node.body.length ? | ||
node.body.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, 'set' + node.name + ' (' + node.param + ')' + sp() + '{' + nli(il + 1) + body.join(';' + nli(il + 1)) + nli(il) + '}') | ||
}, | ||
'NewOperator': function(){ | ||
var constructor = node.constructor ? | ||
node.constructor.type ? | ||
compile(il+1, node.type)(node.constructor) | ||
: node.constructor | ||
: '', | ||
args = node.arguments ? | ||
node.arguments.length ? | ||
node.arguments.map(compile(il, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, 'new ' +constructor +'(' | ||
+args.join(',' +sp()) | ||
+')'); | ||
"NewOperator": function() { | ||
var constructor = (node.constructor ? | ||
(node.constructor.type ? | ||
compile(il + 1, node.type)(node.constructor) | ||
: node.constructor | ||
) | ||
: '' | ||
); | ||
var args = (node.arguments ? | ||
(node.arguments.length ? | ||
node.arguments.map(compile(il, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, 'new ' + constructor + '(' + args.join(',' + sp()) + ')') | ||
}, | ||
'FunctionCallArguments': noop, | ||
'PropertyAccessProperty': noop, | ||
'PostfixExpression': function(){ | ||
var expression = node.expression ? | ||
compile(il, node.type)(node.expression) | ||
: ''; | ||
return new Element(node.type, expression +node.operator); | ||
"FunctionCallArguments": noop, | ||
"PropertyAccessProperty": noop, | ||
"PostfixExpression": function() { | ||
var expression = (node.expression ? | ||
compile(il, node.type)(node.expression) | ||
: '' | ||
); | ||
return new Element(node.type, expression + node.operator) | ||
}, | ||
'UnaryExpression': function(){ | ||
var expression = node.expression ? | ||
compile(il, node.type)(node.expression) | ||
: ''; | ||
return new Element(node.type, node.operator +' ' +expression); | ||
"UnaryExpression": function() { | ||
var expression = (node.expression ? | ||
compile(il, node.type)(node.expression) | ||
: '' | ||
); | ||
return new Element(node.type, node.operator + expression) | ||
}, | ||
'ConditionalExpression': function(){ | ||
var condition = node.condition ? | ||
node.condition.type ? | ||
compile(il, node.type)(node.condition) | ||
: node.condition | ||
: '', | ||
trueExpression = node.trueExpression ? | ||
node.trueExpression.type ? | ||
compile(il+2, node.type)(node.trueExpression) | ||
: node.trueExpression | ||
: '', | ||
falseExpression = node.falseExpression ? | ||
node.falseExpression.type ? | ||
compile(il+2, node.type)(node.falseExpression) | ||
: node.falseExpression | ||
: ''; | ||
return new Element(node.type, '(' +condition +sp() +'?' | ||
+nli(il+1) | ||
+trueExpression | ||
+nli(il+1) | ||
+':' +sp() | ||
+falseExpression +')'); | ||
"ConditionalExpression": function() { | ||
var condition = (node.condition ? | ||
(node.condition.type ? | ||
compile(il, node.type)(node.condition) | ||
: node.condition | ||
) | ||
: '' | ||
); | ||
var trueExpression = (node.trueExpression ? | ||
(node.trueExpression.type ? | ||
compile(il + 1, node.type)(node.trueExpression) | ||
: node.trueExpression | ||
) | ||
: '' | ||
); | ||
var falseExpression = (node.falseExpression ? | ||
(node.falseExpression.type ? | ||
compile(il + 1, node.type)(node.falseExpression) | ||
: node.falseExpression | ||
) | ||
: '' | ||
); | ||
return new Element(node.type, '(' + condition + sp() + '?' + nli(il + 1) + trueExpression + nli(il + 1) + ':' + sp() + falseExpression + nli(il) + ')') | ||
}, | ||
'AssignmentExpression': function(){ | ||
var left = node.left ? | ||
compile(il, node.type)(node.left) : 'undefined', | ||
right = node.right ? | ||
compile(il, node.type)(node.right) : 'undefined'; | ||
return new Element(node.type, left | ||
+sp() | ||
+node.operator | ||
+sp() | ||
+(String(right.toString()).indexOf('var') === 0 ? | ||
right.replace(/^var/,'') | ||
: right)); | ||
"AssignmentExpression": function() { | ||
var left = (node.left ? | ||
compile(il, node.type)(node.left) | ||
: 'undefined' | ||
); | ||
var right = (node.right ? | ||
compile(il, node.type)(node.right) | ||
: 'undefined' | ||
); | ||
return new Element(node.type, left + sp() + node.operator + sp() + (String(right.toString()).indexOf('var') === 0 ? | ||
right.replace(/^var/, '') | ||
: right | ||
)) | ||
}, | ||
'Block': function(){ | ||
var statements = node.statements ? | ||
node.statements.length ? | ||
node.statements.map(compile(il, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, statements.join(';'+nli(il))); | ||
"Block": function() { | ||
var statements = (node.statements ? | ||
(node.statements.length ? | ||
node.statements.map(compile(il, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, statements.reduce(function(code, statement, index) { | ||
var lastElement = index === statements.length - 1; | ||
var notTerminatedElement = statement.type in notTerminatedElements; | ||
return code += statement + (lastElement ? | ||
'' | ||
: (notTerminatedElement ? | ||
'' | ||
: ';' | ||
) + nli(il) | ||
) | ||
}, '')) | ||
}, | ||
'VariableStatement': function(){ | ||
var declarations = node.declarations ? | ||
node.declarations.length ? | ||
"VariableStatement": function() { | ||
var declarations = (node.declarations ? | ||
(node.declarations.length ? | ||
node.declarations.map(compile(il, node.type)) | ||
: [] | ||
: []; | ||
var statement = (par !== 'ReturnStatement' ? 'var ' : ''); | ||
return new Element(node.type, statement+declarations.join(';'+nli(il)+statement)); | ||
) | ||
: [] | ||
); | ||
var statement = (par !== 'ReturnStatement' ? | ||
'var ' | ||
: '' | ||
); | ||
return new Element(node.type, statement + declarations.join(';' + nli(il) + statement)) | ||
}, | ||
'VariableDeclaration': function(){ | ||
var value = node.value ? | ||
compile(il, node.type)(node.value) | ||
: undefined; | ||
return new Element(node.type, node.name +sp() | ||
+(value === undefined ? | ||
'' : '=' +sp() +value)); | ||
"VariableDeclaration": function() { | ||
var value = (node.value ? | ||
compile(il, node.type)(node.value) | ||
: undefined | ||
); | ||
return new Element(node.type, node.name + (value === undefined ? | ||
'' | ||
: sp() + '=' + sp() + value | ||
)) | ||
}, | ||
'BinaryExpression': function(){ | ||
var left = node.left ? | ||
compile(il, node.type)(node.left) : 'undefined', | ||
right = node.right ? | ||
compile(il, node.type)(node.right) : 'undefined'; | ||
if (node.operator === ',') | ||
node.operator = ','+nli(il); | ||
else node.operator = sp() +node.operator +sp(); | ||
return new Element(node.type, left | ||
+node.operator | ||
+right); | ||
"BinaryExpression": function() { | ||
var left = (node.left ? | ||
compile(il, node.type)(node.left) | ||
: 'undefined' | ||
); | ||
var right = (node.right ? | ||
compile(il, node.type)(node.right) | ||
: 'undefined' | ||
); | ||
if (node.operator === ',') node.operator = ',' + nli(il); | ||
else node.operator = sp() + node.operator + sp(); | ||
return new Element(node.type, left + node.operator + right) | ||
}, | ||
'EmptyStatement': function(){ | ||
return new Element(node.type, ''); | ||
"EmptyStatement": function() { | ||
return new Element(node.type, '') | ||
}, | ||
'IfStatement': function(){ | ||
var elseIf = node.elseStatement | ||
&& node.elseStatement.type === 'IfStatement'; | ||
var condition = node.condition ? | ||
compile(il, node.type)(node.condition) : '', | ||
ifStatement = node.ifStatement ? | ||
compile(il+1, node.type)(node.ifStatement) : '', | ||
elseStatement = node.elseStatement ? | ||
compile(il +(!elseIf ? 1 : 0), | ||
node.type)(node.elseStatement) : ''; | ||
return new Element(node.type, (par !== 'IfStatement' ? inl(il) : '') | ||
+'if (' +condition +'){' | ||
+nli(il+1) | ||
+ifStatement | ||
+nli(il) | ||
+'}' +(elseStatement ? | ||
' else ' +(node.elseStatement.length ? '{' : '') | ||
+(elseIf || node.elseStatement.type ? '' : nli(il+1)) | ||
+elseStatement | ||
+(node.elseStatement.length ? nli(il) : '') | ||
+(node.elseStatement.length ? '}' : '') | ||
: '')); | ||
"IfStatement": function() { | ||
var ifStatementBlock = node.ifStatement && node.ifStatement.statements && node.ifStatement.statements.length; | ||
var elseIf = node.elseStatement && node.elseStatement.type === 'IfStatement'; | ||
var elseStatementBlock = node.elseStatement && node.elseStatement.statements && node.elseStatement.statements.length; | ||
var condition = (node.condition ? | ||
compile(il, node.type)(node.condition) | ||
: '' | ||
); | ||
var ifStatement = (node.ifStatement ? | ||
compile(il + 1, node.type)(node.ifStatement) | ||
: '' | ||
); | ||
var elseStatement = (node.elseStatement ? | ||
compile(il + (!elseIf ? | ||
1 | ||
: 0 | ||
), node.type)(node.elseStatement) | ||
: '' | ||
); | ||
return new Element(node.type, (par !== 'IfStatement' ? | ||
inl(il) | ||
: '' | ||
) + 'if' + sp() + '(' + condition + ')' + (ifStatementBlock ? | ||
sp() + '{' + nli(il + 1) | ||
: ' ' | ||
) + ifStatement + (ifStatementBlock ? | ||
nli(il) + '}' | ||
: (elseStatement ? | ||
';' | ||
: '' | ||
) | ||
) + (elseStatement ? | ||
(elseStatementBlock ? | ||
sp() | ||
: nli(il) | ||
) + 'else' + (elseStatementBlock ? | ||
sp() + '{' + nli(il + 1) | ||
: ' ' | ||
) + (elseIf || node.elseStatement.type ? | ||
'' | ||
: nli(il + 1) | ||
) + elseStatement + (elseStatementBlock ? | ||
nli(il) + '}' | ||
: ';' | ||
) | ||
: '' | ||
)) | ||
}, | ||
'DoWhileStatement': function(){ | ||
var condition = node.condition ? | ||
compile(il, node.type)(node.condition) : '', | ||
statement = node.statement ? | ||
compile(il+1, node.type)(node.statement) : ''; | ||
return new Element(node.type, inl(il) +'do {' | ||
+nli(il+1) | ||
+statement | ||
+nli(il) | ||
+'} while(' | ||
+condition | ||
+')'); | ||
"DoWhileStatement": function() { | ||
var condition = (node.condition ? | ||
compile(il, node.type)(node.condition) | ||
: '' | ||
); | ||
var statement = (node.statement ? | ||
compile(il + 1, node.type)(node.statement) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + 'do' + sp() + '{' + nli(il + 1) + statement + nli(il) + '}' + sp() + 'while' + sp() + '(' + condition + ')') | ||
}, | ||
'WhileStatement': function(){ | ||
var condition = node.condition ? | ||
compile(il, node.type)(node.condition) : '', | ||
statement = node.statement ? | ||
compile(il+1, node.type)(node.statement) : ''; | ||
return new Element(node.type, inl(il) +'while(' | ||
+condition | ||
+')' | ||
+'{' | ||
+nli(il+1) | ||
+statement | ||
+nli(il) | ||
+'}'); | ||
"WhileStatement": function() { | ||
var condition = (node.condition ? | ||
compile(il, node.type)(node.condition) | ||
: '' | ||
); | ||
var statement = (node.statement ? | ||
compile(il + 1, node.type)(node.statement) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + 'while (' + condition + ')' + sp() + '{' + nli(il + 1) + statement + nli(il) + '}') | ||
}, | ||
'ForStatement': function(){ | ||
var initializer = node.initializer ? | ||
compile(il, node.type)(node.initializer) | ||
: '', | ||
test = node.test ? | ||
compile(il, node.type)(node.test) | ||
: '', | ||
counter= node.counter ? | ||
compile(il, node.type)(node.counter) | ||
: '', | ||
statement = node.statement ? | ||
compile(il+1, node.type)(node.statement) | ||
: ''; | ||
return new Element(node.type, inl(il) +'for (' | ||
+initializer | ||
+';' +sp() | ||
+test | ||
+';' +sp() | ||
+counter | ||
+'){' | ||
+nli(il+1) | ||
+statement | ||
+nli(il) | ||
+'}'); | ||
"ForStatement": function() { | ||
var initializer = (node.initializer ? | ||
compile(il, node.type)(node.initializer) | ||
: '' | ||
); | ||
var test = (node.test ? | ||
compile(il, node.type)(node.test) | ||
: '' | ||
); | ||
var counter = (node.counter ? | ||
compile(il, node.type)(node.counter) | ||
: '' | ||
); | ||
var statement = (node.statement ? | ||
compile(il + 1, node.type)(node.statement) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + 'for' + sp() + '(' + initializer + ';' + sp() + test + ';' + sp() + counter + ')' + sp() + '{' + nli(il + 1) + statement + nli(il) + '}') | ||
}, | ||
'ForInStatement': function(){ | ||
var iterator = node.iterator ? | ||
node.iterator.type ? | ||
compile(il, node.type)(node.iterator) | ||
: node.iterator | ||
: '', | ||
collection = node.collection ? | ||
compile(il, node.type)(node.collection) | ||
: '', | ||
statement = node.statement ? | ||
compile(il+1, node.type)(node.statement) | ||
: ''; | ||
return new Element(node.type, inl(il) +'for (' | ||
+iterator | ||
+' in ' | ||
+collection | ||
+'){' | ||
+nli(il+1) | ||
+statement | ||
+nli(il) | ||
+'}'); | ||
"ForInStatement": function() { | ||
var iterator = (node.iterator ? | ||
(node.iterator.type ? | ||
compile(il, node.type)(node.iterator) | ||
: node.iterator | ||
) | ||
: '' | ||
); | ||
var collection = (node.collection ? | ||
compile(il, node.type)(node.collection) | ||
: '' | ||
); | ||
var statement = (node.statement ? | ||
compile(il + 1, node.type)(node.statement) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + 'for' + sp() + '(' + iterator + ' in ' + collection + ')' + sp() + '{' + nli(il + 1) + statement + nli(il) + '}') | ||
}, | ||
'ContinueStatement': function(){ | ||
return new Element(node.type, 'continue'); | ||
"ContinueStatement": function() { | ||
return new Element(node.type, 'continue') | ||
}, | ||
'BreakStatement': function(){ | ||
return new Element(node.type, 'break'); | ||
}, | ||
'ReturnStatement': function(){ | ||
var value = node.value ? | ||
node.value.type ? | ||
compile(il, node.type)(node.value) | ||
: node.value | ||
: ''; | ||
return new Element(node.type, 'return' +(value ? ' ' : '') +value); | ||
"BreakStatement": function() { | ||
return new Element(node.type, 'break') | ||
}, | ||
'WithStatement': function(){ | ||
var environment = node.environment ? compile(il, node.type)(node.environment) : '', | ||
statement = node.statement ? compile(il, node.type)(node.statement) : ''; | ||
return new Element(node.type, inl(il) +'with' +sp() + '(' + environment + '){' | ||
+nli(il) +statement +nli(il) | ||
+ '}'); | ||
"ReturnStatement": function() { | ||
var value = (node.value ? | ||
(node.value.type ? | ||
compile(il, node.type)(node.value) | ||
: node.value | ||
) | ||
: '' | ||
); | ||
return new Element(node.type, 'return' + (value ? | ||
' ' | ||
: '' | ||
) + value) | ||
}, | ||
'SwitchStatement': function(){ | ||
var expression = node.expression ? | ||
node.expression.type ? | ||
compile(il, node.type)(node.expression) | ||
: node.expression | ||
: '', | ||
clauses = node.clauses ? | ||
node.clauses.length ? | ||
node.clauses.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, inl(il) +'switch' +sp() +'(' +expression +'){' | ||
+(clauses.length ? | ||
nli(il+1) | ||
+clauses.join(nli(il+1)) | ||
+nli(il) : '') | ||
+'}'); | ||
"WithStatement": function() { | ||
var environment = (node.environment ? | ||
compile(il, node.type)(node.environment) | ||
: '' | ||
); | ||
var statement = (node.statement ? | ||
compile(il, node.type)(node.statement) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + 'with' + sp() + '(' + environment + ')' + sp() + '{' + nli(il) + statement + nli(il) + '}') | ||
}, | ||
'CaseClause': function(){ | ||
var selector = node.selector ? | ||
node.selector.type ? | ||
compile(il, node.type)(node.selector) | ||
: node.selector | ||
: '\"\"', | ||
statements = node.statements ? | ||
node.statements.length ? | ||
node.statements.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, 'case ' +selector +':' | ||
+(statements.length ? | ||
nli(il+1) | ||
+statements.join(';'+nli(il+1)) : '')); | ||
"SwitchStatement": function() { | ||
var expression = (node.expression ? | ||
(node.expression.type ? | ||
compile(il, node.type)(node.expression) | ||
: node.expression | ||
) | ||
: '' | ||
); | ||
var clauses = (node.clauses ? | ||
(node.clauses.length ? | ||
node.clauses.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, inl(il) + 'switch' + sp() + '(' + expression + ')' + sp() + '{' + (clauses.length ? | ||
nli(il + 1) + clauses.join(nli(il + 1)) + nli(il) | ||
: '' | ||
) + '}') | ||
}, | ||
'DefaultClause': function(){ | ||
var statements = node.statements ? | ||
node.statements.length ? | ||
node.statements.map(compile(il+1, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, 'default:' | ||
+nli(il+1) | ||
+statements.join(';'+nli(il)) | ||
+nli(il)); | ||
"CaseClause": function() { | ||
var selector = (node.selector ? | ||
(node.selector.type ? | ||
compile(il, node.type)(node.selector) | ||
: node.selector | ||
) | ||
: '""' | ||
); | ||
var statements = (node.statements ? | ||
(node.statements.length ? | ||
node.statements.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, 'case ' + selector + ':' + (statements.length ? | ||
nli(il + 1) + statements.join(';' + nli(il + 1)) | ||
: '' | ||
)) | ||
}, | ||
'LabelledStatement': noop, | ||
'ThrowStatement': function(){ | ||
var exception = node.exception ? | ||
node.exception.type ? | ||
compile(il, node.type)(node.exception) | ||
: node.exception | ||
: ''; | ||
return new Element(node.type, 'throw ' +exception); | ||
"DefaultClause": function() { | ||
var statements = (node.statements ? | ||
(node.statements.length ? | ||
node.statements.map(compile(il + 1, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, 'default:' + nli(il + 1) + statements.join(';' + nli(il)) + nli(il)) | ||
}, | ||
'TryStatement': function(){ | ||
var block = node.block ? | ||
compile(il+1, node.type)(node.block) | ||
: '', | ||
_catch = node.catch ? | ||
compile(il+1, node.type)(node.catch) | ||
: '', | ||
_finally = node.finally ? | ||
compile(il+1, node.type)(node.finally) | ||
: ''; | ||
return new Element(node.type, inl(il) +'try' +sp() +'{' | ||
+nli(il+1) | ||
+block | ||
+nli(il) | ||
+'}' | ||
+(_catch && _catch ) | ||
+(_finally && _finally )); | ||
"LabelledStatement": function() { | ||
var statement = (node.statement ? | ||
compile(il, node.type)(node.statement) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + node.label + ':' + nli(il) + statement) | ||
}, | ||
'Catch': function(){ | ||
var block = node.block ? | ||
node.block.type ? | ||
compile(il+1, node.type)(node.block) | ||
: node.block | ||
: ''; | ||
return new Element(node.type, sp() +'catch' +sp() +'(' | ||
+(node.identifier ? | ||
node.identifier | ||
: '') | ||
+'){' | ||
+nli(il+1) | ||
+block | ||
+nli(il) | ||
+'}'); | ||
"ThrowStatement": function() { | ||
var exception = (node.exception ? | ||
(node.exception.type ? | ||
compile(il, node.type)(node.exception) | ||
: node.exception | ||
) | ||
: '' | ||
); | ||
return new Element(node.type, 'throw ' + exception) | ||
}, | ||
'Finally': function(){ | ||
var block = node.block ? | ||
node.block.type ? | ||
compile(il+1, node.type)(node.block) | ||
"TryStatement": function() { | ||
var block = (node.block ? | ||
compile(il + 1, node.type)(node.block) | ||
: '' | ||
); | ||
var _catch = (node.catch ? | ||
compile(il, node.type)(node.catch) | ||
: '' | ||
); | ||
var _finally = (node.finally ? | ||
compile(il, node.type)(node.finally) | ||
: '' | ||
); | ||
return new Element(node.type, inl(il) + 'try' + sp() + '{' + nli(il + 1) + block + nli(il) + '}' + _catch && _catch + _finally && _finally) | ||
}, | ||
"Catch": function() { | ||
var block = (node.block ? | ||
(node.block.type ? | ||
compile(il + 1, node.type)(node.block) | ||
: node.block | ||
: ''; | ||
return new Element(node.type, 'finally' +sp() | ||
+'{' | ||
+nli(il+1) | ||
+block | ||
+nli(il) | ||
+'}'); | ||
) | ||
: '' | ||
); | ||
return new Element(node.type, sp() + 'catch' + sp() + '(' + (node.identifier ? | ||
node.identifier | ||
: '' | ||
) + ')' + sp() + '{' + nli(il + 1) + block + nli(il) + '}') | ||
}, | ||
'DebuggerStatement': function(){ | ||
return new Element(node.type, 'debug'); | ||
"Finally": function() { | ||
var block = (node.block ? | ||
(node.block.type ? | ||
compile(il + 1, node.type)(node.block) | ||
: node.block | ||
) | ||
: '' | ||
); | ||
return new Element(node.type, sp() + 'finally' + sp() + '{' + nli(il + 1) + block + nli(il) + '}') | ||
}, | ||
'Program': function(){ | ||
var elements = node.elements ? | ||
node.elements.length ? | ||
node.elements.map(compile(il, node.type)) | ||
: [] | ||
: []; | ||
return new Element(node.type, | ||
elements.join(';'+nli(il))) +';'; | ||
"DebuggerStatement": function() { | ||
return new Element(node.type, 'debug') | ||
}, | ||
"Program": function() { | ||
var elements = (node.elements ? | ||
(node.elements.length ? | ||
node.elements.map(compile(il, node.type)) | ||
: [] | ||
) | ||
: [] | ||
); | ||
return new Element(node.type, elements.reduce(function(code, element, index) { | ||
var lastElement = index === elements.length - 1; | ||
var notTerminatedElement = element.type in notTerminatedElements; | ||
return code += element + (lastElement ? | ||
'' | ||
: (notTerminatedElement ? | ||
'' | ||
: ';' | ||
) + nli(il) | ||
) | ||
}, '')) | ||
} | ||
}; | ||
if (node.type in rules) | ||
return rules[node.type](); | ||
else console.log('missed',node.type); | ||
}; | ||
})(0)(ast).toString(); | ||
}; | ||
if (node.type in rules) return rules[node.type](); | ||
else console.log('missed', node.type); | ||
} | ||
}(0)(ast).toString() | ||
} |
@@ -10,3 +10,3 @@ { | ||
"author": "aynik", | ||
"version": "0.0.9", | ||
"version": "0.1.0", | ||
"repository": { | ||
@@ -13,0 +13,0 @@ "type": "git", |
@@ -14,18 +14,26 @@ var test = require('tape').test; | ||
test("Should run all tests", function(t){ | ||
t.test("sx --tab", function(t){ | ||
t.test("jsjs --tab", function(t){ | ||
t.plan(3); | ||
exec('echo "var b={a:1};" > tmp; ./bin/jsjs --tab 1 tmp; rm tmp', | ||
testOut(t, function(stdout){ | ||
t.same('var b = {\n "a": 1\n};', stdout); | ||
t.same('var b = {\n "a": 1\n}', stdout); | ||
})); | ||
}); | ||
t.test("sx --compress", function(t){ | ||
t.test("jsjs --compress", function(t){ | ||
t.plan(3); | ||
exec('echo "var b={a:1};" > tmp; ./bin/jsjs --compress tmp; rm tmp', | ||
testOut(t, function(stdout){ | ||
t.same('var b={"a":1};', stdout); | ||
t.same('var b={"a":1}', stdout); | ||
})); | ||
}); | ||
t.test("-- self recompilation", function(t){ | ||
t.plan(3); | ||
exec('./bin/jsjs -t 4 index.js > tmp; cat tmp; rm tmp', | ||
testOut(t, function(stdout){ | ||
t.same(fs.readFileSync('./index.js', 'utf-8'), stdout+"\n"); | ||
})); | ||
}); | ||
}); | ||
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is too big to display
773494
16545