From 17d8755c06e7770674ed3b1c051dde79d4222d00 Mon Sep 17 00:00:00 2001
From: nishi <nishi@0f02c867-ac3d-714e-8a88-971ba1f6efcf>
Date: Tue, 30 Apr 2024 00:34:57 +0000
Subject: [PATCH] trying to fix

git-svn-id: file:///raid/svn-main/nishi-serenade/trunk@81 0f02c867-ac3d-714e-8a88-971ba1f6efcf
---
 Serenade/interpreter.c |  8 ++---
 Serenade/parser.c      | 78 +++++++++++++++++++++++++++++++++++++++---
 Serenade/parser.h      |  4 +--
 3 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/Serenade/interpreter.c b/Serenade/interpreter.c
index f485d79..460586d 100644
--- a/Serenade/interpreter.c
+++ b/Serenade/interpreter.c
@@ -182,14 +182,14 @@ void sn_interpreter_free(struct sn_interpreter* sn) {
 	int i;
 	for(i = 0; sn->variables[i] != NULL; i++) {
 		free(sn->variables[i]->key);
-		if(sn->variables[i]->value != NULL) sn_generic_free(sn->variables[i]->value);
+		if(sn->variables[i]->value != NULL) sn_generic_free(sn, sn->variables[i]->value);
 		free(sn->variables[i]);
 	}
 	free(sn->variables);
 	for(i = 0; sn->generics[i] != NULL; i++) {
 		int j;
 		for(j = 0; sn->generics[i][j] != NULL; j++){
-			sn_generic_free(sn->generics[i][j]);
+			sn_generic_free(sn, sn->generics[i][j]);
 		}
 		free(sn->generics[i]);
 	}
@@ -214,7 +214,7 @@ struct sn_interpreter_kv* sn_set_variable(struct sn_interpreter* sn, const char*
 	if(!global) {
 		for(i = 0; sn->local_variables[i] != NULL; i++) {
 			if(strcmp(sn->local_variables[i]->key, name) == 0) {
-				sn->local_variables[i]->value = sn_generic_dup(gen);
+				sn->local_variables[i]->value = gen;
 				replaced = true;
 				return sn->local_variables[i];
 			}
@@ -229,7 +229,7 @@ struct sn_interpreter_kv* sn_set_variable(struct sn_interpreter* sn, const char*
 			}
 			sn->local_variables[i] = malloc(sizeof(struct sn_generic));
 			sn->local_variables[i]->key = sn_strdup(name);
-			sn->local_variables[i]->value = sn_generic_dup(gen);
+			sn->local_variables[i]->value = gen;
 			sn->local_variables[i]->handler = NULL;
 			if(gen != NULL && gen->type == SN_TYPE_FUNCTION) sn->local_variables[i]->handler = gen->handler;
 			sn->local_variables[i + 1] = NULL;
diff --git a/Serenade/parser.c b/Serenade/parser.c
index 7ebb9c0..92b7b60 100644
--- a/Serenade/parser.c
+++ b/Serenade/parser.c
@@ -229,23 +229,91 @@ struct sn_generic** sn_parse(char* data, unsigned long long size) {
 	return gens;
 }
 
-void sn_generic_free(struct sn_generic* g) {
+void sn_generic_free(struct sn_interpreter* sn, struct sn_generic* g) {
 	if(g->type == SN_TYPE_STRING) {
 		free(g->string);
 	} else if(g->type == SN_TYPE_TREE) {
-		sn_tree_free(g->tree);
+		sn_tree_free(sn, g->tree);
 	} else if(g->type == SN_TYPE_FUNCTION || g->type == SN_TYPE_VARIABLE) {
 		free(g->name);
 	}
-	fprintf(stderr, "type %d free\n", g->type);
+	printf("freed type %d\n", g->type);
 	free(g);
+	if(sn == NULL) return;
+	int i;
+	for(i = 0; sn->generics[i] != NULL; i++);
+	struct sn_generic*** gens = malloc(sizeof(struct sn_generic**) * (i + 1));
+	for(i = 0; sn->generics[i] != NULL; i++) gens[i] = sn->generics[i];
+	gens[i] = NULL;
+	for(i = 0; sn->generics[i] != NULL; i++){
+		int j;
+		for(j = 0; sn->generics[i][j] != NULL; j++){
+			struct sn_generic** oldgens = gens[i];
+			int k;
+			int count = 0;
+			int matched = 0;
+			for(k = 0; oldgens[k] != NULL; k++){
+				if(oldgens[k] != g){
+					count++;
+				}else{
+					matched++;
+				}
+			}
+			if(matched == 0) continue;
+			gens[i] = malloc(sizeof(struct sn_generic*) * (count + 1));
+			count = 0;
+			for(k = 0; oldgens[k] != NULL; k++){
+				if(oldgens[k] != g){
+					gens[i][count] = oldgens[k];	
+					count++;
+				}
+			}
+			gens[i][count] = NULL;
+			free(oldgens[k]);
+		}
+	}
+	free(sn->generics);
+	sn->generics = gens;
+
+	for(i = 0; sn->variables[i] != NULL; i++);
+	struct sn_interpreter_kv** kvs = malloc(sizeof(struct sn_interpreter_kv*) * (i + 1));
+	for(i = 0; sn->variables[i] != NULL; i++) kvs[i] = sn->variables[i];
+	kvs[i] = NULL;
+	for(i = 0; sn->variables[i] != NULL; i++){
+		struct sn_interpreter_kv** oldkvs = kvs;
+		int j;
+		int count = 0;
+		int matched = 0;
+		for(j = 0; oldkvs[j] != NULL; j++){
+			if(oldkvs[j]->value != g){
+				count++;
+			}else{
+				matched++;
+			}
+		}
+		if(matched == 0) continue;
+		kvs = malloc(sizeof(struct sn_interpreter_kv*) * (count + 1));
+		count = 0;
+		for(j = 0; oldkvs[j] != NULL; j++){
+			if(oldkvs[j]->value != g){
+				kvs[count] = oldkvs[j];
+				count++;
+			}else{
+				free(oldkvs[j]->key);
+			}
+		}
+		kvs[count] = NULL;
+		free(oldkvs);
+	}
+	free(sn->variables);
+	sn->variables = kvs;
 }
 
-void sn_tree_free(struct sn_tree* t) {
+void sn_tree_free(struct sn_interpreter* sn, struct sn_tree* t) {
 	if(t->args != NULL) {
 		int i;
 		for(i = 0; t->args[i] != NULL; i++) {
-			sn_generic_free(t->args[i]);
+			sn_generic_free(sn, t->args[i]);
 		}
 		free(t->args);
 	}
diff --git a/Serenade/parser.h b/Serenade/parser.h
index 373542c..7bd9101 100644
--- a/Serenade/parser.h
+++ b/Serenade/parser.h
@@ -58,8 +58,8 @@ struct sn_tree {
 };
 
 struct sn_generic** sn_parse(char* data, unsigned long long size);
-void sn_generic_free(struct sn_generic* g);
+void sn_generic_free(struct sn_interpreter* sn, struct sn_generic* g);
 struct sn_generic* sn_generic_dup(struct sn_generic* g);
-void sn_tree_free(struct sn_tree* t);
+void sn_tree_free(struct sn_interpreter* sn, struct sn_tree* t);
 
 #endif
-- 
2.43.0