Added back a way to stringify the TokenType. Updated the way the Parser syncs and added the start of parsing of opcodes.

This commit is contained in:
2025-06-28 23:59:14 -05:00
parent 428556a7a1
commit 39320c7b69
5 changed files with 159 additions and 12 deletions
+1
View File
@@ -51,5 +51,6 @@ 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);
void TokenTypeStringify(TokenType type, char buffer[32]);
#endif #endif
+6 -1
View File
@@ -4,6 +4,9 @@
#include "../includes/opcodes.h" #include "../includes/opcodes.h"
#include "../includes/parser.h" #include "../includes/parser.h"
//For color out puts in the shell
//https://stackoverflow.com/questions/5947742/how-to-change-the-output-color-of-echo-in-linux
int main(int argc, char** argv) { int main(int argc, char** argv) {
char* file; char* file;
size_t count; size_t count;
@@ -28,6 +31,7 @@ int main(int argc, char** argv) {
return 0; return 0;
} }
/*
for(size_t i = 0; i < tokens->Size; i++) { for(size_t i = 0; i < tokens->Size; i++) {
Token* token = tokens->Items[i]; Token* token = tokens->Items[i];
@@ -45,6 +49,7 @@ int main(int argc, char** argv) {
} }
printf("\n"); printf("\n");
*/
//(void) ParseTokens(tokens); (void) ParseTokens(tokens);
} }
+101 -7
View File
@@ -1,4 +1,5 @@
#include "../includes/parser.h" #include "../includes/parser.h"
#include <stdarg.h>
static Array* Tokens; static Array* Tokens;
@@ -9,13 +10,20 @@ char* MessageBuffer;
jmp_buf ParserSyncPointBuffer; jmp_buf ParserSyncPointBuffer;
Token* ParserAdvance(void); Token* ParserAdvance(void);
Token* ParserPeek(void);
void ParserIgnoreLine(void); void ParserIgnoreLine(void);
bool ParserAtEnd(void); bool ParserAtEnd(void);
void ParserHandleKeyword(Keywords keyword); void ParserHandleKeyword(Keywords keyword);
void ParserHandleMnemonic(Mnemonics mnemonic);
void ParserExpectParameter(Instruction* inst);
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); void ParserSync(char* format, ...);
void ParserSyncExpect(TokenType expected, TokenType found);
void ParserSyncMessage(char* message);
Instruction* ParserCreateInstruction(void);
Instructions* ParseTokens(Array* tokens) { Instructions* ParseTokens(Array* tokens) {
MessageBuffer = malloc(MessageBufferLength); MessageBuffer = malloc(MessageBufferLength);
@@ -31,6 +39,9 @@ Instructions* ParseTokens(Array* tokens) {
case Keyword: case Keyword:
ParserHandleKeyword(token->Value.Keyword); ParserHandleKeyword(token->Value.Keyword);
break; break;
case Mnemonic:
ParserHandleMnemonic(token->Value.Mnemonic);
break;
default: default:
break; break;
} }
@@ -39,18 +50,38 @@ Instructions* ParseTokens(Array* tokens) {
return NULL; return NULL;
} }
void ParserSync(Token* got, char* message) { void ParserSync(char* format, ...) {
char* str = TokenStringify(got); va_list args;
fprintf(stderr, "[Line %d] %s but got %s.\n", got->LineNumber, message, str); va_start (args, format);
free(str); vfprintf(stderr, format, args);
va_end (args);
ParserIgnoreLine(); ParserIgnoreLine();
longjmp(ParserSyncPointBuffer, 0); longjmp(ParserSyncPointBuffer, 0);
} }
void ParserSyncExpect(TokenType expected, TokenType found) {
char expectedName[32] = { 0 };
char foundName[32] = { 0 };
TokenTypeStringify(expected, expectedName);
TokenTypeStringify(found, foundName);
Token* current = ParserPeek();
ParserSync("[Line %d] Expected %s but got %s\n", current->LineNumber, expectedName, foundName);
}
void ParserSyncMessage(char* message) {
Token* current = ParserPeek();
ParserSync("[Line %d] %s\n", current->LineNumber, message);
}
void ParserHandleKeyword(Keywords keyword) { void ParserHandleKeyword(Keywords keyword) {
Token* namespace = NULL; Token* namespace = NULL;
@@ -67,13 +98,66 @@ void ParserHandleKeyword(Keywords keyword) {
} }
} }
void ParserHandleMnemonic(Mnemonics mnemonic) {
Instruction* inst = ParserCreateInstruction();
inst->Inst.Opcode = mnemonic;
inst->IsOpcode = true;
switch(mnemonic) {
case ADD:
inst->ParameterCount = 2;
ParserExpectParameter(inst);
break;
default:
break;
}
}
void ParserExpectParameter(Instruction* inst) {
if (ParserAtEnd()) return;
bool isPointer = ParserWant(OpenBracket) != NULL;
Token* token = ParserAdvance();
if (token->Type == Number) {
inst->Parameters[0].Type = Number;
inst->Parameters[0].Value.Number = token->Value.Number;
}
else if (token->Type == Symbol) {
inst->Parameters[0].Type = Symbol;
inst->Parameters[0].Value.Name = token->Value.String;
}
else if (token->Type == Register) {
inst->Parameters[0].Type = Register;
inst->Parameters[0].Value.Register = token->Value.Register;
}
else ParserSyncMessage("No valid parameter found.");
if (inst->ParameterCount == 1) return;
if (token->Type == Symbol) {
inst->Parameters[1].Type = Symbol;
inst->Parameters[1].Value.Name = token->Value.String;
}
if (token->Type == Register) {
inst->Parameters[1].Type = Register;
inst->Parameters[1].Value.Register = token->Value.Register;
}
else ParserSyncMessage("No valid parameter found.");
}
Token* ParserExpect(TokenType type) { Token* ParserExpect(TokenType type) {
if (ParserAtEnd()) return NULL; if (ParserAtEnd()) return NULL;
Token* token = ParserAdvance(); Token* token = ParserAdvance();
if (token->Type != type) { if (token->Type != type) {
ParserSyncExpect(type, token->Type);
} }
return token; return token;
@@ -95,7 +179,7 @@ void ParserExpectLineEnd(void) {
Token* token = ParserAdvance(); Token* token = ParserAdvance();
if (token->Type != LineEnd && token->Type != FileEnd) { if (token->Type != LineEnd && token->Type != FileEnd) {
ParserSync(token, "Expected end of line or file"); ParserSyncMessage("Expected end of line or file.");
} }
return; return;
@@ -120,6 +204,16 @@ Token* ParserAdvance() {
return next; return next;
} }
Token* ParserPeek(void) {
if (ParserAtEnd()) return (Token*) ArrayPeek(Tokens);
return (Token*) ArrayIndex(Tokens, ParserIndex);
}
bool ParserAtEnd() { bool ParserAtEnd() {
return ParserIndex >= Tokens->Size; return ParserIndex >= Tokens->Size;
}
Instruction* ParserCreateInstruction(void) {
return calloc(1, sizeof(Instruction));
} }
+31
View File
@@ -83,4 +83,35 @@ char* TokenStringify(const struct _token* token) {
if (strlen(buffer) > 0) strncpy(str, buffer, sizeof(buffer) - 1); if (strlen(buffer) > 0) strncpy(str, buffer, sizeof(buffer) - 1);
return str; return str;
}
void TokenTypeStringify(TokenType type, char buffer[32]) {
if (!buffer) return;
memset(buffer, '\0', 32);
switch(type) {
case Empty:
strcpy(buffer, "Empty");
break;
case String:
strcpy(buffer, "String");
break;
case Number:
strcpy(buffer, "Number");
break;
case Symbol:
strcpy(buffer, "Symbol");
break;
case LineEnd:
strcpy(buffer, "LineEnd");
break;
case FileEnd:
strcpy(buffer, "FileEnd");
break;
default:
snprintf(buffer, 32, "%c", type);
break;
}
} }
+20 -4
View File
@@ -3,11 +3,14 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
#include <stdbool.h> #include <stdbool.h>
#include <setjmp.h>
#define MAXWORDLENGTH 1024 #define MAXWORDLENGTH 1024
static Array* Tokens; static Array* Tokens;
jmp_buf TokenizerSyncPointBuffer;
const char* SourceCode; const char* SourceCode;
size_t SourceCodeLength = 0; size_t SourceCodeLength = 0;
size_t SourceCodeIndex = 0; size_t SourceCodeIndex = 0;
@@ -25,6 +28,7 @@ void TokenizerExpectWord(void);
void TokenizerExpectString(void); void TokenizerExpectString(void);
void TokenizerExpectNumber(void); void TokenizerExpectNumber(void);
void TokenizerIgnoreLine(); void TokenizerIgnoreLine();
void TokenizerSync(char* message);
Array* Tokenize(const char* sourceCode) { Array* Tokenize(const char* sourceCode) {
Tokens = ArrayCreate(); Tokens = ArrayCreate();
@@ -32,6 +36,8 @@ Array* Tokenize(const char* sourceCode) {
SourceCodeLength = strlen(sourceCode); SourceCodeLength = strlen(sourceCode);
SourceCode = sourceCode; SourceCode = sourceCode;
(void) setjmp(TokenizerSyncPointBuffer);
while(!TokenizerAtEnd()) { while(!TokenizerAtEnd()) {
char c = PeekTokenizer(); char c = PeekTokenizer();
@@ -102,7 +108,6 @@ Array* Tokenize(const char* sourceCode) {
case ')': case ')':
case '[': case '[':
case ']': case ']':
//case ':':
case ',': case ',':
token = TokenCreate((TokenType)c, SourceLineNumber, SourceColumnNumber, true); token = TokenCreate((TokenType)c, SourceLineNumber, SourceColumnNumber, true);
@@ -122,6 +127,14 @@ Array* Tokenize(const char* sourceCode) {
return Tokens; return Tokens;
} }
void TokenizerSync(char* message) {
fprintf(stderr, "[Line %d] %s\n", SourceLineNumber, message);
TokenizerIgnoreLine();
longjmp(TokenizerSyncPointBuffer, 0);
}
void TokenizerExpectNumber(void) { void TokenizerExpectNumber(void) {
char word[256] = { 0 }; char word[256] = { 0 };
int wordLength = 0; int wordLength = 0;
@@ -151,7 +164,8 @@ void TokenizerExpectNumber(void) {
break; break;
} }
if (wordLength == 255) break; //Sync, error etc here at some point. if (wordLength == 255)
TokenizerSync("Number exceeded the maximum character length.");
word[wordLength] = c; word[wordLength] = c;
wordLength++; wordLength++;
@@ -196,7 +210,8 @@ void TokenizerExpectWord() {
break; break;
} }
if (wordLength == 255) break; //Sync, error etc here at some point. if (wordLength == 255)
TokenizerSync("Word exceeded the maximum character length.");
word[wordLength] = c; word[wordLength] = c;
wordLength++; wordLength++;
@@ -267,7 +282,8 @@ void TokenizerExpectString(void) {
if (c != '\\') AdvanceTokenizer(); if (c != '\\') AdvanceTokenizer();
} }
if (wordLength == 255) break; //Sync, error etc here at some point. if (wordLength == 255)
TokenizerSync("String exceeded the maximum character length.");
word[wordLength] = c; word[wordLength] = c;
wordLength++; wordLength++;