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"
struct expression
#include <stdlib.h>
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;
}

View File

@ -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;
};
/* TODO: Statements */
};
struct expression expression_create_integer (int value);
struct expression expression_create_floating (int value);
struct expression expression_create_binop (struct token *op,
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 *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;
};
};
struct expression *expression_create_grouping (struct expression *value);
#endif

View File

@ -1,11 +1,168 @@
#include "parser.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
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");
}
}

View File

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

View File

@ -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)
{

View File

@ -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

View File

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