Create a simple, Pascal like, string to help create messages for the parser. Added a function in the Parser that accepts many TokenTypes and reports the list of types if a sync is required.

This commit is contained in:
2025-06-29 22:25:09 -05:00
parent 39320c7b69
commit c86c424c6f
4 changed files with 152 additions and 13 deletions
+15
View File
@@ -0,0 +1,15 @@
#ifndef PSTRING_H
#define PSTRING_H
#include <string.h>
#include <stdlib.h>
typedef struct pstring PString;
PString* CreateString(void);
void StringAppend(const char* text, PString* string);
void StringFree(PString* string);
void StringTruncate(PString* string);
char* StringToCString(PString* string);
#endif
+75 -12
View File
@@ -1,11 +1,13 @@
#include "../includes/parser.h"
#include "../includes/pstring.h"
#include <stdarg.h>
#define ParserExpects(...) ParserExpectList(sizeof((TokenType[]){__VA_ARGS__})/sizeof(TokenType), __VA_ARGS__)
static Array* Tokens;
size_t ParserIndex = 0;
const size_t MessageBufferLength = 2048 * sizeof(char);
char* MessageBuffer;
PString* MessageString;
jmp_buf ParserSyncPointBuffer;
@@ -18,6 +20,7 @@ void ParserHandleKeyword(Keywords keyword);
void ParserHandleMnemonic(Mnemonics mnemonic);
void ParserExpectParameter(Instruction* inst);
Token* ParserExpect(TokenType type);
Token* ParserExpectList(int count, ...);
Token* ParserWant(TokenType type);
void ParserExpectLineEnd(void);
void ParserSync(char* format, ...);
@@ -26,8 +29,7 @@ void ParserSyncMessage(char* message);
Instruction* ParserCreateInstruction(void);
Instructions* ParseTokens(Array* tokens) {
MessageBuffer = malloc(MessageBufferLength);
MessageString = CreateString();
Tokens = tokens;
(void) setjmp(ParserSyncPointBuffer);
@@ -53,11 +55,11 @@ Instructions* ParseTokens(Array* tokens) {
void ParserSync(char* format, ...) {
va_list args;
va_start (args, format);
va_start(args, format);
vfprintf(stderr, format, args);
va_end (args);
va_end(args);
ParserIgnoreLine();
@@ -107,7 +109,7 @@ void ParserHandleMnemonic(Mnemonics mnemonic) {
case ADD:
inst->ParameterCount = 2;
ParserExpectParameter(inst);
PARSER_EXPECT_LIST(LineEnd, Colon, Comma);
break;
default:
@@ -118,11 +120,15 @@ void ParserHandleMnemonic(Mnemonics mnemonic) {
void ParserExpectParameter(Instruction* inst) {
if (ParserAtEnd()) return;
Token* token = ParserPeek();
if (token->Type == Keyword) {
bool isPointer = ParserWant(OpenBracket) != NULL;
}
Token* token = ParserAdvance();
inst->Parameters[0].Pointer = ParserWant(OpenBracket) != NULL;
token = ParserAdvance();
if (token->Type == Number) {
inst->Parameters[0].Type = Number;
@@ -136,10 +142,18 @@ void ParserExpectParameter(Instruction* inst) {
inst->Parameters[0].Type = Register;
inst->Parameters[0].Value.Register = token->Value.Register;
}
else ParserSyncMessage("No valid parameter found.");
else ParserSyncMessage("No valid parameter found 1.");
if (inst->Parameters[0].Pointer) ParserExpect(CloseBracket);
if (inst->ParameterCount == 1) return;
ParserExpect(Comma);
if (!inst->Parameters[0].Pointer) inst->Parameters[1].Pointer = ParserWant(OpenBracket) != NULL;
token = ParserAdvance();
if (token->Type == Symbol) {
inst->Parameters[1].Type = Symbol;
inst->Parameters[1].Value.Name = token->Value.String;
@@ -148,7 +162,9 @@ void ParserExpectParameter(Instruction* inst) {
inst->Parameters[1].Type = Register;
inst->Parameters[1].Value.Register = token->Value.Register;
}
else ParserSyncMessage("No valid parameter found.");
else ParserSyncMessage("No valid parameter found 2.");
if (inst->Parameters[1].Pointer) ParserExpect(CloseBracket);
}
Token* ParserExpect(TokenType type) {
@@ -163,13 +179,60 @@ Token* ParserExpect(TokenType type) {
return token;
}
Token* ParserWant(TokenType type) {
Token* ParserExpectList(int count, ...) {
if (ParserAtEnd()) return NULL;
Token* token = ParserAdvance();
va_list args;
va_start(args, count);
for(int i = 0; i < count; i++) {
TokenType expect = va_arg(args, TokenType);
if(token->Type == expect) {
va_end(args);
return token;
}
}
//Report the error and sync the parser.
va_end(args);
va_start(args, count);
char buffer[32] = { 0 };
StringTruncate(MessageString);
StringAppend("Expected ", MessageString);
for(int i = 0; i < count; i++) {
TokenType expect = va_arg(args, TokenType);
TokenTypeStringify(expect, buffer);
//Are we at the end?
if (i + 1 >= count) {
StringAppend("or ", MessageString);
StringAppend(buffer, MessageString);
}
else {
StringAppend(buffer, MessageString);
StringAppend(", ", MessageString);
}
}
ParserSyncMessage(StringToCString(MessageString));
}
Token* ParserWant(TokenType type) {
if (ParserAtEnd()) return NULL;
Token* token = ParserPeek();
if (!token || token->Type != type) return NULL;
(void) ParserAdvance();
return token;
}
+61
View File
@@ -0,0 +1,61 @@
#include "../includes/pstring.h"
#define DEFUALT_SSTRING_SIZE 64
struct pstring {
char* Buffer;
size_t Length;
size_t Capacity;
};
PString* CreateString(void) {
PString* string = calloc(1, sizeof(PString));
string->Buffer = calloc(DEFUALT_SSTRING_SIZE, sizeof(char));
string->Capacity = DEFUALT_SSTRING_SIZE;
return string;
}
void StringResize(size_t additionalCapacity, PString* string) {
if (string->Capacity > string->Length + additionalCapacity) return;
while(string->Length + additionalCapacity > string->Capacity) {
string->Buffer = realloc(string->Buffer, string->Capacity * 2);
string->Capacity *= 2;
}
}
void StringAppend(const char* text, PString* string) {
if (!string) return;
size_t additional = strlen(text);
StringResize(additional, string);
memcpy(&string->Buffer[string->Length], text, additional);
string->Length += additional;
string->Buffer[string->Length] = '\0';
}
void StringFree(PString* string) {
if (!string) return;
free(string->Buffer);
free(string);
}
char* StringToCString(PString* string) {
if (!string) return NULL;
return string->Buffer;
}
void StringTruncate(PString* string) {
if (!string) return;
string->Length = 0;
string->Buffer[0] = '\0';
}
+1 -1
View File
@@ -110,7 +110,7 @@ void TokenTypeStringify(TokenType type, char buffer[32]) {
strcpy(buffer, "FileEnd");
break;
default:
snprintf(buffer, 32, "%c", type);
snprintf(buffer, 32, "'%c'", type);
break;
}