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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <sysexits.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) {
|
void RunFile(const char* path) {
|
||||||
printf("Running '%s'\n", path);
|
printf("Running '%s'\n", path);
|
||||||
char* contents = GetFileContents(path);
|
char* contents = GetFileContents(path);
|
||||||
//Tokenize(contents);
|
TokenList* tokens = ScanTokens(contents);
|
||||||
|
Print(tokens);
|
||||||
|
|
||||||
|
DestroyTokenList(tokens);
|
||||||
|
free(contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
char* GetFileContents(const char* path) {
|
char* GetFileContents(const char* path) {
|
||||||
|
|||||||
@@ -10,9 +10,9 @@ int current; //points to the character currently being considered.
|
|||||||
int length;
|
int length;
|
||||||
int line = 1;
|
int line = 1;
|
||||||
|
|
||||||
char Advance(void);
|
const char* Advance(void);
|
||||||
int IsAtend(void);
|
int IsAtend(void);
|
||||||
void ScanToken(void);
|
void ScanToken(TokenList*);
|
||||||
TokenList* CreateList(void);
|
TokenList* CreateList(void);
|
||||||
|
|
||||||
TokenList* ScanTokens(const char* source) {
|
TokenList* ScanTokens(const char* source) {
|
||||||
@@ -23,12 +23,15 @@ TokenList* ScanTokens(const char* source) {
|
|||||||
|
|
||||||
if (length == 0) return NULL;
|
if (length == 0) return NULL;
|
||||||
|
|
||||||
|
TokenList* tokens = CreateList();
|
||||||
|
|
||||||
while(!IsAtend()) {
|
while(!IsAtend()) {
|
||||||
start = current;
|
start = current;
|
||||||
ScanToken();
|
ScanToken(tokens);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Add EOF token and return list once that's set up.
|
//Add EOF token and return list once that's set up.
|
||||||
|
return tokens;
|
||||||
}
|
}
|
||||||
|
|
||||||
TokenList* CreateList() {
|
TokenList* CreateList() {
|
||||||
@@ -57,7 +60,7 @@ void DestroyTokenList(TokenList* list) {
|
|||||||
if (!list) return;
|
if (!list) return;
|
||||||
|
|
||||||
for(int i = 0; i < list->size; i++) {
|
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]);
|
free(list->tokens[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,7 +68,7 @@ void DestroyTokenList(TokenList* list) {
|
|||||||
free(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;
|
if (!tokens) return 0;
|
||||||
Token* token = calloc(1, sizeof(Token));
|
Token* token = calloc(1, sizeof(Token));
|
||||||
|
|
||||||
@@ -76,6 +79,7 @@ int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) {
|
|||||||
|
|
||||||
token->lexeme = lexeme;
|
token->lexeme = lexeme;
|
||||||
token->type = type;
|
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) {
|
if ((tokens->size + 1) > tokens->capacity) {
|
||||||
void* new_ptr = realloc(tokens->tokens, sizeof(Token*) * tokens->capacity * 2);//calloc(tokens->capacity * 2, sizeof(Token*));
|
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;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ScanToken() {
|
void ScanToken(TokenList* tokens) {
|
||||||
char c = Advance();
|
const char* c = Advance();
|
||||||
|
|
||||||
switch (c) {
|
switch (*c) {
|
||||||
case '(':
|
case '(':
|
||||||
|
AddTokenToList(LParen, c, 1, tokens);
|
||||||
|
break;
|
||||||
case ')':
|
case ')':
|
||||||
|
AddTokenToList(RParen, c, 1, tokens);
|
||||||
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
|
AddTokenToList(LBrace, c, 1, tokens);
|
||||||
|
break;
|
||||||
case '}':
|
case '}':
|
||||||
|
AddTokenToList(RBrace, c, 1, tokens);
|
||||||
|
break;
|
||||||
case ',':
|
case ',':
|
||||||
|
AddTokenToList(Comma, c, 1, tokens);
|
||||||
|
break;
|
||||||
case '.':
|
case '.':
|
||||||
|
AddTokenToList(Dot, c, 1, tokens);
|
||||||
|
break;
|
||||||
case '-':
|
case '-':
|
||||||
|
AddTokenToList(Minus, c, 1, tokens);
|
||||||
|
break;
|
||||||
case '+':
|
case '+':
|
||||||
|
AddTokenToList(Plus, c, 1, tokens);
|
||||||
|
break;
|
||||||
case ';':
|
case ';':
|
||||||
|
AddTokenToList(Semicolon, c, 1, tokens);
|
||||||
|
break;
|
||||||
case '*':
|
case '*':
|
||||||
|
AddTokenToList(Star, c, 1, tokens);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int IsAtEnd() {
|
int IsAtend() {
|
||||||
return current >= length;
|
return current >= length;
|
||||||
}
|
}
|
||||||
|
|
||||||
char Advance() {
|
const char* Advance() {
|
||||||
return source_code[current++];
|
return &source_code[current++];
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user