diff --git a/includes/lexer.h b/includes/lexer.h index 1257e96..81f7af2 100644 --- a/includes/lexer.h +++ b/includes/lexer.h @@ -7,34 +7,7 @@ #include #include "list.h" #include "tokenizer.h" - -typedef enum { - PLUS, - MINUS, - STAR, - SLASH, - POWER, - LPARAM, - RPARAM, - LBRACKET, - RBracket, - COMMA, - IDENTIFIER, - NUMBER, - HEX, - //Keywords - DB, ORG, - //Opcodes - COPY, ADD, SUB, JZ, INT, YLD, RET, - CMP, IN, OUT, - //Registers - R1, R2, R3, R4, R5, R6, R7, R8 -} TokenType; - -typedef struct { - TokenType type; - char* value; -} Token; +#include "token.h" List* GetTokensFromLine(char*); diff --git a/includes/scanner.h b/includes/scanner.h index cbf697f..086b16e 100644 --- a/includes/scanner.h +++ b/includes/scanner.h @@ -3,9 +3,11 @@ #include #include +#include #include "stdlib.h" #include "token.h" #include "list.h" +#include "opcodes.h" List* GenerateTokenList(const char*); diff --git a/src/lexer.c b/src/lexer.c index 1502533..dca4b04 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -4,7 +4,6 @@ #include #include -Token* CreateToken(TokenType, char*); Token* GetNextToken(char *); int TokenIsNumeric(const char*, int *); @@ -74,17 +73,6 @@ Token* GetNextToken(char *string) { return NULL; } -Token* CreateToken(TokenType type, char* value) { - Token* token = calloc(1, sizeof(Token)); - - if (!token) return NULL; - - token->type = type; - token->value = value; - - return token; -} - int TokenIsNumeric(const char* token, int *base) { *base = 0; diff --git a/src/main.c b/src/main.c index 370cc5d..7114b94 100644 --- a/src/main.c +++ b/src/main.c @@ -6,6 +6,7 @@ #include "../includes/lexer.h" #include "../includes/parser.h" #include "../includes/futil.h" +#include "../includes/scanner.h" List* get_strings(const char*); @@ -20,30 +21,12 @@ int main(int argc, char* args[]) { if (!ReadAllString(args[1], &source_code, &bytes_read)) return EX_IOERR; - char* token = strtok(source_code, "\n"); - int line_number = 1; + List* list = GenerateTokenList(source_code); - while(token != NULL) { + for(int i = 0; i < list->size; i++) { + Token* t = (Token*) list->content[i]; - List* tokens = GetTokensFromLine(token); - - if (line_number == 1 || line_number == 2) { - ParseTokens(tokens); - } - - for (int i = 0; i < tokens->size; i++) { - Token* t = (Token*) tokens->content[i]; - - printf("Token Type: '%d' Value: '%s' (%d)\n", t->type, t->value, line_number); - - if (t->type <= ORG) free(t->value); - } - - DestroyList(tokens); - - token = strtok(NULL, "\n"); - - line_number++; + printf("[%i] '%s'\n", t->type, t->value); } free(source_code); diff --git a/src/scanner.c b/src/scanner.c index b9349ad..48d85d9 100644 --- a/src/scanner.c +++ b/src/scanner.c @@ -1,9 +1,11 @@ #include "../includes/scanner.h" +#include #include #include #include const char* SourceCode; +int Line = 0; int Position = 0; int SourceLength = 0; int ScannerAtEnd(void); @@ -12,6 +14,8 @@ char AdvanceScanner(void); Token* ParseString(void); Token* ParseDirective(void); Token* ParseIdentifier(void); +Token* ParseNumber(void); +void IgnoreLine(void); List* GenerateTokenList(const char* source) { List* tokens = CreateList(); @@ -23,15 +27,20 @@ List* GenerateTokenList(const char* source) { SourceLength = strlen(source); for(int i = 0; i < SourceLength; i++) { - char c = AdvanceScanner(); + char c = PeekScanner(); + switch(c) { case ' ': case '\r': case '\t': + AdvanceScanner(); break; //Ignore whitespace + case '\n': + AdvanceScanner(); + Line++; + break; case ';': - while(!ScannerAtEnd() && PeekScanner() != '\n') AdvanceScanner(); - + IgnoreLine(); break; case '.': //directive like ".org" or ".db" token = ParseDirective(); @@ -42,15 +51,15 @@ List* GenerateTokenList(const char* source) { if (token) AddListItem(token, sizeof(Token), tokens); break; case ',': + AdvanceScanner(); AddListItem(CreateToken(COMMA, ","), sizeof(Token), tokens); break; default: - // if (c >= '0' && c <= '9') { - // //Number - - // break; - // } + if (c >= '0' && c <= '9') { + ParseNumber(); + break; + } token = ParseIdentifier(); if (token) AddListItem(token, sizeof(Token), tokens); @@ -64,31 +73,66 @@ List* GenerateTokenList(const char* source) { return tokens; } -Token* ParseDirective(void) { - char directive[10] = { 0 }; - int length = 0; +Token* ParseNumber(void) { + int start = Position; - for(; length < sizeof directive - 1; length++) { - if (PeekScanner() == ' ') break; + while(!ScannerAtEnd() && PeekScanner() >= '0' && PeekScanner() <= '9') + AdvanceScanner(); - directive[length] = AdvanceScanner(); - } + char* lexeme = calloc(Position - start + 1, sizeof(char)); - 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"); + if (!lexeme) { + fprintf(stderr, "Failed to calloc space for number.\n"); return NULL; } - fprintf(stderr, "[Error] Unknown assembler directive '%s'\n", directive); - //Ignore the line - while(PeekScanner() != '\n') AdvanceScanner(); + memcpy(lexeme, &SourceCode[start], Position - start); + return CreateToken(NUMBER, lexeme); +} + +Token* ParseDirective(void) { + int start = Position; + + while(!ScannerAtEnd() && PeekScanner() != ' ' && PeekScanner() != '\n') AdvanceScanner(); + + if (start == Position) return NULL; + + char* directive = calloc(Position - start + 1, sizeof(char)); + + if (!directive) { + fprintf(stderr, "Failed to calloc for the assmebler directive.\n"); + return NULL; + } + + memcpy(directive, &SourceCode[start], Position - start); + + if (strcmp(directive, ".db") == 0) { + return CreateToken(DB, directive); + } + // else if (strcmp(directive, ".org") == 0) { + // fprintf(stderr, "[Warning] Org is not a supported directive.\n"); + // IgnoreLine(); + // return NULL; + // } + + fprintf(stderr, "[Error] Unknown assembler directive '%s'\n", directive); + + free(directive); + + //Ignore the line + IgnoreLine(); + return NULL; } +void IgnoreLine(void) { + while(!ScannerAtEnd() && PeekScanner() != '\n') AdvanceScanner(); +} + Token* ParseString(void) { + AdvanceScanner(); //Consume the first double quote. + int start = Position; while(!ScannerAtEnd() && PeekScanner() != '"') { @@ -96,9 +140,9 @@ Token* ParseString(void) { } char* lexeme = calloc(Position - start, sizeof(char)); - memccpy(lexeme, &SourceCode[start], sizeof(char), Position - start); + memcpy(lexeme, &SourceCode[start], Position - start); - AdvanceScanner(); + AdvanceScanner(); //Consume the trailing double quote. Token* token = CreateToken(STRING, lexeme); @@ -108,20 +152,24 @@ Token* ParseString(void) { Token* ParseIdentifier(void) { int start = Position; - while(!ScannerAtEnd() && PeekScanner() != ' ' && PeekScanner() != '\n') { + while(!ScannerAtEnd() && PeekScanner() != ',' && 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); + TokenType type; + memcpy(lexeme, &SourceCode[start], Position - start); + + if (IsOpcode(lexeme, &type)) return CreateToken(type, lexeme); + if (IsRegister(lexeme, &type)) return CreateToken(type, lexeme); return CreateToken(IDENTIFIER, lexeme); } char PeekScanner(void) { - if (Position > SourceLength) return '\0'; + if (Position >= SourceLength) return '\0'; return SourceCode[Position]; }