You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							519 lines
						
					
					
						
							14 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							519 lines
						
					
					
						
							14 KiB
						
					
					
				
								#!/usr/bin/env node
							 | 
						|
								
							 | 
						|
								var path = require('path');
							 | 
						|
								var fs = require('fs');
							 | 
						|
								var package = require('../package.json');
							 | 
						|
								var compiler = require("../dist/compiler.cjs");
							 | 
						|
								var helpers = compiler.helpers;
							 | 
						|
								
							 | 
						|
								function iter$(a){ return a ? (a.toArray ? a.toArray() : a) : []; };
							 | 
						|
								
							 | 
						|
								var self = {};
							 | 
						|
								// imba$v2=0
							 | 
						|
								
							 | 
						|
								var imbac1;
							 | 
						|
								
							 | 
						|
								var stdin = process.stdin;
							 | 
						|
								var stdout = process.stdout;
							 | 
						|
								var ansi = helpers.ansi;
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								var parseOpts = {
							 | 
						|
									alias: {
							 | 
						|
										o: 'output',
							 | 
						|
										h: 'help',
							 | 
						|
										s: 'stdio',
							 | 
						|
										p: 'print',
							 | 
						|
										m: 'sourcemap',
							 | 
						|
										t: 'tokenize',
							 | 
						|
										v: 'version',
							 | 
						|
										w: 'watch',
							 | 
						|
										d: 'debug'
							 | 
						|
									},
							 | 
						|
									
							 | 
						|
									schema: {
							 | 
						|
										output: {type: 'string'},
							 | 
						|
										outext: {type: 'string'},
							 | 
						|
										sourcemap: {type: 'string'}, // inline | extern
							 | 
						|
										platform: {type: 'string'}, // node | browser | worker
							 | 
						|
										styles: {type: 'string'}, // extern | inline
							 | 
						|
										imbaPath: {type: 'string'}, // global | inline | import
							 | 
						|
										sourceId: {type: 'string'},
							 | 
						|
										bin: {type: 'string'},
							 | 
						|
										hmr: null,
							 | 
						|
										raw: null
							 | 
						|
									},
							 | 
						|
									
							 | 
						|
									groupz: ['sourcemap']
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								var help = `\n
							 | 
						|
								Usage: imbac [options] path/to/script.imba
							 | 
						|
								
							 | 
						|
								  -h, --help             display this help message
							 | 
						|
								  -v, --version          display the version number
							 | 
						|
								  -w, --watch            recompile files on change
							 | 
						|
								  -m, --sourcemap       generate source map and add inline to .js files
							 | 
						|
								  -o, --output [dir]     set the output directory for compiled JavaScript
							 | 
						|
								  -p, --print            print out the compiled JavaScript
							 | 
						|
								  -d, --debug            Enable compiler debugging
							 | 
						|
								  -s, --stdio            listen for and compile scripts over stdio
							 | 
						|
								  -t, --tokenize         print out the tokens that the lexer/rewriter produce
							 | 
						|
								  --bin [bin]            compile file with a hashbang: 'node', 'bun', etc.
							 | 
						|
								  --platform [type]      Specify platform: 'node', 'browser', 'worker'
							 | 
						|
								  --styles [format]      Specify how styles should be added: 'extern', 'inline'
							 | 
						|
								  --silent               only print out errors (skip warnings)
							 | 
						|
								  --hmr                  compile for hot-module-reloading
							 | 
						|
								  --analyze          print out the scopes and variables of your script
							 | 
						|
								`;
							 | 
						|
								
							 | 
						|
								function CLI(options){
							 | 
						|
									if(options === undefined) options = {};
							 | 
						|
									this._options = options;
							 | 
						|
									this._sources = [];
							 | 
						|
									this._current = null;
							 | 
						|
									if(!options.fs) Object.defineProperty(options,'fs',{value: fs, enumerable:false});
							 | 
						|
									if(!options.path) Object.defineProperty(options,'path',{value: path, enumerable:false});
							 | 
						|
									
							 | 
						|
									this;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								CLI.prototype.sources = function(v){ return this._sources; }
							 | 
						|
								CLI.prototype.setSources = function(v){ this._sources = v; return this; };
							 | 
						|
								
							 | 
						|
								CLI.prototype.ensureDir = function (src){
							 | 
						|
									if (fs.existsSync(src)) { return true };
							 | 
						|
									var parts = path.normalize(src).split(path.sep);
							 | 
						|
									for (let i = 0, items = iter$(parts), len = items.length, part; i < len; i++) {
							 | 
						|
										part = items[i];
							 | 
						|
										if (i < 1) { continue; };
							 | 
						|
										// what about relative paths here? no good? might be important for symlinks etc no?
							 | 
						|
										var dir = parts.slice(0,i + 1).join(path.sep);
							 | 
						|
										
							 | 
						|
										if (fs.existsSync(dir)) {
							 | 
						|
											var stat = fs.statSync(dir);
							 | 
						|
										} else if (part.match(/\.(imba\d?|js)$/) || i == len - 1) {
							 | 
						|
											true;
							 | 
						|
										} else {
							 | 
						|
											fs.mkdirSync(dir);
							 | 
						|
											console.log(ansi.green(("+ mkdir " + dir)));
							 | 
						|
										};
							 | 
						|
									};
							 | 
						|
									return;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.findRecursive = function (root,pattern){
							 | 
						|
									var m;
							 | 
						|
									if(pattern === undefined) pattern = /\.imba\d?$/;
							 | 
						|
									var results = [];
							 | 
						|
									root = path.relative(process.cwd(),root);
							 | 
						|
									root = path.normalize(root);
							 | 
						|
									
							 | 
						|
									var read = function(src,depth) {
							 | 
						|
										src = path.normalize(src);
							 | 
						|
										var stat = fs.statSync(src);
							 | 
						|
										
							 | 
						|
										if (stat.isDirectory() && depth > 0) {
							 | 
						|
											var files = fs.readdirSync(src);
							 | 
						|
											let res = [];
							 | 
						|
											for (let i = 0, items = iter$(files), len = items.length; i < len; i++) {
							 | 
						|
												res.push(read(src + '/' + items[i],depth - 1));
							 | 
						|
											};
							 | 
						|
											return res;
							 | 
						|
										} else if (src.match(pattern)) {
							 | 
						|
											return results.push(src);
							 | 
						|
										};
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									if (m = root.match(/\/\*\.imba\d?$/)) {
							 | 
						|
										root = root.slice(0,-m[0].length);
							 | 
						|
										read(root,1);
							 | 
						|
									} else {
							 | 
						|
										read(root,10);
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									return results;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.pathToSource = function (src,coll,o,root){
							 | 
						|
									if(root === undefined) root = null;
							 | 
						|
									var abs = path.resolve(process.cwd(),src);
							 | 
						|
									var stat = fs.statSync(abs);
							 | 
						|
									
							 | 
						|
									if (stat.isDirectory()) {
							 | 
						|
										// console.log "is directory",findRecursive(abs)
							 | 
						|
										var files = this.findRecursive(abs);
							 | 
						|
										for (let i = 0, items = iter$(files), len = items.length; i < len; i++) {
							 | 
						|
											this.pathToSource(items[i],coll,o,abs);
							 | 
						|
										};
							 | 
						|
										return;
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									var file = {
							 | 
						|
										filename: path.basename(src),
							 | 
						|
										sourcePath: abs,
							 | 
						|
										sourceBody: fs.readFileSync(abs,'utf8')
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									if (o.output) {
							 | 
						|
										var rel = root ? path.relative(root,abs) : file.filename;
							 | 
						|
										file.targetPath = path.resolve(o.output,rel);
							 | 
						|
									} else if (!o.stdio) {
							 | 
						|
										file.targetPath = file.sourcePath;
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									if (file.targetPath) {
							 | 
						|
										var ext = ('.' + (o.outext || 'js')).replace(/^\.+/,'.');
							 | 
						|
										file.targetPath = file.targetPath.replace(/\.imba\d?$/,ext);
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									return coll.push(file);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								CLI.prototype.cwd = function (){
							 | 
						|
									return process.cwd();
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.run = function (){
							 | 
						|
									var self = this, o_, main_;
							 | 
						|
									(o_ = self.o()).platform || (o_.platform = 'node');
							 | 
						|
									
							 | 
						|
									if (self.o().output) {
							 | 
						|
										self.o().output = path.normalize(path.resolve(self.cwd(),self.o().output));
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									var paths = ((typeof (main_ = self.o().main)=='string'||main_ instanceof String)) ? [self.o().main] : ((self.o().main || []));
							 | 
						|
									for (let i = 0, items = iter$(paths), len = items.length; i < len; i++) {
							 | 
						|
										self.pathToSource(items[i],self._sources,self._options);
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									if (self.o().stdio) {
							 | 
						|
										if (!self.o().output) { self.o().print = true };
							 | 
						|
										var chunks = [];
							 | 
						|
										stdin.resume();
							 | 
						|
										stdin.setEncoding('utf8');
							 | 
						|
										stdin.on('data',function(chunk) { return chunks.push(chunk); });
							 | 
						|
										stdin.on('end',function() {
							 | 
						|
											self.sources().push({sourcePath: 'stdin',sourceBody: chunks.join()});
							 | 
						|
											return self.finish();
							 | 
						|
										});
							 | 
						|
									} else {
							 | 
						|
										self.finish();
							 | 
						|
									};
							 | 
						|
									return self;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.o = function (){
							 | 
						|
									return this._options;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.traverse = function (cb){
							 | 
						|
									for (let i = 0, items = iter$(this.sources()), len = items.length, src; i < len; i++) {
							 | 
						|
										src = items[i];
							 | 
						|
										this._current = src;
							 | 
						|
										cb(src);
							 | 
						|
									};
							 | 
						|
									return this;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.log = function (message){
							 | 
						|
									if (!this.o().print) { console.log(message) };
							 | 
						|
									return this;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.b = function (text){
							 | 
						|
									return this.o().colors ? ansi.bold(text) : text;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.gray = function (text){
							 | 
						|
									return this.o().colors ? ansi.gray(text) : text;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.red = function (text){
							 | 
						|
									return this.o().colors ? ansi.red(text) : text;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.green = function (text){
							 | 
						|
									return this.o().colors ? ansi.green(text) : text;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.yellow = function (text){
							 | 
						|
									return this.o().colors ? ansi.yellow(text) : text;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.rel = function (src){
							 | 
						|
									src = src.sourcePath || src;
							 | 
						|
									return path.relative(process.cwd(),src);
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.present = function (data){
							 | 
						|
									if (this.o().print) {
							 | 
						|
										process.stdout.write(data);
							 | 
						|
									};
							 | 
						|
									return this;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.analyze = function (){
							 | 
						|
									var self = this;
							 | 
						|
									return self.traverse(function(src) {
							 | 
						|
										var o2 = Object.create(self.o());
							 | 
						|
										o2.sourcePath = src.sourcePath;
							 | 
						|
										o2.entities = true;
							 | 
						|
										var out = compiler.analyze(src.sourceBody,o2);
							 | 
						|
										src.analysis = out;
							 | 
						|
										return self.present(JSON.stringify(out,null,2));
							 | 
						|
									});
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.tokenize = function (){
							 | 
						|
									// should prettyprint tokens
							 | 
						|
									var self = this;
							 | 
						|
									return self.traverse(function(src) {
							 | 
						|
										var o2 = Object.create(self.o());
							 | 
						|
										o2.sourcePath = src.sourcePath;
							 | 
						|
										o2.rewrite = self.o().rewrite;
							 | 
						|
										var out
							 | 
						|
										try {
							 | 
						|
											out = compiler.tokenize(src.sourceBody,o2);	
							 | 
						|
										} catch(e){
							 | 
						|
											console.log('error in tokenizer:',e.message);
							 | 
						|
											throw e;
							 | 
						|
											out = e._options.tokens;
							 | 
						|
										}
							 | 
						|
										
							 | 
						|
										src.tokens = out;
							 | 
						|
										
							 | 
						|
										let res = [];
							 | 
						|
										for (let i = 0, items = iter$(src.tokens), len = items.length, t; i < len; i++) {
							 | 
						|
											t = items[i];
							 | 
						|
											var typ = t._type;
							 | 
						|
											var id = t._value;
							 | 
						|
											var s;
							 | 
						|
											if (typ == 'TERMINATOR') {
							 | 
						|
												s = "[" + self.b(id.replace(/\n/g,"\\n").replace(/\t/g,"\\t")) + "]\n";
							 | 
						|
											} else if (typ == 'IDENTIFIER') {
							 | 
						|
												s = id;
							 | 
						|
											} else if (typ == 'NUMBER') {
							 | 
						|
												s = id;
							 | 
						|
											} else if (id == typ) {
							 | 
						|
												s = "[" + self.b(id) + "]";
							 | 
						|
											} else {
							 | 
						|
												s = self.b(("[" + typ + " " + id + "]"));
							 | 
						|
											};
							 | 
						|
											
							 | 
						|
											if (t._loc != -1 && self.o().sourcemap) {
							 | 
						|
												s = ("(" + (t._loc) + ":" + (t._len) + ")") + s; // chalk.bold(s)
							 | 
						|
											};
							 | 
						|
											
							 | 
						|
											res.push(s);
							 | 
						|
										};
							 | 
						|
										var strings = res;
							 | 
						|
										
							 | 
						|
										return process.stdout.write(strings.join(' ') + '\n');
							 | 
						|
									});
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.compile = function (){
							 | 
						|
									var self = this;
							 | 
						|
									return self.traverse(function(src) { return self.compileFile(src); });
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.compileFile = function (src){
							 | 
						|
									var self = this;
							 | 
						|
									var opts = Object.create(self.o());
							 | 
						|
									// opts.filename = src.filename;
							 | 
						|
									opts.sourcePath = src.sourcePath;
							 | 
						|
									
							 | 
						|
									if(opts.extlib) opts.imbaPath = null;
							 | 
						|
									
							 | 
						|
									var out = {};
							 | 
						|
									var t = Date.now();
							 | 
						|
									var at = new Date().toTimeString().substr(0,8);
							 | 
						|
									var srcp = self.o().stdio ? src.sourcePath : path.relative(process.cwd(),src.sourcePath);
							 | 
						|
									var dstp = src.targetPath && path.relative(process.cwd(),src.targetPath);
							 | 
						|
									
							 | 
						|
									var srcpAbs = path.resolve(srcp);
							 | 
						|
									var dstpAbs = path.resolve(dstp);
							 | 
						|
									
							 | 
						|
									if (srcp.indexOf("../") >= 0) {
							 | 
						|
										srcp = srcpAbs;
							 | 
						|
										dstp = dstpAbs;
							 | 
						|
									};
							 | 
						|
								
							 | 
						|
									opts.sourcePath = srcpAbs;
							 | 
						|
									
							 | 
						|
									try {
							 | 
						|
										if (src.sourcePath.match(/\.imba1$/)) {
							 | 
						|
											imbac1 || (imbac1 = require("../script/bootstrap.compiler.js"));
							 | 
						|
											opts.filename = opts.sourcePath;
							 | 
						|
											out = imbac1.compile(src.sourceBody,opts);
							 | 
						|
										} else {
							 | 
						|
											out = compiler.compile(src.sourceBody,opts);
							 | 
						|
											if(opts.runtime == 'inline'){
							 | 
						|
												out.js = fs.readFileSync(path.resolve(__dirname,'..','dist','imba.js'),'utf8') + '\n' + out.js;
							 | 
						|
											}
							 | 
						|
										};
							 | 
						|
									} catch (e) {
							 | 
						|
										console.log('error',e);
							 | 
						|
										out = {errors: [e]};
							 | 
						|
									};
							 | 
						|
								
							 | 
						|
									if(out.errors && out.errors.length){
							 | 
						|
										// out = { error: out.errors[0].toError() }
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									out.compileTime = Date.now() - t;
							 | 
						|
								
							 | 
						|
									let sourcemap = opts.sourcemap && out.sourcemap;
							 | 
						|
								
							 | 
						|
									if (sourcemap) {
							 | 
						|
										// TODO this should clearly happen inside the compiler??
							 | 
						|
										if(opts.sourcemap == 'inline'){
							 | 
						|
											// var base64 = new Buffer(JSON.stringify(sourcemap)).toString("base64");
							 | 
						|
											// out.js = out.js + "\n//# sourceMappingURL=data:application/json;base64," + base64;	
							 | 
						|
										} else if (opts.sourcemap && opts.sourcemap != 'external'){
							 | 
						|
											out.js = out.js + "\n//# sourceMappingURL=" + path.basename(src.targetPath + '.map');
							 | 
						|
										}
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									src.output = out;
							 | 
						|
									
							 | 
						|
									let status = ("" + self.gray(("" + at + " compile")) + " " + srcp + " " + self.gray("to") + " " + dstp + " " + self.green(out.compileTime + "ms"));
							 | 
						|
									
							 | 
						|
									if (out.error) {
							 | 
						|
								
							 | 
						|
										status += self.red(" [1 error]");
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									if (out.warnings && out.warnings.length) {
							 | 
						|
										let count = out.warnings.length;
							 | 
						|
										status += self.yellow((" [" + count + " warning" + ((count > 1) ? 's' : '') + "]"));
							 | 
						|
									};
							 | 
						|
								
							 | 
						|
									if (out.errors && out.errors.length) {
							 | 
						|
										let count = out.errors.length;
							 | 
						|
										status += self.red((" [" + count + " error" + ((count > 1) ? 's' : '') + "]"));
							 | 
						|
										if (!self.o().print) {
							 | 
						|
											self.log(status);
							 | 
						|
											
							 | 
						|
											out.errors.forEach(function(err,i){
							 | 
						|
												if(err.toError instanceof Function){
							 | 
						|
													err = err.toError();
							 | 
						|
												}
							 | 
						|
												// log "{gray("{at} compile")} {srcp} {gray("to")} {dstp} {red(out:compileTime + "ms")}"
							 | 
						|
												if (err.excerpt) {
							 | 
						|
													self.log("   " + err.excerpt({colors: self.o().colors}));
							 | 
						|
												} else if(err instanceof SyntaxError && err.stack){
							 | 
						|
													self.log(err.stack);
							 | 
						|
												} else {
							 | 
						|
													self.log("   " + err.message);
							 | 
						|
													self.log("   " + ("in file " + srcp));
							 | 
						|
													if (err.stack) { self.log(err.stack) };
							 | 
						|
												};
							 | 
						|
											})
							 | 
						|
										};
							 | 
						|
									}
							 | 
						|
									else if (src.targetPath && out.js !== undefined && !self.o().print) {
							 | 
						|
										self.ensureDir(src.targetPath);
							 | 
						|
										let outString
							 | 
						|
										if (opts.bin) {
							 | 
						|
											let hashbang = '#! /usr/bin/env ' + opts.bin + '\n'
							 | 
						|
											outString = hashbang + out.js
							 | 
						|
										} else {
							 | 
						|
											outString = out.js
							 | 
						|
										}
							 | 
						|
										fs.writeFileSync(src.targetPath,outString,'utf8');
							 | 
						|
										if (!self.o().print) { self.log(status) };
							 | 
						|
								
							 | 
						|
										if(sourcemap && !opts.print && opts.sourcemap != 'inline') { // And webpack
							 | 
						|
											fs.writeFileSync(src.targetPath + '.map',JSON.stringify(sourcemap,null,2),'utf8');
							 | 
						|
										}
							 | 
						|
										// log "{gray("{at} compile")} {srcp} {gray("to")} {dstp} {green(out:compileTime + "ms")}"
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									if (out.warnings && !self.o().silent && !self.o().print) {
							 | 
						|
										// log "   {out:warnings:length} warnings"
							 | 
						|
										out.warnings.forEach(function(err,i){
							 | 
						|
											if(err.toError instanceof Function){
							 | 
						|
												err = err.toError();
							 | 
						|
											}
							 | 
						|
											// log "{gray("{at} compile")} {srcp} {gray("to")} {dstp} {red(out:compileTime + "ms")}"
							 | 
						|
											if (err.excerpt) {
							 | 
						|
												self.log("   " + err.excerpt({colors: self.o().colors}));
							 | 
						|
											} else if(err instanceof SyntaxError && err.stack){
							 | 
						|
												self.log(err.stack);
							 | 
						|
											} else {
							 | 
						|
												self.log("   " + err.message);
							 | 
						|
												self.log("   " + ("in file " + srcp));
							 | 
						|
												if (err.stack) { self.log(err.stack) };
							 | 
						|
											};
							 | 
						|
										})
							 | 
						|
										// helpers
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									
							 | 
						|
									if (self.o().watch && !src.watcher) {
							 | 
						|
										var now = Date.now();
							 | 
						|
										src.watcher = fs.watch(src.sourcePath,function(type,filename) {
							 | 
						|
											if (type == 'change') {
							 | 
						|
												return setTimeout(function() {
							 | 
						|
													return fs.readFile(src.sourcePath,'utf8',function(err,body) {
							 | 
						|
														if (body != src.sourceBody) {
							 | 
						|
															src.sourceBody = body;
							 | 
						|
															return self.compileFile(src);
							 | 
						|
														};
							 | 
						|
													});
							 | 
						|
												},100);
							 | 
						|
											};
							 | 
						|
										});
							 | 
						|
									};
							 | 
						|
									
							 | 
						|
									
							 | 
						|
									if (self.o().print && out.js) {
							 | 
						|
										process.stdout.write(out.js);
							 | 
						|
									};
							 | 
						|
									return self;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								CLI.prototype.finish = function (){
							 | 
						|
									try {
							 | 
						|
										if (this.o().analyze) {
							 | 
						|
											this.o().print = true;
							 | 
						|
											this.analyze(this.sources(),this.o());
							 | 
						|
										} else if (this.o().tokenize) {
							 | 
						|
											this.o().print = true;
							 | 
						|
											this.tokenize(this.sources(),this.o());
							 | 
						|
										} else {
							 | 
						|
											this.compile(this.sources(),this.o());
							 | 
						|
										};
							 | 
						|
									} catch (e) {
							 | 
						|
										if (this._current) {
							 | 
						|
											this.log(("ERROR in " + this.b(this.rel(this._current))));
							 | 
						|
										};
							 | 
						|
										if (e.excerpt) {
							 | 
						|
											this.log(e.excerpt({colors: true}));
							 | 
						|
										} else {
							 | 
						|
											throw e;
							 | 
						|
										};
							 | 
						|
									};
							 | 
						|
									return this;
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								function main(){
							 | 
						|
									var o = helpers.parseArgs(process.argv.slice(2),parseOpts);
							 | 
						|
								
							 | 
						|
									(o.colors == null) ? (o.colors = true) : o.colors;
							 | 
						|
									
							 | 
						|
									if (o.version) {
							 | 
						|
										return console.log(package.version);
							 | 
						|
									} else if (!(o.main || o.stdio) || o.help) {
							 | 
						|
										return console.log(help);
							 | 
						|
									} else {
							 | 
						|
										return new CLI(o).run();
							 | 
						|
									};
							 | 
						|
								};
							 | 
						|
								
							 | 
						|
								main();
							 | 
						|
								
							 |