3 Commits
6 changed files with 182 additions and 13 deletions
+2 -2
View File
@@ -1,5 +1,5 @@
CC = gcc CC = gcc
CFLAGS=-g -Wall -DDEBUG CFLAGS=-g -Wall -DDEBUG -Wpedantic
SRCDIR=src SRCDIR=src
OBJDIR=obj OBJDIR=obj
SRCS=$(wildcard $(SRCDIR)/*.c) SRCS=$(wildcard $(SRCDIR)/*.c)
@@ -11,7 +11,7 @@ BIN=$(BINDIR)/clox
all: $(BIN) all: $(BIN)
release: CFLAGS=-Wall -O2 release: CFLAGS=-Wall -Wpedantic -O2
release: clean release: clean
release: $(BIN) release: $(BIN)
+13 -6
View File
@@ -13,6 +13,10 @@ void RunPrompt(void);
char* GetFileContents(const char*); char* GetFileContents(const char*);
int main(int argc, char** argv) { int main(int argc, char** argv) {
#ifdef DEBUG
printf("Debug clox build.\n");
#endif
if (argc > 2) { if (argc > 2) {
printf("Useage: clox [script]\n"); printf("Useage: clox [script]\n");
exit(EX_USAGE); exit(EX_USAGE);
@@ -39,13 +43,16 @@ void RunFile(const char* path) {
char* contents = GetFileContents(path); char* contents = GetFileContents(path);
TokenList* tokens = ScanTokens(contents); TokenList* tokens = ScanTokens(contents);
free(contents); free(contents);
Print(tokens); printf("TOKENS:\n");
printf("TREE:\n"); //Print(tokens);
Expr* tree = GenerateExpressionTree(tokens); printf("EXPRESSION TREE:\n");
PrintExpressionTree(tree); //Expr* tree = GenerateExpressionTree(tokens);
StatementList* statements = Parse(tokens);
//PrintExpressionTree(tree);
printf("\n"); printf("\n");
Interpret(tree); //Interpret(tree);
FreeExpressionTree(tree); FreeStatementList(statements);
//FreeExpressionTree(tree);
DestroyTokenList(tokens); DestroyTokenList(tokens);
} }
+113 -3
View File
@@ -1,7 +1,10 @@
#include "parser.h" #include "parser.h"
#include "expr.h" #include "expr.h"
#include "statement.h"
#include "token.h" #include "token.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
Expr* Expression(void); Expr* Expression(void);
Expr* Equality(void); Expr* Equality(void);
@@ -10,6 +13,11 @@ Expr* Term(void);
Expr* Factor(void); Expr* Factor(void);
Expr* Unary(void); Expr* Unary(void);
Expr* Primary(void); Expr* Primary(void);
Stmt* Statement(void);
Stmt* PrintStatement(void);
Stmt* ExpressionStatement(void);
StatementList* CreateStatementList(void);
int AddStatementToList(Stmt*, StatementList*);
int Match(int, ...); int Match(int, ...);
int Check(TokenType); int Check(TokenType);
int ParserAtEnd(void); int ParserAtEnd(void);
@@ -17,14 +25,29 @@ Token* ParserPeek(void);
Token* Previous(void); Token* Previous(void);
Token* AdvanceParser(void); Token* AdvanceParser(void);
void SynchronizeParser(void); void SynchronizeParser(void);
void FreeExpressionTree(Expr*);
const TokenList* ListOfTokens; const TokenList* ListOfTokens;
int Current = 0; int Current = 0;
Expr* GenerateExpressionTree(const TokenList* list) { StatementList* Parse(const TokenList* list) {
ListOfTokens = 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 //Simply expands the equality rule
@@ -32,6 +55,40 @@ Expr* Expression() {
return Equality(); return Equality();
} }
Stmt* Statement(void) {
if (Match(1, PRINT)) return PrintStatement();
return ExpressionStatement();
}
Stmt* PrintStatement(void) {
Expr* value = Expression();
if (!Match(1, Semicolon)) {
fprintf(stderr, "Expected ';' after value\n");
return NULL;
}
AdvanceParser();
return CreateStatement(value, STMT_Print);
}
Stmt* ExpressionStatement(void) {
Expr* expr = Expression();
if (!Match(1, Semicolon)) {
fprintf(stderr, "Expected ';' after expression\n");
return NULL;
}
AdvanceParser();
return CreateStatement(expr, STMT_Expression);
}
Stmt* ExpressionStatement(void);
Expr* Equality() { Expr* Equality() {
Expr* expr = Comparison(); Expr* expr = Comparison();
@@ -146,7 +203,7 @@ Expr* Primary() {
return temp; return temp;
} }
printf("Bad expression\n"); fprintf(stderr, "Bad expression, this should be unreachable.\n");
return NULL; return NULL;
} }
@@ -253,4 +310,57 @@ void FreeExpressionTree(Expr* tree) {
} }
free(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;
}
list->capacity = STATEMENTLIST_DEFAULT_SIZE;
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;
} }
+11 -2
View File
@@ -4,12 +4,21 @@
#include "expr.h" #include "expr.h"
#include "scanner.h" #include "scanner.h"
#include "token.h" #include "token.h"
#include "statement.h"
#include <stdarg.h> #include <stdarg.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
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 PrintExpressionTree(const Expr*);
void FreeExpressionTree(Expr*); void FreeStatementList(StatementList*);
#endif #endif
+21
View File
@@ -0,0 +1,21 @@
#include "statement.h"
Stmt* CreateStatement(Expr* expression, StatementType type) {
Stmt* stmt = calloc(1, sizeof(Stmt));
if (!stmt) {
fprintf(stderr, "Failed to calloc space for Statement. %s.\n", strerror(errno));
return NULL;
}
stmt->expression = expression;
stmt->type = type;
return stmt;
}
void FreeStatement(Stmt* stmt) {
if (!stmt) return;
free(stmt);
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef STATEMENT_H
#define STATEMENT_H
#include "expr.h"
#include <stdlib.h>
#include <string.h>
#include <errno.h>
typedef enum {
STMT_Expression,
STMT_Print
} StatementType;
typedef struct stmt {
StatementType type;
Expr* expression;
} Stmt;
Stmt* CreateStatement(Expr*, StatementType);
void FreeStatement(Stmt*);
#endif