From 73067fcc1f70a990de9ec4df05d4a6e07ac6668e Mon Sep 17 00:00:00 2001 From: Garritt McCune Date: Wed, 23 Mar 2022 19:43:46 +0000 Subject: [PATCH] Added statements to the Parser, currently just the Print and Expression statements. 8.1 isn't quite done yet, maybe half way there. --- src/lox.c | 3 ++- src/parser.c | 34 +++++++++++++++++++++++++++++++++- src/parser.h | 1 + src/statement.c | 21 +++++++++++++++++++++ src/statement.h | 22 ++++++++++++++++++++++ 5 files changed, 79 insertions(+), 2 deletions(-) create mode 100644 src/statement.c create mode 100644 src/statement.h diff --git a/src/lox.c b/src/lox.c index d1cf93a..b63d491 100644 --- a/src/lox.c +++ b/src/lox.c @@ -39,8 +39,9 @@ void RunFile(const char* path) { char* contents = GetFileContents(path); TokenList* tokens = ScanTokens(contents); free(contents); + printf("TOKENS:\n"); Print(tokens); - printf("TREE:\n"); + printf("EXPRESSION TREE:\n"); Expr* tree = GenerateExpressionTree(tokens); PrintExpressionTree(tree); printf("\n"); diff --git a/src/parser.c b/src/parser.c index e8ffa69..10093ae 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,5 +1,6 @@ #include "parser.h" #include "expr.h" +#include "statement.h" #include "token.h" #include @@ -10,6 +11,9 @@ Expr* Term(void); Expr* Factor(void); Expr* Unary(void); Expr* Primary(void); +Stmt* Statement(void); +Stmt* PrintStatement(void); +Stmt* ExpressionStatement(void); int Match(int, ...); int Check(TokenType); int ParserAtEnd(void); @@ -32,6 +36,34 @@ Expr* Expression() { 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"); + + AdvanceParser(); + + return CreateStatement(value, STMT_Print); +} + +Stmt* ExpressionStatement(void) { + Expr* expr = Expression(); + + if (!Match(1, Semicolon)) fprintf(stderr, "Expected ';' after expression\n"); + + AdvanceParser(); + + return CreateStatement(expr, STMT_Expression); +} + +Stmt* ExpressionStatement(void); + Expr* Equality() { Expr* expr = Comparison(); @@ -146,7 +178,7 @@ Expr* Primary() { return temp; } - printf("Bad expression\n"); + fprintf(stderr, "Bad expression, this should be unreachable.\n"); return NULL; } diff --git a/src/parser.h b/src/parser.h index 9cb9d80..d66e67b 100644 --- a/src/parser.h +++ b/src/parser.h @@ -4,6 +4,7 @@ #include "expr.h" #include "scanner.h" #include "token.h" +#include "statement.h" #include #include #include diff --git a/src/statement.c b/src/statement.c new file mode 100644 index 0000000..92f3144 --- /dev/null +++ b/src/statement.c @@ -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); +} \ No newline at end of file diff --git a/src/statement.h b/src/statement.h new file mode 100644 index 0000000..bfcea8b --- /dev/null +++ b/src/statement.h @@ -0,0 +1,22 @@ +#ifndef STATEMENT_H +#define STATEMENT_H + +#include "expr.h" +#include +#include +#include + +typedef enum { + STMT_Expression, + STMT_Print +} StatementType; + +typedef struct stmt { + StatementType type; + Expr* expression; +} Stmt; + +Stmt* CreateStatement(Expr*, StatementType); +void FreeStatement(Stmt*); + +#endif \ No newline at end of file