Updated the parser to be able to handle the changes made to the ISA.

This commit is contained in:
2023-06-18 00:50:18 -05:00
parent 403439def4
commit 0eaa5527ea
5 changed files with 139 additions and 152 deletions
+3 -3
View File
@@ -24,9 +24,9 @@ typedef enum {
typedef enum { typedef enum {
DB, DB,
Include, Include,
Byte, Byte
Load, // Load,
Store // Store
} Directive; } Directive;
typedef enum { typedef enum {
+9 -7
View File
@@ -1,6 +1,6 @@
.db MAX_MEM 0xFFFF .db MAX_MEM 0xFFFF
.db VIDEO_MEM 0xF37F .db VIDEO_MEM 0xF37F
.db MAX_LENGTH MAX_MEM - MAX_LENGTH ;.db MAX_LENGTH MAX_MEM - MAX_LENGTH
.db MSG "Hello, World!", 0 .db MSG "Hello, World!", 0
_start: _start:
@@ -9,7 +9,7 @@ _start:
call strlen call strlen
copy r1, MSG copy r1, MSG
cmp r2, 0 cmp r2, 0
je _end jz _end
cmp r2, MAX_LENGTH cmp r2, MAX_LENGTH
jg _end jg _end
draw_loop: draw_loop:
@@ -18,7 +18,7 @@ draw_loop:
inc r8 inc r8
dec r2 dec r2
cmp r2, 0 cmp r2, 0
je _end jz _end
jmp draw_loop jmp draw_loop
_end: _end:
jmp _end jmp _end
@@ -28,12 +28,14 @@ _end:
; Returns: R2 - Contains the length of the string ; Returns: R2 - Contains the length of the string
strlen: strlen:
copy r2, 0 ; length copy r2, 0 ; length
cmp [r1], 0 copy byte r4, [r1]
je end ;The string is zero length cmp r3, 0
jz end ;The string is zero length
loop: loop:
inc r1 inc r1
cmp [r1], 0 copy byte r3, [r1]
je end cmp r3, 0
jz end
inc r2 inc r2
jmp loop jmp loop
end: end:
+3 -4
View File
@@ -4,11 +4,10 @@
.db msg "Hello, world!", 0 .db msg "Hello, world!", 0
.db NOTERM "No terminating byte here" .db NOTERM "No terminating byte here"
.db null_byte 0 .db null_byte 0
jmp [r4]
;load r2, label ;load r2, label
something_insance: something_insance:
load r1, unknown_symbol load r1, unknown_symbol
load byte r1, r3
load r1, 5 load r1, 5
.db fun_alright 0x70;does this break? .db fun_alright 0x70;does this break?
load r3, r4 load r3, r4
@@ -23,6 +22,6 @@ inc r1 ;increment r1
xor r1, r1 ;clear self xor r1, r1 ;clear self
pop r3 pop r3
jmp unknown_symbol jmp unknown_symbol
jmp r4 jmp [r4]
jz unknown_symbol jz [r6]
;And a comment at the end ;And a comment at the end
+112 -126
View File
@@ -108,104 +108,6 @@ void HandleAssemblerDirective() {
HeapSize += symbol->Length; HeapSize += symbol->Length;
} }
break; 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: default:
fprintf(stderr, "Synatx error on line %d, %s.\n", directive->LineNumber, directive->Lemexe); fprintf(stderr, "Synatx error on line %d, %s.\n", directive->LineNumber, directive->Lemexe);
exit(1); exit(1);
@@ -218,6 +120,86 @@ void HandleOpcode(void) {
AdvanceParser(); AdvanceParser();
switch(opcode->Value.Mnemonic) { 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: case CMP:
{ {
ExpectRegister(); ExpectRegister();
@@ -226,7 +208,7 @@ void HandleOpcode(void) {
TokenClass class = PeekToken()->Class; TokenClass class = PeekToken()->Class;
if (class == NumberClass) { if (class == NumberClass || class & IdentifierClass) {
opcode->Value.Mnemonic = CMPI; opcode->Value.Mnemonic = CMPI;
opcode->Lemexe = "CMPI"; opcode->Lemexe = "CMPI";
@@ -272,55 +254,59 @@ void HandleOpcode(void) {
{ {
Token* arg = PeekToken(); Token* arg = PeekToken();
opcode->Value.Mnemonic = JMPI; if (arg->Class & IdentifierClass) {
opcode->Lemexe = "jmpi";
if (arg->Class == IdentifierClass) {
ExpectIdentifier(0, ForwardParser); ExpectIdentifier(0, ForwardParser);
opcode->Value.Mnemonic = JMP; opcode->Value.Mnemonic = JMP;
opcode->Lemexe = "jmp"; opcode->Lemexe = "jmp";
} }
else ExpectRegister(); else
{
ExpectPuncuation(LBracket, ForwardParser);
ExpectRegister();
ExpectPuncuation(RBracket, ForwardParser);
opcode->Value.Mnemonic = JMPI;
opcode->Lemexe = "jmpi";
}
} }
break; break;
case JZ: case JZ:
{ {
Token* arg = PeekToken(); ExpectIdentifier(0, ForwardParser);
if (arg->Class == IdentifierClass) { opcode->Value.Mnemonic = JZ;
ExpectIdentifier(0, ForwardParser); opcode->Lemexe = "jz";
opcode->Value.Mnemonic = JZ;
opcode->Lemexe = "jz";
}
else ExpectRegister();
} }
break; break;
case JG: case JG:
{ {
Token* arg = PeekToken(); ExpectIdentifier(0, ForwardParser);
opcode->Value.Mnemonic = JG;
if (arg->Class == IdentifierClass) { opcode->Lemexe = "jg";
ExpectIdentifier(0, ForwardParser);
opcode->Value.Mnemonic = JG;
opcode->Lemexe = "jg";
}
else ExpectRegister();
} }
break; break;
case JL: case JL:
{
ExpectIdentifier(0, ForwardParser);
opcode->Value.Mnemonic = JL;
opcode->Lemexe = "jl";
}
break;
case CALL:
{ {
Token* arg = PeekToken(); Token* arg = PeekToken();
if (arg->Class == IdentifierClass) { if ((arg->Class & IdentifierClass) == 0) {
ExpectIdentifier(0, ForwardParser); fprintf(stderr, "Syntax error on line %d: expected subroutine call target.\n", opcode->LineNumber);
opcode->Value.Mnemonic = JL; exit(1);
opcode->Lemexe = "jl";
} }
else ExpectRegister();
ExpectIdentifier(0, ForwardParser);
} }
break; break;
default: default:
+12 -12
View File
@@ -283,14 +283,14 @@ Token* ParseIdentifier(void) {
return token; return token;
} }
if (strcmp(lexeme, "load") == 0) { // if (strcmp(lexeme, "load") == 0) {
Token* token = CreateToken(Line, DirectiveClass); // Token* token = CreateToken(Line, DirectiveClass);
token->Lemexe = lexeme; // token->Lemexe = lexeme;
token->Value.Directive = Load; // token->Value.Directive = Load;
return token; // return token;
} // }
if (strcmp(lexeme, "byte") == 0) { if (strcmp(lexeme, "byte") == 0) {
Token* token = CreateToken(Line, DirectiveClass); Token* token = CreateToken(Line, DirectiveClass);
@@ -299,14 +299,14 @@ Token* ParseIdentifier(void) {
return token; return token;
} }
if (strcmp(lexeme, "store") == 0) { // if (strcmp(lexeme, "store") == 0) {
Token* token = CreateToken(Line, DirectiveClass); // Token* token = CreateToken(Line, DirectiveClass);
token->Lemexe = lexeme; // token->Lemexe = lexeme;
token->Value.Directive = Store; // token->Value.Directive = Store;
return token; // return token;
} // }
Token* token = CreateToken(Line, IdentifierClass); Token* token = CreateToken(Line, IdentifierClass);