8SA1Sim/js/asm_compiler.js

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;
}
}
}
}
}
}