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で実行していたが、アセンブリの作成が入ってくるのね。