Updated the parser to be able to handle the changes made to the ISA.
This commit is contained in:
+112
-126
@@ -108,104 +108,6 @@ void HandleAssemblerDirective() {
|
||||
HeapSize += symbol->Length;
|
||||
}
|
||||
break;
|
||||
case Load:
|
||||
{
|
||||
AdvanceParser();
|
||||
Token* reg = PeekToken();
|
||||
|
||||
if (reg->Class != RegisterClass && reg->Class != DirectiveClass) {
|
||||
fprintf(stderr, "[Line %d] Syntax error, expected register or keyword 'byte'.\n", reg->LineNumber);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (reg->Class == RegisterClass) {
|
||||
AdvanceParser();
|
||||
|
||||
ExpectPuncuation(Comma, ForwardParser);
|
||||
|
||||
if (PeekToken()->Class != IdentifierClass && PeekToken()->Class != NumberClass && PeekToken()->Class != RegisterClass) {
|
||||
fprintf(stderr, "[Line %d] Syntax error, expected either a symbol, numeric literal or a register.\n", PeekToken()->LineNumber);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
if (PeekToken()->Class == NumberClass) {
|
||||
directive->Class = MnemonicClass;
|
||||
directive->Value.Mnemonic = COPYI;
|
||||
directive->Lemexe = "copyi";
|
||||
AdvanceParser(); //Number, register or identifier
|
||||
}
|
||||
else if (PeekToken()->Class == RegisterClass) {
|
||||
directive->Class = MnemonicClass;
|
||||
directive->Value.Mnemonic = COPY;
|
||||
directive->Lemexe = "copy";
|
||||
AdvanceParser(); //Number, register or identifier
|
||||
}
|
||||
else {
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
|
||||
directive->Class = MnemonicClass;
|
||||
directive->Value.Mnemonic = COPYA;
|
||||
directive->Lemexe = "copya";
|
||||
}
|
||||
}
|
||||
// else if (reg->Class == DirectiveClass) {
|
||||
// if (reg->Value.Directive != Byte) {
|
||||
// fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", reg->LineNumber);
|
||||
// exit(3);
|
||||
// }
|
||||
|
||||
// RemoveCurrentToken(); //byte
|
||||
|
||||
// ExpectRegister();
|
||||
|
||||
// ExpectPuncuation(Comma, ForwardParser);
|
||||
|
||||
// ExpectRegister();
|
||||
|
||||
// directive->Class = MnemonicClass;
|
||||
// directive->Value.Mnemonic = LODB;
|
||||
// directive->Lemexe = "LODB";
|
||||
// }
|
||||
|
||||
ExpectLineEndOrFileEnd(ForwardParser);
|
||||
}
|
||||
|
||||
break;
|
||||
case Store:
|
||||
{
|
||||
AdvanceParser();
|
||||
|
||||
Token* next = PeekToken();
|
||||
|
||||
if (next->Class != DirectiveClass) {
|
||||
//If the token after the current one is invalid then the expect function ahead will exit, so we can
|
||||
//go ahead and change the STORE directive into a proper opcode here.
|
||||
directive->Value.Mnemonic = COPY;
|
||||
directive->Class = MnemonicClass;
|
||||
directive->Lemexe = "copy";
|
||||
}
|
||||
else {
|
||||
if (next->Value.Directive != Byte) {
|
||||
fprintf(stderr, "[Line %d] Syntax error, expected keyword 'byte'.\n", next->LineNumber);
|
||||
exit(10);
|
||||
}
|
||||
|
||||
RemoveCurrentToken(); //Remove byte modifier token.
|
||||
|
||||
directive->Value.Mnemonic = COPYB;
|
||||
directive->Class = MnemonicClass;
|
||||
directive->Lemexe = "copyb";
|
||||
}
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
ExpectPuncuation(Comma, ForwardParser);
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
ExpectLineEndOrFileEnd(ForwardParser);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Synatx error on line %d, %s.\n", directive->LineNumber, directive->Lemexe);
|
||||
exit(1);
|
||||
@@ -218,6 +120,86 @@ void HandleOpcode(void) {
|
||||
AdvanceParser();
|
||||
|
||||
switch(opcode->Value.Mnemonic) {
|
||||
case COPY:
|
||||
{
|
||||
Token* arg = PeekToken();
|
||||
int isByte = 0;
|
||||
|
||||
if (arg->Class == DirectiveClass) {
|
||||
if (arg->Value.Directive != Byte) {
|
||||
fprintf(stderr, "Syntax error on line %d: expected keyword 'byte'.\n", opcode->LineNumber);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
RemoveCurrentToken(); //byte
|
||||
|
||||
isByte = 1;
|
||||
|
||||
arg = PeekToken();
|
||||
}
|
||||
|
||||
if (arg->Class == RegisterClass) {
|
||||
ExpectRegister();
|
||||
|
||||
ExpectPuncuation(Comma, ForwardParser);
|
||||
|
||||
arg = PeekToken();
|
||||
|
||||
if (arg->Class == NumberClass) {
|
||||
opcode->Value.Mnemonic = isByte ? COPYB : COPYI;
|
||||
opcode->Lemexe = isByte ? "copyb" : "copyi";
|
||||
|
||||
AdvanceParser();
|
||||
}
|
||||
else if (arg->Class == RegisterClass) {
|
||||
if (isByte) {
|
||||
fprintf(stderr, "Syntax error on line %d: unexpected modifier 'Byte' for Register to Register copy.\n", opcode->LineNumber);
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
opcode->Value.Mnemonic = COPY;
|
||||
opcode->Lemexe = "copy";
|
||||
}
|
||||
else if (arg->Class & IdentifierClass) {
|
||||
opcode->Value.Mnemonic = isByte ? COPYAB : COPYA;
|
||||
opcode->Lemexe = isByte ? "copyab" : "copya";
|
||||
|
||||
AdvanceParser();
|
||||
}
|
||||
else {
|
||||
ExpectPuncuation(LBracket, ForwardParser);
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
ExpectPuncuation(RBracket, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = isByte ? COPYRAB : COPYRA;
|
||||
opcode->Lemexe = isByte ? "copyrab" : "copyra";
|
||||
}
|
||||
}
|
||||
else {
|
||||
ExpectPuncuation(LBracket, ForwardParser);
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
ExpectPuncuation(RBracket, ForwardParser);
|
||||
|
||||
ExpectPuncuation(Comma, ForwardParser);
|
||||
|
||||
ExpectPuncuation(LBracket, ForwardParser);
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
ExpectPuncuation(RBracket, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = isByte ? COPYRARAB : COPYRARA;
|
||||
opcode->Lemexe = isByte ? "copyrarab" : "copyrara";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CMP:
|
||||
{
|
||||
ExpectRegister();
|
||||
@@ -226,7 +208,7 @@ void HandleOpcode(void) {
|
||||
|
||||
TokenClass class = PeekToken()->Class;
|
||||
|
||||
if (class == NumberClass) {
|
||||
if (class == NumberClass || class & IdentifierClass) {
|
||||
opcode->Value.Mnemonic = CMPI;
|
||||
opcode->Lemexe = "CMPI";
|
||||
|
||||
@@ -272,55 +254,59 @@ void HandleOpcode(void) {
|
||||
{
|
||||
Token* arg = PeekToken();
|
||||
|
||||
opcode->Value.Mnemonic = JMPI;
|
||||
opcode->Lemexe = "jmpi";
|
||||
|
||||
if (arg->Class == IdentifierClass) {
|
||||
if (arg->Class & IdentifierClass) {
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = JMP;
|
||||
opcode->Lemexe = "jmp";
|
||||
}
|
||||
else ExpectRegister();
|
||||
else
|
||||
{
|
||||
ExpectPuncuation(LBracket, ForwardParser);
|
||||
|
||||
ExpectRegister();
|
||||
|
||||
ExpectPuncuation(RBracket, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = JMPI;
|
||||
opcode->Lemexe = "jmpi";
|
||||
}
|
||||
}
|
||||
break;
|
||||
case JZ:
|
||||
{
|
||||
Token* arg = PeekToken();
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
|
||||
if (arg->Class == IdentifierClass) {
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = JZ;
|
||||
opcode->Lemexe = "jz";
|
||||
}
|
||||
else ExpectRegister();
|
||||
opcode->Value.Mnemonic = JZ;
|
||||
opcode->Lemexe = "jz";
|
||||
}
|
||||
break;
|
||||
case JG:
|
||||
{
|
||||
Token* arg = PeekToken();
|
||||
|
||||
if (arg->Class == IdentifierClass) {
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = JG;
|
||||
opcode->Lemexe = "jg";
|
||||
}
|
||||
else ExpectRegister();
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
opcode->Value.Mnemonic = JG;
|
||||
opcode->Lemexe = "jg";
|
||||
}
|
||||
break;
|
||||
case JL:
|
||||
{
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
|
||||
opcode->Value.Mnemonic = JL;
|
||||
opcode->Lemexe = "jl";
|
||||
}
|
||||
break;
|
||||
case CALL:
|
||||
{
|
||||
Token* arg = PeekToken();
|
||||
|
||||
if (arg->Class == IdentifierClass) {
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
if ((arg->Class & IdentifierClass) == 0) {
|
||||
fprintf(stderr, "Syntax error on line %d: expected subroutine call target.\n", opcode->LineNumber);
|
||||
|
||||
opcode->Value.Mnemonic = JL;
|
||||
opcode->Lemexe = "jl";
|
||||
exit(1);
|
||||
}
|
||||
else ExpectRegister();
|
||||
|
||||
ExpectIdentifier(0, ForwardParser);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user