Updated the parser to better handle parameters, sort of and including a string length assembly program to use as a test for the whole assembler.

This commit is contained in:
2022-10-03 21:26:28 +00:00
parent 706f480e31
commit be91e3c112
5 changed files with 76 additions and 73 deletions
+1 -1
View File
@@ -3,7 +3,7 @@
#include "parser.h" #include "parser.h"
void Disassemble(unsigned char image[HIGHMEMORY]); //void Disassemble(unsigned char image[HIGHMEMORY]);
#endif #endif
+1
View File
@@ -24,6 +24,7 @@ typedef struct {
Mnemonic Mnemonic; Mnemonic Mnemonic;
OpcodeParameter ParameterOneType; OpcodeParameter ParameterOneType;
OpcodeParameter ParameterTwoType; OpcodeParameter ParameterTwoType;
int LineNumber;
union { union {
int Constant; int Constant;
+25 -25
View File
@@ -1,27 +1,27 @@
;.org 0x100 .db video_start 0xF37F
.db msg "Hello, world!", 0 .db msg "Hello, world!", 0
.db more_stuff "AA", 0
copy r7, msg ; //
;cmp r8, msg ;1000 1111
;add r4, 0x42
;sub r1, r8
int 20
jz 45
jmp msg
in 10
call more_stuff
ret
yld
;copy r1, 45 ;//B0 = 10110000 load r1, [msg] ; Because the lod* instructions can't load an address
;copy 2, 45 ; from anything but a register, this becomes laa r1, [msg]
;loop:
; cmp r1, 0 ;Routine: string_length
; jz loop ;In: String address in r1
; add r1, 1 ;Out: Length in R2
;mov r1, 5 ; move the immediate value 5 into r1
;add r1,5 ; add 5 into r1 string_length:
;int 21 ; maybe that will call some string drawing BIOS-like routine loadb r3, [r1] ; Load the byte from the address in R1, into R3
;ret load r2, 0 ; String length
; 4 byte header cmp r3, 0 ; Is R3 a null byte?
; | Address of First Opcode (2 bytes) | End of Binary (2 bytes) | je end
inc r2
start:
inc r1 ; next char
loadb r3, [r1] ; Load the next character byte into R3
cmpi r3, 0 ; Null byte?
je end
inc r2 ; Nope, increment the length counter
jmp start
end:
ret
+2 -2
View File
@@ -14,7 +14,7 @@ const unsigned char ADDRESSMASK = 0x10; //0001 0000
int IsRegisterPattern(unsigned char pattern, char* lexeme); int IsRegisterPattern(unsigned char pattern, char* lexeme);
void GetParameter(unsigned char instruction, char* text); void GetParameter(unsigned char instruction, char* text);
/*
void Disassemble(unsigned char image[HIGHMEMORY]) { void Disassemble(unsigned char image[HIGHMEMORY]) {
Image = image; Image = image;
int position = image[0] + image[1]; int position = image[0] + image[1];
@@ -117,7 +117,7 @@ void Disassemble(unsigned char image[HIGHMEMORY]) {
memset(parameter2, '\0', sizeof(char) * 32); memset(parameter2, '\0', sizeof(char) * 32);
} }
} }
*/
int IsRegisterPattern(unsigned char pattern, char* lexeme) { int IsRegisterPattern(unsigned char pattern, char* lexeme) {
if (pattern > 8) { if (pattern > 8) {
lexeme[0] = '\0'; lexeme[0] = '\0';
+47 -45
View File
@@ -10,19 +10,14 @@ int CurrentToken = 0;
//int HeapStart = 4; // zero indexed, used for declared variables. //int HeapStart = 4; // zero indexed, used for declared variables.
//int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header) //int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header)
//IROpcode* CreateIROpcode(Mnemonic mnemonic);
void PrintSymbols(void); void PrintSymbols(void);
void HandleOperation(void); void HandleOperation(void);
void HandleAssemblerDirective(void); void HandleAssemblerDirective(void);
void AdvanceParser(void); void AdvanceParser(void);
void IgnoreParserLine(void);
Token* PeekToken(void); Token* PeekToken(void);
int ParserAtEnd(void); int ParserAtEnd(void);
int Expect(int, ...); int Expect(int, ...);
//List* SymbolsTable;
// unsigned int HeapTop = 4;
// unsigned int ProgramCounter = 0;
// unsigned char Heap[HIGHMEMORY];
// unsigned char Memory[HIGHMEMORY];
IRState MachineState; IRState MachineState;
IRState* ParseTokens(List* tokens) { IRState* ParseTokens(List* tokens) {
@@ -40,9 +35,8 @@ IRState* ParseTokens(List* tokens) {
Token* t = PeekToken(); Token* t = PeekToken();
switch(t->Class) { switch(t->Class) {
case DirectiveClass: case DirectiveClass: //Maybe these should be ignored, let another process handle that.
//HandleAssemblerDirective(); IgnoreParserLine();
//while(!ParserAtEnd() && (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != NewLine)) AdvanceParser();
break; break;
case MnemonicClass: case MnemonicClass:
HandleOperation(); HandleOperation();
@@ -50,7 +44,7 @@ IRState* ParseTokens(List* tokens) {
case LabelClass: case LabelClass:
printf("%s: \n", t->Lemexe); printf("%s: \n", t->Lemexe);
AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable); AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable);
//AddSymbol(t, 2, ProgramCounter, 1); AdvanceParser(); //Consume the NewLine
break; break;
default: default:
fprintf(stderr, "[Error] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class); fprintf(stderr, "[Error] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class);
@@ -161,45 +155,43 @@ void HandleOperation() {
AdvanceParser(); AdvanceParser();
while(!ParserAtEnd()) { //No parameters here, we have a line break.
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) { if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
break; goto InsertInstruction;
}
ins->ParameterOneType = GetParameterType(&token);
if (ins->ParameterOneType == NoParameter) {
AdvanceParser(); //Comsume the line end
break;
}
if (PeekToken()->Class == PunctuationClass) {
if (PeekToken()->Value.Punctuation == NewLine) {
AdvanceParser(); //Comsume end line.
break;
}
else if (PeekToken()->Value.Punctuation != Comma) {
fprintf(stderr, "[Error] Line %d: comma need for %s\n", token->LineNumber, mn);
exit(1);
}
} else {
fprintf(stderr, "[Error] Line %d: comma needed for %s\n", token->LineNumber, mn);
exit(1);
}
AdvanceParser(); //Comsume the comma
ins->ParameterTwoType = GetParameterType(&token);
AdvanceParser();//comsume the end line.
break;
//AdvanceParser();
} }
ins->ParameterOneType = GetParameterType(&token);
if (ins->ParameterOneType == NoParameter) {
//This would be an error if the next token isn't a line break.
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != NewLine) {
fprintf(stderr, "[Error] Line %d: Syntax error, expected line break but got %s.\n", token->LineNumber, token->Lemexe);
exit(1);
}
goto InsertInstruction;
}
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) {
goto InsertInstruction;
}
if (PeekToken()->Class != PunctuationClass || PeekToken()->Value.Punctuation != Comma) {
//Syntax error
fprintf(stderr, "[Error] Line %d: Expected comma.\n", token->LineNumber);
exit(1);
}
AdvanceParser(); //Consume the comma
ins->ParameterTwoType = GetParameterType(&token);
InsertInstruction:
AddListItem(ins, sizeof(Instruction), MachineState.Instructions); AddListItem(ins, sizeof(Instruction), MachineState.Instructions);
AdvanceParser(); //Consume the line break
free(ins); free(ins);
} }
@@ -651,4 +643,14 @@ int ParserAtEnd(void) {
Token* PeekToken(void) { Token* PeekToken(void) {
return TokensList->content[CurrentToken]; return TokensList->content[CurrentToken];
}
void IgnoreParserLine(void) {
while(!ParserAtEnd()) {
if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) break;
if (PeekToken()->EndOfFile) break;
AdvanceParser();
}
} }