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"
|
#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;
|
||||||
}
|
}
|
||||||
|
36
src/model.h
36
src/model.h
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* TODO: Statements */
|
||||||
};
|
};
|
||||||
struct expression expression_create_integer (int value);
|
struct expression *expression_create_integer (int value);
|
||||||
struct expression expression_create_floating (int value);
|
struct expression *expression_create_floating (float value);
|
||||||
struct expression expression_create_binop (struct token *op,
|
struct expression *expression_create_binop (struct token *op,
|
||||||
struct expression *left,
|
struct expression *left,
|
||||||
struct expression *right);
|
struct expression *right);
|
||||||
struct expression expression_create_unop (struct token *op,
|
struct expression *expression_create_unop (struct token *op,
|
||||||
struct expression *operand);
|
struct expression *operand);
|
||||||
struct expression expression_create_grouping (struct expression *value);
|
struct expression *expression_create_grouping (struct expression *value);
|
||||||
|
|
||||||
/********************************
|
|
||||||
* Statements
|
|
||||||
********************************/
|
|
||||||
struct stmt
|
|
||||||
{
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
} while_stmt;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
} assignment;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
203
src/parser.c
203
src/parser.c
@ -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");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
struct parser
|
struct parser
|
||||||
{
|
{
|
||||||
struct vector *tokens;
|
struct vector *tokens;
|
||||||
|
struct vector ast;
|
||||||
unsigned int curr;
|
unsigned int curr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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)
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
--------------------------------
|
--------------------------------
|
||||||
-- Evaluate a simple expression
|
-- Evaluate a simple expression
|
||||||
--------------------------------
|
--------------------------------
|
||||||
2 + 42 * 2 + (47 * -21)
|
2 / 42.22 * 2 + (47 * -21)
|
Loading…
x
Reference in New Issue
Block a user