Lots of changes and too much dragging my feet on this. But I think this is going in the right direction now.
This commit is contained in:
+123
@@ -0,0 +1,123 @@
|
||||
#include "../includes/parser.h"
|
||||
|
||||
#define KEYWORD_COUNT 7
|
||||
|
||||
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;
|
||||
|
||||
Token* ParserAdvance(void);
|
||||
void ParserIgnoreLine(void);
|
||||
bool ParserAtEnd(void);
|
||||
Parameter* ParserExpectParameter(void);
|
||||
void ParserHandleKeyword(Keywords keyword);
|
||||
Token* ParserExpect(TokenType type);
|
||||
Token* ParserWant(TokenType type);
|
||||
void ParserExpectLineEnd(void);
|
||||
|
||||
Instructions* ParseTokens(Array* tokens) {
|
||||
Tokens = tokens;
|
||||
Keywords keyword;
|
||||
|
||||
while(!ParserAtEnd()) {
|
||||
Token* token = ParserAdvance();
|
||||
|
||||
switch(token->Type) {
|
||||
case Keyword:
|
||||
ParserHandleKeyword(token->Value.Keyword);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ParserHandleKeyword(Keywords keyword) {
|
||||
Token* namespace = NULL;
|
||||
|
||||
switch(keyword) {
|
||||
case NAMESPACE:
|
||||
namespace = ParserExpect(Symbol);
|
||||
|
||||
ParserExpectLineEnd();
|
||||
|
||||
printf("Namespace `%s` seen\n", namespace->Value.String);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Token* ParserExpect(TokenType type) {
|
||||
if (ParserAtEnd()) return NULL;
|
||||
|
||||
Token* token = ParserAdvance();
|
||||
|
||||
if (!token || token->Type != type) return NULL;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
Token* ParserWant(TokenType type) {
|
||||
if (ParserAtEnd()) return NULL;
|
||||
|
||||
Token* token = ParserAdvance();
|
||||
|
||||
if (!token || token->Type != type) return NULL;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
void ParserExpectLineEnd(void) {
|
||||
if (ParserAtEnd()) return;
|
||||
|
||||
Token* token = ParserAdvance();
|
||||
|
||||
if (token->Type != LineEnd && token->Type != FileEnd) {
|
||||
//Error / sync
|
||||
printf("Expected end of line on line %d.\n", token->LineNumber);
|
||||
|
||||
ParserIgnoreLine();
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void ParserIgnoreLine(void) {
|
||||
while(!ParserAtEnd()) {
|
||||
Token* token = ParserAdvance();
|
||||
|
||||
if (token->Type == LineEnd || token->Type == FileEnd)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Token* ParserAdvance() {
|
||||
if (ParserAtEnd()) return (Token*) ArrayPeek(Tokens);
|
||||
if (ParserIndex == Tokens->Size) return (Token*) ArrayPeek(Tokens);
|
||||
|
||||
Token* next = ArrayIndex(Tokens, ParserIndex);
|
||||
ParserIndex++;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
bool ParserAtEnd() {
|
||||
return ParserIndex >= Tokens->Size;
|
||||
}
|
||||
Reference in New Issue
Block a user