-
Notifications
You must be signed in to change notification settings - Fork 0
/
generateOp.ts
137 lines (111 loc) · 4 KB
/
generateOp.ts
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import superagent from 'superagent';
import fs from 'fs';
// 00000
// ABCDE,AUX
// each bit represents a different argument
enum OpMode {
None = 0b00000,
A = 0b10000,
AB = 0b11000,
AC = 0b10100,
ABC = 0b11100,
AD = 0b10010,
D = 0b00010,
//AE = 0b10001,
E = 0b00001,
}
interface Opcode {
name: string; // the name of the opcode
mode: number; // the mode of the opcode
opcode: number; // the opcode value
hasAUX: boolean; // does the opcode have an AUX value?
}
async function main() {
let req = await superagent.get("https://raw.githubusercontent.com/luau-lang/luau/master/Common/include/Luau/Bytecode.h");
const AllOpcodes: Opcode[] = [];
let lines = req.text.split("\n");
let hasBegunOpcodes = false;
let TotalOpcodes = 0;
for (let i = 0; i < lines.length; i++) {
if (lines[i].includes("enum LuauOpcode")) // the beginning of the opcodes
{
hasBegunOpcodes = true;
i++ // skip the { character
continue;
}
if (hasBegunOpcodes && lines[i].includes("}")) // the end of the opcodes
{
console.log("Found the end of the opcodes");
break;
}
if (!hasBegunOpcodes) continue;
// we are in the OpCodes!
// remove beginning whitespace
let line = lines[i].trim();
if (line.startsWith("LOP_")) {
let opCode = line.split(",")[0]
let Desc = "";
let argNumber = 0b000000;
let currentLine = i;
let hasFoundOPDescription = false;
while (!hasFoundOPDescription) {
currentLine--;
let line = lines[currentLine].trim();
if (line == "" || line.includes("{")) {
hasFoundOPDescription = true;
Desc = lines[currentLine + 1].trim().split("// ")[1].trim();
}
// ABCDE + AUX
if (line.includes("// A:")) argNumber += 0b1000000;
if (line.includes("// B:")) argNumber += 0b0100000;
if (line.includes("// C:")) argNumber += 0b0010000;
if (line.includes("// D:")) argNumber += 0b0001000;
if (line.includes("// E:")) argNumber += 0b0000100;
// cus we can have two AUX values
if (line.includes("// AUX:")){
if (argNumber & 0b0000010)
{
argNumber += 0b0000001
} else {
argNumber += 0b0000010
}
}
}
if (OpMode[argNumber>>2] == undefined){
console.warn("Invalid argument mode for opcode " + opCode);
}
let op = {
name: opCode,
mode: argNumber,
opcode: AllOpcodes.length,
hasAUX: ((argNumber & 0b0000001) == 0b0000001) || ((argNumber & 0b0000010) == 0b0000010)
} as Opcode
AllOpcodes.push(op);
console.log(op.opcode,": Found opcode: " + opCode + ":", OpMode[argNumber>>2], "Has Aux?:", op.hasAUX);
}
}
AllOpcodes[59].mode = 0b10010_00
AllOpcodes[61].mode = 0b10010_00
let OpCodeFile = `// This file is generated by generateOp.ts\n`
function writeLine(line: string) {OpCodeFile += line + "\n"};
writeLine(`// Generated at ${new Date().toUTCString()}`);
writeLine(`export const OpCodeNames = [`);
for (let op of AllOpcodes) {
writeLine(` "${op.name.replace("LOP_", "")}", // OP: ${op.opcode}`);
}
writeLine(`]`);
writeLine(``)
writeLine(`export enum OpCode {`);
for (let op of AllOpcodes) {
writeLine(` ${op.name.replace("LOP_", "")} = ${op.opcode},`);
}
writeLine(`}`);
writeLine(``)
writeLine(`export const OpCodeModes = [`);
for (let op of AllOpcodes) {
writeLine(` ${op.mode},`);
}
writeLine(`]`);
fs.writeFileSync("./OpCodes.ts", OpCodeFile);
}
main();