113 lines
5.7 KiB
JavaScript
113 lines
5.7 KiB
JavaScript
class ASM_Compiler {
|
|
constructor(assemblycode) {
|
|
this.ASM = assemblycode.replace(/ +/g, ' ').replace(/\\t+/g, ' ').replace(/\\r+/g, '');
|
|
this.Labels = new Array();
|
|
this.Directives = {
|
|
Globals: new Array()
|
|
};
|
|
this.Sections = new Array();
|
|
this.CompileError = false;
|
|
this.CompileErrorReason = "";
|
|
}
|
|
firstPass() {
|
|
let codeLines = this.ASM.split("\n");
|
|
let currentSection = "";
|
|
console.log(`There are ${codeLines.length} lines`);
|
|
for (let linenum = 0; linenum < codeLines.length; linenum++) {
|
|
console.log(`Line ${linenum}: ${codeLines[linenum]}`);
|
|
let globalDeclared = false;
|
|
let sectionDeclared = false;
|
|
let lineColumns = codeLines[linenum].split(" ");
|
|
for (let colnum = 0; colnum < lineColumns.length; colnum++) {
|
|
console.log(`Column ${colnum}: ${lineColumns[colnum]}`);
|
|
switch (colnum) {
|
|
case 0: { // Labels
|
|
if (currentSection === "" && lineColumns[colnum] !== "") {
|
|
// error, shouldn't be anything here in the directives section
|
|
this.CompileError = true;
|
|
this.CompileErrorReason = "Unexpected label in directives section: " + lineColumns[colnum];
|
|
this.CompileErrorLine = linenum+1;
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
case 1: { // Instructions
|
|
if (currentSection === "" && lineColumns[colnum] === "") {
|
|
// Error, in directive there should be SOMETHING here
|
|
this.CompileError = true;
|
|
this.CompileErrorReason = "Missing Directive";
|
|
this.CompileErrorLine = linenum+1;
|
|
return false;
|
|
}
|
|
|
|
if (currentSection === "") {
|
|
switch (lineColumns[colnum].toLowerCase()) {
|
|
case "global": {
|
|
if (colnum === lineColumns.length - 1) {
|
|
this.CompileError = true;
|
|
this.CompileErrorReason = "Missing Global Label";
|
|
this.CompileErrorLine = linenum + 1;
|
|
return false;
|
|
}
|
|
globalDeclared = true;
|
|
break;
|
|
}
|
|
case "section": {
|
|
if (colnum === lineColumns.length - 1) {
|
|
this.CompileError = true;
|
|
this.CompileErrorReason = "Missing section type";
|
|
this.CompileErrorLine = linenum + 1;
|
|
return false;
|
|
}
|
|
sectionDeclared = true;
|
|
break;
|
|
}
|
|
default: {
|
|
this.CompileError = true;
|
|
this.CompileErrorReason = "Unknown directive: " + lineColumns[colnum];
|
|
this.CompileErrorLine = linenum + 1;
|
|
return false;
|
|
}
|
|
}
|
|
break;
|
|
} else {
|
|
if (!FindInstructon({Instruction:lineColumns[colnum]})) {
|
|
this.CompileError = true;
|
|
this.CompileErrorReason = "Unknown instruction: " + lineColumns[colnum];
|
|
this.CompileErrorLine = linenum + 1;
|
|
return false;
|
|
}
|
|
}
|
|
}
|
|
case 2: { // Operands
|
|
if (currentSection === "" && lineColumns[colnum] === "" && (globalDeclared === true || sectionDeclared === true)) {
|
|
// There should be a label here!
|
|
this.CompileError = true;
|
|
if (globalDeclared) this.CompileErrorReason = "Missing Global Label";
|
|
if (sectionDeclared) this.CompileErrorReason = "Missing Section type";
|
|
this.CompileErrorLine = linenum+1;
|
|
return false;
|
|
}
|
|
|
|
if (globalDeclared) {
|
|
let globallabel = {
|
|
Label: lineColumns[colnum].replace(":", ""),
|
|
Address: 0
|
|
};
|
|
this.Directives.Globals.push(globallabel);
|
|
}
|
|
if (sectionDeclared) {
|
|
let sectionType = {
|
|
Label: lineColumns[colnum].replace(".", ""),
|
|
Address: 0
|
|
};
|
|
currentSection = sectionType;
|
|
this.Sections.push(currentSection);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} |