From 72525959f696e03630d37a5c2f7b117f9b72c42d Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Thu, 12 May 2022 20:26:14 +0000 Subject: [PATCH] Reworked the tokens to include a broad class to make parameter matching a bit easier, and removed the hexadecimal distinction. --- includes/opcodes.h | 16 +++++---------- includes/token.h | 9 ++++++++- src/opcodes.c | 26 +++++++++++++++--------- src/parser.c | 49 ++++++++++++++++++++++++++++++++++++++++------ src/scanner.c | 10 +++------- src/token.c | 18 +++++++++++++++++ 6 files changed, 94 insertions(+), 34 deletions(-) diff --git a/includes/opcodes.h b/includes/opcodes.h index a2e04c6..c7da0f9 100644 --- a/includes/opcodes.h +++ b/includes/opcodes.h @@ -7,29 +7,23 @@ #define OPCODECOUNT 10 #define REGISTERCOUNT 8 -typedef enum { - None = 0, - Reg, - Imm8, - Imm16 -} ParameterType; - typedef struct { char* lexeme; TokenType op; - ParameterType parameter_one; - ParameterType parameter_two; -} OpCode; + TokenClass parameter_one; + TokenClass parameter_two; +} Instruction; typedef struct { char* lexeme; TokenType type; } Register; -extern OpCode opcodes[OPCODECOUNT]; +extern Instruction instructions[OPCODECOUNT]; extern Register registers[REGISTERCOUNT]; int IsOpcode(const char*, TokenType*); int IsRegister(const char*, TokenType*); +const Instruction* GetOpcodeDetails(TokenType); #endif \ No newline at end of file diff --git a/includes/token.h b/includes/token.h index ae3313c..fbcfeab 100644 --- a/includes/token.h +++ b/includes/token.h @@ -21,7 +21,6 @@ typedef enum { IDENTIFIER, LABEL, NUMBER, - HEX, //Keywords DB, ORG, //Opcodes @@ -31,11 +30,19 @@ typedef enum { R1, R2, R3, R4, R5, R6, R7, R8 } TokenType; +typedef enum { + None, + Reg, + Immediate16, + Opcode +} TokenClass; + typedef struct { TokenType type; char* lexeme; void* value; int line; + TokenClass token_class; } Token; Token* CreateToken(char*, void*, int, TokenType); diff --git a/src/opcodes.c b/src/opcodes.c index 4c30c85..701f9e6 100644 --- a/src/opcodes.c +++ b/src/opcodes.c @@ -2,15 +2,15 @@ #include #include -OpCode opcodes[OPCODECOUNT] = { - { "copy", COPY, Reg, Reg | Imm8 | Imm16 }, - { "add", ADD, Reg, Reg | Imm8 | Imm16 }, - { "sub", SUB, Reg, Reg | Imm8 | Imm16 }, - { "jz", JZ, Imm8 | Imm16, None }, - { "int", INT, Imm8, None }, +Instruction instructions[OPCODECOUNT] = { + { "copy", COPY, Reg, Reg | Immediate16 }, + { "add", ADD, Reg, Reg | Immediate16 }, + { "sub", SUB, Reg, Reg | Immediate16 }, + { "jz", JZ, Immediate16, None }, + { "int", INT, Immediate16, None }, { "yld", YLD, None, None }, { "ret", RET, None, None }, - { "cmp", CMP, Reg | Imm8 | Imm16, Reg | Imm8 | Imm16 }, + { "cmp", CMP, Reg | Immediate16, Reg | Immediate16 }, { "in", IN, None, None}, { "out", OUT, None, None} }; @@ -26,12 +26,20 @@ Register registers[REGISTERCOUNT] = { { "r8", R8 } }; +const Instruction* GetOpcodeDetails(TokenType type) { + for(int i = 0; i < OPCODECOUNT; i++) { + if (instructions[i].op == type) return &instructions[i]; + } + + return NULL; +} + int IsOpcode(const char* text, TokenType* opcode) { if (!text) return 0; for(int i = 0; i < OPCODECOUNT; i++) { - if (strcmp(opcodes[i].lexeme, text) == 0) { - if (opcode) *opcode = opcodes[i].op; + if (strcmp(instructions[i].lexeme, text) == 0) { + if (opcode) *opcode = instructions[i].op; return 1; } } diff --git a/src/parser.c b/src/parser.c index 5af7c6b..4f863f9 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,4 +1,5 @@ #include "../includes/parser.h" +#include #ifndef HIGHMEMORY #define HIGHMEMORY 65535 //64KiB - 1 AKA 0xFFFF @@ -10,13 +11,24 @@ typedef struct { } Symbol; Symbol* CreateSymbol(Token*, int); +const List* TokensList; +int CurrentToken = 0; + void AddSymbol(Token*, int); void PrintSymbols(void); +void HandleOperation(Token*); +void AdvanceParser(void); +Token* PeekToken(void); +int Expect(int, ...); Token* GetSymbol(char*); List* SymbolsTable; unsigned int ProgramCounter = 0; void ParseTokens(List* tokens) { + if (!tokens) return; + + TokensList = tokens; + SymbolsTable = CreateList(); for(int i = 0; i < tokens->size; i++){ @@ -30,12 +42,13 @@ void ParseTokens(List* tokens) { case STRING: ProgramCounter += strlen(t->lexeme); break; - case NUMBER: - case HEX: //Number's will be 2 bytes + case NUMBER: //Number's will be 2 bytes ProgramCounter += 2; break; default: //Instructions are 1 byte wide. - if (IsOpcode(t->lexeme, NULL)) ProgramCounter += 1; + if (t->token_class == Opcode) { + ProgramCounter++; + } break; } @@ -46,6 +59,32 @@ void ParseTokens(List* tokens) { printf("Program Counter: %d\n", ProgramCounter); } +void HandleOperation(Token* token) { + const Instruction* inst = GetOpcodeDetails(token->type); + + if (!inst) return; + + +} + +int Expect(int count, ...) { + va_list list; + + va_start(list, count); + + for(int i = 0; i < count; i++) { + if (va_arg(list, TokenClass) == PeekToken()->token_class) { + va_end(list); + //advance + return 1; + } + } + + va_end(list); + + return 0; +} + void PrintSymbols(void) { printf("-----SYMBOLS-----\n"); for(int i = 0; i < SymbolsTable->size; i++) { @@ -79,9 +118,7 @@ Token* GetSymbol(char* name) { Symbol* CreateSymbol(Token* token, int address) { Symbol* symbol = calloc(1, sizeof(Symbol)); - if (!symbol) { - return NULL; - } + if (!symbol) return NULL; symbol->token = token; symbol->address = address; diff --git a/src/scanner.c b/src/scanner.c index 07f97ce..f21370f 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -79,13 +79,11 @@ List* GenerateTokenList(const char* source) { Token* ParseNumber(void) { int start = Position; - int base = 10; while(!ScannerAtEnd() && isdigit(PeekScanner())) AdvanceScanner(); if (PeekScanner() == 'x' && isdigit(PeekAheadScanner())) { - base = 16; AdvanceScanner(); //Consume the 'x' while(!ScannerAtEnd() && isdigit(PeekScanner())) AdvanceScanner(); } @@ -109,12 +107,10 @@ Token* ParseNumber(void) { } memcpy(lexeme, &SourceCode[start], length); - - *value = strtol(lexeme, NULL, base); + // Setting the base to zero means the function will pick the base. + *value = strtol(lexeme, NULL, 0); - if (base == 10) return CreateToken(lexeme, value, Line, NUMBER); - - return CreateToken(lexeme, value, Line, HEX); + return CreateToken(lexeme, value, Line, NUMBER); } Token* ParseDirective(void) { diff --git a/src/token.c b/src/token.c index 382ed8a..03f7c15 100644 --- a/src/token.c +++ b/src/token.c @@ -1,5 +1,7 @@ #include "../includes/token.h" +TokenClass GetTokenClass(TokenType); + Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) { Token* token = calloc(1, sizeof(Token)); @@ -12,10 +14,26 @@ Token* CreateToken(char* lexeme, void* value, int lineNumber, TokenType type) { token->line = lineNumber; token->lexeme = lexeme; token->value = value; + token->token_class = GetTokenClass(type); return token; } +TokenClass GetTokenClass(TokenType type) { + if (type >= R1 && type <= R8) return Reg; + if (type >= COPY && type <= OUT) return Opcode; + + switch(type) { + case STRING: + case IDENTIFIER: + case LABEL: + case NUMBER: + return Immediate16; + default: + return None; + } +} + void FreeToken(Token* token) { if (!token) return;