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:
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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++;
|
||||||
|
|||||||
Reference in New Issue
Block a user