From cd1258a7245aa775c211624f6d64ebf56ec03ef5 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Mon, 3 Oct 2022 19:58:44 -0500 Subject: [PATCH] Fixed various Parser bugs. --- misc/test.asm | 2 +- src/main.c | 2 - src/parser.c | 533 ++++++++------------------------------------------ src/scanner.c | 9 + 4 files changed, 95 insertions(+), 451 deletions(-) diff --git a/misc/test.asm b/misc/test.asm index 6919423..a49b3ec 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -18,7 +18,7 @@ inc r2 start: inc r1 ; next char loadb r3, [r1] ; Load the next character byte into R3 - cmpi r3, 0 ; Null byte? + cmp r3, 0 ; Null byte? je end inc r2 ; Nope, increment the length counter jmp start diff --git a/src/main.c b/src/main.c index b65d46f..3289e68 100644 --- a/src/main.c +++ b/src/main.c @@ -32,8 +32,6 @@ int main(int argc, char* args[]) { if (t->Class == PunctuationClass){ if(t->Value.Punctuation == NewLine) { - //if(i - 1 >= 0 && (((Token*)list->content[i - 1])->Class == PunctuationClass && ((Token*)list->content[i - 1])->Value.Punctuation == NewLine)) continue; - printf("\n"); continue; } diff --git a/src/parser.c b/src/parser.c index 4edaa63..b6731b8 100644 --- a/src/parser.c +++ b/src/parser.c @@ -23,9 +23,6 @@ IRState MachineState; IRState* ParseTokens(List* tokens) { if (!tokens) return NULL; - // memset(Memory, 0, sizeof(Memory)); - // memset(Heap, 0, sizeof(Heap)); - TokensList = tokens; MachineState.SymbolsTable = CreateSymbolTable(); @@ -37,11 +34,13 @@ IRState* ParseTokens(List* tokens) { switch(t->Class) { case DirectiveClass: //Maybe these should be ignored, let another process handle that. IgnoreParserLine(); + AdvanceParser(); break; case MnemonicClass: HandleOperation(); break; case LabelClass: + AdvanceParser(); printf("%s: \n", t->Lemexe); AddSymbolToTable(t->Lemexe, NULL, strlen(t->Lemexe), MachineState.SymbolsTable); AdvanceParser(); //Consume the NewLine @@ -49,10 +48,11 @@ IRState* ParseTokens(List* tokens) { default: fprintf(stderr, "[Error] Line %d: Syntax error, expected start of expression, got '%c' [%d].\n", t->LineNumber, t->Value.Punctuation, t->Class); //exit(1); + AdvanceParser(); break; } - AdvanceParser(); + //AdvanceParser(); } if (MachineState.SymbolsTable->Size > 0) PrintSymbols(); @@ -87,61 +87,103 @@ IRState* ParseTokens(List* tokens) { return &MachineState; } - OpcodeParameter GetParameterType(Token** sourceToken) { Token* token = PeekToken(); + OpcodeParameter parameterType; - while(!ParserAtEnd()) { - if (token->EndOfFile || (token->Class == PunctuationClass && token->Value.Punctuation == NewLine)) break; - - if (token->Class == RegisterClass) { + switch(token->Class) { + case RegisterClass: *sourceToken = token; AdvanceParser(); return RegisterParameter; - } - - if (token->Class == PunctuationClass) { - if (token->Value.Punctuation == LBracket) { - AdvanceParser(); - token = PeekToken(); - - *sourceToken = token; - - AdvanceParser(); - - if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != RBracket) { - //error - fprintf(stderr, "[Error] Line %d Expected closing bracket.\n", token->LineNumber); - exit(1); - } - else AdvanceParser(); - - return AddressParameter; - } - else { - //error - fprintf(stderr, "[Error] Line: %d Expected opening bracket.\n", token->LineNumber); + case LabelClass: + case IdentifierClass: + *sourceToken = token; + AdvanceParser(); + return AddressParameter; + case PunctuationClass: + if (token->Value.Punctuation != LBracket) { + fprintf(stderr, "[Error] Line %d: Expected opening bracket\n", token->LineNumber); exit(1); } - } - if (token->Class == NumberClass) { + AdvanceParser(); // [ + + parameterType = GetParameterType(sourceToken); + + token = PeekToken(); + + if (token->Class != PunctuationClass || token->Value.Punctuation != RBracket) { + fprintf(stderr, "[Error] Line %d: Expected closing bracket.\n", token->LineNumber); + exit(1); + } + + AdvanceParser(); // ] + + return AddressParameter; + case NumberClass: *sourceToken = token; AdvanceParser(); return ConstantParameter; - } - - if (token->Class & AddressClass) { - *sourceToken = token; - AdvanceParser(); - return AddressParameter; - } + default: + break; } + // while(!ParserAtEnd()) { + // if (token->EndOfFile || (token->Class == PunctuationClass && token->Value.Punctuation == NewLine)) break; + + // if (token->Class == RegisterClass) { + // *sourceToken = token; + + // AdvanceParser(); + + // return RegisterParameter; + // } + + // if (token->Class == PunctuationClass) { + // if (token->Value.Punctuation == LBracket) { + // AdvanceParser(); + // token = PeekToken(); + + // *sourceToken = token; + + // AdvanceParser(); + + // if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation != RBracket) { + // //error + // fprintf(stderr, "[Error] Line %d Expected closing bracket.\n", token->LineNumber); + // exit(1); + // } + // else AdvanceParser(); + + // return AddressParameter; + // } + // else { + // //error + // fprintf(stderr, "[Error] Line: %d Expected opening bracket.\n", token->LineNumber); + // exit(1); + // } + // } + + // if (token->Class == NumberClass) { + // *sourceToken = token; + + // AdvanceParser(); + + // return ConstantParameter; + // } + + // if (token->Class & AddressClass) { + // *sourceToken = token; + // AdvanceParser(); + // return AddressParameter; + // } + // } + return NoParameter; } @@ -156,7 +198,7 @@ void HandleOperation() { AdvanceParser(); //No parameters here, we have a line break. - if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine) { + if (PeekToken()->EndOfFile || (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == NewLine)) { goto InsertInstruction; } @@ -195,353 +237,6 @@ void HandleOperation() { free(ins); } -// void HandleAssemblerDirective(void) { - -// if (PeekToken()->Value.Directive == DB) { -// AdvanceParser(); - -// Token* identifier = PeekToken(); - -// if (!Expect(1, IdentifierClass)) { -// fprintf(stderr, "Expected identifier on line %d\n", identifier->LineNumber); -// exit(1); -// } - -// Symbol* symbol = AddSymbolToTable(identifier->Lemexe, NULL, strlen(identifier->Lemexe), MachineState.SymbolsTable); - -// identifier = PeekToken(); - -// switch(identifier->Class) { -// case CharacterClass: -// //printf("[INFO] %s = '%s' (%#04X)\n", identifier->lexeme, identifier->lexeme, HeapTop); - -// // for(int i = 0; i < strlen(identifier->lexeme); i++) { -// // //Memory[ProgramCounter + i] = PeekToken()->lexeme[i]; -// // Heap[HeapTop + i] = identifier->lexeme[i]; -// // } - -// //ProgramCounter += strlen(PeekToken()->lexeme); -// //HeapTop += strlen(identifier->Lemexe); -// symbol->Length = strlen(identifier->Lemexe); - -// AdvanceParser(); - -// if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) { -// AdvanceParser(); - -// if (PeekToken()-> Class != NumberClass) { -// fprintf(stderr, "Expected string termination byte on line %d\n", PeekToken()->LineNumber); -// exit(1); -// } -// else { -// //Hideous... -// // int oldLength = strlen(identifier->lexeme); -// // identifier->lexeme = realloc(identifier->lexeme, oldLength + 2); -// // identifier->value = identifier->lexeme; -// // identifier->lexeme[oldLength + 1] = '\0';//*PeekToken()->lexeme & 0x0F; -// symbol->Length++; //Basically, read in the NULL byte at the end of the string. -// //HeapTop++; -// return; -// } -// } -// case NumberClass: -// break; -// default: -// fprintf(stderr, "[Line: %d] Expected either a number or string after identifier '%s'.\n", PeekToken()->LineNumber, identifier->Lemexe); -// exit(1); -// } -// } -// } - -// void HandleRegisterBasedOpcode(unsigned char mask) { -// //Memory[ProgramCounter] = mask; - -// //ProgramCounter++; - -// Token* token = PeekToken(); - -// Instruction* opcode = CreateInstruction(token->Value.Mnemonic); //CreateIROpcode(token->Value.Mnemonic); - -// AdvanceParser(); - -// token = PeekToken(); - -// if (token->Class == RegisterClass) { -// //Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; -// opcode->ParameterOneType = RegisterParameter; -// AdvanceParser(); -// } -// else if (token->Class & AddressClass && token->Value.Mnemonic == COPY) { -// //opcode->ParameterOneType = Address; - -// Symbol* symbol = TryGetSymbol(token->Lemexe, MachineState.SymbolsTable); //GetSymbol(token->Lemexe); - -// if (!symbol) { -// opcode->ParameterOneType = AddressParameter; -// //AddSymbol(token, 2, 0, 0); -// opcode->ParameterOne.Symbol = AddSymbolToTable(token->Lemexe, NULL, strlen(token->Lemexe), MachineState.SymbolsTable); -// } -// else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved); -// } -// else { -// fprintf(stderr, "[Error] Line %d: Expected register operand.\n", token->LineNumber); -// exit(1); -// } - -// token = PeekToken(); - -// if (!Expect(1, Comma)) { -// fprintf(stderr, "[Error] Expected comma on line %d.\n", token->LineNumber); -// exit(1); -// } - -// token = PeekToken(); - -// if (token->Class & AddressClass) { -// opcode->ParameterTwoType = IdentifierClass; -// Symbol* symbol = GetSymbol(token->Lemexe); - -// // if (!symbol) { -// // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", token->line, token->lexeme); -// // exit(1); -// // } -// if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 2, 0, 0);//CreateSymbol(token, 0, 0); -// else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved); - -// // Memory[ProgramCounter - 1] |= 0x10;//0b00010000; - -// // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; -// // Memory[ProgramCounter + 1] = symbol->address & 0xFF; - -// AdvanceParser(); -// } -// else if (token->Class == NumberClass) { -// //opcode->ParameterTwoType = ; - -// opcode->ParameterTwo.Constant = PeekToken()->Value.Number; -// // Memory[ProgramCounter - 1] |= 0x08; //0b00001000; - -// // int* value = PeekToken()->value; - -// // Memory[ProgramCounter] = 2 >> *value & 0xFF; -// // Memory[ProgramCounter + 1] = *value & 0xFF; - -// AdvanceParser(); -// } -// else if (token->Class == RegisterClass) { -// //opcode->ParameterTwoType = ; -// opcode->ParameterTwo.Constant = PeekToken()->Value.Register &0x07; -// //Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07; - -// AdvanceParser(); - -// ProgramCounter++; -// return; -// } -// else { -// fprintf(stderr, "[Error] Expected operand, got %s\n", token->Lemexe); -// exit(1); -// } - -// ProgramCounter += 2; - -// AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes); -// } - -// void HandleOperation(void) { -// Token* token = PeekToken(); -// //const Instruction* inst = GetOpcodeDetails(opcode->type); -// const unsigned char registerBasedOpcodeMask = 0xE0; - -// //if (!inst) return; - -// // AdvanceParser(); - -// unsigned char mask = GetInstructionMask(token->Value.Mnemonic); - -// if (mask & registerBasedOpcodeMask) { -// HandleRegisterBasedOpcode(mask); -// return; -// } - -// IROpcode* opcode = CreateIROpcode(token->Value.Mnemonic); -// //opcode->ParameterTwoType = None; - -// AdvanceParser(); - -// switch (mask) { -// case 0: //NOP -// //Memory[ProgramCounter] = 0x00; -// //opcode->ParameterOneType = None; - -// ProgramCounter++; -// return; -// case 1: //JZ -// //Memory[ProgramCounter] = 0x01; - -// ProgramCounter++; - -// if (PeekToken()->Class == IdentifierClass || PeekToken()->Class == LabelClass) { -// Symbol* symbol = GetSymbol(PeekToken()->Lemexe); -// //opcode->ParameterOneType = Address; - -// if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 2, 0, 0); -// else opcode->ParameterOne.Address = symbol; -// // if (!symbol) { -// // fprintf(stderr, "[Error] %s is undefined.\n", PeekToken()->lexeme); -// // exit(1); -// // } - -// // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; -// // Memory[ProgramCounter + 1] = symbol->address & 0xFF; -// } -// else if (PeekToken()->Class == NumberClass) { -// //opcode->ParameterOneType = Constant; -// opcode->ParameterOne.Constant = PeekToken()->Value.Number; -// // int* value = PeekToken()->value; - -// // Memory[ProgramCounter] = 2 >> *value & 0xFF; -// // Memory[ProgramCounter + 1] = *value & 0xFF; -// } -// else { -// fprintf(stderr, "[Error] Line: %d: Expected address after jump if zero (JZ) instruction.\n", ((Token*) TokensList->content[CurrentToken - 1])->LineNumber); -// exit(1); -// } - -// ProgramCounter += 2; - -// return; -// case 2: //INT -// //Memory[ProgramCounter] = 0x02; - -// ProgramCounter++; - -// if (PeekToken()->Class == NumberClass) { -// // int* value = PeekToken()->value; -// //opcode->ParameterOneType = ; -// opcode->ParameterOne.Constant = PeekToken()->Value.Number; - -// // Memory[ProgramCounter] = 2 >> *value & 0xFF; -// // Memory[ProgramCounter + 1] = *value & 0xFF; -// } -// else { -// fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->LineNumber); -// exit(1); -// } - -// ProgramCounter += 2; - -// return; -// case 3: //YLD -// //Memory[ProgramCounter] = 0x03; -// //opcode->ParameterOneType = ; - -// ProgramCounter++; -// break; -// case 4: //RET -// //Memory[ProgramCounter] = 0x04; -// //opcode->ParameterOneType = ; - -// ProgramCounter++; -// break; -// case 5: //CALL -// //Memory[ProgramCounter] = 0x05; - -// ProgramCounter++; - -// if (PeekToken()->Class == IdentifierClass || PeekToken()->Class == LabelClass) { -// Symbol* symbol = GetSymbol(PeekToken()->Lemexe); -// //opcode->ParameterOneType = ; - -// // if (!symbol) { -// // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); -// // exit(1); -// // } -// if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 2, 0, 0); -// else opcode->ParameterOne.Address = symbol; -// //Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; -// //Memory[ProgramCounter + 1] = symbol->address & 0xFF; -// } -// else { -// fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->LineNumber); -// exit(1); -// } - -// ProgramCounter += 2; -// break; -// case 6: //JMP -// //Memory[ProgramCounter] = 0x06; - -// ProgramCounter++; - -// if (PeekToken()->Class == IdentifierClass || PeekToken()->Class == LabelClass) { -// Symbol* symbol = GetSymbol(PeekToken()->Lemexe); -// //opcode->ParameterOneType = Address; - -// // if (!symbol) { -// // fprintf(stderr, "[Error] Line %d: %s is undefined.\n", PeekToken()->line, PeekToken()->lexeme); -// // exit(1); -// // } -// if (!symbol) opcode->ParameterOne.Address = AddSymbol(PeekToken(), 2, 0, 0); -// else opcode->ParameterOne.Address = symbol; - -// // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; -// // Memory[ProgramCounter + 1] = symbol->address & 0xFF; -// } -// else { -// fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->LineNumber); -// exit(1); -// } - -// ProgramCounter += 2; -// break; -// case 7: //IN -// //Memory[ProgramCounter] = 0x07; - -// ProgramCounter++; - -// if (PeekToken()->Class == NumberClass) { -// //opcode->ParameterOneType = ; -// opcode->ParameterOne.Constant = PeekToken()->Value.Number; -// // int* value = PeekToken()->value; - -// // Memory[ProgramCounter] = 2 >> *value & 0xFF; -// // Memory[ProgramCounter + 1] = *value & 0xFF; -// } -// else { -// fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->LineNumber); -// exit(1); -// } - -// ProgramCounter += 2; -// break; -// case 8: //OUT -// //Memory[ProgramCounter] = 0x08; - -// ProgramCounter++; - -// if (PeekToken()->Class == NumberClass) { -// //opcode->ParameterOneType = ; -// opcode->ParameterOne.Constant = PeekToken()->Value.Number; -// // int* value = PeekToken()->value; - -// // Memory[ProgramCounter] = 2 >> *value & 0xFF; -// // Memory[ProgramCounter + 1] = *value & 0xFF; -// } -// else { -// fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->LineNumber); -// exit(1); -// } - -// ProgramCounter += 2; -// break; -// } - -// AddListItem(opcode, sizeof(IROpcode), MachineState.Opcodes); - -// return; -// } - int Expect(int count, ...) { va_list list; Token* token = PeekToken(); @@ -566,69 +261,11 @@ void PrintSymbols(void) { for(int i = 0; i < MachineState.SymbolsTable->Size; i++) { Symbol* symbol = MachineState.SymbolsTable->Symbols[i]; - printf("[Resolved? %d] %s\n", symbol->Resolved, symbol->Name);//symbol->address, symbol->token->Lemexe); + printf("[Resolved? %d] %s\n", symbol->Resolved, symbol->Name); } printf("-----SYMBOLS-----\n"); } -// Symbol* AddSymbol(Token* token, int length, int address, int resolved) { -// if (!token) return NULL; -// if (token->Class != IdentifierClass && token->Class != LabelClass) return NULL; - -// for(int i = 0; i < MachineState.SymbolsTable->size; i++) { -// Symbol* s = MachineState.SymbolsTable->content[i]; - -// if (strcmp(s->token->Lemexe, token->Lemexe) == 0) { -// if (s->resolved) { -// fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->LineNumber, token->Lemexe); -// exit(1); -// } -// s->resolved = resolved; -// s->address = address; -// s->length = length; -// return s; -// } -// } - -// Symbol* symbol = CreateSymbol(token, length, address, resolved); - -// AddListItem(symbol, sizeof(Symbol), MachineState.SymbolsTable); - -// return symbol; -// } - -// Symbol* GetSymbol(char* name) { -// if (!name) return NULL; - -// for(int i = 0; i < MachineState.SymbolsTable->size; i++) { -// Symbol* s = MachineState.SymbolsTable->content[i]; - -// if (strcmp(s->token->Lemexe, name) == 0) return s; -// } - -// return NULL; -// } - -// Symbol* CreateSymbol(Token* token, int length, int address, int resolved) { -// Symbol* symbol = calloc(1, sizeof(Symbol)); - -// if (!symbol) return NULL; - -// symbol->token = token; -// symbol->address = address; -// symbol->resolved = resolved; - -// return symbol; -// } - -// IROpcode* CreateIROpcode(Mnemonic mnemonic) { -// IROpcode* opcode = calloc(1, sizeof(IROpcode)); - -// opcode->Mnemonic = mnemonic; - -// return opcode; -// } - void AdvanceParser(void) { if (ParserAtEnd()) return; diff --git a/src/scanner.c b/src/scanner.c index 93a0164..e6c9abd 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -98,6 +98,15 @@ List* GenerateTokenList(const char* source) { token = NULL; } + if (tokens->size > 0) { + token = tokens->content[tokens->size - 1]; + + if (token->Class == PunctuationClass && token->Value.Punctuation == NewLine) { + //If the last token is a line break, remove it as its not too meaningful. + tokens->size--; + } + } + token = CreateToken(Line, PunctuationClass); token->EndOfFile = 1;