summaryrefslogtreecommitdiff
path: root/src/data/tree.c
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2008-05-15 23:28:07 +0000
committerPaul Buetow <paul@buetow.org>2008-05-15 23:28:07 +0000
commitbe839900419c7a74c4a46efd279d0ca16b35dc1f (patch)
tree1355c8f238d1c58ffd5cb8803bcc2adf987e79aa /src/data/tree.c
parent33c945e58f86267b0d3bdca4c3421155e11eb0d9 (diff)
Moved stuff into trunk.
Diffstat (limited to 'src/data/tree.c')
-rw-r--r--src/data/tree.c250
1 files changed, 250 insertions, 0 deletions
diff --git a/src/data/tree.c b/src/data/tree.c
new file mode 100644
index 0000000..c1f01c1
--- /dev/null
+++ b/src/data/tree.c
@@ -0,0 +1,250 @@
+/*:*
+ *: File: ./src/data/tree.c
+ *: A simple interpreter
+ *:
+ *: WWW : http://fype.buetow.org
+ *: E-Mail : fype@dev.buetow.org
+ *:
+ *: Copyright (c) 2005 2006 2007 2008, Paul Buetow (http://www.pblabs.net)
+ *: All rights reserved.
+ *:
+ *: Redistribution and use in source and binary forms, with or without modi-
+ *: fication, are permitted provided that the following conditions are met:
+ *: * Redistributions of source code must retain the above copyright
+ *: notice, this list of conditions and the following disclaimer.
+ *: * Redistributions in binary form must reproduce the above copyright
+ *: notice, this list of conditions and the following disclaimer in the
+ *: documentation and/or other materials provided with the distribution.
+ *: * Neither the name of P. B. Labs nor the names of its contributors may
+ *: be used to endorse or promote products derived from this software
+ *: without specific prior written permission.
+ *:
+ *: THIS SOFTWARE IS PROVIDED BY Paul Buetow AS IS'' AND ANY EXPRESS OR
+ *: IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ *: WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ *: DISCLAIMED. IN NO EVENT SHALL Paul Buetow BE LIABLE FOR ANY DIRECT,
+ *: INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ *: (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ *: SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ *: HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ *: STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ *: IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ *: POSSIBILITY OF SUCH DAMAGE.
+ *:*/
+
+#include "tree.h"
+
+Tree*
+tree_new() {
+ Tree *p_tree = malloc(sizeof(Tree));
+
+ p_tree->p_treenode_root = NULL;
+
+ return p_tree;
+}
+
+
+void
+tree_delete(Tree *p_tree) {
+ if (!p_tree)
+ return;
+
+ if (p_tree->p_treenode_root)
+ treenode_delete(p_tree->p_treenode_root);
+
+ free(p_tree);
+}
+
+void _tree_print(TreeNode *p_treenode, int i_indent);
+
+void _indent(int i_indent) {
+ for (int i = 0; i < i_indent; ++i)
+ if (i % TREE_PRINT_INDENT)
+ printf(" ");
+ else
+ printf("|");
+}
+
+void
+_tree_print_cb2(void *p_void, void *p_indent) {
+ _tree_print(p_void, (int) p_indent);
+}
+
+void
+_tree_print_cb(void *p_void, void *p_indent) {
+ TreeNode *ptn = p_void;
+ _indent((int) p_indent);
+
+#ifdef FYPE
+ TokenType tt = (TokenType) treenode_get_val(ptn);
+
+ if (IS_NOT_TERMINAL(tt))
+ goto no_token_val;
+
+ Token *p_token = treenode_get_val2(ptn);
+
+ if (!p_token)
+ goto no_token_val;
+
+ char *c_token_val = token_get_val(p_token);
+ TokenType tt_token = token_get_tt(p_token);
+
+ if (!c_token_val)
+ c_token_val = "";
+
+ printf(" %s=%s", tt_get_name(tt_token), c_token_val);
+ return;
+
+no_token_val:
+ printf(" %s", tt_get_name(tt));
+
+#else
+ printf(" %d", (int) treenode_get_val(ptn));
+#endif
+}
+
+void
+_tree_print(TreeNode *p_treenode, int i_indent) {
+ TokenType tt = (TokenType)treenode_get_val(p_treenode);
+
+#ifdef FYPE
+ _Bool b_print_nl = false;
+ if (IS_NOT_TERMINAL(tt)) {
+ _indent(i_indent);
+ printf("%s:", tt_get_name(tt));
+ b_print_nl = true;
+ }
+#else
+ _indent(i_indent);
+ printf("%s:", tt_get_name(tt));
+#endif
+
+ array_iterate2(p_treenode->p_array_childs, _tree_print_cb, (void*) 0);
+
+#ifdef FYPE
+ if (b_print_nl)
+#endif
+ printf("\nTree ");
+
+ array_iterate2(p_treenode->p_array_childs, _tree_print_cb2, (void*) (i_indent + TREE_PRINT_INDENT));
+}
+
+void
+tree_print(Tree *p_tree) {
+ if (!p_tree)
+ return;
+
+ printf("\nTree ");
+ _tree_print(tree_get_root(p_tree), 0);
+ printf("\n");
+}
+
+TreeNode*
+treenode_new(void *p_val) {
+ return treenode_new2(p_val, NULL);
+}
+
+TreeNode*
+treenode_new2(void *p_val, void *p_val2) {
+ TreeNode *p_treenode = malloc(sizeof(TreeNode));
+
+ p_treenode->tnt = IS_LEAF;
+ p_treenode->p_array_childs = array_new();
+ p_treenode->p_val = p_val;
+ p_treenode->p_val2 = p_val2;
+
+ return p_treenode;
+}
+
+void
+treenode_delete(TreeNode *p_treenode) {
+ if (!p_treenode)
+ return;
+
+ int i_size = array_get_size(p_treenode->p_array_childs);
+
+ for (int i = 0; i < i_size; ++i)
+ treenode_delete(array_get(p_treenode->p_array_childs, i));
+
+ array_delete(p_treenode->p_array_childs);
+
+ free(p_treenode);
+}
+
+void
+treenode_insert_left(TreeNode *p_treenode, TreeNode *p_treenode2) {
+ array_unshift(p_treenode->p_array_childs, p_treenode2);
+}
+
+void
+treenode_insert_right(TreeNode *p_treenode, TreeNode *p_treenode2) {
+ array_push(p_treenode->p_array_childs, p_treenode2);
+}
+
+TreeIteratorState*
+treeiteratorstate_new(TreeNode *ptn) {
+ TreeIteratorState *p_state = malloc(sizeof(TreeIteratorState));
+
+ p_state->ptn = ptn;
+ p_state->i_pos = 0;
+
+ return p_state;
+}
+
+void
+treeiteratorstate_delete(TreeIteratorState *p_state) {
+ free(p_state);
+}
+
+TreeIterator*
+treeiterator_new(Tree *p_tree) {
+ TreeIterator *p_iter = malloc(sizeof(TreeIterator));
+
+ p_iter->p_stack = stack_new();
+ p_iter->p_state = treeiteratorstate_new(tree_get_root(p_tree));
+
+ return p_iter;
+}
+
+void
+treeiterator_delete(TreeIterator *p_iter) {
+ while (!stack_empty(p_iter->p_stack))
+ treeiteratorstate_delete(stack_pop(p_iter->p_stack));
+
+ stack_delete(p_iter->p_stack);
+
+ if (p_iter->p_state)
+ treeiteratorstate_delete(p_iter->p_state);
+}
+
+_Bool
+treeiterator_has_next(TreeIterator *p_iter) {
+ return p_iter->p_state != NULL;
+}
+
+TreeNode*
+treeiterator_next(TreeIterator *p_iter) {
+ if (!treeiterator_has_next(p_iter))
+ return NULL;
+
+ TreeNode *ptn = p_iter->p_state->ptn;
+
+ Array *p_array_childs = treenode_get_childs(ptn);
+ int i_num_childs = array_get_size(p_array_childs);
+
+ if (p_iter->p_state->i_pos >= i_num_childs) {
+ treeiteratorstate_delete(p_iter->p_state);
+
+ p_iter->p_state =
+ stack_empty(p_iter->p_stack) ? NULL : stack_pop(p_iter->p_stack);
+
+ return ptn;
+ }
+
+ TreeNode *ptn_next = array_get(p_array_childs, p_iter->p_state->i_pos++);
+ stack_push(p_iter->p_stack, p_iter->p_state);
+ p_iter->p_state = treeiteratorstate_new(ptn_next);
+
+ return ptn;
+}
+