/*
* Copyright (C) 2023 Johnny Richard
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
#ifndef AST_H
#define AST_H
#include "string_view.h"
#include "vector.h"
#include
#define ast_visitor_visit(visitor, node) ast_node_accept_visitor(node, (ast_visitor_t *)visitor);
typedef enum
{
TYPE_I32
} type_t;
typedef struct ast_visitor_t ast_visitor_t;
typedef struct ast_node_t ast_node_t;
typedef struct ast_return_stmt_t
{
ast_node_t *argument;
} ast_return_stmt_t;
typedef struct ast_function_declaration_t
{
string_view_t name;
type_t return_type;
vector_t *body;
} ast_function_declaration_t;
typedef struct ast_binary_operation_t
{
// FIXME: We want to use enum to distinguish operators
string_view_t op;
ast_node_t *left;
ast_node_t *right;
} ast_binary_operation_t;
typedef enum
{
AST_LITERAL_INTEGER
} ast_literal_kind_t;
typedef union
{
uint32_t integer;
} ast_literal_value_t;
typedef struct ast_literal_t
{
ast_literal_kind_t kind;
ast_literal_value_t value;
} ast_literal_t;
typedef struct ast_identifier_t
{
string_view_t name;
} ast_identifier_t;
typedef struct ast_variable_declaration_t
{
string_view_t name;
type_t type;
ast_node_t *value;
} ast_variable_declaration_t;
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
{
AST_BINARY_OPERATION,
AST_FUNCTION_DECLARATION,
AST_IDENTIFIER,
AST_LITERAL,
AST_RETURN_STMT,
AST_UNKOWN_NODE,
AST_VARIABLE_DECLARATION,
} ast_node_kind_t;
typedef union
{
ast_binary_operation_t binary_operation;
ast_function_declaration_t function;
ast_literal_t literal;
ast_return_stmt_t return_stmt;
ast_variable_declaration_t variable;
ast_identifier_t identifier;
} ast_node_data_t;
typedef struct ast_node_t
{
void (*accept_visitor)(ast_node_t *, ast_visitor_t *);
ast_node_kind_t kind;
ast_node_data_t data;
} ast_node_t;
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_binary_operation(ast_node_t *node, string_view_t op, ast_node_t *left, ast_node_t *right);
void
ast_node_init_function_declaration(ast_node_t *node, string_view_t name, type_t return_type, vector_t *body);
void
ast_node_init_identifier(ast_node_t *node, string_view_t name);
void
ast_node_init_return_stmt(ast_node_t *node, ast_node_t *argument);
void
ast_node_init_variable_declaration(ast_node_t *node, string_view_t variable_name, type_t type, ast_node_t *value);
// FIXME: use the naming convention
void
ast_literal_integer_create(ast_node_t *node, uint32_t number);
#endif /* AST_H */