Cleaned up the TokenStringify function and started toying with ways to handle syncing in the parser.
This commit is contained in:
+1
-1
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 '*':
|
||||||
|
|||||||
Reference in New Issue
Block a user