forked from JohnEarnest/Octo
-
Notifications
You must be signed in to change notification settings - Fork 0
/
octo
executable file
·104 lines (91 loc) · 2.93 KB
/
octo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#!/usr/bin/env node
// simple piped commandline octo compiler
var compiler = require('./js/compiler');
var decompiler = require('./js/decompiler');
var fs = require('fs');
function extractFlag(name) {
var index = process.argv.indexOf(name);
if (index == -1) { return false; }
process.argv.splice(index, 1);
return true;
}
function compile(sourceCode) {
var comp = new compiler.Compiler(sourceCode);
try {
var comp = new compiler.Compiler(sourceCode);
comp.go();
return comp.rom;
}
catch(err) {
var line = 1;
for(var x = 0; x < comp.pos[1]-1; x++) {
if (sourceCode.charAt(x) == '\n') { line++; }
}
console.error("line %d: %s", line, err);
process.exit(1);
}
}
function compileFile(src, dst) {
var programText = fs.readFileSync(src, { encoding:'utf8' });
var programBinary = new Buffer(compile(programText));
if (typeof dst == "undefined") { process.stdout.write(programBinary); }
else { fs.writeFileSync(dst, programBinary, { encoding:'binary' }); }
return programBinary;
}
function decompileFile(src, dst) {
var buff = fs.readFileSync(src);
decompiler.analyze(buff, options);
var programText = decompiler.formatProgram(buff.length);
if (typeof dst == "undefined") { console.log(programText); }
else { fs.writeFileSync(dst, programText); }
return programText;
}
function printUsage() {
console.log("usage: octo [--decompile] [--roundtrip] [--qshift] [--qloadstore] <source> [<destination>]");
process.exit(1);
}
var options = {};
options['shiftQuirks' ] = extractFlag("--qshift");
options['loadStoreQuirks'] = extractFlag("--qloadstore");
var decompileFlag = extractFlag("--decompile");
var roundTripFlag = extractFlag("--roundtrip");
if (process.argv.length != 3 && process.argv.length != 4) { printUsage(); }
var sourceFile = process.argv[2];
var destFile = process.argv[3];
var decompiledText = "";
if (decompileFlag) {
decompiledText = decompileFile(sourceFile, destFile);
}
else if (!roundTripFlag) {
compileFile(sourceFile, destFile);
}
if (roundTripFlag) {
var startBinary = fs.readFileSync(sourceFile);
if (decompiledText == "") {
decompiler.analyze(startBinary, options);
decompiledText = decompiler.formatProgram(startBinary.length);
}
var endBinary = compile(decompiledText);
function hexFormat(num) {
if (typeof num == "undefined") { return "(none)"; }
var hex = num.toString(16).toUpperCase();
return "0x" + ((hex.length > 1) ? hex : "0" + hex);
}
var mismatch = false;
for(var x = 0; x < Math.max(startBinary.length, endBinary.length); x++) {
var mishere = (startBinary[x] != endBinary[x]);
if (!mishere) { continue; }
if (!mismatch) { console.error("round trip mismatch!"); }
mismatch |= mishere;
console.error("%s: original: %s output: %s",
hexFormat(x + 0x200),
hexFormat(startBinary[x]),
hexFormat(endBinary[x])
);
}
if (startBinary.length != endBinary.length) {
console.error("binary sizes do not match!");
mismatch = true;
}
if (mismatch) { process.exit(1); }
}