#include "group.h" #include "token.h" #include #include static int group_enclosed(Token **list, unsigned int open_tok, unsigned int clos_tok, unsigned int group_type) { for (;;) { Token *begin = token_search(*list, open_tok); Token *end = token_search_closing(begin, clos_tok, open_tok); if (begin == NULL && end == NULL) break; if (begin == NULL || end == NULL) { fprintf(stderr, "unclosed pair\n"); return 1; } Token *group = group_create(list, begin, end); if (group == NULL) { fprintf(stderr, "group_create failed\n"); return 1; } group->group.type = group_type; token_delete(&group->group.tokens, begin); token_delete(&group->group.tokens, end); if (group_scope(&group->group.tokens)) { fprintf(stderr, "group_enclosed failed\n"); return 1; } } for (Token *e = *list; e != NULL; e = e->next) if (e->type == TOK_GROUP) group_enclosed(&e->group.tokens, open_tok, clos_tok, group_type); return 0; } Token * group_create(Token **list, Token *begin, Token *end) { Token *group = malloc(sizeof(Token)); if (group == NULL) { perror("group_create:malloc"); return NULL; } group->type = TOK_GROUP; group->group.type = GROUP_NONE; group->group.tokens = begin; group->group.scope = NULL; group->prev = begin->prev; group->next = end->next; begin->prev = NULL; end->next = NULL; if (*list == begin) *list = group; else if (group->prev != NULL) group->prev->next = group; if (group->next != NULL) group->next->prev = group; return group; } void group_extract(Token **list, Token *group) { if (group->type != TOK_GROUP) return; if (group->group.scope != NULL) token_destroy(group->group.scope); if (*list == group) { if ((*list)->next != NULL) { (*list)->next->prev = group->group.tokens; token_last(group->group.tokens)->next = (*list)->next; } *list = group->group.tokens; } else { if (group->prev != NULL) group->prev->next = group->group.tokens; if (group->next != NULL) group->next->prev = token_last(group->group.tokens); } free(group); } int group_scope(Token **list) { return group_enclosed(list, TOK_OPEN_CURL, TOK_CLOS_CURL, GROUP_SCOPE); } int group_funcall(Token **list) { return group_enclosed(list, TOK_OPEN_PAREN, TOK_CLOS_PAREN, GROUP_FUNCALL); } int group_deref(Token **list) { return group_enclosed(list, TOK_OPEN_SQUAR, TOK_CLOS_SQUAR, GROUP_DEREF); } int group_atom(Token **list) { // Recurse in child GROUP_SCOPEs. for (Token *e = *list; e != NULL; e = e->next) if (token_isgroup(e, GROUP_SCOPE)) if (group_atom(&e->group.tokens)) return 1; Token *e = *list; for (;;) { Token *end = token_search(e, TOK_END); if (end == NULL) break; if (end != *list) { Token *group = group_create(list, e, end->prev); if (group == NULL) { fprintf(stderr, "group_create failed\n"); return 1; } group->group.type = GROUP_ATOM; e = end->next; } token_delete(list, end); } return 0; }