cor-lang
Version:
The Language of the Web
142 lines (104 loc) • 3.35 kB
JavaScript
(function(cor){
var yy = cor.yy;
var Compiler = cor.Class({
generateSourceMap: true,
program: null,
columnsTrace: null,
sourceMap: null,
parser: null,
src: null,
lineOffset: null,
rIndent: /^\s+/,
env: null,
init: function(src, filename, generateSourceMap, lineOffset) {
this.filename = filename || '<vm>';
this.lineOffset = (lineOffset || 0);
this.src = src;
this.columnsTrace = [];
this.program = [];
this.parser = new cor.Parser();
this.parser.yy = yy;
if (generateSourceMap) {
this.sourceMap = new cor.SourceMap();
}
this.env = yy.env = new cor.yy.Environment(this.filename);
this.setup();
},
setup: function(){
var match, piece,
lineContent, line,
src = this.src.split('\n'),
count = src.length;
for (line = 1; line <= count; line++) {
lineContent = src[line - 1];
match = this.rIndent.exec(lineContent);
piece = match ? match[0].replace(/\t/, ' '): '';
this.program[line] = piece;
this.traceColumn(line, piece.length);
}
},
traceColumn: function(line, value) {
return this.columnsTrace[line] = (this.columnsTrace[line] || 0) + value;
},
parse: function() {
return this.parser.parse(this.src);
},
generateCode: function() {
this.program.shift();
return this.program.join('\n');
},
pushCode: function(compiled, lineno) {
this.program[lineno] += compiled;
},
compile: function(ast) {
var i,
comments = this.env.getComments(),
len = comments.length;
this.visitNode(ast);
for (i = 0; i < len; i++) {
this.visitNode(comments[i]);
}
return this.generateCode();
},
afterCompile: function(node, compiled, lineno) {
var column;
if (this.sourceMap) {
if (node instanceof yy.Lit && node.loc && !isNaN(node.loc.first_line)) {
column = this.columnsTrace[lineno];
this.sourceMap.add(
node.loc.first_line - 1,
node.loc.first_column,
lineno + (this.lineOffset - 1),
column
);
}
this.traceColumn(lineno, compiled.length);
}
},
visitNode: function(node) {
var i, ch, lineno, compiled;
if (!node) {
return;
}
if (node instanceof yy.Node) {
compiled = node.compile();
lineno = node.lineno;
ch = node.children;
if (typeof compiled === 'string' && typeof lineno !== 'undefined') {
this.pushCode(compiled, lineno);
this.afterCompile(node, compiled, lineno);
}
}
// visit children recursively
if (ch instanceof Array) {
for (i = 0; i < ch.length; i++) {
this.visitNode(ch[i]);
}
}
if (node instanceof yy.ContextAwareNode) {
yy.env.popContext();
}
}
});
cor.Compiler = Compiler;
})(typeof cor === 'undefined' ? {} : cor);