summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast.c24
-rw-r--r--src/ast.h7
-rw-r--r--src/parser.c28
3 files changed, 39 insertions, 20 deletions
diff --git a/src/ast.c b/src/ast.c
index 5c94d68..b2efc42 100644
--- a/src/ast.c
+++ b/src/ast.c
@@ -30,21 +30,31 @@ ast_node_accept_visitor(ast_node_t *node, ast_visitor_t *visitor)
static void
ast_node_function_accept_visitor(ast_node_t *node, ast_visitor_t *visitor)
{
+ assert(visitor->visit_function && "unimplemented visit_function");
visitor->visit_function(visitor, &node->data.function);
}
static void
ast_node_return_stmt_accept_visitor(ast_node_t *node, ast_visitor_t *visitor)
{
+ assert(visitor->visit_return_stmt && "unimplemented visit_return_stmt");
visitor->visit_return_stmt(visitor, &node->data.return_stmt);
}
static void
ast_node_literal_visitor(ast_node_t *node, ast_visitor_t *visitor)
{
+ assert(visitor->visit_literal && "unimplemented visit_literal");
visitor->visit_literal(visitor, &node->data.literal);
}
+static void
+ast_node_binary_operation_visitor(ast_node_t *node, ast_visitor_t *visitor)
+{
+ assert(visitor->visit_binary_operation && "unimplemented visit_binary_operation");
+ visitor->visit_binary_operation(visitor, &node->data.binary_operation);
+}
+
ast_node_t*
ast_node_new()
{
@@ -120,3 +130,17 @@ ast_literal_integer_create(ast_node_t *node, uint32_t number)
}
};
}
+
+void
+ast_node_init_binary_operation(ast_node_t *node, string_view_t op, ast_node_t *left, ast_node_t *right)
+{
+ node->accept_visitor = &ast_node_binary_operation_visitor;
+ node->kind = AST_BINARY_OPERATION;
+ node->data = (ast_node_data_t) {
+ .binary_operation = {
+ .op = op,
+ .left = left,
+ .right = right
+ }
+ };
+}
diff --git a/src/ast.h b/src/ast.h
index cb9b8d5..70852b1 100644
--- a/src/ast.h
+++ b/src/ast.h
@@ -62,6 +62,7 @@ typedef struct ast_visitor_t {
void (*visit_function)(struct ast_visitor_t *, ast_function_declaration_t *);
void (*visit_return_stmt)(struct ast_visitor_t *, ast_return_stmt_t *);
void (*visit_literal)(struct ast_visitor_t *, ast_literal_t *);
+ void (*visit_binary_operation)(struct ast_visitor_t *, ast_binary_operation_t *);
} ast_visitor_t;
typedef enum {
@@ -90,8 +91,10 @@ void ast_node_accept_visitor(ast_node_t *node, ast_visitor_t *visitor);
ast_node_t* ast_node_new();
void ast_node_destroy(ast_node_t *node);
-void ast_node_init_function_declaration(ast_node_t* node, string_view_t name, type_t return_type, ast_node_t *body);
-void ast_node_init_return_stmt(ast_node_t* node, ast_node_t *argument);
+void ast_node_init_function_declaration(ast_node_t *node, string_view_t name, type_t return_type, ast_node_t *body);
+void ast_node_init_return_stmt(ast_node_t *node, ast_node_t *argument);
+void ast_node_init_binary_operation(ast_node_t *node, string_view_t op, ast_node_t *left, ast_node_t *right);
+// FIXME: use the naming convention
void ast_literal_integer_create(ast_node_t* node, uint32_t number);
#endif /* AST_H */
diff --git a/src/parser.c b/src/parser.c
index ad38125..a123648 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -145,17 +145,13 @@ parser_parse_term(parser_t *parser, ast_node_t *node)
lexer_next_token(parser->lexer, &token);
while (token.kind == TOKEN_OP && (string_view_eq(token.value, string_view_from_str("*")) || string_view_eq(token.value, string_view_from_str("/")))) {
- ast_node_t *binary_op = ast_node_new();
- binary_op->kind = AST_BINARY_OPERATION;
- binary_op->data.binary_operation.op = token.value;
+ ast_node_t *left = ast_node_new();
+ *left = *node;
- binary_op->data.binary_operation.left = ast_node_new();
- *binary_op->data.binary_operation.left = *node;
+ ast_node_t *right = ast_node_new();
+ if (!parser_parse_factor(parser, right)) return false;
- binary_op->data.binary_operation.right = ast_node_new();
- if (!parser_parse_factor(parser, binary_op->data.binary_operation.right)) return false;
-
- *node = *binary_op;
+ ast_node_init_binary_operation(node, token.value, left, right);
lexer_next_token(parser->lexer, &token);
}
@@ -181,18 +177,14 @@ parser_parse_expression(parser_t *parser, ast_node_t *node)
lexer_next_token(parser->lexer, &token);
while (token.kind == TOKEN_OP && (string_view_eq(token.value, string_view_from_str("+")) || string_view_eq(token.value, string_view_from_str("-")))) {
+ ast_node_t *left = ast_node_new();
+ *left = *node;
- ast_node_t *binary_op = ast_node_new();
- binary_op->kind = AST_BINARY_OPERATION;
- binary_op->data.binary_operation.op = token.value;
-
- binary_op->data.binary_operation.left = ast_node_new();
- *binary_op->data.binary_operation.left = *node;
+ ast_node_t *right = ast_node_new();
+ if (!parser_parse_term(parser, right)) return false;
- binary_op->data.binary_operation.right = ast_node_new();
- if (!parser_parse_term(parser, binary_op->data.binary_operation.right)) return false;
+ ast_node_init_binary_operation(node, token.value, left, right);
- *node = *binary_op;
lexer_next_token(parser->lexer, &token);
}