From 3a5788f4ab16f72a163eb4d1827dbbdd34a8a2a6 Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Thu, 26 Jun 2025 00:36:37 -0500 Subject: [PATCH] Cleaned up the TokenStringify function and started toying with ways to handle syncing in the parser. --- examples/strlen.asm | 2 +- includes/token.h | 5 +- src/dictionary.c | 2 +- src/parser.c | 49 +++++++++-------- src/token.c | 124 ++++++++++++++------------------------------ src/tokenizer.c | 4 +- 6 files changed, 70 insertions(+), 116 deletions(-) diff --git a/examples/strlen.asm b/examples/strlen.asm index 577b213..c19e755 100644 --- a/examples/strlen.asm +++ b/examples/strlen.asm @@ -1,5 +1,5 @@ namespace string 67; my string namespace here - +namespace text "some string in the middle of nowhere" word FRAMEBUFFER 0x00200500 asciiz Msg "Hello World!" diff --git a/includes/token.h b/includes/token.h index 984bf2b..b8f19d2 100644 --- a/includes/token.h +++ b/includes/token.h @@ -9,7 +9,7 @@ #include "keywords.h" typedef enum { - Empty, + Empty = 0, String, Number, Symbol, @@ -46,8 +46,9 @@ typedef struct _token { bool Resolved; } Token; +extern const Token TokenEmpty; + Token* TokenCreate(TokenType type, int lineNumber, int columnNumber, bool resolved); char* TokenStringify(const Token* token); -int StringifyTokenType(TokenType type, char buffer[32]); #endif \ No newline at end of file diff --git a/src/dictionary.c b/src/dictionary.c index 047d0db..e46c927 100644 --- a/src/dictionary.c +++ b/src/dictionary.c @@ -13,7 +13,7 @@ struct _dictionary { struct _dictionary* DictionaryCreate(void) { struct _dictionary* dict = calloc(1, sizeof(Dictionary)); - dict->Pairs = calloc(sizeof(KeyValPair*), DEFAULT_DICT_SIZE); + dict->Pairs = calloc(DEFAULT_DICT_SIZE, sizeof(KeyValPair*)); dict->Capacity = DEFAULT_DICT_SIZE; diff --git a/src/parser.c b/src/parser.c index 48fe7f7..8977b8a 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,39 +1,24 @@ #include "../includes/parser.h" -#define KEYWORD_COUNT 7 - static Array* Tokens; -struct _instruction { - char* Name; - bool IsDirective; - union { - Mnemonics Mnemonic; - Keywords Keyword; - } Value; -}; - -typedef struct parameter { - bool IsRegister; - Registers Register; - unsigned char Width; - uint32_t Offset; -} Parameter; - size_t ParserIndex = 0; +const size_t MessageBufferLength = 2048 * sizeof(char); +char* MessageBuffer; Token* ParserAdvance(void); void ParserIgnoreLine(void); bool ParserAtEnd(void); -Parameter* ParserExpectParameter(void); void ParserHandleKeyword(Keywords keyword); Token* ParserExpect(TokenType type); Token* ParserWant(TokenType type); void ParserExpectLineEnd(void); +void ParserSync(Token* got, char* message); Instructions* ParseTokens(Array* tokens) { + MessageBuffer = malloc(MessageBufferLength); + Tokens = tokens; - Keywords keyword; while(!ParserAtEnd()) { Token* token = ParserAdvance(); @@ -46,6 +31,18 @@ Instructions* ParseTokens(Array* tokens) { break; } } + + return NULL; +} + +void ParserSync(Token* got, char* message) { + char* str = TokenStringify(got); + + fprintf(stderr, "[Line %d] %s but got %s.\n", got->LineNumber, message, str); + + free(str); + + ParserIgnoreLine(); } void ParserHandleKeyword(Keywords keyword) { @@ -53,12 +50,15 @@ void ParserHandleKeyword(Keywords keyword) { switch(keyword) { case NAMESPACE: + { namespace = ParserExpect(Symbol); ParserExpectLineEnd(); printf("Namespace `%s` seen\n", namespace->Value.String); + break; + } default: break; } @@ -69,7 +69,9 @@ Token* ParserExpect(TokenType type) { Token* token = ParserAdvance(); - if (!token || token->Type != type) return NULL; + if (token->Type != type) { + + } return token; } @@ -90,10 +92,7 @@ void ParserExpectLineEnd(void) { Token* token = ParserAdvance(); if (token->Type != LineEnd && token->Type != FileEnd) { - //Error / sync - printf("Expected end of line on line %d.\n", token->LineNumber); - - ParserIgnoreLine(); + ParserSync(token, "Expected end of line or file"); } return; diff --git a/src/token.c b/src/token.c index 5cf231f..df09940 100644 --- a/src/token.c +++ b/src/token.c @@ -1,5 +1,7 @@ #include "../includes/token.h" +const Token TokenEmpty = { 0 }; + struct _token* TokenCreate(TokenType type, int lineNumber, int columnNumber, bool resolved) { struct _token* token = calloc(1, sizeof(Token)); @@ -12,112 +14,62 @@ struct _token* TokenCreate(TokenType type, int lineNumber, int columnNumber, boo } char* TokenStringify(const struct _token* token) { - if (!token) return false; + if (!token) return NULL; - char word[32]; - char* buffer = NULL; + size_t bufferSize = 64; + char* str; + + if (token->Type == String) { + // Add three for 2 quotes and a NUL byte. + bufferSize = strlen(token->Value.String) + 3; + + str = malloc(bufferSize); + + snprintf(str, bufferSize, "\"%s\"", token->Value.String); + + return str; + } + else if (token->Type == Symbol) { + bufferSize = strlen(token->Value.String) + 1; + str = calloc(bufferSize, sizeof(char)); + + strncpy(str, token->Value.String, bufferSize); + + return str; + } + else { + str = malloc(bufferSize * sizeof(char)); + } + + char buffer[32] = { 0 }; switch(token->Type) { case Register: - GetRegisterText(token->Value.Register, word); - - buffer = calloc(sizeof(word), sizeof(char)); - - strncpy(buffer, word, sizeof(word)); - + GetRegisterText(token->Value.Register, buffer); break; case Mnemonic: - GetMnemonicText(token->Value.Mnemonic, word); - - buffer = calloc(sizeof(word), sizeof(char)); - - strncpy(buffer, word, sizeof(word)); - + GetMnemonicText(token->Value.Mnemonic, buffer); break; case Keyword: - GetKeywordText(token->Value.Keyword, word); - - buffer = calloc(sizeof(word), sizeof(char)); - - strncpy(buffer, word, sizeof(word)); - - break; - case String: - case Symbol: - buffer = calloc(strlen(token->Value.String) + 1, sizeof(char)); - - strncpy(buffer, token->Value.String, strlen(token->Value.String)); - + GetKeywordText(token->Value.Keyword, buffer); break; case Empty: - buffer = calloc(8, sizeof(char)); - - strncpy(buffer, "<>", sizeof(char) * 2); - + strcpy(str, "(Empty)"); break; case Number: - buffer = calloc(32, sizeof(char)); - - sprintf(buffer, "%d", token->Value.Number); - + sprintf(str, "%d", token->Value.Number); break; case LineEnd: - buffer = calloc(8, sizeof(char)); - - strncpy(buffer, "\n", sizeof(char)); - + strcpy(str, "(LineEnd)"); break; case FileEnd: break; default: - buffer = calloc(16, sizeof(char)); - - strncpy(buffer, token->Value.Operator, sizeof(char)); - + sprintf(str, "%s", token->Value.Operator); break; } - return buffer; -} + if (strlen(buffer) > 0) strncpy(str, buffer, sizeof(buffer) - 1); -int StringifyTokenType(TokenType type, char buffer[32]) { - if (!buffer) return 0; - - memset(buffer, '\0', 32); - - switch(type) { - case Empty: - strncpy(buffer, "", 8); - break; - case Register: - strncpy(buffer, "", 8); - break; - case Mnemonic: - strncpy(buffer, "", 8); - break; - case Keyword: - strncpy(buffer, "", 8); - break; - case String: - strncpy(buffer, "", 8); - break; - case Number: - strncpy(buffer, "", 8); - break; - case Symbol: - strncpy(buffer, "", 8); - break; - case LineEnd: - strncpy(buffer, "", 8); - break; - case FileEnd: - strncpy(buffer, "", 8); - break; - default: - snprintf(buffer, 8, "<%c >", type); - - break; - } - - return 8; + return str; } \ No newline at end of file diff --git a/src/tokenizer.c b/src/tokenizer.c index 9420dcf..09d99a8 100644 --- a/src/tokenizer.c +++ b/src/tokenizer.c @@ -68,7 +68,9 @@ Array* Tokenize(const char* sourceCode, Dictionary** variables) { case '\n': token = (Token*) ArrayPeek(Tokens); //Is there a previous token and if so, was it a line break? - if (token && token->Type == LineEnd) break; //Discard empty line. + if (token && token->Type == LineEnd) + break; //Discard empty line. + __attribute__ ((fallthrough)); case '+': case '-': case '*':