diff --git a/Makefile b/Makefile index d50b88b..e7441f9 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC = gcc -CFLAGS=-g -Wall -DDEBUG +CFLAGS=-g -Wall -DDEBUG -Wpedantic SRCDIR=src OBJDIR=obj SRCS=$(wildcard $(SRCDIR)/*.c) @@ -11,7 +11,7 @@ BIN=$(BINDIR)/clox all: $(BIN) -release: CFLAGS=-Wall -O2 +release: CFLAGS=-Wall -Wpedantic -O2 release: clean release: $(BIN) diff --git a/src/lox.c b/src/lox.c index b63d491..78c8732 100644 --- a/src/lox.c +++ b/src/lox.c @@ -13,6 +13,10 @@ void RunPrompt(void); char* GetFileContents(const char*); int main(int argc, char** argv) { + #ifdef DEBUG + printf("Debug clox build.\n"); + #endif + if (argc > 2) { printf("Useage: clox [script]\n"); exit(EX_USAGE); @@ -40,13 +44,15 @@ void RunFile(const char* path) { TokenList* tokens = ScanTokens(contents); free(contents); printf("TOKENS:\n"); - Print(tokens); + //Print(tokens); printf("EXPRESSION TREE:\n"); - Expr* tree = GenerateExpressionTree(tokens); - PrintExpressionTree(tree); + //Expr* tree = GenerateExpressionTree(tokens); + StatementList* statements = Parse(tokens); + //PrintExpressionTree(tree); printf("\n"); Interpret(tree); - FreeExpressionTree(tree); + FreeStatementList(statements); + //FreeExpressionTree(tree); DestroyTokenList(tokens); } diff --git a/src/parser.c b/src/parser.c index 10093ae..c8f0ec7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -3,6 +3,8 @@ #include "statement.h" #include "token.h" #include +#include +#include Expr* Expression(void); Expr* Equality(void); @@ -14,6 +16,8 @@ Expr* Primary(void); Stmt* Statement(void); Stmt* PrintStatement(void); Stmt* ExpressionStatement(void); +StatementList* CreateStatementList(void); +int AddStatementToList(Stmt*, StatementList*); int Match(int, ...); int Check(TokenType); int ParserAtEnd(void); @@ -21,14 +25,29 @@ Token* ParserPeek(void); Token* Previous(void); Token* AdvanceParser(void); void SynchronizeParser(void); +void FreeExpressionTree(Expr*); const TokenList* ListOfTokens; int Current = 0; -Expr* GenerateExpressionTree(const TokenList* list) { +StatementList* Parse(const TokenList* list) { ListOfTokens = list; + StatementList* statements = CreateStatementList(); + Stmt* statement = NULL; - return Expression(); + if (!statements) return NULL; + + while(!ParserAtEnd()) { + statement = Statement(); + if (!statement) { + fprintf(stderr, "[Warn] No statement generated\n"); + continue; + } + + AddStatementToList(statement, statements); + } + + return statements; } //Simply expands the equality rule @@ -285,4 +304,55 @@ void FreeExpressionTree(Expr* tree) { } free(tree); +} + +void FreeStatementList(StatementList* list) { + if (!list) return; + + for(int i = 0; i < list->size; i++) { + FreeExpressionTree(list->content[i]->expression); + free(list->content[i]); + } + + free(list); +} + +StatementList* CreateStatementList(void) { + StatementList* list = calloc(1, sizeof(StatementList)); + + if (!list) { + fprintf(stderr, "Failed to calloc StatementList. %s\n", strerror(errno)); + return NULL; + } + + list->content = calloc(STATEMENTLIST_DEFAULT_SIZE, sizeof(Stmt)); + + if (!list->content) { + fprintf(stderr, "Failed to calloc StatementList contents. %s\n", strerror(errno)); + free(list); + return NULL; + } + + return list; +} + +int AddStatementToList(Stmt* statement, StatementList* list) { + if (!statement || !list) return 0; + + if (list->size == list->capacity) { + void* new_ptr = realloc(list->content, sizeof(Stmt) * list->capacity * 2); + + if (!new_ptr) { + fprintf(stderr, "Failed to realloc StatmentList to size %d. %s\n", list->capacity * 2, strerror(errno)); + return 0; + } + + list->content = new_ptr; + list->capacity *= 2; + } + + list->content[list->size] = statement; + list->size++; + + return 1; } \ No newline at end of file diff --git a/src/parser.h b/src/parser.h index d66e67b..4b22506 100644 --- a/src/parser.h +++ b/src/parser.h @@ -9,8 +9,16 @@ #include #include -Expr* GenerateExpressionTree(const TokenList* list); +#define STATEMENTLIST_DEFAULT_SIZE 32 + +typedef struct { + Stmt** content; + int size; + int capacity; +} StatementList; + +StatementList* Parse(const TokenList*); void PrintExpressionTree(const Expr*); -void FreeExpressionTree(Expr*); +void FreeStatementList(StatementList*); #endif \ No newline at end of file