#include "ctx.h" #include "node.h" #include #include #include #include #include #include static void print_state_stack(struct ivy_parser *parser) { b_queue_iterator it = {0}; b_queue_foreach (&it, &parser->p_state) { struct parser_state *state = b_unbox(struct parser_state, it.entry, s_entry); printf(" %s\n", ivy_ast_node_type_to_string(state->s_node->n_type)); } } 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); *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) { while (true) { struct parser_state *state = parser_get_state_generic(parser); if (!state) { parser->p_status = IVY_ERR_INTERNAL_FAILURE; break; } token_parse_function func = get_token_parser(state->s_node, tok); if (func) { struct token_parse_result result = func(parser, tok); parser->p_status = result.r_status; printf("states (after token)\n"); print_state_stack(parser); if (result.r_flags & PARSE_REPEAT_TOKEN) { continue; } break; } if (tok->t_type == IVY_TOK_LINEFEED) { ivy_token_destroy(tok); parser->p_status = IVY_OK; break; } parser->p_status = IVY_ERR_BAD_SYNTAX; break; } 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_get_parent_state_generic(struct ivy_parser *parser, enum ivy_ast_node_type type) { b_queue_entry *entry = b_queue_last(&parser->p_state); if (!entry) { return NULL; } entry = b_queue_prev(entry); if (!entry) { return NULL; } struct parser_state *state = b_unbox(struct parser_state, entry, s_entry); if (state->s_node->n_type != type) { return NULL; } return state; } struct parser_state *parser_push_state( struct ivy_parser *parser, enum ivy_ast_node_type type) { const struct ast_node_type *node_type = get_ast_node_type(type); if (!node_type) { return NULL; } struct parser_state *state = malloc(node_type->n_state_size); if (!state) { return NULL; } memset(state, 0x0, node_type->n_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(type); b_queue_push_back(&parser->p_state, &state->s_entry); if (node_type->n_init_state) { node_type->n_init_state(parser, state); } printf("states (after push)\n"); print_state_stack(parser); 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 (state && (flags & STATE_ADD_NODE_TO_PARENT)) { parser_add_child(parser, state->s_node); } free(state); printf("states (after pop)\n"); print_state_stack(parser); } void parser_replace_current_node( struct ivy_parser *parser, struct ivy_ast_node *new_node) { struct parser_state *state = parser_get_state_generic(parser); if (!state) { return; } ivy_ast_node_destroy(state->s_node); state->s_node = new_node; } enum ivy_status parser_add_child( struct ivy_parser *parser, struct ivy_ast_node *new_node) { struct parser_state *state = parser_get_state_generic(parser); if (!state) { return IVY_ERR_NOT_SUPPORTED; } const struct ast_node_type *node_type = get_ast_node_type(state->s_node->n_type); if (!node_type || !node_type->n_add_child) { return IVY_ERR_NOT_SUPPORTED; } return node_type->n_add_child(state, new_node); } bool ivy_parser_is_node_complete(struct ivy_parser *parser) { return (parser->p_state.q_first == parser->p_state.q_last); } struct ivy_ast_node *ivy_parser_root_node(struct ivy_parser *parser) { b_queue_entry *entry = b_queue_first(&parser->p_state); struct parser_state *state = b_unbox(struct parser_state, entry, s_entry); return state ? state->s_node : NULL; } struct ivy_ast_node *ivy_parser_dequeue_node(struct ivy_parser *parser) { b_queue_entry *entry = b_queue_first(&parser->p_state); struct parser_state *state = b_unbox(struct parser_state, entry, s_entry); if (!state) { return NULL; } if (state->s_node->n_type != IVY_AST_UNIT) { return NULL; } struct ivy_ast_unit_node *unit = (struct ivy_ast_unit_node *)state->s_node; entry = b_queue_pop_front(&unit->n_children); if (!entry) { return NULL; } return b_unbox(struct ivy_ast_node, entry, n_entry); }