From be91e3c112415d85e7ac310eb81055d744ae31b8 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Mon, 3 Oct 2022 21:26:28 +0000 Subject: [PATCH] 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. --- includes/disass.h | 2 +- includes/opcodes.h | 1 + misc/test.asm | 50 ++++++++++++------------- src/disass.c | 4 +- src/parser.c | 92 +++++++++++++++++++++++----------------------- 5 files changed, 76 insertions(+), 73 deletions(-) diff --git a/includes/disass.h b/includes/disass.h index 1d18a01..db23321 100644 --- a/includes/disass.h +++ b/includes/disass.h @@ -3,7 +3,7 @@ #include "parser.h" -void Disassemble(unsigned char image[HIGHMEMORY]); +//void Disassemble(unsigned char image[HIGHMEMORY]); #endif diff --git a/includes/opcodes.h b/includes/opcodes.h index 805474d..b9cae7c 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -24,6 +24,7 @@ typedef struct { Mnemonic Mnemonic; OpcodeParameter ParameterOneType; OpcodeParameter ParameterTwoType; + int LineNumber; union { int Constant; diff --git a/misc/test.asm b/misc/test.asm index b933ba5..6919423 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -1,27 +1,27 @@ -;.org 0x100 +.db video_start 0xF37F .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 -;copy 2, 45 -;loop: -; cmp r1, 0 -; jz loop -; add r1, 1 -;mov r1, 5 ; move the immediate value 5 into r1 -;add r1,5 ; add 5 into r1 -;int 21 ; maybe that will call some string drawing BIOS-like routine -;ret -; 4 byte header -; | Address of First Opcode (2 bytes) | End of Binary (2 bytes) | \ No newline at end of file +load r1, [msg] ; Because the lod* instructions can't load an address + ; from anything but a register, this becomes laa r1, [msg] + +;Routine: string_length +;In: String address in r1 +;Out: Length in R2 + +string_length: +loadb r3, [r1] ; Load the byte from the address in R1, into R3 +load r2, 0 ; String length +cmp r3, 0 ; Is R3 a null byte? +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 diff --git a/src/disass.c b/src/disass.c index 1aae88f..aaedb05 100644 --- a/src/disass.c +++ b/src/disass.c @@ -14,7 +14,7 @@ const unsigned char ADDRESSMASK = 0x10; //0001 0000 int IsRegisterPattern(unsigned char pattern, char* lexeme); void GetParameter(unsigned char instruction, char* text); - +/* void Disassemble(unsigned char image[HIGHMEMORY]) { Image = image; int position = image[0] + image[1]; @@ -117,7 +117,7 @@ void Disassemble(unsigned char image[HIGHMEMORY]) { memset(parameter2, '\0', sizeof(char) * 32); } } - +*/ int IsRegisterPattern(unsigned char pattern, char* lexeme) { if (pattern > 8) { lexeme[0] = '\0'; diff --git a/src/parser.c b/src/parser.c index 4fa9081..4edaa63 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,19 +10,14 @@ int CurrentToken = 0; //int HeapStart = 4; // zero indexed, used for declared variables. //int BinaryEnd = 4; // Zero indexed (binary starts with a 4 byte header) -//IROpcode* CreateIROpcode(Mnemonic mnemonic); void PrintSymbols(void); void HandleOperation(void); void HandleAssemblerDirective(void); void AdvanceParser(void); +void IgnoreParserLine(void); Token* PeekToken(void); int ParserAtEnd(void); int Expect(int, ...); -//List* SymbolsTable; -// unsigned int HeapTop = 4; -// unsigned int ProgramCounter = 0; -// unsigned char Heap[HIGHMEMORY]; -// unsigned char Memory[HIGHMEMORY]; IRState MachineState; IRState* ParseTokens(List* tokens) { @@ -40,9 +35,8 @@ IRState* ParseTokens(List* tokens) { Token* t = PeekToken(); switch(t->Class) { - case DirectiveClass: - //HandleAssemblerDirective(); - //while(!ParserAtEnd() && (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != NewLine)) AdvanceParser(); + case DirectiveClass: //Maybe these should be ignored, let another process handle that. + IgnoreParserLine(); break; case MnemonicClass: HandleOperation(); @@ -50,7 +44,7 @@ IRState* ParseTokens(List* tokens) { case LabelClass: printf("%s: \n", t->Lemexe); AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable); - //AddSymbol(t, 2, ProgramCounter, 1); + AdvanceParser(); //Consume the NewLine break; default: 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(); - while(!ParserAtEnd()) { - if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) { - break; - } - - 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(); + //No parameters here, we have a line break. + if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) { + goto InsertInstruction; } + 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); + AdvanceParser(); //Consume the line break + free(ins); } @@ -651,4 +643,14 @@ int ParserAtEnd(void) { Token* PeekToken(void) { return TokensList->content[CurrentToken]; +} + +void IgnoreParserLine(void) { + while(!ParserAtEnd()) { + if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) break; + + if (PeekToken()->EndOfFile) break; + + AdvanceParser(); + } } \ No newline at end of file