return ret;
}
+
+tree_t* tree_walk(tree_t* tree, tree_walker_t* walker)
+{
+ size_t idx;
+ tree_t* new_node;
+ new_node = walker->fn(walker->env, tree, PRE_NODE);
+ if (tree->tag == TREE) {
+ walker->fn(walker->env, tree, PRE_CHILDREN);
+ for (idx = 0; idx < vec_size(tree->ptr.vec); idx++) {
+ tree_t* child = vec_at(tree->ptr.vec, idx);
+ walker->fn(walker->env, tree, PRE_CHILD);
+ tree_t* new_child = tree_walk( child, walker );
+ walker->fn(walker->env, tree, POST_CHILD);
+ if ((NULL != new_node) && (new_node->tag == TREE) && (NULL != new_child)) {
+ vec_push_back(new_node->ptr.vec, new_child);
+ }
+ }
+ walker->fn(walker->env, tree, POST_CHILDREN);
+ }
+ return new_node;
+}
+
+tree_walker_t* tree_walker(void* env, tree_walk_fn_t fn)
+{
+ tree_walker_t* p_walker = (tree_walker_t*)mem_allocate(sizeof(tree_walker_t),NULL);
+ p_walker->env = env;
+ p_walker->fn = fn;
+ return p_walker;
+}
+
} ptr;
} tree_t;
+typedef enum {
+ PRE_NODE,
+ POST_NODE,
+ PRE_CHILDREN,
+ POST_CHILDREN,
+ PRE_CHILD,
+ POST_CHILD,
+} tree_walk_pos_t;
+
+typedef tree_t* (*tree_walk_fn_t)(void* env, tree_t* node, tree_walk_pos_t pos);
+
+typedef struct {
+ void* env;
+ tree_walk_fn_t fn;
+} tree_walker_t;
+
tree_t* tree_convert(tree_t* p_tree);
tree_t* tree_new(tree_tag_t tag, void* p_obj);
tree_t* tree_get_child(tree_t* p_tree, size_t idx);
void* tree_get_val(tree_t* p_tree);
void* tree_get_child_val(tree_t* p_tree, size_t idx);
bool tree_is_formtype(tree_t* p_tree, const char* val);
+tree_t* tree_walk(tree_t* tree, tree_walker_t* walker);
+tree_walker_t* tree_walker(void* env, tree_walk_fn_t fn);
#endif /* TREE_H */