started to work in the ast
This commit is contained in:
parent
41e5298288
commit
19e9b8dfee
52
src/model.c
52
src/model.c
@ -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;
|
||||
}
|
||||
|
40
src/model.h
40
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
|
||||
|
203
src/parser.c
203
src/parser.c
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
struct parser
|
||||
{
|
||||
struct vector *tokens;
|
||||
struct vector ast;
|
||||
unsigned int curr;
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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
|
||||
|
@ -1,4 +1,4 @@
|
||||
--------------------------------
|
||||
-- Evaluate a simple expression
|
||||
--------------------------------
|
||||
2 + 42 * 2 + (47 * -21)
|
||||
2 / 42.22 * 2 + (47 * -21)
|
Loading…
x
Reference in New Issue
Block a user