lang: ast: re-factor parser into multiple files
This commit is contained in:
112
lang/ast/ctx.c
Normal file
112
lang/ast/ctx.c
Normal file
@@ -0,0 +1,112 @@
|
||||
#include "ctx.h"
|
||||
|
||||
#include "node.h"
|
||||
#include "parse.h"
|
||||
|
||||
#include <blue/core/queue.h>
|
||||
#include <ivy/lang/ast.h>
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
enum ivy_status ivy_parser_create(struct ivy_parser **parser)
|
||||
{
|
||||
struct ivy_parser *out = malloc(sizeof *out);
|
||||
if (!out) {
|
||||
return IVY_ERR_NO_MEMORY;
|
||||
}
|
||||
|
||||
memset(out, 0x0, sizeof *out);
|
||||
|
||||
parser_push_state(
|
||||
out, IVY_AST_UNIT, struct ivy_ast_unit_node, struct parser_state);
|
||||
|
||||
*parser = out;
|
||||
return IVY_OK;
|
||||
}
|
||||
|
||||
void ivy_parser_destroy(struct ivy_parser *parser)
|
||||
{
|
||||
free(parser);
|
||||
}
|
||||
|
||||
enum ivy_status ivy_parser_get_status(struct ivy_parser *parser)
|
||||
{
|
||||
return parser->p_status;
|
||||
}
|
||||
|
||||
enum ivy_status ivy_parser_push_token(
|
||||
struct ivy_parser *parser, struct ivy_token *tok)
|
||||
{
|
||||
struct parser_state *state = parser_get_state_generic(parser);
|
||||
if (!state) {
|
||||
parser->p_status = IVY_ERR_INTERNAL_FAILURE;
|
||||
return IVY_ERR_INTERNAL_FAILURE;
|
||||
}
|
||||
|
||||
token_parse_function func = get_token_parser(state->s_node, tok);
|
||||
if (!func) {
|
||||
parser->p_status = IVY_ERR_BAD_SYNTAX;
|
||||
return IVY_ERR_BAD_SYNTAX;
|
||||
}
|
||||
|
||||
parser->p_status = func(parser, tok);
|
||||
return parser->p_status;
|
||||
}
|
||||
|
||||
struct parser_state *parser_get_state_generic(struct ivy_parser *parser)
|
||||
{
|
||||
b_queue_entry *entry = b_queue_last(&parser->p_state);
|
||||
if (!entry) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct parser_state *state = b_unbox(struct parser_state, entry, s_entry);
|
||||
return state;
|
||||
}
|
||||
|
||||
struct parser_state *parser_push_state_generic(
|
||||
struct ivy_parser *parser, enum ivy_ast_node_type type,
|
||||
size_t node_size, size_t state_size)
|
||||
{
|
||||
struct parser_state *state = malloc(state_size);
|
||||
if (!state) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
memset(state, 0x0, state_size);
|
||||
|
||||
b_queue_entry *current_state_entry = b_queue_last(&parser->p_state);
|
||||
if (current_state_entry) {
|
||||
struct parser_state *current_state = b_unbox(
|
||||
struct parser_state, current_state_entry, s_entry);
|
||||
state->s_parent = current_state->s_node;
|
||||
}
|
||||
|
||||
state->s_node = ast_node_create_with_size(type, node_size);
|
||||
|
||||
const struct ast_node_type *node_type = get_ast_node_type(type);
|
||||
if (node_type && node_type->n_init_state) {
|
||||
node_type->n_init_state(state);
|
||||
}
|
||||
|
||||
b_queue_push_back(&parser->p_state, &state->s_entry);
|
||||
return state;
|
||||
}
|
||||
|
||||
void parser_pop_state(struct ivy_parser *parser, enum pop_state_flags flags)
|
||||
{
|
||||
if (parser->p_state.q_first == parser->p_state.q_last) {
|
||||
return;
|
||||
}
|
||||
|
||||
b_queue_entry *entry = b_queue_last(&parser->p_state);
|
||||
struct parser_state *state = b_unbox(struct parser_state, entry, s_entry);
|
||||
b_queue_pop_back(&parser->p_state);
|
||||
|
||||
if (flags & STATE_ADD_NODE_TO_PARENT) {
|
||||
ast_node_add_child(state->s_parent, state->s_node);
|
||||
}
|
||||
|
||||
free(state);
|
||||
}
|
||||
Reference in New Issue
Block a user