summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkdx <kdx@42l.fr>2023-03-17 02:26:25 +0100
committerkdx <kdx@42l.fr>2023-03-17 02:26:25 +0100
commit4160e9650bcfe7449beb150cdf8196b768a92eb3 (patch)
tree14d4e2d4131d3c7a198466ba899efa5978808686
parenta60f03db9ef3eb65b8898a9bf0ad70fbc2d2cc53 (diff)
downloadgolem-4160e9650bcfe7449beb150cdf8196b768a92eb3.tar.gz
extract scope
-rwxr-xr-xdebug.sh2
-rw-r--r--group.c23
-rw-r--r--group.h2
-rw-r--r--main.c18
-rw-r--r--scope.c27
-rw-r--r--scope.h4
-rw-r--r--token.c31
-rw-r--r--token.h2
8 files changed, 101 insertions, 8 deletions
diff --git a/debug.sh b/debug.sh
new file mode 100755
index 0000000..eb8f5ab
--- /dev/null
+++ b/debug.sh
@@ -0,0 +1,2 @@
+#!/bin/sh
+gcc -O0 -g -std=c99 -Wall -Wextra -o golem *.c
diff --git a/group.c b/group.c
index 4f774bc..0df0512 100644
--- a/group.c
+++ b/group.c
@@ -48,6 +48,7 @@ group_create(Token **list, Token *begin, Token *end)
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;
@@ -61,6 +62,28 @@ group_create(Token **list, Token *begin, Token *end)
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)
{
diff --git a/group.h b/group.h
index a2bf63f..571bf17 100644
--- a/group.h
+++ b/group.h
@@ -20,9 +20,11 @@ struct Token;
typedef struct {
unsigned int type;
struct Token *tokens;
+ struct Token *scope;
} Group;
struct Token *group_create(struct Token **l, struct Token *b, struct Token *e);
+void group_extract(struct Token **list, struct Token *group);
int group_scope(struct Token **list);
int group_funcall(struct Token **list);
int group_deref(struct Token **list);
diff --git a/main.c b/main.c
index 778fae9..7ba3033 100644
--- a/main.c
+++ b/main.c
@@ -5,6 +5,7 @@
#include "group.h"
#include "identify.h"
#include "check.h"
+#include "scope.h"
#include <stdio.h>
#include <stdlib.h>
@@ -48,10 +49,21 @@ main(int argc, char **argv)
identify(tokens, identify_else, GROUP_ELSE, 1);
identify(tokens, identify_while, GROUP_WHILE, 1);
identify(tokens, identify_expression, GROUP_EXPRESSION, 1);
- if (check_atom(tokens))
- fprintf(stderr, "unidentified atoms are left\n");
- else
+ do {
+ if (check_atom(tokens)) {
+ fprintf(stderr, "unidentified atoms are left\n");
+ break;
+ }
+ Token *group = group_create(&tokens, tokens,
+ token_last(tokens));
+ if (group == NULL) {
+ fprintf(stderr, "group_create failed\n");
+ break;
+ }
+ group->group.type = GROUP_SCOPE;
+ scope_extract(tokens);
token_print(tokens, 1, 0);
+ } while(0);
token_destroy(tokens);
}
diff --git a/scope.c b/scope.c
new file mode 100644
index 0000000..722e430
--- /dev/null
+++ b/scope.c
@@ -0,0 +1,27 @@
+#include "scope.h"
+#include "group.h"
+#include "token.h"
+#include <stdio.h>
+
+void
+scope_extract(Token *list)
+{
+ // Recurse in child scopes.
+ for (Token *e = list->group.tokens; e != NULL; e = e->next)
+ if (e->type == TOK_GROUP)
+ scope_extract(e);
+ if (!token_isgroup(list, GROUP_SCOPE))
+ return;
+
+ // Extract let groups.
+ Token *e = list->group.tokens;
+ while (e != NULL)
+ if (token_isgroup(e, GROUP_LET)) {
+ token_append(&list->group.scope,
+ token_extract(&list->group.tokens, e));
+ group_extract(&list->group.scope,
+ token_last(list->group.scope));
+ e = list->group.tokens; // XXX: this is slow
+ } else
+ e = e->next;
+}
diff --git a/scope.h b/scope.h
new file mode 100644
index 0000000..96ab8cb
--- /dev/null
+++ b/scope.h
@@ -0,0 +1,4 @@
+#pragma once
+#include "token.h"
+
+void scope_extract(Token *list);
diff --git a/token.c b/token.c
index 05808f1..25223c0 100644
--- a/token.c
+++ b/token.c
@@ -24,8 +24,10 @@ token_destroy(Token *token)
{
while (token != NULL) {
Token *next = token->next;
- if (token->type == TOK_GROUP)
+ if (token->type == TOK_GROUP) {
token_destroy(token->group.tokens);
+ token_destroy(token->group.scope);
+ }
free(token);
token = next;
}
@@ -39,9 +41,7 @@ token_append(Token **list, Token *elem)
return *list;
}
- Token *end = *list;
- while (end->next != NULL)
- end = end->next;
+ Token *end = token_last(*list);
end->next = elem;
elem->prev = end;
return *list;
@@ -50,13 +50,22 @@ token_append(Token **list, Token *elem)
void
token_delete(Token **list, Token *elem)
{
+ token_extract(list, elem);
+ free(elem);
+}
+
+Token *
+token_extract(Token **list, Token *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);
+ elem->prev = NULL;
+ elem->next = NULL;
+ return elem;
}
Token *
@@ -97,6 +106,8 @@ token_print(Token *token, int recurse, int depth)
if (token->type == TOK_GROUP) {
printf("type: TOK_GROUP group.type: %c\n",
token->group.type);
+ if (token->group.scope != NULL)
+ token_print(token->group.scope, 1, depth);
token_print(token->group.tokens, 1, depth + 1);
} else {
printf("type: %c slice: ", token->type);
@@ -125,3 +136,13 @@ token_len(Token *token)
}
return len;
}
+
+Token *
+token_last(Token *token)
+{
+ if (token == NULL)
+ return NULL;
+ while (token->next != NULL)
+ token = token->next;
+ return token;
+}
diff --git a/token.h b/token.h
index d74c1a0..018ee10 100644
--- a/token.h
+++ b/token.h
@@ -39,8 +39,10 @@ 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_extract(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);
int token_isgroup(Token *token, unsigned int type);
int token_len(Token *token);
+Token *token_last(Token *token);