From 19e9b8dfeee9ed4493ef7c53be089275c253929b Mon Sep 17 00:00:00 2001 From: ghostie Date: Sun, 13 Jul 2025 14:19:52 -0500 Subject: [PATCH] started to work in the ast --- src/model.c | 52 ++++++++---- src/model.h | 40 +++------ src/parser.c | 203 ++++++++++++++++++++++++++++++++++++++++++++- src/parser.h | 1 + src/utils/vector.c | 11 ++- src/utils/vector.h | 1 + tests/expr.pinky | 2 +- 7 files changed, 263 insertions(+), 47 deletions(-) diff --git a/src/model.c b/src/model.c index 013222d..f5c61d2 100644 --- a/src/model.c +++ b/src/model.c @@ -1,36 +1,58 @@ #include "model.h" -struct expression +#include + +struct expression * +alloc_expr () +{ + return (struct expression *)calloc (1, sizeof (struct expression)); +} + +struct expression * expression_create_integer (int value) { - return (struct expression){ .type = EXPR_INT, .integer = value }; + struct expression *expr = alloc_expr (); + expr->type = EXPR_INT; + expr->integer = value; + return expr; } -struct expression -expression_create_floating (int value) +struct expression * +expression_create_floating (float value) { - return (struct expression){ .type = EXPR_FLOAT, .floating = value }; + struct expression *expr = alloc_expr (); + expr->type = EXPR_FLOAT; + expr->floating = value; + return expr; } -struct expression +struct expression * expression_create_binop (struct token *op, struct expression *left, struct expression *right) { - return (struct expression){ .type = EXPR_BINOP, - .binop - = { .op = op, .left = left, .right = right } }; + struct expression *expr = alloc_expr (); + expr->type = EXPR_BINOP; + expr->binop.op = op; + expr->binop.left = left; + expr->binop.right = right; + return expr; } -struct expression +struct expression * expression_create_unop (struct token *op, struct expression *operand) { - return (struct expression){ .type = EXPR_UNOP, - .unop = { .op = op, .operand = operand } }; + struct expression *expr = alloc_expr (); + expr->type = EXPR_UNOP; + expr->unop.op = op; + expr->unop.operand = operand; + return expr; } -struct expression +struct expression * expression_create_grouping (struct expression *value) { - return (struct expression){ .type = EXPR_GROUP, - .grouping = { .value = value } }; + struct expression *expr = alloc_expr (); + expr->type = EXPR_GROUP; + expr->grouping.value = value; + return expr; } diff --git a/src/model.h b/src/model.h index 633a08c..6d97883 100644 --- a/src/model.h +++ b/src/model.h @@ -3,16 +3,15 @@ #include "token.h" -/******************************** - * Expression - ********************************/ enum expression_type { EXPR_INT, EXPR_FLOAT, EXPR_BINOP, EXPR_UNOP, - EXPR_GROUP + EXPR_GROUP, + + /* TODO: Statements */ }; struct expression @@ -48,31 +47,16 @@ struct expression struct expression *value; } grouping; }; -}; -struct expression expression_create_integer (int value); -struct expression expression_create_floating (int value); -struct expression expression_create_binop (struct token *op, - struct expression *left, - struct expression *right); -struct expression expression_create_unop (struct token *op, - struct expression *operand); -struct expression expression_create_grouping (struct expression *value); -/******************************** - * Statements - ********************************/ -struct stmt -{ - union - { - struct - { - } while_stmt; - - struct - { - } assignment; - }; + /* TODO: Statements */ }; +struct expression *expression_create_integer (int value); +struct expression *expression_create_floating (float value); +struct expression *expression_create_binop (struct token *op, + struct expression *left, + struct expression *right); +struct expression *expression_create_unop (struct token *op, + struct expression *operand); +struct expression *expression_create_grouping (struct expression *value); #endif diff --git a/src/parser.c b/src/parser.c index 286d1aa..6bacaa7 100644 --- a/src/parser.c +++ b/src/parser.c @@ -1,11 +1,168 @@ #include "parser.h" #include +#include + +#include "model.h" + +/* prototypes */ +struct expression *primary (struct parser *p); +struct expression *unary (struct parser *p); +struct expression *factor (struct parser *p); +struct expression *term (struct parser *p); +struct expression *expression (struct parser *p); + +/* util functions */ +/* static struct token * */ +/* advance (struct parser *p) */ +/* { */ +/* if (!p) */ +/* return NULL; */ + +/* if (p->curr >= vector_len (p->tokens)) */ +/* return NULL; */ + +/* struct token *tok = (struct token *)vector_at (p->curr, p->tokens); */ +/* p->curr++; */ +/* return tok; */ +/* } */ + +/* static struct token * */ +/* peek (struct parser *p) */ +/* { */ +/* if (!p) */ +/* return NULL; */ + +/* return (struct token *)vector_at (p->curr, p->tokens); */ +/* } */ + +/* static _Bool */ +/* expect (enum token_type type, struct parser *p) */ +/* { */ +/* if (!p) */ +/* return 0; */ + +/* struct token *tok = (struct token *)vector_at (p->curr, p->tokens); */ +/* return tok->type == type; */ +/* } */ + +static struct token * +prev_tok (struct parser *p) +{ + if (!p) + return NULL; + + if (p->curr <= 0) + return NULL; + + return (struct token *)vector_at (p->curr - 1, p->tokens); +} + +static struct token * +match (enum token_type type, struct parser *p) +{ + if (!p) + return NULL; + + struct token *tok = (struct token *)vector_at (p->curr, p->tokens); + if (!tok || tok->type != type) + return NULL; + + p->curr++; + return tok; +} + +/* recursively descending functions */ +struct expression * +primary (struct parser *p) +{ + if (!p) + return NULL; + + struct token *tok = NULL; + if ((tok = match (TOK_INTEGER, p))) + return expression_create_integer (atoi (buffer_get (&tok->lexeme))); + if ((tok = match (TOK_FLOAT, p))) + return expression_create_floating (atof (buffer_get (&tok->lexeme))); + if ((tok = match (TOK_LPAREN, p))) + { + struct expression *expr = expression (p); + if (!(tok = match (TOK_RPAREN, p))) + { + fprintf (stderr, "Error: `)' expected at line %d.\n", tok->line); + exit (1); + } + return expression_create_grouping (expr); + } + return NULL; /* unmatched */ +} + +struct expression * +unary (struct parser *p) +{ + if (!p) + return NULL; + + if (match (TOK_NOT, p) || match (TOK_MINUS, p) || match (TOK_PLUS, p)) + { + struct token *op = prev_tok (p); + struct expression *right = unary (p); + return expression_create_unop (op, right); + } + + return primary (p); +} + +struct expression * +factor (struct parser *p) +{ + if (!p) + return NULL; + + return unary (p); +} + +struct expression * +term (struct parser *p) +{ + if (!p) + return NULL; + + struct expression *expr = factor (p); + while (match (TOK_STAR, p) || match (TOK_SLASH, p)) + { + struct token *op = prev_tok (p); + struct expression *right = factor (p); + expr = expression_create_binop (op, expr, right); + } + + return expr; +} + +struct expression * +expression (struct parser *p) +{ + if (!p) + return NULL; + + struct expression *expr = term (p); + while (match (TOK_PLUS, p) || match (TOK_MINUS, p)) + { + struct token *op = prev_tok (p); + struct expression *right = term (p); + expr = expression_create_binop (op, expr, right); + } + + return expr; +} struct parser parser_create (struct vector *tokens) { - return (struct parser){ .tokens = tokens, .curr = 0 }; + struct parser parser = { 0 }; + parser.tokens = tokens; + parser.ast = vector_create (); + return parser; } void @@ -13,10 +170,52 @@ parser_parse (struct parser *p) { if (!p) return; + + vector_push_back (expression (p), &p->ast); +} + +void +expr_print (struct expression *expr) +{ + switch (expr->type) + { + case EXPR_INT: + printf ("Integer[%d]", expr->integer); + break; + case EXPR_FLOAT: + printf ("Float[%f]", expr->floating); + break; + case EXPR_BINOP: + printf ("BinOp('%s', ", buffer_get (&expr->binop.op->lexeme)); + expr_print (expr->binop.left); + printf (", "); + expr_print (expr->binop.right); + printf (")"); + break; + case EXPR_UNOP: + printf ("UnOp('%s', ", buffer_get (&expr->unop.op->lexeme)); + expr_print (expr->unop.operand); + printf (")"); + break; + case EXPR_GROUP: + printf ("Grouping("); + expr_print (expr->grouping.value); + printf (")"); + break; + default: + fprintf (stderr, "Unknown expression type: %d\n", expr->type); + break; + } } void parser_print (struct parser *p) { - puts ("Parser:"); + puts ("Parsed Ast:"); + for (unsigned int i = 0; i < vector_len (&p->ast); i++) + { + struct expression *expr = (struct expression *)vector_at (i, &p->ast); + expr_print (expr); + printf ("\n"); + } } diff --git a/src/parser.h b/src/parser.h index 7926278..be6fa94 100644 --- a/src/parser.h +++ b/src/parser.h @@ -6,6 +6,7 @@ struct parser { struct vector *tokens; + struct vector ast; unsigned int curr; }; diff --git a/src/utils/vector.c b/src/utils/vector.c index 55fa692..c3bf9e3 100644 --- a/src/utils/vector.c +++ b/src/utils/vector.c @@ -50,7 +50,7 @@ vector_at (size_t i, struct vector *v) if (!v) return NULL; - if (i >= v->length) + if (i > v->length) { fprintf (stderr, "vector_at: cannot access index '%lu' in an array of '%lu' " @@ -61,6 +61,15 @@ vector_at (size_t i, struct vector *v) return v->elements[i]; } +size_t +vector_len (struct vector *v) +{ + if (!v) + return 0; + + return v->length; +} + void vector_free (struct vector *v) { diff --git a/src/utils/vector.h b/src/utils/vector.h index 7561695..ae00dca 100644 --- a/src/utils/vector.h +++ b/src/utils/vector.h @@ -15,6 +15,7 @@ struct vector struct vector vector_create (); _Bool vector_push_back (void *elm, struct vector *v); void *vector_at (size_t i, struct vector *v); +size_t vector_len (struct vector *v); void vector_free (struct vector *v); #endif diff --git a/tests/expr.pinky b/tests/expr.pinky index af8e105..76c62ce 100644 --- a/tests/expr.pinky +++ b/tests/expr.pinky @@ -1,4 +1,4 @@ -------------------------------- -- Evaluate a simple expression -------------------------------- -2 + 42 * 2 + (47 * -21) \ No newline at end of file +2 / 42.22 * 2 + (47 * -21) \ No newline at end of file