#include "../includes/scanner.h" #include #include #include const char* SourceCode; int Position = 0; int SourceLength = 0; int ScannerAtEnd(void); char PeekScanner(void); char AdvanceScanner(void); Token* ParseString(void); Token* ParseDirective(void); Token* ParseIdentifier(void); List* GenerateTokenList(const char* source) { List* tokens = CreateList(); Token* token = NULL; if (!tokens) return NULL; SourceCode = source; SourceLength = strlen(source); for(int i = 0; i < SourceLength; i++) { char c = AdvanceScanner(); switch(c) { case ' ': case '\r': case '\t': break; //Ignore whitespace case ';': while(!ScannerAtEnd() && PeekScanner() != '\n') AdvanceScanner(); break; case '.': //directive like ".org" or ".db" token = ParseDirective(); if (token) AddListItem(token, sizeof(Token), tokens); break; case '"': token = ParseString(); if (token) AddListItem(token, sizeof(Token), tokens); break; case ',': AddListItem(CreateToken(COMMA, ","), sizeof(Token), tokens); break; default: // if (c >= '0' && c <= '9') { // //Number // break; // } token = ParseIdentifier(); if (token) AddListItem(token, sizeof(Token), tokens); break; } token = NULL; } return tokens; } Token* ParseDirective(void) { char directive[10] = { 0 }; int length = 0; for(; length < sizeof directive - 1; length++) { if (PeekScanner() == ' ') break; directive[length] = AdvanceScanner(); } if (strcmp(directive, ".db") == 0) { return CreateToken(DB, ".db"); } else if (strcmp(directive, ".org") == 0) { //fprintf(stderr, "[Warning] Org is not a supported directive.\n"); return NULL; } fprintf(stderr, "[Error] Unknown assembler directive '%s'\n", directive); //Ignore the line while(PeekScanner() != '\n') AdvanceScanner(); return NULL; } Token* ParseString(void) { int start = Position; while(!ScannerAtEnd() && PeekScanner() != '"') { AdvanceScanner(); } char* lexeme = calloc(Position - start, sizeof(char)); memccpy(lexeme, &SourceCode[start], sizeof(char), Position - start); AdvanceScanner(); Token* token = CreateToken(STRING, lexeme); return token; } Token* ParseIdentifier(void) { int start = Position; while(!ScannerAtEnd() && PeekScanner() != ' ' && PeekScanner() != '\n') { AdvanceScanner(); } if (Position - start == 0) return NULL; char* lexeme = calloc(Position - start, sizeof(char)); memccpy(lexeme, &SourceCode[start], sizeof(char), Position - start); return CreateToken(IDENTIFIER, lexeme); } char PeekScanner(void) { if (Position > SourceLength) return '\0'; return SourceCode[Position]; } char AdvanceScanner(void) { if (ScannerAtEnd()) return '\0'; return SourceCode[Position++]; } int ScannerAtEnd(void) { return Position >= SourceLength; }