summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kikoodx@paranoici.org>2023-03-14 18:11:59 +0100
committerkdx <kikoodx@paranoici.org>2023-03-14 18:11:59 +0100
commit6602bdf7c86e0f579588fe25618d00cb7b5cfe5e (patch)
tree523628d97f86fe94a9baa8cc8d6a826dc25ccbcc
parentaaa3835ffcf9460325864783f9fda81a63616289 (diff)
downloadgolem-6602bdf7c86e0f579588fe25618d00cb7b5cfe5e.tar.gz
group scopes
-rw-r--r--group.c30
-rw-r--r--token.c44
-rw-r--r--token.h5
3 files changed, 60 insertions, 19 deletions
diff --git a/group.c b/group.c
index 4d39010..4f0c5b5 100644
--- a/group.c
+++ b/group.c
@@ -13,21 +13,39 @@ Token *group_create(Token **list, Token *begin, Token *end)
group->type = TOK_GROUP;
group->group.type = GROUP_NONE;
group->group.tokens = begin;
+ group->prev = begin->prev;
group->next = end->next;
if (*list == begin)
*list = group;
else
- for (Token *e = *list; e != NULL; e = e->next)
- if (e->next == begin) {
- e->next = group;
- break;
- }
+ begin->prev->next = group;
+ begin->prev = NULL;
end->next = NULL;
return group;
}
int group_scope(Token **list)
{
- group_create(list, *list, (*list)->next->next);
+ for (;;) {
+ Token *begin = token_search(*list, TOK_OPEN_CURL);
+ Token *end = token_search_closing(*list, TOK_CLOS_CURL, TOK_OPEN_CURL);
+ if (begin == NULL && end == NULL)
+ return 0;
+ if (begin == NULL || end == NULL) {
+ fprintf(stderr, "unclosed CURL pair\n");
+ return 1;
+ }
+ Token *group = group_create(list, begin, end);
+ if (group == NULL) {
+ fprintf(stderr, "group_create failed\n");
+ return 1;
+ }
+ token_delete(&group->group.tokens, begin);
+ token_delete(&group->group.tokens, end);
+ if (group_scope(&group->group.tokens)) {
+ fprintf(stderr, "group_scope failed\n");
+ return 1;
+ }
+ }
return 0;
}
diff --git a/token.c b/token.c
index ec3bb37..b9ab802 100644
--- a/token.c
+++ b/token.c
@@ -14,6 +14,7 @@ token_create(Slice slice, unsigned int type)
}
token->slice = slice;
token->type = type;
+ token->prev = NULL;
token->next = NULL;
return token;
}
@@ -42,29 +43,48 @@ token_append(Token **list, Token *elem)
while (end->next != NULL)
end = end->next;
end->next = elem;
+ elem->prev = end;
return *list;
}
void
token_delete(Token **list, Token *elem)
{
- if (*list == elem) {
+ if (elem->prev != NULL)
+ elem->prev->next = elem->next;
+ if (elem->next != NULL)
+ elem->next->prev = elem->prev;
+ if (*list == elem)
*list = elem->next;
- free(elem);
- return;
+ free(elem);
+}
+
+Token *
+token_search(Token *list, unsigned int type)
+{
+ while (list != NULL) {
+ if (list->type == type)
+ return list;
+ list = list->next;
}
+ return NULL;
+}
- Token *e = *list;
- while (e != NULL) {
- if (e->next == elem) {
- Token *next = elem->next;
- free(elem);
- e->next = next;
- return;
+Token *
+token_search_closing(Token *list, unsigned int type, unsigned int opn)
+{
+ int count = 0;
+ while (list != NULL) {
+ if (list->type == opn)
+ count += 1;
+ if (list->type == type) {
+ count -= 1;
+ if (count <= 0)
+ return list;
}
- e = e->next;
+ list = list->next;
}
- assert(0); // elem not found in list
+ return NULL;
}
Token *
diff --git a/token.h b/token.h
index 204c7b9..4cfee5a 100644
--- a/token.h
+++ b/token.h
@@ -27,11 +27,12 @@ enum {
typedef struct Token Token;
struct Token {
- unsigned int type;
+ unsigned char type;
union {
Slice slice;
Group group;
};
+ Token *prev;
Token *next;
};
@@ -39,4 +40,6 @@ Token *token_create(Slice slice, unsigned int type);
void token_destroy(Token *token);
Token *token_append(Token **list, Token *elem);
void token_delete(Token **list, Token *elem);
+Token *token_search(Token *list, unsigned int type);
+Token *token_search_closing(Token *list, unsigned int type, unsigned int opn);
Token *token_print(Token *token, int recurse, int depth);