started to work in the ast

This commit is contained in:
ghostie 2025-07-13 14:19:52 -05:00
parent 41e5298288
commit 19e9b8dfee
7 changed files with 263 additions and 47 deletions

View File

@ -1,36 +1,58 @@
#include "model.h" #include "model.h"
struct expression #include <stdlib.h>
struct expression *
alloc_expr ()
{
return (struct expression *)calloc (1, sizeof (struct expression));
}
struct expression *
expression_create_integer (int value) 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 struct expression *
expression_create_floating (int value) 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, expression_create_binop (struct token *op, struct expression *left,
struct expression *right) struct expression *right)
{ {
return (struct expression){ .type = EXPR_BINOP, struct expression *expr = alloc_expr ();
.binop expr->type = EXPR_BINOP;
= { .op = op, .left = left, .right = right } }; 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) expression_create_unop (struct token *op, struct expression *operand)
{ {
return (struct expression){ .type = EXPR_UNOP, struct expression *expr = alloc_expr ();
.unop = { .op = op, .operand = operand } }; expr->type = EXPR_UNOP;
expr->unop.op = op;
expr->unop.operand = operand;
return expr;
} }
struct expression struct expression *
expression_create_grouping (struct expression *value) expression_create_grouping (struct expression *value)
{ {
return (struct expression){ .type = EXPR_GROUP, struct expression *expr = alloc_expr ();
.grouping = { .value = value } }; expr->type = EXPR_GROUP;
expr->grouping.value = value;
return expr;
} }

View File

@ -3,16 +3,15 @@
#include "token.h" #include "token.h"
/********************************
* Expression
********************************/
enum expression_type enum expression_type
{ {
EXPR_INT, EXPR_INT,
EXPR_FLOAT, EXPR_FLOAT,
EXPR_BINOP, EXPR_BINOP,
EXPR_UNOP, EXPR_UNOP,
EXPR_GROUP EXPR_GROUP,
/* TODO: Statements */
}; };
struct expression struct expression
@ -48,31 +47,16 @@ struct expression
struct expression *value; struct expression *value;
} grouping; } 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);
/******************************** /* TODO: Statements */
* Statements
********************************/
struct stmt
{
union
{
struct
{
} while_stmt;
struct
{
} assignment;
};
}; };
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 #endif

View File

@ -1,11 +1,168 @@
#include "parser.h" #include "parser.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#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 struct parser
parser_create (struct vector *tokens) 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 void
@ -13,10 +170,52 @@ parser_parse (struct parser *p)
{ {
if (!p) if (!p)
return; 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 void
parser_print (struct parser *p) 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");
}
} }

View File

@ -6,6 +6,7 @@
struct parser struct parser
{ {
struct vector *tokens; struct vector *tokens;
struct vector ast;
unsigned int curr; unsigned int curr;
}; };

View File

@ -50,7 +50,7 @@ vector_at (size_t i, struct vector *v)
if (!v) if (!v)
return NULL; return NULL;
if (i >= v->length) if (i > v->length)
{ {
fprintf (stderr, fprintf (stderr,
"vector_at: cannot access index '%lu' in an array of '%lu' " "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]; return v->elements[i];
} }
size_t
vector_len (struct vector *v)
{
if (!v)
return 0;
return v->length;
}
void void
vector_free (struct vector *v) vector_free (struct vector *v)
{ {

View File

@ -15,6 +15,7 @@ struct vector
struct vector vector_create (); struct vector vector_create ();
_Bool vector_push_back (void *elm, struct vector *v); _Bool vector_push_back (void *elm, struct vector *v);
void *vector_at (size_t i, 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); void vector_free (struct vector *v);
#endif #endif

View File

@ -1,4 +1,4 @@
-------------------------------- --------------------------------
-- Evaluate a simple expression -- Evaluate a simple expression
-------------------------------- --------------------------------
2 + 42 * 2 + (47 * -21) 2 / 42.22 * 2 + (47 * -21)