#include "ctx.h" #include "node.h" #include "parse.h" #include #include #include #include #include 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); }