From 2ae60a607c0dad08a6a4589ef73404e8134d10bc Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Thu, 15 Sep 2022 21:29:27 +0000 Subject: [PATCH] Incomplete, but I want to make sure the ideas I have here don't get wiped. Sadly this commit won't compile. --- includes/opcodes.h | 50 ++++++++---- includes/parser.h | 17 ++-- includes/symbols_table.h | 1 + includes/token.h | 76 +++++++++--------- src/opcodes.c | 24 +++--- src/parser.c | 168 +++++++++++++++++++-------------------- src/scanner.c | 82 +++++++++++++------ src/token.c | 30 +------ 8 files changed, 238 insertions(+), 210 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index ea3688f..4264da6 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -2,30 +2,46 @@ #define OPCODES_H #include -#include "token.h" +#include "symbols_table.h" #define OPCODECOUNT 13 -#define REGISTERCOUNT 8 -//const unsigned char COPYADDRESSMASK = 0x80; + +typedef enum { + R1, R2, R3, R4, R5, R6, R7, R8 +} Registers; + +typedef enum { + COPY, ADD, SUB, JZ, INT, YLD, RET, + CMP, NOP, JMP, CALL, IN, OUT, +} Mnemonic; + +typedef enum { + None, + Constant, + Address +} OpcodeParameter; typedef struct { - char* lexeme; - TokenType op; - TokenClass parameter_one; - TokenClass parameter_two; + Mnemonic Mnemonic; + OpcodeParameter ParameterOneType; + OpcodeParameter ParameterTwoType; + + union { + int Constant; + Symbol* Symbol; + } ParameterOne; + + union { + int Constant; + Symbol* Symbol; + } ParameterTwo; } Instruction; -typedef struct { - char* lexeme; - TokenType type; -} Register; - extern Instruction instructions[OPCODECOUNT]; -extern Register registers[REGISTERCOUNT]; -int IsOpcode(const char*, TokenType*); -int IsRegister(const char*, TokenType*); -const Instruction* GetOpcodeDetails(TokenType); -unsigned char GetInstructionMask(TokenType type); +int IsOpcode(const char*, Mnemonic*); +int IsRegister(const char*, Registers*); +//const Instruction* GetOpcodeDetails(Mnemonic); +unsigned char GetInstructionMask(Mnemonic type); #endif \ No newline at end of file diff --git a/includes/parser.h b/includes/parser.h index 8851298..e182d1d 100644 --- a/includes/parser.h +++ b/includes/parser.h @@ -7,18 +7,19 @@ #include "list.h" #include "token.h" #include "opcodes.h" +#include "symbols_table.h" #define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF -typedef struct { - Token* token; - int length; - int address; - int resolved; -} Symbol; +// typedef struct { +// Token* token; +// int length; +// int address; +// int resolved; +// } Symbol; typedef struct { - TokenType Mnemonic; + Mnemonic Mnemonic; TokenClass ParameterOneType; TokenClass ParameterTwoType; @@ -35,7 +36,7 @@ typedef struct { typedef struct { List* Opcodes; - List* SymbolsTable; + SymbolTable* SymbolsTable; } IRState; IRState* ParseTokens(List*); diff --git a/includes/symbols_table.h b/includes/symbols_table.h index a15bfe9..c7704b7 100644 --- a/includes/symbols_table.h +++ b/includes/symbols_table.h @@ -12,6 +12,7 @@ typedef struct { void* Value; char* Name; int Length; + int Resolved; } Symbol; typedef struct { diff --git a/includes/token.h b/includes/token.h index d50cc8b..f26e2d3 100644 --- a/includes/token.h +++ b/includes/token.h @@ -5,50 +5,54 @@ #include #include #include +#include "opcodes.h" typedef enum { - PLUS, - MINUS, - STAR, - SLASH, - POWER, - LPARAM, - RPARAM, - LBRACKET, - RBracket, - COMMA, - STRING, - IDENTIFIER, - LABEL, - NUMBER, - LineEnd, - //Keywords - DB, ORG, - //Mnemonics - COPY, ADD, SUB, JZ, INT, YLD, RET, - CMP, NOP, JMP, CALL, IN, OUT, - //Registers - R1, R2, R3, R4, R5, R6, R7, R8 -} TokenType; + Plus = '+', + Minus = '-', + Star = '*', + Slash = '/', + Power = '^', + LParan = '(', + RParan = ')', + LBracket = '[', + RBracket = ']', + Comma = ',', + NewLine = '\n' +} TokenPunctuation; typedef enum { - None = 0, - Reg = 1, - Constant = 2, - Address = 4, - Mnemonic = 8, - Directive = 16 + DB, + Origin +} Directive; + +typedef enum { + RegisterClass = 0, + NumberClass = 1, + CharacterClass = 2, + MnemonicClass = 4, + DirectiveClass = 8, + PunctuationClass = 16, + IdentifierClass = 32, + LabelClass = 64, + AddressClass = LabelClass | IdentifierClass } TokenClass; typedef struct { - TokenType type; - char* lexeme; - void* value; - int line; - TokenClass token_class; + char* Lemexe; + TokenClass Class; + int LineNumber; + + union { + TokenPunctuation Punctuation; + Registers Register; + Mnemonic Mnemonic; + Directive Directive; + int Number; + } Value; } Token; -Token* CreateToken(char*, void*, int, TokenType); -void FreeToken(Token*); +Token* CreateToken(int lineNumber, TokenClass tokenClass); +void FreeToken(Token* token); #endif \ No newline at end of file diff --git a/src/opcodes.c b/src/opcodes.c index a5ee8f4..473ee30 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -18,7 +18,7 @@ Instruction instructions[OPCODECOUNT] = { { "call", CALL, Address, None} }; -unsigned char GetInstructionMask(TokenType type) { +unsigned char GetInstructionMask(Mnemonic type) { switch (type) { case COPY: return 0x20; //0b00100000; ORing 0x80 marks the first parameter as an address @@ -93,7 +93,7 @@ Register registers[REGISTERCOUNT] = { { "r8", R8 } }; -const Instruction* GetOpcodeDetails(TokenType type) { +const Instruction* GetOpcodeDetails(Mnemonic type) { for(int i = 0; i < OPCODECOUNT; i++) { if (instructions[i].op == type) return &instructions[i]; } @@ -101,12 +101,12 @@ const Instruction* GetOpcodeDetails(TokenType type) { return NULL; } -int IsOpcode(const char* text, TokenType* opcode) { +int IsOpcode(const char* text, Mnemonic* opcode) { if (!text) return 0; for(int i = 0; i < OPCODECOUNT; i++) { - if (strcmp(instructions[i].lexeme, text) == 0) { - if (opcode) *opcode = instructions[i].op; + if (strcmp(instructions[i], text) == 0) { + if (opcode) *opcode = instructions[i].Mnemonic; return 1; } } @@ -114,15 +114,13 @@ int IsOpcode(const char* text, TokenType* opcode) { return 0; } -int IsRegister(const char* text, TokenType* reg) { +int IsRegister(const char* text, Registers* reg) { if (!text) return 0; - for(int i = 0; i < REGISTERCOUNT; i++) { - if (strcmp(registers[i].lexeme, text) == 0) { - *reg = registers[i].type; - return 1; - } - } + int length = strlen(text); - return 0; + if (length != 2) return 0; + if (text[0] != 'r') return 0; + + return text[1] >= '1' && text[1] <= '8'; } \ No newline at end of file diff --git a/src/parser.c b/src/parser.c index 2bea996..421b6b1 100644 --- a/src/parser.c +++ b/src/parser.c @@ -10,8 +10,7 @@ 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(TokenType mnemonic); -Symbol* AddSymbol(Token* token, int length, int address, int resolved); +IROpcode* CreateIROpcode(Mnemonic mnemonic); void PrintSymbols(void); void HandleOperation(void); void HandleAssemblerDirective(void); @@ -19,7 +18,6 @@ void AdvanceParser(void); Token* PeekToken(void); int ParserAtEnd(void); int Expect(int, ...); -Symbol* GetSymbol(char*); //List* SymbolsTable; unsigned int HeapTop = 4; unsigned int ProgramCounter = 0; @@ -35,24 +33,22 @@ IRState* ParseTokens(List* tokens) { TokensList = tokens; - MachineState.SymbolsTable = CreateList(); + MachineState.SymbolsTable = CreateSymbolTable(); MachineState.Opcodes = CreateList(); while(!ParserAtEnd()) { Token* t = PeekToken(); - switch(t->token_class) { - case Directive: + switch(t->Class) { + case DirectiveClass: HandleAssemblerDirective(); break; - case Mnemonic: + case MnemonicClass: HandleOperation(); break; - case Address: - if (t->type == LABEL) { - printf("%s: \n", t->lexeme); - AddSymbol(t, 2, ProgramCounter, 1); - } + case LabelClass: + printf("%s: \n", t->Lemexe); + AddSymbol(t, 2, ProgramCounter, 1); break; default: break; @@ -61,7 +57,7 @@ IRState* ParseTokens(List* tokens) { AdvanceParser(); } - if (MachineState.SymbolsTable->size > 0) PrintSymbols(); + if (MachineState.SymbolsTable->Size > 0) PrintSymbols(); //DestroyList(SymbolsTable); @@ -85,22 +81,22 @@ IRState* ParseTokens(List* tokens) { void HandleAssemblerDirective(void) { - if (PeekToken()->type == DB) { + if (PeekToken()->Value.Directive == DB) { AdvanceParser(); Token* identifier = PeekToken(); - if (!Expect(1, IDENTIFIER)) { - fprintf(stderr, "Expected identifier on line %d\n", identifier->line); + if (!Expect(1, IdentifierClass)) { + fprintf(stderr, "Expected identifier on line %d\n", identifier->LineNumber); exit(1); } - Symbol* symbol = AddSymbol(identifier, 0, HeapTop, 1); + Symbol* symbol = AddSymbolToTable(identifier->Lemexe, NULL, strlen(identifier->Lemexe), MachineState.SymbolsTable); identifier = PeekToken(); - switch(identifier->type) { - case STRING: + 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++) { @@ -109,16 +105,16 @@ void HandleAssemblerDirective(void) { // } //ProgramCounter += strlen(PeekToken()->lexeme); - HeapTop += strlen(identifier->lexeme); - symbol->length = strlen(identifier->lexeme); + HeapTop += strlen(identifier->Lemexe); + symbol->Length = strlen(identifier->Lemexe); AdvanceParser(); - if (PeekToken()->type == COMMA) { + if (PeekToken()->Class == PunctuationClass && PeekToken()->Value.Punctuation == Comma) { AdvanceParser(); - if (PeekToken()-> type != NUMBER) { - fprintf(stderr, "Expected string termination byte on line %d\n", PeekToken()->line); + if (PeekToken()-> Class != NumberClass) { + fprintf(stderr, "Expected string termination byte on line %d\n", PeekToken()->LineNumber); exit(1); } else { @@ -127,15 +123,15 @@ void HandleAssemblerDirective(void) { // 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. + symbol->Length++; //Basically, read in the NULL byte at the end of the string. HeapTop++; return; } } - case NUMBER: + case NumberClass: break; default: - fprintf(stderr, "[Line: %d] Expected either a number or string after identifier '%s'.\n", PeekToken()->line, identifier->lexeme); + fprintf(stderr, "[Line: %d] Expected either a number or string after identifier '%s'.\n", PeekToken()->LineNumber, identifier->Lemexe); exit(1); } } @@ -148,42 +144,42 @@ void HandleRegisterBasedOpcode(unsigned char mask) { Token* token = PeekToken(); - IROpcode* opcode = CreateIROpcode(token->type); + IROpcode* opcode = CreateIROpcode(token->Value.Mnemonic); AdvanceParser(); token = PeekToken(); - if (token->token_class == Reg) { + if (token->Class == RegisterClass) { //Memory[ProgramCounter - 1] |= (PeekToken()->type - R1) & 0x07; - opcode->ParameterOneType = Reg; + opcode->ParameterOneType = RegisterClass; AdvanceParser(); } - else if (token->token_class == Address && token->type == COPY) { - opcode->ParameterOneType = Address; + else if (token->Class & AddressClass && token->Value.Mnemonic == COPY) { + //opcode->ParameterOneType = Address; - Symbol* symbol = GetSymbol(token->lexeme); + Symbol* symbol = GetSymbol(token->Lemexe); if (!symbol) opcode->ParameterOne.Address = AddSymbol(token, 2, 0, 0); else opcode->ParameterOne.Address = symbol;//CreateSymbol(token, symbol->address, symbol->resolved); } else { - fprintf(stderr, "[Error] Line %d: Expected register operand.\n", token->line); + 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->line); + if (!Expect(1, Comma)) { + fprintf(stderr, "[Error] Expected comma on line %d.\n", token->LineNumber); exit(1); } token = PeekToken(); - if (token->type == IDENTIFIER || token->type == LABEL) { - opcode->ParameterTwoType = Address; - Symbol* symbol = GetSymbol(token->lexeme); + 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); @@ -199,10 +195,10 @@ void HandleRegisterBasedOpcode(unsigned char mask) { AdvanceParser(); } - else if (token->type == NUMBER) { - opcode->ParameterTwoType = Constant; + else if (token->Class == NumberClass) { + //opcode->ParameterTwoType = ; - opcode->ParameterTwo.Constant = *(int*)PeekToken()->value; + opcode->ParameterTwo.Constant = PeekToken()->Value.Number; // Memory[ProgramCounter - 1] |= 0x08; //0b00001000; // int* value = PeekToken()->value; @@ -212,9 +208,9 @@ void HandleRegisterBasedOpcode(unsigned char mask) { AdvanceParser(); } - else if (token->token_class == Reg) { - opcode->ParameterTwoType = Reg; - opcode->ParameterTwo.Constant = (PeekToken()->type - R1) &0x07; + else if (token->Class == RegisterClass) { + //opcode->ParameterTwoType = ; + opcode->ParameterTwo.Constant = PeekToken()->Value.Register &0x07; //Memory[ProgramCounter] = (PeekToken()->type - R1) & 0x07; AdvanceParser(); @@ -223,7 +219,7 @@ void HandleRegisterBasedOpcode(unsigned char mask) { return; } else { - fprintf(stderr, "[Error] Expected operand, got %s\n", token->lexeme); + fprintf(stderr, "[Error] Expected operand, got %s\n", token->Lemexe); exit(1); } @@ -241,22 +237,22 @@ void HandleOperation(void) { // AdvanceParser(); - unsigned char mask = GetInstructionMask(token->type); + unsigned char mask = GetInstructionMask(token->Value.Mnemonic); if (mask & registerBasedOpcodeMask) { HandleRegisterBasedOpcode(mask); return; } - IROpcode* opcode = CreateIROpcode(token->type); - opcode->ParameterTwoType = None; + IROpcode* opcode = CreateIROpcode(token->Value.Mnemonic); + //opcode->ParameterTwoType = None; AdvanceParser(); switch (mask) { case 0: //NOP //Memory[ProgramCounter] = 0x00; - opcode->ParameterOneType = None; + //opcode->ParameterOneType = None; ProgramCounter++; return; @@ -265,9 +261,9 @@ void HandleOperation(void) { ProgramCounter++; - if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - Symbol* symbol = GetSymbol(PeekToken()->lexeme); - opcode->ParameterOneType = Address; + 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; @@ -279,16 +275,16 @@ void HandleOperation(void) { // Memory[ProgramCounter] = 2 >> symbol->address & 0xFF; // Memory[ProgramCounter + 1] = symbol->address & 0xFF; } - else if (PeekToken()->type == NUMBER) { - opcode->ParameterOneType = Constant; - opcode->ParameterOne.Constant = *(int*)PeekToken()->value; + 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])->line); + fprintf(stderr, "[Error] Line: %d: Expected address after jump if zero (JZ) instruction.\n", ((Token*) TokensList->content[CurrentToken - 1])->LineNumber); exit(1); } @@ -300,16 +296,16 @@ void HandleOperation(void) { ProgramCounter++; - if (PeekToken()->type == NUMBER) { + if (PeekToken()->Class == NumberClass) { // int* value = PeekToken()->value; - opcode->ParameterOneType = Constant; - opcode->ParameterOne.Constant = *(int*)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()->line); + fprintf(stderr, "[Error] Line %d: Expected Interrupt vector.\n", PeekToken()->LineNumber); exit(1); } @@ -318,13 +314,13 @@ void HandleOperation(void) { return; case 3: //YLD //Memory[ProgramCounter] = 0x03; - opcode->ParameterOneType = None; + //opcode->ParameterOneType = ; ProgramCounter++; break; case 4: //RET //Memory[ProgramCounter] = 0x04; - opcode->ParameterOneType = None; + //opcode->ParameterOneType = ; ProgramCounter++; break; @@ -333,9 +329,9 @@ void HandleOperation(void) { ProgramCounter++; - if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - Symbol* symbol = GetSymbol(PeekToken()->lexeme); - opcode->ParameterOneType = Address; + 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); @@ -347,7 +343,7 @@ void HandleOperation(void) { //Memory[ProgramCounter + 1] = symbol->address & 0xFF; } else { - fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); + fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->LineNumber); exit(1); } @@ -358,9 +354,9 @@ void HandleOperation(void) { ProgramCounter++; - if (PeekToken()->type == IDENTIFIER || PeekToken()->type == LABEL) { - Symbol* symbol = GetSymbol(PeekToken()->lexeme); - opcode->ParameterOneType = Address; + 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); @@ -373,7 +369,7 @@ void HandleOperation(void) { // Memory[ProgramCounter + 1] = symbol->address & 0xFF; } else { - fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->line); + fprintf(stderr, "[Error] Line %d: Expected address or label.\n", PeekToken()->LineNumber); exit(1); } @@ -384,16 +380,16 @@ void HandleOperation(void) { ProgramCounter++; - if (PeekToken()->type == NUMBER) { - opcode->ParameterOneType = Constant; - opcode->ParameterOne.Constant = *(int*)PeekToken()->value; + 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()->line); + fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->LineNumber); exit(1); } @@ -404,16 +400,16 @@ void HandleOperation(void) { ProgramCounter++; - if (PeekToken()->type == NUMBER) { - opcode->ParameterOneType = Constant; - opcode->ParameterOne.Constant = *(int*)PeekToken()->value; + 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()->line); + fprintf(stderr, "[Error] Line %d: Expected port number.\n", PeekToken()->LineNumber); exit(1); } @@ -433,7 +429,7 @@ int Expect(int count, ...) { va_start(list, count); for(int i = 0; i < count; i++) { - if (va_arg(list, TokenType) == token->type) { + if (va_arg(list, TokenClass) == token->Class) { va_end(list); AdvanceParser(); return 1; @@ -449,21 +445,21 @@ void PrintSymbols(void) { printf("-----SYMBOLS-----\n"); for(int i = 0; i < MachineState.SymbolsTable->size; i++) { Symbol* symbol = MachineState.SymbolsTable->content[i]; - printf("[%#06X] %s\n", symbol->address, symbol->token->lexeme); + printf("[%#06X] %s\n", symbol->address, symbol->token->Lemexe); } printf("-----SYMBOLS-----\n"); } Symbol* AddSymbol(Token* token, int length, int address, int resolved) { if (!token) return NULL; - if (token->type != IDENTIFIER && token->type != LABEL) 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->lexeme, token->lexeme) == 0) { + if (strcmp(s->token->Lemexe, token->Lemexe) == 0) { if (s->resolved) { - fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->line, token->lexeme); + fprintf(stderr, "[Error] Line %d: Attempted to redeclare %s.\n", token->LineNumber, token->Lemexe); exit(1); } s->resolved = resolved; @@ -486,7 +482,7 @@ Symbol* GetSymbol(char* name) { for(int i = 0; i < MachineState.SymbolsTable->size; i++) { Symbol* s = MachineState.SymbolsTable->content[i]; - if (strcmp(s->token->lexeme, name) == 0) return s; + if (strcmp(s->token->Lemexe, name) == 0) return s; } return NULL; @@ -504,7 +500,7 @@ Symbol* CreateSymbol(Token* token, int length, int address, int resolved) { return symbol; } -IROpcode* CreateIROpcode(TokenType mnemonic) { +IROpcode* CreateIROpcode(Mnemonic mnemonic) { IROpcode* opcode = calloc(1, sizeof(IROpcode)); opcode->Mnemonic = mnemonic; diff --git a/src/scanner.c b/src/scanner.c index c65ceff..0b065e3 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -37,7 +37,8 @@ List* GenerateTokenList(const char* source) { AdvanceScanner(); break; //Ignore whitespace case '\n': - token = CreateToken("^", NULL, Line, LineEnd); + token = CreateToken(Line, PunctuationClass); + token->Value.Punctuation = NewLine; AddListItem(token, sizeof(Token), tokens); AdvanceScanner(); Line++; @@ -95,24 +96,20 @@ Token* ParseNumber(void) { if (length == 0) return NULL; char* lexeme = calloc(sizeof(char), length + 1); - long* value = calloc(1, sizeof(long)); if (!lexeme) { fprintf(stderr, "Failed to calloc space for number. %s.\n", strerror(errno)); return NULL; } - if (!value) { - free(lexeme); - fprintf(stderr, "Failed to calloc space for the raw numeric value of a token. %s.\n", strerror(errno)); - return NULL; - } - memcpy(lexeme, &SourceCode[start], length); - // Setting the base to zero means the function will pick the base. - *value = strtol(lexeme, NULL, 0); + + Token* token = CreateToken(Line, NumberClass); - return CreateToken(lexeme, value, Line, NUMBER); + token->Value.Number = strtol(lexeme, NULL, 0); + token->Lemexe = lexeme; + + return token; } Token* ParseDirective(void) { @@ -133,12 +130,17 @@ Token* ParseDirective(void) { memcpy(directive, &SourceCode[start], length); + Token* token = CreateToken(Line, DirectiveClass); + if (strcmp(directive, ".db") == 0) { - return CreateToken(directive, directive, Line, DB); + token->Value.Directive = DB; + + return token; } else if (strcmp(directive, ".org") == 0) { fprintf(stderr, "[Warning] Org is not a supported directive.\n"); free(directive); + free(token); IgnoreLine(); return NULL; } @@ -178,7 +180,9 @@ Token* ParseString(void) { AdvanceScanner(); //Consume the trailing double quote. - Token* token = CreateToken(lexeme, lexeme, Line, STRING); + Token* token = CreateToken(Line, CharacterClass); + + token->Lemexe = lexeme; return token; } @@ -194,7 +198,8 @@ Token* ParseIdentifier(void) { if (length == 0) return NULL; - TokenType type; + Mnemonic mnemonics; + Registers reg; char* lexeme = calloc(sizeof(char), length + 1); if (!lexeme) { @@ -204,14 +209,33 @@ Token* ParseIdentifier(void) { memcpy(lexeme, &SourceCode[start], length); - if (IsOpcode(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type); - if (IsRegister(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type); + if (IsOpcode(lexeme, &mnemonics)) { + Token* token = CreateToken(Line, MnemonicClass); + + token->Value.Mnemonic = mnemonics; + + return token; + } + if (IsRegister(lexeme, ®)) { + Token* token = CreateToken(Line, RegisterClass); + token->Value.Register = reg; + + return token; + } if (lexeme[length - 1] == ':') { lexeme[length - 1] = '\0'; //Bit hacky, but this makes the parser's job a bit easier. - return CreateToken(lexeme, lexeme, Line, LABEL); + Token* token = CreateToken(Line, LabelClass); + + token->Lemexe = lexeme; + + return token; } - return CreateToken(lexeme, lexeme, Line, IDENTIFIER); + Token* token = CreateToken(Line, IdentifierClass); + + token->Lemexe = lexeme; + + return token; } char PeekScanner(void) { @@ -250,18 +274,30 @@ int IsPunctuation(char c) { } Token* ParsePunctuation(char c) { + TokenPunctuation punctuation; + switch(c) { case '[': - return CreateToken("[", NULL, Line, LBRACKET); + punctuation = LBracket; + break; case ']': - return CreateToken("]", NULL, Line, RBracket); + punctuation = RBracket; + break; case '(': - return CreateToken("(", NULL, Line, LPARAM); + punctuation = LParan; + break; case ')': - return CreateToken(")", NULL, Line, RPARAM); + punctuation = RParan; + break; case ',': - return CreateToken(",", NULL, Line, COMMA); + punctuation = Comma; + break; default: return NULL; } + + Token* token = CreateToken(Line, PunctuationClass); + token->Value.Punctuation = punctuation; + + return token; } \ No newline at end of file diff --git a/src/token.c b/src/token.c index 605ab49..bd9c49f 100644 --- a/src/token.c +++ b/src/token.c @@ -1,8 +1,6 @@ #include "../includes/token.h" -TokenClass GetTokenClass(TokenType); - -Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) { +Token* CreateToken(int lineNumber, TokenClass tokenClass) { Token* token = calloc(1, sizeof(Token)); if (!token) { @@ -10,36 +8,14 @@ Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) { return NULL; } - token->type = type; - token->line = lineNumber; - token->lexeme = lexeme; - token->value = value; - token->token_class = GetTokenClass(type); + token->Class = tokenClass; + token->LineNumber = lineNumber; return token; } -TokenClass GetTokenClass(TokenType type) { - if (type >= R1 && type <= R8) return Reg; - if (type >= COPY && type <= OUT) return Mnemonic; - if (type >= DB && type <= ORG) return Directive; - - switch(type) { - case STRING: - case IDENTIFIER: - case LABEL: - return Address; - case NUMBER: - return Constant; - default: - return None; - } -} - void FreeToken(Token* token) { if (!token) return; - if (token->value && (token->type >= STRING || token->type == NUMBER)) free(token->value); - free(token); } \ No newline at end of file