UNPKG

lowleveljs

Version:

1. 使用`@babel/parser`解析出js代码的语法树 2. 把所有的功能语句编译成最基础的操作指令列表 3. 编写解释器来运行这些基础操作指令

65 lines (59 loc) 2.05 kB
#!/usr/bin/env node // lljs --mask 123456 --compile-es5 test.js --out test.bin // lljs --mask 123456 --run test.bin const p=process.argv.slice(2) let opts={} for(let i=0; i<p.length; i++) { if(p[i]==='--version') { console.log('version: '+require(__dirname+'/package.json').version) process.exit() } if(p[i]==='--mask') opts.mask=p[++i] if(p[i]==='--run') opts.run=p[++i] if(p[i]==='--compile-es5') opts.compileFilename=p[++i] if(p[i]==='--out') opts.out=p[++i] if(p[i]==='--params') { const node=process.argv[0] process.argv.splice(0, i+3) process.argv.unshift(node, opts.run) break } // 以下为实验参数,不展示在README.md中 // * 1. 特定前缀表达式转换为随机变量名字 if(p[i]==='--replace-prefix') opts.repVars=p[++i] // * 2. 文件内容读取之后,先转换成es5语法 if(p[i]==='--transform') opts.transform=1 // * 3. 使用uglifyjs混淆源码 if(p[i]==='--use-uglifyjs') opts.uglifyjs=1 } const fl=(...a)=>require('fs').readFileSync(...a) const {compile, run, _compile}=require(__dirname) if(opts.run) { run(opts.mask, opts.run) }else if(opts.compileFilename) { if(!opts.out) { console.log('必须指定输出文件名:--out 文件名') process.exit(1) } let sourceCode=fl(opts.compileFilename, 'utf8') const {TXT, MEM, GVARS, SEQ, BIN}=_compile(sourceCode, opts) console.log('预编译结果 <数字(表示MEM的下标,或者该指令的特殊用法) 和 变量名称>:') console.log(TXT) console.log('='.repeat(32)) console.log('内存常量:') console.log(MEM) console.log('='.repeat(32)) console.log('全局变量:') console.log(GVARS) console.log('='.repeat(32)) console.log('打包后的结果:') console.log(BIN) console.log('='.repeat(32)) require('fs').writeFileSync(opts.out, Buffer.from(BIN)) console.log('保存完成') }else{ console.log('不支持此用法,请查看README.md') console.log() console.log(require('fs').readFileSync(__dirname+'/README.md', 'utf8')) process.exit() }