Cleaned up the TokenStringify function and started toying with ways to handle syncing in the parser.

This commit is contained in:
2025-06-26 00:36:37 -05:00
parent b759589e84
commit 3a5788f4ab
6 changed files with 70 additions and 116 deletions
+1 -1
View File
@@ -1,5 +1,5 @@
namespace string 67; my string namespace here namespace string 67; my string namespace here
namespace text "some string in the middle of nowhere"
word FRAMEBUFFER 0x00200500 word FRAMEBUFFER 0x00200500
asciiz Msg "Hello World!" asciiz Msg "Hello World!"
+3 -2
View File
@@ -9,7 +9,7 @@
#include "keywords.h" #include "keywords.h"
typedef enum { typedef enum {
Empty, Empty = 0,
String, String,
Number, Number,
Symbol, Symbol,
@@ -46,8 +46,9 @@ typedef struct _token {
bool Resolved; bool Resolved;
} Token; } Token;
extern const Token TokenEmpty;
Token* TokenCreate(TokenType type, int lineNumber, int columnNumber, bool resolved); Token* TokenCreate(TokenType type, int lineNumber, int columnNumber, bool resolved);
char* TokenStringify(const Token* token); char* TokenStringify(const Token* token);
int StringifyTokenType(TokenType type, char buffer[32]);
#endif #endif
+1 -1
View File
@@ -13,7 +13,7 @@ struct _dictionary {
struct _dictionary* DictionaryCreate(void) { struct _dictionary* DictionaryCreate(void) {
struct _dictionary* dict = calloc(1, sizeof(Dictionary)); 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; dict->Capacity = DEFAULT_DICT_SIZE;
+24 -25
View File
@@ -1,39 +1,24 @@
#include "../includes/parser.h" #include "../includes/parser.h"
#define KEYWORD_COUNT 7
static Array* Tokens; 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; size_t ParserIndex = 0;
const size_t MessageBufferLength = 2048 * sizeof(char);
char* MessageBuffer;
Token* ParserAdvance(void); Token* ParserAdvance(void);
void ParserIgnoreLine(void); void ParserIgnoreLine(void);
bool ParserAtEnd(void); bool ParserAtEnd(void);
Parameter* ParserExpectParameter(void);
void ParserHandleKeyword(Keywords keyword); void ParserHandleKeyword(Keywords keyword);
Token* ParserExpect(TokenType type); Token* ParserExpect(TokenType type);
Token* ParserWant(TokenType type); Token* ParserWant(TokenType type);
void ParserExpectLineEnd(void); void ParserExpectLineEnd(void);
void ParserSync(Token* got, char* message);
Instructions* ParseTokens(Array* tokens) { Instructions* ParseTokens(Array* tokens) {
MessageBuffer = malloc(MessageBufferLength);
Tokens = tokens; Tokens = tokens;
Keywords keyword;
while(!ParserAtEnd()) { while(!ParserAtEnd()) {
Token* token = ParserAdvance(); Token* token = ParserAdvance();
@@ -46,6 +31,18 @@ Instructions* ParseTokens(Array* tokens) {
break; 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) { void ParserHandleKeyword(Keywords keyword) {
@@ -53,12 +50,15 @@ void ParserHandleKeyword(Keywords keyword) {
switch(keyword) { switch(keyword) {
case NAMESPACE: case NAMESPACE:
{
namespace = ParserExpect(Symbol); namespace = ParserExpect(Symbol);
ParserExpectLineEnd(); ParserExpectLineEnd();
printf("Namespace `%s` seen\n", namespace->Value.String); printf("Namespace `%s` seen\n", namespace->Value.String);
break; break;
}
default: default:
break; break;
} }
@@ -69,7 +69,9 @@ Token* ParserExpect(TokenType type) {
Token* token = ParserAdvance(); Token* token = ParserAdvance();
if (!token || token->Type != type) return NULL; if (token->Type != type) {
}
return token; return token;
} }
@@ -90,10 +92,7 @@ void ParserExpectLineEnd(void) {
Token* token = ParserAdvance(); Token* token = ParserAdvance();
if (token->Type != LineEnd && token->Type != FileEnd) { if (token->Type != LineEnd && token->Type != FileEnd) {
//Error / sync ParserSync(token, "Expected end of line or file");
printf("Expected end of line on line %d.\n", token->LineNumber);
ParserIgnoreLine();
} }
return; return;
+38 -86
View File
@@ -1,5 +1,7 @@
#include "../includes/token.h" #include "../includes/token.h"
const Token TokenEmpty = { 0 };
struct _token* TokenCreate(TokenType type, int lineNumber, int columnNumber, bool resolved) { struct _token* TokenCreate(TokenType type, int lineNumber, int columnNumber, bool resolved) {
struct _token* token = calloc(1, sizeof(Token)); 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) { char* TokenStringify(const struct _token* token) {
if (!token) return false; if (!token) return NULL;
char word[32]; size_t bufferSize = 64;
char* buffer = NULL; 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) { switch(token->Type) {
case Register: case Register:
GetRegisterText(token->Value.Register, word); GetRegisterText(token->Value.Register, buffer);
buffer = calloc(sizeof(word), sizeof(char));
strncpy(buffer, word, sizeof(word));
break; break;
case Mnemonic: case Mnemonic:
GetMnemonicText(token->Value.Mnemonic, word); GetMnemonicText(token->Value.Mnemonic, buffer);
buffer = calloc(sizeof(word), sizeof(char));
strncpy(buffer, word, sizeof(word));
break; break;
case Keyword: case Keyword:
GetKeywordText(token->Value.Keyword, word); GetKeywordText(token->Value.Keyword, buffer);
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));
break; break;
case Empty: case Empty:
buffer = calloc(8, sizeof(char)); strcpy(str, "(Empty)");
strncpy(buffer, "<>", sizeof(char) * 2);
break; break;
case Number: case Number:
buffer = calloc(32, sizeof(char)); sprintf(str, "%d", token->Value.Number);
sprintf(buffer, "%d", token->Value.Number);
break; break;
case LineEnd: case LineEnd:
buffer = calloc(8, sizeof(char)); strcpy(str, "(LineEnd)");
strncpy(buffer, "\n", sizeof(char));
break; break;
case FileEnd: case FileEnd:
break; break;
default: default:
buffer = calloc(16, sizeof(char)); sprintf(str, "%s", token->Value.Operator);
strncpy(buffer, token->Value.Operator, sizeof(char));
break; break;
} }
return buffer; if (strlen(buffer) > 0) strncpy(str, buffer, sizeof(buffer) - 1);
}
int StringifyTokenType(TokenType type, char buffer[32]) { return str;
if (!buffer) return 0;
memset(buffer, '\0', 32);
switch(type) {
case Empty:
strncpy(buffer, "<empty >", 8);
break;
case Register:
strncpy(buffer, "<Reg >", 8);
break;
case Mnemonic:
strncpy(buffer, "<Mnemon>", 8);
break;
case Keyword:
strncpy(buffer, "<Key >", 8);
break;
case String:
strncpy(buffer, "<string>", 8);
break;
case Number:
strncpy(buffer, "<number>", 8);
break;
case Symbol:
strncpy(buffer, "<symbol>", 8);
break;
case LineEnd:
strncpy(buffer, "<LnEnd >", 8);
break;
case FileEnd:
strncpy(buffer, "<filend>", 8);
break;
default:
snprintf(buffer, 8, "<%c >", type);
break;
}
return 8;
} }
+3 -1
View File
@@ -68,7 +68,9 @@ Array* Tokenize(const char* sourceCode, Dictionary** variables) {
case '\n': case '\n':
token = (Token*) ArrayPeek(Tokens); token = (Token*) ArrayPeek(Tokens);
//Is there a previous token and if so, was it a line break? //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 '-': case '-':
case '*': case '*':