aboutsummaryrefslogtreecommitdiff
path: root/tree.c
diff options
context:
space:
mode:
authorWaldemar Celes <celes@tecgraf.puc-rio.br>1994-07-19 18:24:17 -0300
committerWaldemar Celes <celes@tecgraf.puc-rio.br>1994-07-19 18:24:17 -0300
commit1c749a3059051c52c3bc24540e27b0ccbcfff273 (patch)
tree55013cf056590f361dc444d2223dba23d8100aff /tree.c
parentcde6ab178200cc4bb79c287ecf40a7508953933a (diff)
downloadlua-1c749a3059051c52c3bc24540e27b0ccbcfff273.tar.gz
lua-1c749a3059051c52c3bc24540e27b0ccbcfff273.tar.bz2
lua-1c749a3059051c52c3bc24540e27b0ccbcfff273.zip
Arvore binaria de strings, variaveis e constantes.
Diffstat (limited to 'tree.c')
-rw-r--r--tree.c210
1 files changed, 210 insertions, 0 deletions
diff --git a/tree.c b/tree.c
new file mode 100644
index 00000000..a1a0ac83
--- /dev/null
+++ b/tree.c
@@ -0,0 +1,210 @@
1/*
2** tree.c
3** TecCGraf - PUC-Rio
4*/
5
6char *rcs_tree="$Id: $";
7
8
9#include <stdlib.h>
10#include <string.h>
11
12#include "lua.h"
13#include "tree.h"
14
15
16#define lua_strcmp(a,b) (a[0]<b[0]?(-1):(a[0]>b[0]?(1):strcmp(a,b)))
17
18
19typedef struct TreeNode
20{
21 struct TreeNode *right;
22 struct TreeNode *left;
23 Word index;
24 char str[1]; /* \0 byte already reserved */
25} TreeNode;
26
27static TreeNode *string_root = NULL;
28static TreeNode *constant_root = NULL;
29static TreeNode *variable_root = NULL;
30
31/*
32** Insert a new string/constant/variable at the tree.
33*/
34static char *tree_create (TreeNode **node, char *str)
35{
36 if (*node == NULL)
37 {
38 *node = (TreeNode *) malloc (sizeof(TreeNode)+strlen(str));
39 if (*node == NULL)
40 lua_error ("memoria insuficiente\n");
41 (*node)->left = (*node)->right = NULL;
42 strcpy((*node)->str, str);
43 (*node)->index = UNMARKED_STRING;
44 return (*node)->str;
45 }
46 else
47 {
48 int c = lua_strcmp(str, (*node)->str);
49 if (c < 0)
50 return tree_create(&(*node)->left, str);
51 else if (c > 0)
52 return tree_create(&(*node)->right, str);
53 else
54 return (*node)->str;
55 }
56}
57
58char *lua_strcreate (char *str)
59{
60 return tree_create(&string_root, str);
61}
62
63char *lua_constcreate (char *str)
64{
65 return tree_create(&constant_root, str);
66}
67
68char *lua_varcreate (char *str)
69{
70 return tree_create(&variable_root, str);
71}
72
73
74
75/*
76** Free a node of the tree
77*/
78static TreeNode *lua_strfree (TreeNode *parent)
79{
80 if (parent->left == NULL && parent->right == NULL) /* no child */
81 {
82 free (parent);
83 return NULL;
84 }
85 else if (parent->left == NULL) /* only right child */
86 {
87 TreeNode *p = parent->right;
88 free (parent);
89 return p;
90 }
91 else if (parent->right == NULL) /* only left child */
92 {
93 TreeNode *p = parent->left;
94 free (parent);
95 return p;
96 }
97 else /* two children */
98 {
99 TreeNode *p = parent, *r = parent->right;
100 while (r->left != NULL)
101 {
102 p = r;
103 r = r->left;
104 }
105 if (p == parent)
106 {
107 r->left = parent->left;
108 parent->left = NULL;
109 parent->right = r->right;
110 r->right = lua_strfree(parent);
111 }
112 else
113 {
114 TreeNode *t = r->right;
115 r->left = parent->left;
116 r->right = parent->right;
117 parent->left = NULL;
118 parent->right = t;
119 p->left = lua_strfree(parent);
120 }
121 return r;
122 }
123}
124
125/*
126** Traverse tree for garbage collection
127*/
128static TreeNode *lua_travcollector (TreeNode *r)
129{
130 if (r == NULL) return NULL;
131 r->right = lua_travcollector(r->right);
132 r->left = lua_travcollector(r->left);
133 if (r->index == UNMARKED_STRING)
134 return lua_strfree(r);
135 else
136 {
137 r->index = UNMARKED_STRING;
138 return r;
139 }
140}
141
142
143/*
144** Garbage collection function.
145** This function traverse the tree freening unindexed strings
146*/
147void lua_strcollector (void)
148{
149 string_root = lua_travcollector(string_root);
150}
151
152/*
153** Return next variable.
154*/
155static TreeNode *tree_next (TreeNode *node, char *str)
156{
157#if 0
158 if (node == NULL) return NULL;
159 if (str == NULL || lua_strcmp(str, node->str) < 0)
160 {
161 TreeNode *result = tree_next(node->left, str);
162 return result == NULL ? node : result;
163 }
164 else
165 {
166 return tree_next(node->right, str);
167 }
168#else
169 if (node == NULL) return NULL;
170 else if (str == NULL) return node;
171 else
172 {
173 int c = lua_strcmp(str, node->str);
174 if (c == 0)
175 return node->left != NULL ? node->left : node->right;
176 else if (c < 0)
177 {
178 TreeNode *result = tree_next(node->left, str);
179 return result != NULL ? result : node->right;
180 }
181 else
182 return tree_next(node->right, str);
183 }
184#endif
185}
186
187char *lua_varnext (char *n)
188{
189 TreeNode *result = tree_next(variable_root, n);
190 return result != NULL ? result->str : NULL;
191}
192
193
194/*
195** Given an id, find the string with exaustive search
196*/
197static char *tree_name (TreeNode *node, Word index)
198{
199 if (node == NULL) return NULL;
200 if (node->index == index) return node->str;
201 else
202 {
203 char *result = tree_name(node->left, index);
204 return result != NULL ? result : tree_name(node->right, index);
205 }
206}
207char *lua_varname (Word index)
208{
209 return tree_name(variable_root, index);
210}