import * as fs from "fs"; const shema = { NOP:{c:0,l:[]}, LDA:{c:1,l:[1,2]}, LDB:{c:2,l:[1,2]}, LDC:{c:3,l:[1,2]}, LDX:{c:4,l:[1,2]}, LOA:{c:5,l:[1,2]}, LOB:{c:6,l:[1,2]}, LOC:{c:7,l:[1,2]}, STA:{c:8,l:[1,2]}, STB:{c:9,l:[1,2]}, STC:{c:10,l:[1,2]}, STX:{c:11,l:[1,2]}, SOA:{c:12,l:[1,2]}, SOB:{c:13,l:[1,2]}, SOC:{c:14,l:[1,2]}, LIA:{c:15,l:[4]}, LIB:{c:16,l:[4]}, LIC:{c:17,l:[4]}, LIX:{c:18,l:[4]}, CAB:{c:19,l:[]}, CBC:{c:20,l:[]}, CCA:{c:21,l:[]}, CAC:{c:22,l:[]}, CCB:{c:23,l:[]}, CBA:{c:24,l:[]}, CAX:{c:25,l:[]}, CBX:{c:26,l:[]}, CCX:{c:27,l:[]}, CXA:{c:28,l:[]}, CXB:{c:29,l:[]}, CXC:{c:30,l:[]}, CVA:{c:31,l:[1,1]}, CVB:{c:32,l:[1,1]}, CVC:{c:33,l:[1,1]}, ADD:{c:34,l:[1,1,1]}, SUB:{c:35,l:[1,1,1]}, MUL:{c:36,l:[1,1,1]}, DIV:{c:37,l:[1,1,1]}, MOD:{c:38,l:[1,1,1]}, POW:{c:39,l:[1,1,1]}, ROT:{c:40,l:[1,1,1]}, LOG:{c:41,l:[1,1]}, SR:{c:42,l:[]}, SL:{c:43,l:[]}, INC:{c:44,l:[1]}, DEC:{c:45,l:[1]}, BWO:{c:46,l:[]}, BWA:{c:47,l:[]}, BWX:{c:48,l:[]}, CMP:{c:49,l:[1,1]}, JMP:{c:50,l:[2]}, JE: {c:51,l:[2]}, JNE:{c:52,l:[2]}, JB: {c:53,l:[2]}, JNB:{c:54,l:[2]}, JS: {c:55,l:[2]}, JNS:{c:56,l:[2]}, PSH:{c:57,l:[1]}, PUL:{c:58,l:[1]}, JSR:{c:59,l:[2]}, JSA:{c:60,l:[]}, RSR:{c:61,l:[]}, IN :{c:252,l:[]}, OUT:{c:253,l:[1]}, SHS:{c:254,l:[2]}, HLT:{c:255,l:[]}, }; var path = process.argv[2]; var pathout = process.argv[3]; if(!path||!pathout){ console.log("PLease this Schema: node compile.js [path] [pathout]"); process.exit(); } var file = fs.readFileSync(path).toString().split("\n"); var s1 = []; var vars = {}; var label = false; file.forEach((dd, i) => { let d = dd.split(";")[0].trim(); if(d.length == 0) return; if(d.endsWith(":")){ label = d.replace(":",""); }else if(d.includes("=")){ var line = d.split("="); vars[line[0].trim()] = Number(line[1].trim()); }else{ var line = d.replace(/ +(?= )/g,'').split(" "); var base = {d:line.splice(1)}; if(label){ base.label = label; label = false; } var shem = shema[line[0]]; if(!shem){ console.log("Cout not parse command:",line[0]); process.exit(); } s1.push(Object.assign(base,shem)); } }); function findLabel(l){ var count = 0; for (var i = 0; i < s1.length; i++) { if(s1[i].label==l)return count; count += 1; s1[i].l.forEach((item, i) => { count += item; }); } console.log("Cout not pase label:",l); process.exit(); } s1.forEach((d, i) => { if(d.d.length){ d.d = d.d.map(e=>{ if (e.startsWith(".")){ return findLabel(e.substr(1)); }else if(!isNaN(e)){ var n = Number(e); if(Number.isInteger(n)){ if(n>=0){ return n; }else{ var buf = new ArrayBuffer(4); (new Int32Array(buf))[0] = n; return (new Uint32Array(buf))[0]; } }else{ var buf = new ArrayBuffer(4); (new Float32Array(buf))[0] = n; return (new Uint32Array(buf))[0]; } }else if(e=="NaN"){ return 2143289344; }else if(typeof vars[e] == "number"){ return vars[e]; }else{ console.log("Cout not parse:", e); process.exit(); } }); } }); var s2 = []; s1.forEach((d, i) => { s2.push(d.c); d.l.forEach((item, i) => { for (var j = item-1; j >= 0; j--) { s2.push(((d.d[i]??0)>>(8*j))&0xff); } }); }); var finish = s2.map(d=>d.toString(16).padStart(2,"0")).join(""); fs.writeFileSync(pathout,finish); console.log(`Finished converting in ${Math.round(performance.now())/1000}sec. The Size is: ${s2.length}byts. Binary in HEX saved to: ${pathout}`);