summaryrefslogtreecommitdiff
path: root/src/data
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
parent33c945e58f86267b0d3bdca4c3421155e11eb0d9 (diff)
Moved stuff into trunk.
Diffstat (limited to 'src/data')
-rw-r--r--src/data/array.c266
-rw-r--r--src/data/array.h86
-rw-r--r--src/data/dat.c267
-rw-r--r--src/data/dat.h88
-rw-r--r--src/data/hash.c290
-rw-r--r--src/data/hash.h80
-rw-r--r--src/data/list.c458
-rw-r--r--src/data/list.h105
-rw-r--r--src/data/map.c283
-rw-r--r--src/data/map.h82
-rw-r--r--src/data/queue.c210
-rw-r--r--src/data/queue.h81
-rw-r--r--src/data/stack.c234
-rw-r--r--src/data/stack.h76
-rw-r--r--src/data/tree.c250
-rw-r--r--src/data/tree.h106
-rw-r--r--src/data/tupel.c53
-rw-r--r--src/data/tupel.h47
-rw-r--r--src/data/types.h64
19 files changed, 3126 insertions, 0 deletions
diff --git a/src/data/array.c b/src/data/array.c
new file mode 100644
index 0000000..e893a6d
--- /dev/null
+++ b/src/data/array.c
@@ -0,0 +1,266 @@
+/*:*
+ *: File: ./src/data/array.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 "array.h"
+
+Array*
+array_new() {
+ Array *p_array = malloc(sizeof(Array));
+
+ p_array->i_size = 0;
+ p_array->pp_ae = NULL;
+
+ return p_array;
+}
+
+
+void
+array_delete(Array *p_array) {
+ if (!p_array)
+ return;
+
+ if (p_array->i_size)
+ for (int i = p_array->i_size - 1; i >= 0; --i)
+ arrayelement_delete(p_array->pp_ae[i]);
+
+ if (p_array->pp_ae)
+ free(p_array->pp_ae);
+
+ free(p_array);
+}
+
+void
+array_set(Array *p_array, int i_index, void *p_val) {
+ if (p_array->i_size > i_index) {
+ p_array->pp_ae[i_index]->p_val = p_val;
+
+ } else {
+ array_resize(p_array, i_index + 1);
+ p_array->pp_ae[i_index]->p_val = p_val;
+ }
+}
+
+void
+array_insert(Array *p_array, int i_index, void *p_val) {
+ if (p_array->i_size <= i_index) {
+ array_set(p_array, i_index, p_val);
+
+ } else {
+ array_resize(p_array, p_array->i_size + 1);
+
+ ArrayElement *p_ae = p_array->pp_ae[p_array->i_size-1];
+ int i;
+ for (i = p_array->i_size - 1; i > i_index; --i)
+ p_array->pp_ae[i] = p_array->pp_ae[i-1];
+
+ p_array->pp_ae[i] = p_ae;
+ p_ae->p_val = p_val;
+ }
+}
+
+void*
+array_remove(Array *p_array, int i_index) {
+ if (p_array->i_size <= i_index)
+ return NULL;
+
+ ArrayElement *p_ae = p_array->pp_ae[i_index];
+ void *p_ret = p_ae->p_val;
+ int i;
+
+ for (i = i_index+1; i < p_array->i_size; ++i)
+ p_array->pp_ae[i-1] = p_array->pp_ae[i];
+
+ p_array->pp_ae[i-1] = p_ae;
+
+ array_resize(p_array, p_array->i_size - 1);
+
+ return p_ret;
+}
+
+void
+array_print_int(Array *p_array) {
+ printf("Array:");
+ for (int i = 0; i < p_array->i_size; ++i)
+ printf(" (%d,%d)", i, (int) array_get(p_array, i));
+ printf("\n");
+}
+
+void
+array_resize(Array *p_array, int i_size) {
+ if (i_size == p_array->i_size)
+ return;
+
+ if (i_size < p_array->i_size)
+ for (int i = p_array->i_size - 1; i >= i_size; --i)
+ arrayelement_delete(p_array->pp_ae[i]);
+
+ if (i_size == 0) {
+ free(p_array->pp_ae);
+ p_array->pp_ae = NULL;
+
+ } else if (p_array->pp_ae != NULL) {
+ p_array->pp_ae = realloc(p_array->pp_ae,
+ sizeof(ArrayElement) * i_size);
+
+ } else {
+ p_array->pp_ae = malloc(sizeof(ArrayElement) * i_size);
+ }
+
+ if (i_size > p_array->i_size)
+ for (int i = p_array->i_size; i < i_size; ++i)
+ p_array->pp_ae[i] = arrayelement_new(NULL);
+
+ p_array->i_size = i_size;
+}
+
+void*
+array_get(Array *p_array, int i_index) {
+ if (p_array->i_size > i_index)
+ return p_array->pp_ae[i_index]->p_val;
+
+ return NULL;
+}
+
+_Bool
+array_defined(Array *p_array, int i_index) {
+ if (i_index >= p_array->i_size)
+ return false;
+
+ return p_array->pp_ae[i_index]->p_val != NULL;
+}
+
+void
+array_splice(Array *p_array, int i_index, Array *p_array2) {
+ if (i_index >= array_get_size(p_array))
+ return;
+
+ array_remove(p_array, i_index);
+
+ int i_size1= array_get_size(p_array);
+ int i_size2 = array_get_size(p_array2);
+ int i_size = i_size1 + i_size2;
+
+ array_resize(p_array, i_size);
+
+ for (int i = i_size1 - 1; i >= i_index; --i)
+ p_array->pp_ae[i+i_size2]->p_val = p_array->pp_ae[i]->p_val;
+
+ for (int i = 0; i < i_size2; ++i)
+ p_array->pp_ae[i+i_index]->p_val = p_array2->pp_ae[i]->p_val;
+
+}
+
+void
+array_unshift(Array *p_array, void *p_void) {
+ int i_size = array_get_size(p_array);
+ array_set(p_array, i_size, p_void);
+}
+
+void
+array_push(Array *p_array, void *p_void) {
+ int i_size = array_get_size(p_array);
+ array_resize(p_array, ++i_size);
+
+ for (int i = i_size - 1; i > 0; --i)
+ p_array->pp_ae[i]->p_val = p_array->pp_ae[i-1]->p_val;
+
+ array_set(p_array, 0, p_void);
+}
+
+void
+array_iterate(Array *p_array, void (*func)(void *)) {
+ if (!p_array)
+ return;
+
+ for (int i = 0; i < array_get_size(p_array); ++i)
+ (*func) (array_get(p_array, i));
+}
+
+void
+array_iterate2(Array *p_array, void (*func)(void *, void *), void *p_void) {
+ if (!p_array)
+ return;
+
+ for (int i = 0; i < array_get_size(p_array); ++i)
+ (*func) (array_get(p_array, i), p_void);
+}
+
+ArrayElement*
+arrayelement_new(void *p_val) {
+ ArrayElement *p_ae = malloc(sizeof(ArrayElement));
+
+ p_ae->p_val = p_val;
+
+ return p_ae;
+}
+
+void
+arrayelement_delete(ArrayElement *p_ae) {
+ if (!p_ae)
+ return;
+
+ free(p_ae);
+}
+
+ArrayIterator*
+arrayiterator_new(Array *p_array) {
+ if (!p_array)
+ return NULL;
+
+ ArrayIterator *p_arrayiterator = malloc(sizeof(ArrayIterator));
+ p_arrayiterator->p_array = p_array;
+ p_arrayiterator->i_cur_pos = 0;
+
+ return p_arrayiterator;
+}
+
+void
+arrayiterator_delete(ArrayIterator *p_arrayiterator) {
+ if (p_arrayiterator)
+ free(p_arrayiterator);
+}
+
+_Bool
+arrayiterator_has_next(ArrayIterator *p_arrayiterator) {
+ return p_arrayiterator->i_cur_pos <
+ array_get_size(p_arrayiterator->p_array);
+}
+
+void*
+arrayiterator_next(ArrayIterator *p_arrayiterator) {
+ if (!arrayiterator_has_next(p_arrayiterator))
+ return NULL;
+
+ return array_get(p_arrayiterator->p_array, p_arrayiterator->i_cur_pos++);
+}
diff --git a/src/data/array.h b/src/data/array.h
new file mode 100644
index 0000000..a60fa03
--- /dev/null
+++ b/src/data/array.h
@@ -0,0 +1,86 @@
+/*:*
+ *: File: ./src/data/array.h
+ *: 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.
+ *:*/
+
+#ifndef ARRAY_H
+#define ARRAY_H
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "../defines.h"
+
+#define array_get_size(a) a->i_size
+#define array_empty(a) a->i_size == 0
+#define array_clear(a) array_resize(a, 0)
+#define array_get_first(a) array_get(a, 0)
+#define array_get_last(a) array_get(a, array_get_size(a)-1)
+
+typedef struct {
+ void *p_val;
+} ArrayElement;
+
+typedef struct {
+ ArrayElement **pp_ae;
+ int i_size;
+} Array;
+
+typedef struct {
+ Array *p_array;
+ int i_cur_pos;
+} ArrayIterator;
+
+Array *array_new();
+void array_delete(Array *p_array);
+void array_set(Array *p_array, int i_index, void *p_val);
+void array_insert(Array *p_array, int i_index, void *p_val);
+void *array_remove(Array *p_array, int i_index);
+void *array_get(Array *p_array, int i_index);
+void array_resize(Array *p_array, int i_size);
+_Bool array_defined(Array *p_array, int i_index);
+void array_print_int(Array *p_array);
+void array_splice(Array *p_array, int i_index, Array *p_array2);
+void array_push(Array *p_array, void *p_void);
+void array_unshift(Array *p_array, void *p_void);
+void array_iterate(Array *p_array, void (*func)(void *));
+void array_iterate2(Array *p_array, void (*func)(void *, void *),
+ void *p_void);
+
+ArrayElement *arrayelement_new(void *p_val);
+void arrayelement_delete(ArrayElement *p_ae);
+
+ArrayIterator *arrayiterator_new(Array *p_array);
+void arrayiterator_delete(ArrayIterator *p_arrayiterator);
+_Bool arrayiterator_has_next(ArrayIterator *p_arrayiterator);
+void *arrayiterator_next(ArrayIterator *p_arrayiterator);
+#endif
diff --git a/src/data/dat.c b/src/data/dat.c
new file mode 100644
index 0000000..1becf25
--- /dev/null
+++ b/src/data/dat.c
@@ -0,0 +1,267 @@
+/*:*
+ *: File: ./src/data/dat.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 "dat.h"
+
+#include <stdlib.h>
+
+Dat*
+dat_new() {
+ Dat *p_dat = (Dat *) malloc(sizeof(Dat));
+
+ p_dat->p_first = 0;
+ p_dat->p_last = 0;
+ p_dat->i_size = 0;
+
+ return p_dat;
+}
+
+DatElem*
+datelem_new() {
+ return datelem_new_t(TYPE_UNKNOWN);
+}
+
+DatElem*
+datelem_new_t(TYPE type) {
+ DatElem *p_elem = (DatElem *) malloc(sizeof(DatElem));
+
+ p_elem->p_next = 0;
+ p_elem->p_val = 0;
+ p_elem->type = type;
+
+ return p_elem;
+}
+
+_Bool
+dat_empty(Dat *p_dat) {
+ if (p_dat == NULL)
+ return 0;
+
+ return p_dat->i_size == 0;
+}
+
+void
+dat_push(Dat *p_dat, void *p_val) {
+ dat_push_t(p_dat, p_val, TYPE_UNKNOWN);
+}
+
+void
+dat_push_t(Dat *p_dat, void *p_val, TYPE type) {
+ DatElem *p_elem = datelem_new_t(type);
+ p_elem->p_val = p_val;
+
+ if (0 == p_dat->i_size++)
+ p_dat->p_first = p_elem;
+ else
+ p_dat->p_last->p_next = p_elem;
+
+ p_dat->p_last = p_elem;
+}
+
+void*
+dat_pop(Dat *p_dat) {
+ TYPE type;
+ return dat_pop_t(p_dat, &type);
+}
+
+void*
+dat_pop_t(Dat *p_dat, TYPE *p_type) {
+ if (dat_empty(p_dat))
+ return 0;
+
+ DatElem *p_elem = p_dat->p_first;
+ p_dat->p_first = p_elem->p_next;
+
+ --p_dat->i_size;
+
+ void *p_ret = p_elem->p_val;
+ *p_type = p_elem->type;
+ free(p_elem);
+ return p_ret;
+}
+
+void
+dat_clear(Dat *p_dat) {
+ for (;!dat_empty(p_dat); dat_pop(p_dat));
+}
+
+void
+dat_delete(Dat *p_dat) {
+ dat_clear(p_dat);
+ free(p_dat);
+}
+
+unsigned
+dat_size(Dat *p_dat) {
+ return p_dat->i_size;
+}
+
+void
+dat_iterate(Dat *p_dat, void (*func)(void *)) {
+ DatElem *p_elem = p_dat->p_first;
+ while (p_elem) {
+ if (p_elem->p_val)
+ (*func) (p_elem->p_val);
+
+ p_elem = p_elem->p_next;
+ }
+}
+
+void
+dat_iterate_t(Dat *p_dat, void (*func)(void *, TYPE)) {
+ DatElem *p_elem = p_dat->p_first;
+ while (p_elem) {
+ if (p_elem->p_val)
+ (*func) (p_elem->p_val, p_elem->type);
+
+ p_elem = p_elem->p_next;
+ }
+}
+
+void
+dat_iterate_tl(Dat *p_dat, void (*func)(void *, TYPE, _Bool)) {
+ DatElem *p_elem = p_dat->p_first;
+ while (p_elem) {
+ if (p_elem->p_val)
+ (*func) (p_elem->p_val, p_elem->type, p_elem->p_next == NULL);
+
+ p_elem = p_elem->p_next;
+ }
+}
+
+void*
+dat_first(Dat *p_dat) {
+ if (dat_empty(p_dat))
+ return NULL;
+
+ return p_dat->p_first->p_val;
+}
+
+void*
+dat_second(Dat *p_dat) {
+ if ( 2 > dat_size(p_dat))
+ return NULL;
+
+ return p_dat->p_first->p_next->p_val;
+}
+
+void*
+dat_last(Dat *p_dat) {
+ if (dat_empty(p_dat))
+ return NULL;
+
+ return p_dat->p_last->p_val;
+}
+
+void*
+dat_first_t(Dat *p_dat, TYPE *p_type) {
+ if (dat_empty(p_dat))
+ return NULL;
+
+ *p_type = p_dat->p_first->type;
+ return p_dat->p_first->p_val;
+}
+
+void*
+dat_second_t(Dat *p_dat, TYPE *p_type) {
+ if ( 2 > dat_size(p_dat))
+ return NULL;
+
+ *p_type = p_dat->p_first->p_next->type;
+ return p_dat->p_first->p_next->p_val;
+}
+
+void*
+dat_last_t(Dat *p_dat, TYPE *p_type) {
+ if (dat_empty(p_dat))
+ return NULL;
+
+ *p_type = p_dat->p_last->type;
+ return p_dat->p_last->p_val;
+}
+
+DatIter*
+datiter_new(Dat *p_dat) {
+ DatIter *p_iter =
+ (DatIter *) malloc(sizeof(DatIter));
+
+ p_iter->p_current = NULL;
+ p_iter->p_next = p_dat->p_first;
+ p_iter->i_left = dat_size(p_dat);
+ p_iter->p_dat = p_dat;
+
+ return p_iter;
+}
+
+void
+datiter_delete(DatIter *p_iter) {
+ free(p_iter);
+}
+
+void
+datiter_skip(DatIter *p_iter, unsigned i_num) {
+ for (int i = 0; i < i_num; ++i)
+ datiter_next(p_iter);
+}
+
+void*
+datiter_next(DatIter *p_iter) {
+ TYPE type;
+ return datiter_next_t(p_iter, &type);
+}
+
+void*
+datiter_next_t(DatIter *p_iter, TYPE *p_type) {
+ if (p_iter->p_next == NULL)
+ return NULL;
+
+ void *p_ret = p_iter->p_next->p_val;
+ *p_type = p_iter->p_next->type;
+ p_iter->p_current = p_iter->p_next;
+ p_iter->p_next = p_iter->p_next->p_next;
+ --p_iter->i_left;
+
+ return p_ret;
+}
+
+unsigned
+datiter_left(DatIter *p_iter) {
+ return p_iter->i_left;
+}
+
+Dat*
+datiter_dat(DatIter *p_iter) {
+ return p_iter->p_dat;
+}
+
diff --git a/src/data/dat.h b/src/data/dat.h
new file mode 100644
index 0000000..82264e4
--- /dev/null
+++ b/src/data/dat.h
@@ -0,0 +1,88 @@
+/*:*
+ *: File: ./src/data/dat.h
+ *: 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.
+ *:*/
+
+#ifndef DAT_H
+#define DAT_H
+
+#include "types.h"
+
+typedef struct DatElem_ {
+ struct DatElem_ *p_next;
+ void *p_val;
+ TYPE type;
+} DatElem;
+
+typedef struct {
+ DatElem *p_first;
+ DatElem *p_last;
+ unsigned i_size;
+} Dat;
+
+typedef struct {
+ unsigned i_left;
+ Dat *p_dat;
+ DatElem *p_current;
+ DatElem *p_next;
+} DatIter;
+
+Dat *dat_new();
+DatElem *datelem_new();
+DatElem *datelem_new_t(TYPE type);
+_Bool dat_empty(Dat *p_dat);
+void dat_push(Dat *p_dat, void *p_val);
+void dat_push_t(Dat *p_dat, void *p_val, TYPE type);
+void *dat_pop(Dat *p_dat);
+void *dat_pop_t(Dat *p_dat, TYPE *p_type);
+void dat_clear(Dat *p_dat);
+void dat_delete(Dat *p_dat);
+unsigned dat_size(Dat *p_dat);
+void dat_iterate(Dat *p_dat, void (*func)(void *));
+void dat_iterate_t(Dat *p_dat, void (*func)(void *, TYPE));
+void dat_iterate_tl(Dat *p_dat, void (*func)(void *, TYPE, _Bool));
+void *dat_first(Dat *p_dat);
+void *dat_second(Dat *p_dat);
+void *dat_last(Dat *p_dat);
+void *dat_first_t(Dat *p_dat, TYPE *p_type);
+void *dat_second_t(Dat *p_dat, TYPE *p_type);
+void *dat_last_t(Dat *p_dat, TYPE *p_type);
+
+DatIter *datiter_new(Dat *p_dat);
+void datiter_delete(DatIter *p_iter);
+void datiter_skip(DatIter *p_iter, unsigned i_num);
+void *datiter_next(DatIter *p_iter);
+void *datiter_next_t(DatIter *p_iter, TYPE *p_type);
+unsigned datiter_left(DatIter *p_iter);
+Dat *datiter_dat(DatIter *p_iter);
+
+#endif
diff --git a/src/data/hash.c b/src/data/hash.c
new file mode 100644
index 0000000..cc32a6b
--- /dev/null
+++ b/src/data/hash.c
@@ -0,0 +1,290 @@
+/*:*
+ *: File: ./src/data/hash.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 "hash.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+Hash*
+hash_new(unsigned i_size) {
+ Hash *p_hash = (Hash *) malloc(sizeof(Hash));
+
+ p_hash->i_size = i_size;
+ p_hash->i_cur_size = 0;
+ p_hash->p_elems = (HashElem *) calloc(i_size, sizeof(HashElem));
+
+ /*Set all positions as "free" */
+ for (int i = 0; i < i_size; ++i)
+ p_hash->p_elems[i].flag = 'f';
+
+ return p_hash;
+}
+
+void
+hash_delete(Hash *p_hash) {
+ if (p_hash->p_elems) {
+ free(p_hash->p_elems);
+ p_hash->p_elems = 0;
+ }
+
+ free(p_hash);
+}
+
+RETCODE
+hash_insert_ht(Hash *p_hash, char *c_key, void *p_val, TYPE type) {
+ if (p_hash->i_cur_size == p_hash->i_size)
+ hash_size(p_hash, p_hash->i_size *2);
+
+ int i_addr = hash_getaddr(p_hash, c_key, free_ADDR);
+
+ if (i_addr == RET_ERROR )
+ return RET_NO_SPACE;
+
+ strncpy(p_hash->p_elems[i_addr].c_key, c_key, HASH_MKEYLEN);
+
+ p_hash->p_elems[i_addr].flag = 'o';
+ p_hash->p_elems[i_addr].type = type;
+ p_hash->p_elems[i_addr].p_val = p_val;
+ p_hash->i_cur_size++;
+
+ return RET_OK;
+}
+
+RETCODE
+hash_insert(Hash *p_hash, char *c_key, void *p_val) {
+ return hash_insert_ht(p_hash, c_key, p_val, TYPE_VOIDP);
+}
+
+void*
+hash_remove(Hash *p_hash, char *c_key) {
+ if (p_hash->i_cur_size < p_hash->i_size / 3)
+ hash_size(p_hash, p_hash->i_size / 2);
+
+ int i_addr = hash_getaddr(p_hash, c_key, OCC_ADDR);
+
+ if (i_addr == -1 )
+ return 0;
+
+ void *p_val = p_hash->p_elems[i_addr].p_val;
+ p_hash->p_elems[i_addr].flag = 'm';
+ p_hash->p_elems[i_addr].p_val = 0;
+ --p_hash->i_cur_size;
+
+ return p_val;
+}
+
+void*
+hash_get_ht(Hash *p_hash, char *c_key, TYPE *p_type) {
+ int i_addr;
+ return hash_get_ht_addr(p_hash, c_key, p_type, &i_addr);
+}
+
+void*
+hash_get_ht_addr(Hash *p_hash, char *c_key, TYPE *p_type, int *p_addr) {
+ int i_addr = *p_addr = hash_getaddr(p_hash, c_key, OCC_ADDR);
+
+ if (i_addr == -1 )
+ return 0;
+
+ *p_type = p_hash->p_elems[i_addr].type;
+ return p_hash->p_elems[i_addr].p_val;
+}
+
+void*
+hash_get(Hash *p_hash, char *c_key) {
+ TYPE type;
+ return hash_get_ht(p_hash, c_key, &type);
+}
+
+int
+hash_getaddr(Hash *p_hash, char *c_key, HASH_OP OP) {
+ int i_len = strlen(c_key);
+ int i_addr = 0;
+
+ if (i_len > HASH_MKEYLEN) {
+ ERROR(": Key length %d is greater than HASH_MKEYLEN = %d!",
+ i_len, HASH_MKEYLEN);
+ //i_len = HASH_MKEYLEN;
+ }
+
+ for (int i= 0; i < i_len; ++i)
+ i_addr = (i_addr *p_hash->i_size + (int) c_key[i]) % p_hash->i_size;
+
+ switch (OP) {
+ case free_ADDR:
+ if (!hash_addrisfree(p_hash,i_addr))
+ return i_addr;
+ break;
+
+ case OCC_ADDR:
+ if (!hash_addrisocc(p_hash,i_addr, c_key))
+ return i_addr;
+ break;
+
+ default:
+ return RET_ERROR;
+ }
+
+ return hash_nextaddr(p_hash, p_hash->i_size, c_key, i_addr, OP);
+}
+
+RETCODE
+hash_addrisfree(Hash *p_hash, int i_addr) {
+ if (p_hash->p_elems[i_addr].flag == 'f' ||
+ p_hash->p_elems[i_addr].flag == 'm')
+ return RET_OK;
+
+ return RET_ERROR;
+}
+
+RETCODE
+hash_addrisocc(Hash *p_hash, int i_addr, char *c_key) {
+ if (p_hash->p_elems[i_addr].flag == 'o' &&
+ !strcmp(p_hash->p_elems[i_addr].c_key, c_key))
+ return RET_OK;
+
+ return RET_ERROR;
+}
+
+int
+hash_nextaddr(Hash *p_hash, int i_max_tries, char *c_key, int i_addr,
+ HASH_OP OP) {
+ if ( --i_max_tries < 0 )
+ return RET_ERROR;
+
+ i_addr = (i_addr + 1) % p_hash->i_size;
+
+ switch (OP) {
+ case free_ADDR:
+ if (!hash_addrisfree(p_hash,i_addr))
+ return i_addr;
+ break;
+
+ case OCC_ADDR:
+ if (!hash_addrisocc(p_hash,i_addr, c_key))
+ return i_addr;
+ break;
+ }
+
+ return hash_nextaddr(p_hash, i_max_tries, c_key, i_addr, OP);
+}
+
+void
+hash_print(Hash *p_hash) {
+ printf("hash_print [size:%d,cur:%d] syntax (flag[,key][=TYPE[<val>]]):\n -> ",
+ p_hash->i_size,p_hash->i_cur_size);
+
+ for (int i = 0; i < p_hash->i_size; ++i) {
+ switch (p_hash->p_elems[i].flag) {
+ case 'f':
+ printf("(f");
+ break;
+ case 'm':
+ printf("(m,%s=", p_hash->p_elems[i].c_key);
+ hash_print_addrval(p_hash, i);
+ break;
+ case 'o':
+ printf("(o,%s=", p_hash->p_elems[i].c_key);
+ hash_print_addrval(p_hash, i);
+ break;
+ }
+ printf(") ");
+ }
+
+ printf("\n");
+
+}
+
+void
+hash_print_addrval(Hash *p_hash, int i_addr) {
+ switch (p_hash->p_elems[i_addr].type) {
+ case TYPE_NUMBER: {
+ double d_val = *(double *) p_hash->p_elems[i_addr].p_val;
+
+ if ( (int) d_val == d_val )
+ printf("TYPE_NUMBER<%.0f>",d_val);
+ else
+ printf("TYPE_NUMBER<%f>",d_val);
+ }
+ break;
+
+ case TYPE_STRING:
+ printf("TYPE_STRING<%s>", (char *) p_hash->p_elems[i_addr].p_val);
+ break;
+
+ case TYPE_VOIDP:
+ printf("TYPE_VOIDP");
+ break;
+
+ default:
+ printf("UNKNOWN");
+ break;
+ }
+}
+
+RETCODE
+hash_size(Hash *p_hash, int i_size) {
+ if (i_size < p_hash->i_cur_size) {
+ ERROR("The new hash has not enough elements"
+ "to contain the old hash!");
+ }
+
+ HashElem *p_old_elems = p_hash->p_elems;
+ unsigned i_old_size = p_hash->i_size;
+
+ p_hash->p_elems = (HashElem *) calloc(i_size, sizeof(HashElem));
+ p_hash->i_size = i_size;
+ p_hash->i_cur_size = 0;
+
+ /*Set all positions as "free" */
+ for (int i = 0; i < i_size; ++i)
+ p_hash->p_elems[i].flag = 'f';
+
+ for (int i = 0; i < i_old_size; ++i)
+ if (p_old_elems[i].flag == 'o')
+ hash_insert_ht(p_hash, p_old_elems[i].c_key,
+ p_old_elems[i].p_val, p_old_elems[i].type);
+
+ free(p_old_elems);
+ return RET_OK;
+}
+
+void
+hash_iterate(Hash *p_hash, void (*func)(void *)) {
+ for (int i = 0; i < p_hash->i_size; ++i)
+ if (p_hash->p_elems[i].flag == 'o')
+ (*func) (p_hash->p_elems[i].p_val);
+}
diff --git a/src/data/hash.h b/src/data/hash.h
new file mode 100644
index 0000000..8616549
--- /dev/null
+++ b/src/data/hash.h
@@ -0,0 +1,80 @@
+/*:*
+ *: File: ./src/data/hash.h
+ *: 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: