source
print("hello world")
compiler.js
var {exec, write, show, error} = require("./utils.js");
var lexer = require("./lexer.js");
var parser = require("./parser-comp.js");
var genasm = require("./genasm.js");
var source = read("source.3");
var tokens = lexer(source);
show("処理前tokens =", tokens);
parser(tokens);
console.log("-------------");
exec("as source.s -o source.o");
exec("ld -lc --dynamic-linker /lib64/ld-linux-x86-64.so.2 -o exec source.o");
console.log(exec("./exec"));
parser-comp.js
module.exports = parser;
var {write,expect,accept,show,error} = require("./utils.js");
var tokens;
function parser(t) {
tokens = t;
return callprint();
}
function callprint(){
if(tokens.length==0) return;
expect(tokens,"print");
expect(tokens,"(");
var msg = tokens.shift();
var codes = [];
codes.push(".text");
codes.push(".global _start");
codes.push("_start:");
codes.push("mov x2, #13");
codes.push("adr x1, msg");
codes.push("mov x0, #1 ");
codes.push("mov x8, #64");
codes.push("svc #0");
codes.push("mov x0, xzr");
codes.push("mov x8, #93");
codes.push("svc #0 ");
codes.push("msg:");
codes.push(".asciz " + msg);
codes.push("\n");
var asm = codes.join("\n")+"\n";
write("source.s",asm);
expect(tokens,")");
}
utils.js
module.exports = {exec, write, read, show, error, accept, expect}
function exec(cmd) {
return require('child_process').execSync(cmd, {encoding:"utf8"});
}
function write(filename, data){
require('fs').writeFileSync(filename,data);
}
parser-comp.jsのcallfunctionでarm64用のassemblyを書いて保存する。
assemblerの実行は別に分ける。
interpreterの方はrun.jsで実行していたが、アセンブリの作成が入ってくるのね。