From fbef044905432a22659d36783268e3571da36016 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Fri, 6 May 2022 18:55:22 +0000 Subject: [PATCH] Added some simple symbol handling to the Parser. --- includes/parser.h | 8 ++-- misc/test.asm | 1 + src/main.c | 16 +++---- src/parser.c | 112 ++++++++++++++++++++++++++++++---------------- src/scanner.c | 10 ++--- 5 files changed, 90 insertions(+), 57 deletions(-) diff --git a/includes/parser.h b/includes/parser.h index c059a4e..9db721c 100644 --- a/includes/parser.h +++ b/includes/parser.h @@ -1,12 +1,10 @@ #ifndef PARSER_H #define PARSER_H +#include +#include #include "list.h" - -typedef struct { - char* name; - int address; -} Symbol; +#include "token.h" void ParseTokens(List*); diff --git a/misc/test.asm b/misc/test.asm index 0e0c739..349113d 100644 --- a/misc/test.asm +++ b/misc/test.asm @@ -1,5 +1,6 @@ .org 0x100 .db msg "Hello, world!", 0 +.db more_stuff "And yet another string!", 0 copy r1, msg copy r2, 0 diff --git a/src/main.c b/src/main.c index 5d04ffa..60831c1 100644 --- a/src/main.c +++ b/src/main.c @@ -7,8 +7,6 @@ #include "../includes/futil.h" #include "../includes/scanner.h" -List* get_strings(const char*); - int main(int argc, char* args[]) { if (argc == 1) { printf("Usage: assm \n"); @@ -22,13 +20,15 @@ int main(int argc, char* args[]) { List* list = GenerateTokenList(source_code); - for(int i = 0; i < list->size; i++) { - Token* t = (Token*) list->content[i]; + // for(int i = 0; i < list->size; i++) { + // Token* t = (Token*) list->content[i]; - printf("[%i] '%s'", t->type, t->lexeme); - if (t->type == NUMBER || t->type == HEX) printf(" NUM: %ld", *((long *) t->value)); - printf("\n"); - } + // printf("[%i] '%s'", t->type, t->lexeme); + // if (t->type == LABEL) printf("*"); + // printf("\n"); + // } + + ParseTokens(list); free(source_code); } \ No newline at end of file diff --git a/src/parser.c b/src/parser.c index 47d7d27..4b92693 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,55 +1,89 @@ #include "../includes/parser.h" -#include "../includes/token.h" #include #include +#include -//static List* SymbolsTable; -//static unsigned int program_counter = 0; -void ProcessDirective(List*); -void ProcessVariableDeclaration(List*); +typedef struct { + Token* token; + int address; +} Symbol; + +Symbol* CreateSymbol(Token*, int); +void AddSymbol(Token*); +void PrintSymbols(void); +Token* GetSymbol(char*); +List* SymbolsTable; +unsigned int ProgramCounter = 0; void ParseTokens(List* tokens) { - // for(int i = 0; i < tokens->size; i++) { - // if (((Token *) tokens->content[i])->type == TK_Directive){ - // ProcessDirective(tokens); - // } - // } -} + SymbolsTable = CreateList(); -void ProcessDirective(List* tokens) { - if (tokens->size < 2) { - printf("Directives failed\n"); - return; - } + for(int i = 0; i < tokens->size; i++){ + Token* t = tokens->content[i]; - Token* directive = (Token *) tokens->content[0]; - - if (strcmp(".org", directive->value) == 0) { - Token* address_start = (Token*) tokens->content[1]; - if (address_start->type == NUMBER) { - long address = strtol(address_start->value, NULL, 10); - printf("Address starting at '%ld'\n", address); - } - else if (address_start->type == HEX) { - long address = strtol(address_start->value, NULL, 16); - printf("Setting address to '%ld'\n", address); + switch(t->type) { + case IDENTIFIER: + case LABEL: + AddSymbol(t); + break; + case STRING: + ProgramCounter += strlen(t->lexeme); + break; + case NUMBER: + case HEX: + if ((long) t->value < 256) ProgramCounter += 1; + else ProgramCounter += 2; + break; + default: + if (t->type > ORG) ProgramCounter += 1; + break; } } - if (strcmp(".db", directive->value) == 0) { - ProcessVariableDeclaration(tokens); - } + PrintSymbols(); + DestroyList(SymbolsTable); + printf("Program Counter: %d\n", ProgramCounter); } -void ProcessVariableDeclaration(List* tokens) { - if (tokens->size < 3) { - printf("Invalid variable delcaration\n"); - return; +void PrintSymbols(void) { + printf("-----SYMBOLS-----\n"); + for(int i = 0; i < SymbolsTable->size; i++) { + Symbol* symbol = SymbolsTable->content[i]; + printf("[%#08X] %s\n", symbol->address, symbol->token->lexeme); } - - Token* symbol_token = (Token*) tokens->content[1]; - Token* string_literal = (Token*) tokens->content[2]; + printf("-----SYMBOLS-----\n"); +} - printf("Found string literal.\n"); - printf("Name '%s' value: '%s'\n", symbol_token->lexeme, string_literal->lexeme); +void AddSymbol(Token* token) { + if (!token) return; + if (token->type != IDENTIFIER && token->type != LABEL) return; + + for(int i = 0; i < SymbolsTable->size; i++) { + Symbol* s = SymbolsTable->content[i]; + + if (strcmp(s->token->lexeme, token->lexeme) == 0) return; + } + + Symbol* symbol = CreateSymbol(token, ProgramCounter); + + AddListItem(symbol, sizeof(Symbol), SymbolsTable); +} + +Token* GetSymbol(char* name) { + if (!name) return NULL; + + return NULL; +} + +Symbol* CreateSymbol(Token* token, int offset) { + Symbol* symbol = calloc(1, sizeof(Symbol)); + + if (!symbol) { + return NULL; + } + + symbol->token = token; + symbol->address = offset; + + return symbol; } \ No newline at end of file diff --git a/src/scanner.c b/src/scanner.c index 7426131..07f97ce 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -149,7 +149,6 @@ Token* ParseDirective(void) { free(directive); - //Ignore the line IgnoreLine(); return NULL; @@ -164,9 +163,7 @@ Token* ParseString(void) { int start = Position; - while(!ScannerAtEnd() && PeekScanner() != '"') { - AdvanceScanner(); - } + while(!ScannerAtEnd() && PeekScanner() != '"') AdvanceScanner(); int length = Position - start; @@ -211,7 +208,10 @@ Token* ParseIdentifier(void) { if (IsOpcode(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type); if (IsRegister(lexeme, &type)) return CreateToken(lexeme, lexeme, Line, type); - if (lexeme[length - 1] == ':') return CreateToken(lexeme, lexeme, Line, LABEL); + 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); + } return CreateToken(lexeme, lexeme, Line, IDENTIFIER); }