123 lines
2.5 KiB
C
123 lines
2.5 KiB
C
#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;
|
|
} |