Refactored the scanner and updated the Token struct to store the length of its lexeme to avoid malloc()ing new strings for every token.
This commit is contained in:
@@ -1,3 +1,4 @@
|
||||
#include "scanner.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sysexits.h>
|
||||
@@ -19,10 +20,26 @@ int main(int argc, char** argv) {
|
||||
}
|
||||
}
|
||||
|
||||
void Print(TokenList* list) {
|
||||
char lexeme[100];
|
||||
|
||||
for(int i = 0; i < list->size; i++) {
|
||||
printf("[Line %d] ", list->tokens[i]->line);
|
||||
for(int j = 0; j < list->tokens[i]->length; j++) {
|
||||
printf("%c", list->tokens[i]->lexeme[j]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
void RunFile(const char* path) {
|
||||
printf("Running '%s'\n", path);
|
||||
char* contents = GetFileContents(path);
|
||||
//Tokenize(contents);
|
||||
TokenList* tokens = ScanTokens(contents);
|
||||
Print(tokens);
|
||||
|
||||
DestroyTokenList(tokens);
|
||||
free(contents);
|
||||
}
|
||||
|
||||
char* GetFileContents(const char* path) {
|
||||
|
||||
@@ -10,9 +10,9 @@ int current; //points to the character currently being considered.
|
||||
int length;
|
||||
int line = 1;
|
||||
|
||||
char Advance(void);
|
||||
const char* Advance(void);
|
||||
int IsAtend(void);
|
||||
void ScanToken(void);
|
||||
void ScanToken(TokenList*);
|
||||
TokenList* CreateList(void);
|
||||
|
||||
TokenList* ScanTokens(const char* source) {
|
||||
@@ -23,12 +23,15 @@ TokenList* ScanTokens(const char* source) {
|
||||
|
||||
if (length == 0) return NULL;
|
||||
|
||||
TokenList* tokens = CreateList();
|
||||
|
||||
while(!IsAtend()) {
|
||||
start = current;
|
||||
ScanToken();
|
||||
ScanToken(tokens);
|
||||
}
|
||||
|
||||
//Add EOF token and return list once that's set up.
|
||||
return tokens;
|
||||
}
|
||||
|
||||
TokenList* CreateList() {
|
||||
@@ -57,7 +60,7 @@ void DestroyTokenList(TokenList* list) {
|
||||
if (!list) return;
|
||||
|
||||
for(int i = 0; i < list->size; i++) {
|
||||
free(list->tokens[i]->lexeme);
|
||||
//free(list->tokens[i]->lexeme); This shouldn't be needed since the lexeme is a pointer into the source code.
|
||||
free(list->tokens[i]);
|
||||
}
|
||||
|
||||
@@ -65,7 +68,7 @@ void DestroyTokenList(TokenList* list) {
|
||||
free(list);
|
||||
}
|
||||
|
||||
int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) {
|
||||
int AddTokenToList(TokenType type, const char* lexeme, int length, TokenList* tokens) {
|
||||
if (!tokens) return 0;
|
||||
Token* token = calloc(1, sizeof(Token));
|
||||
|
||||
@@ -76,6 +79,7 @@ int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) {
|
||||
|
||||
token->lexeme = lexeme;
|
||||
token->type = type;
|
||||
token->length = length; //Set the length of the lexeme (which is just a pointer into the complete soure listing).
|
||||
|
||||
if ((tokens->size + 1) > tokens->capacity) {
|
||||
void* new_ptr = realloc(tokens->tokens, sizeof(Token*) * tokens->capacity * 2);//calloc(tokens->capacity * 2, sizeof(Token*));
|
||||
@@ -95,28 +99,47 @@ int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ScanToken() {
|
||||
char c = Advance();
|
||||
void ScanToken(TokenList* tokens) {
|
||||
const char* c = Advance();
|
||||
|
||||
switch (c) {
|
||||
switch (*c) {
|
||||
case '(':
|
||||
AddTokenToList(LParen, c, 1, tokens);
|
||||
break;
|
||||
case ')':
|
||||
AddTokenToList(RParen, c, 1, tokens);
|
||||
break;
|
||||
case '{':
|
||||
AddTokenToList(LBrace, c, 1, tokens);
|
||||
break;
|
||||
case '}':
|
||||
AddTokenToList(RBrace, c, 1, tokens);
|
||||
break;
|
||||
case ',':
|
||||
AddTokenToList(Comma, c, 1, tokens);
|
||||
break;
|
||||
case '.':
|
||||
AddTokenToList(Dot, c, 1, tokens);
|
||||
break;
|
||||
case '-':
|
||||
AddTokenToList(Minus, c, 1, tokens);
|
||||
break;
|
||||
case '+':
|
||||
AddTokenToList(Plus, c, 1, tokens);
|
||||
break;
|
||||
case ';':
|
||||
AddTokenToList(Semicolon, c, 1, tokens);
|
||||
break;
|
||||
case '*':
|
||||
break;
|
||||
AddTokenToList(Star, c, 1, tokens);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int IsAtEnd() {
|
||||
int IsAtend() {
|
||||
return current >= length;
|
||||
}
|
||||
|
||||
char Advance() {
|
||||
return source_code[current++];
|
||||
const char* Advance() {
|
||||
return &source_code[current++];
|
||||
}
|
||||
Reference in New Issue
Block a user